|
14 | 14 | // |
15 | 15 | //===----------------------------------------------------------------------===// |
16 | 16 |
|
| 17 | +#include "llvm/ADT/SmallString.h" |
17 | 18 | #include "llvm/Support/CommandLine.h" |
| 19 | +#include "llvm/Support/PrettyStackTrace.h" |
18 | 20 | #include "llvm/Support/raw_ostream.h" |
19 | 21 | #include "swift/Basic/Assertions.h" |
20 | 22 | #include <iostream> |
@@ -52,6 +54,9 @@ static void ASSERT_help() { |
52 | 54 | llvm::errs() << " Continue after any failed assertion\n\n"; |
53 | 55 | } |
54 | 56 |
|
| 57 | +[[noreturn]] |
| 58 | +static inline void _abortWithMessage(llvm::StringRef message); |
| 59 | + |
55 | 60 | void ASSERT_failure(const char *expr, const char *filename, int line, const char *func) { |
56 | 61 | // Find the last component of `filename` |
57 | 62 | // Needed on Windows MSVC, which lacks __FILE_NAME__ |
@@ -86,3 +91,50 @@ void ASSERT_failure(const char *expr, const char *filename, int line, const char |
86 | 91 | int CONDITIONAL_ASSERT_enabled() { |
87 | 92 | return (CONDITIONAL_ASSERT_Global_enable_flag != 0); |
88 | 93 | } |
| 94 | + |
| 95 | +// MARK: ABORT |
| 96 | + |
| 97 | +namespace { |
| 98 | +/// Similar to PrettyStackTraceString, but formats multi-line strings for |
| 99 | +/// the stack trace. |
| 100 | +class PrettyStackTraceMultilineString : public llvm::PrettyStackTraceEntry { |
| 101 | + llvm::StringRef Str; |
| 102 | + |
| 103 | +public: |
| 104 | + PrettyStackTraceMultilineString(llvm::StringRef str) : Str(str) {} |
| 105 | + void print(llvm::raw_ostream &OS) const override { |
| 106 | + // For each line, add a leading character and indentation to better match |
| 107 | + // the formatting of the stack trace. |
| 108 | + for (auto c : Str.rtrim('\n')) { |
| 109 | + OS << c; |
| 110 | + if (c == '\n') |
| 111 | + OS << "| \t"; |
| 112 | + } |
| 113 | + OS << '\n'; |
| 114 | + } |
| 115 | +}; |
| 116 | +} // end anonymous namespace |
| 117 | + |
| 118 | +static void _abortWithMessage(llvm::StringRef message) { |
| 119 | + // Use a pretty stack trace to ensure the message gets picked up the |
| 120 | + // crash reporter. |
| 121 | + PrettyStackTraceMultilineString trace(message); |
| 122 | + |
| 123 | + abort(); |
| 124 | +} |
| 125 | + |
| 126 | +void _ABORT(const char *file, int line, const char *func, |
| 127 | + llvm::function_ref<void(llvm::raw_ostream &)> message) { |
| 128 | + llvm::SmallString<0> errorStr; |
| 129 | + llvm::raw_svector_ostream out(errorStr); |
| 130 | + out << "Abort: " << "function " << func << " at " |
| 131 | + << file << ":" << line << "\n"; |
| 132 | + message(out); |
| 133 | + |
| 134 | + _abortWithMessage(errorStr); |
| 135 | +} |
| 136 | + |
| 137 | +void _ABORT(const char *file, int line, const char *func, |
| 138 | + llvm::StringRef message) { |
| 139 | + _ABORT(file, line, func, [&](auto &out) { out << message; }); |
| 140 | +} |
0 commit comments