mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Basic] Rename abortWithPrettyStackTraceMessage to ABORT
Turn it into a wrapping macro that includes the file location, and move into `Assertions.h`.
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
#ifndef SWIFT_BASIC_ASSERTIONS_H
|
||||
#define SWIFT_BASIC_ASSERTIONS_H
|
||||
|
||||
#include "swift/Basic/LLVM.h"
|
||||
|
||||
// Only for use in this header
|
||||
#if __has_builtin(__builtin_expect)
|
||||
#define ASSERT_UNLIKELY(expression) (__builtin_expect(!!(expression), 0))
|
||||
@@ -183,4 +185,33 @@ extern int CONDITIONAL_ASSERT_Global_enable_flag;
|
||||
#define SWIFT_ASSERT_ONLY_DECL DEBUG_ASSERT_DECL
|
||||
#define SWIFT_ASSERT_ONLY DEBUG_ASSERT_EXPR
|
||||
|
||||
// ================================ Abort ======================================
|
||||
|
||||
/// Implementation for \c ABORT, not to be used directly.
|
||||
[[noreturn]]
|
||||
void _ABORT(const char *file, int line, const char *func,
|
||||
llvm::function_ref<void(llvm::raw_ostream &)> message);
|
||||
|
||||
/// Implementation for \c ABORT, not to be used directly.
|
||||
[[noreturn]]
|
||||
void _ABORT(const char *file, int line, const char *func,
|
||||
llvm::StringRef message);
|
||||
|
||||
// Aborts the program, printing a given message to a PrettyStackTrace frame
|
||||
// before exiting. This should be preferred over manually logging to stderr and
|
||||
// `abort()`'ing since that won't be picked up by the crash reporter.
|
||||
//
|
||||
// There are two different forms of ABORT:
|
||||
//
|
||||
// ```
|
||||
// ABORT("abort with string");
|
||||
//
|
||||
// ABORT([&](auto &out) {
|
||||
// out << "abort with arbitrary stream";
|
||||
// node.dump(out);
|
||||
// });
|
||||
// ```
|
||||
//
|
||||
#define ABORT(arg) _ABORT(_FILENAME_FOR_ASSERT, __LINE__, __func__, (arg))
|
||||
|
||||
#endif // SWIFT_BASIC_ASSERTIONS_H
|
||||
|
||||
@@ -50,19 +50,6 @@ public:
|
||||
void print(llvm::raw_ostream &OS) const override;
|
||||
};
|
||||
|
||||
/// Aborts the program, printing a given message to a PrettyStackTrace frame
|
||||
/// before exiting. This should be preferred over manually logging to stderr and
|
||||
/// aborting since that won't be picked up by the crash reporter.
|
||||
[[noreturn]]
|
||||
void abortWithPrettyStackTraceMessage(
|
||||
llvm::function_ref<void(llvm::raw_ostream &)> message);
|
||||
|
||||
/// Aborts the program, printing a given message to a PrettyStackTrace frame
|
||||
/// before exiting. This should be preferred over manually logging to stderr and
|
||||
/// aborting since that won't be picked up by the crash reporter.
|
||||
[[noreturn]]
|
||||
void abortWithPrettyStackTraceMessage(llvm::StringRef message);
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
#endif // SWIFT_BASIC_PRETTYSTACKTRACE_H
|
||||
|
||||
@@ -72,7 +72,7 @@ void ASTScopeImpl::dumpOneScopeMapLocation(
|
||||
|
||||
void ASTScopeImpl::abortWithVerificationError(
|
||||
llvm::function_ref<void(llvm::raw_ostream &)> messageFn) const {
|
||||
abortWithPrettyStackTraceMessage([&](auto &out) {
|
||||
ABORT([&](auto &out) {
|
||||
out << "ASTScopeImpl verification error in source file '"
|
||||
<< getSourceFile()->getFilename() << "':\n";
|
||||
messageFn(out);
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
#include <iostream>
|
||||
@@ -52,6 +54,9 @@ static void ASSERT_help() {
|
||||
llvm::errs() << " Continue after any failed assertion\n\n";
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
static inline void _abortWithMessage(llvm::StringRef message);
|
||||
|
||||
void ASSERT_failure(const char *expr, const char *filename, int line, const char *func) {
|
||||
// Find the last component of `filename`
|
||||
// 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
|
||||
int CONDITIONAL_ASSERT_enabled() {
|
||||
return (CONDITIONAL_ASSERT_Global_enable_flag != 0);
|
||||
}
|
||||
|
||||
// MARK: ABORT
|
||||
|
||||
namespace {
|
||||
/// Similar to PrettyStackTraceString, but formats multi-line strings for
|
||||
/// the stack trace.
|
||||
class PrettyStackTraceMultilineString : public llvm::PrettyStackTraceEntry {
|
||||
llvm::StringRef Str;
|
||||
|
||||
public:
|
||||
PrettyStackTraceMultilineString(llvm::StringRef str) : Str(str) {}
|
||||
void print(llvm::raw_ostream &OS) const override {
|
||||
// For each line, add a leading character and indentation to better match
|
||||
// the formatting of the stack trace.
|
||||
for (auto c : Str.rtrim('\n')) {
|
||||
OS << c;
|
||||
if (c == '\n')
|
||||
OS << "| \t";
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static void _abortWithMessage(llvm::StringRef message) {
|
||||
// Use a pretty stack trace to ensure the message gets picked up the
|
||||
// crash reporter.
|
||||
PrettyStackTraceMultilineString trace(message);
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
void _ABORT(const char *file, int line, const char *func,
|
||||
llvm::function_ref<void(llvm::raw_ostream &)> message) {
|
||||
llvm::SmallString<0> errorStr;
|
||||
llvm::raw_svector_ostream out(errorStr);
|
||||
out << "Abort: " << "function " << func << " at "
|
||||
<< file << ":" << line << "\n";
|
||||
message(out);
|
||||
|
||||
_abortWithMessage(errorStr);
|
||||
}
|
||||
|
||||
void _ABORT(const char *file, int line, const char *func,
|
||||
llvm::StringRef message) {
|
||||
_ABORT(file, line, func, [&](auto &out) { out << message; });
|
||||
}
|
||||
|
||||
@@ -202,13 +202,13 @@ void Mangler::verify(StringRef nameStr, ManglingFlavor Flavor) {
|
||||
Demangler Dem;
|
||||
NodePointer Root = Dem.demangleSymbol(nameStr);
|
||||
if (!Root || treeContains(Root, Node::Kind::Suffix)) {
|
||||
abortWithPrettyStackTraceMessage([&](auto &out) {
|
||||
ABORT([&](auto &out) {
|
||||
out << "Can't demangle: " << nameStr;
|
||||
});
|
||||
}
|
||||
auto mangling = mangleNode(Root, Flavor);
|
||||
if (!mangling.isSuccess()) {
|
||||
abortWithPrettyStackTraceMessage([&](auto &out) {
|
||||
ABORT([&](auto &out) {
|
||||
out << "Can't remangle: " << nameStr;
|
||||
});
|
||||
}
|
||||
@@ -216,7 +216,7 @@ void Mangler::verify(StringRef nameStr, ManglingFlavor Flavor) {
|
||||
if (Remangled == nameStr)
|
||||
return;
|
||||
|
||||
abortWithPrettyStackTraceMessage([&](auto &out) {
|
||||
ABORT([&](auto &out) {
|
||||
out << "Remangling failed:\n";
|
||||
out << "original = " << nameStr << "\n";
|
||||
out << "remangled = " << Remangled;
|
||||
|
||||
@@ -39,39 +39,3 @@ void PrettyStackTraceFileContents::print(llvm::raw_ostream &out) const {
|
||||
void PrettyStackTraceSwiftVersion::print(llvm::raw_ostream &out) const {
|
||||
out << version::getSwiftFullVersion() << '\n';
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// Similar to PrettyStackTraceString, but formats multi-line strings for
|
||||
/// the stack trace.
|
||||
class PrettyStackTraceMultilineString : public llvm::PrettyStackTraceEntry {
|
||||
StringRef Str;
|
||||
|
||||
public:
|
||||
PrettyStackTraceMultilineString(StringRef str) : Str(str) {}
|
||||
void print(raw_ostream &OS) const override {
|
||||
// For each line, add a leading character and indentation to better match
|
||||
// the formatting of the stack trace.
|
||||
for (auto c : Str.rtrim('\n')) {
|
||||
OS << c;
|
||||
if (c == '\n')
|
||||
OS << "| \t";
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
void swift::abortWithPrettyStackTraceMessage(
|
||||
llvm::function_ref<void(llvm::raw_ostream &)> message) {
|
||||
llvm::SmallString<0> errorStr;
|
||||
llvm::raw_svector_ostream out(errorStr);
|
||||
message(out);
|
||||
|
||||
PrettyStackTraceMultilineString trace(errorStr);
|
||||
abort();
|
||||
}
|
||||
|
||||
void swift::abortWithPrettyStackTraceMessage(StringRef message) {
|
||||
PrettyStackTraceMultilineString trace(message);
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -695,7 +695,7 @@ std::string ModuleFileSharedCore::Dependency::getPrettyPrintedPath() const {
|
||||
}
|
||||
|
||||
void ModuleFileSharedCore::fatal(llvm::Error error) const {
|
||||
abortWithPrettyStackTraceMessage([&](auto &out) {
|
||||
ABORT([&](auto &out) {
|
||||
out << "*** DESERIALIZATION FAILURE ***\n";
|
||||
out << "*** If any module named here was modified in the SDK, please delete the ***\n";
|
||||
out << "*** new swiftmodule files from the SDK and keep only swiftinterfaces. ***\n";
|
||||
|
||||
@@ -5337,7 +5337,7 @@ void Serializer::writeASTBlockEntity(const Decl *D) {
|
||||
SWIFT_DEFER {
|
||||
// This is important enough to leave on in Release builds.
|
||||
if (initialOffset == Out.GetCurrentBitNo()) {
|
||||
abortWithPrettyStackTraceMessage("failed to serialize anything");
|
||||
ABORT("failed to serialize anything");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6164,7 +6164,7 @@ void Serializer::writeASTBlockEntity(Type ty) {
|
||||
SWIFT_DEFER {
|
||||
// This is important enough to leave on in Release builds.
|
||||
if (initialOffset == Out.GetCurrentBitNo()) {
|
||||
abortWithPrettyStackTraceMessage("failed to serialize anything");
|
||||
ABORT("failed to serialize anything");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user