1 //===-- runtime/terminator.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // Termination of the image
10 
11 #ifndef FORTRAN_RUNTIME_TERMINATOR_H_
12 #define FORTRAN_RUNTIME_TERMINATOR_H_
13 
14 #include <cstdarg>
15 
16 namespace Fortran::runtime {
17 
18 // A mixin class for statement-specific image error termination
19 // for errors detected in the runtime library
20 class Terminator {
21 public:
Terminator()22   Terminator() {}
23   Terminator(const Terminator &) = default;
24   explicit Terminator(const char *sourceFileName, int sourceLine = 0)
25       : sourceFileName_{sourceFileName}, sourceLine_{sourceLine} {}
26 
sourceFileName()27   const char *sourceFileName() const { return sourceFileName_; }
sourceLine()28   int sourceLine() const { return sourceLine_; }
29 
30   void SetLocation(const char *sourceFileName = nullptr, int sourceLine = 0) {
31     sourceFileName_ = sourceFileName;
32     sourceLine_ = sourceLine;
33   }
34   [[noreturn]] void Crash(const char *message, ...) const;
35   [[noreturn]] void CrashArgs(const char *message, va_list &) const;
36   [[noreturn]] void CheckFailed(
37       const char *predicate, const char *file, int line) const;
38   [[noreturn]] void CheckFailed(const char *predicate) const;
39 
40   // For test harnessing - overrides CrashArgs().
41   static void RegisterCrashHandler(void (*)(const char *sourceFile,
42       int sourceLine, const char *message, va_list &ap));
43 
44 private:
45   const char *sourceFileName_{nullptr};
46   int sourceLine_{0};
47 };
48 
49 // RUNTIME_CHECK() guarantees evaluation of its predicate.
50 #define RUNTIME_CHECK(terminator, pred) \
51   if (pred) \
52     ; \
53   else \
54     (terminator).CheckFailed(#pred, __FILE__, __LINE__)
55 
56 #define INTERNAL_CHECK(pred) \
57   if (pred) \
58     ; \
59   else \
60     Terminator{__FILE__, __LINE__}.CheckFailed(#pred)
61 
62 void NotifyOtherImagesOfNormalEnd();
63 void NotifyOtherImagesOfFailImageStatement();
64 void NotifyOtherImagesOfErrorTermination();
65 } // namespace Fortran::runtime
66 
67 namespace Fortran::runtime::io {
68 void FlushOutputOnCrash(const Terminator &);
69 }
70 
71 #endif // FORTRAN_RUNTIME_TERMINATOR_H_
72