Index: include/clang/AST/PrettyDeclStackTrace.h =================================================================== --- include/clang/AST/PrettyDeclStackTrace.h +++ include/clang/AST/PrettyDeclStackTrace.h @@ -13,31 +13,31 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H -#define LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H +#ifndef LLVM_CLANG_AST_PRETTYDECLSTACKTRACE_H +#define LLVM_CLANG_AST_PRETTYDECLSTACKTRACE_H #include "clang/Basic/SourceLocation.h" #include "llvm/Support/PrettyStackTrace.h" namespace clang { +class ASTContext; class Decl; -class Sema; class SourceManager; /// PrettyDeclStackTraceEntry - If a crash occurs in the parser while /// parsing something related to a declaration, include that /// declaration in the stack trace. class PrettyDeclStackTraceEntry : public llvm::PrettyStackTraceEntry { - Sema &S; + ASTContext &Context; Decl *TheDecl; SourceLocation Loc; const char *Message; public: - PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc, + PrettyDeclStackTraceEntry(ASTContext &Ctx, Decl *D, SourceLocation Loc, const char *Msg) - : S(S), TheDecl(D), Loc(Loc), Message(Msg) {} + : Context(Ctx), TheDecl(D), Loc(Loc), Message(Msg) {} void print(raw_ostream &OS) const override; }; Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -27,6 +27,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/ODRHash.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Stmt.h" @@ -76,6 +77,24 @@ return D->getASTContext().getPrimaryMergedDecl(D); } +void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const { + SourceLocation Loc = this->Loc; + if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation(); + if (Loc.isValid()) { + Loc.print(OS, Context.getSourceManager()); + OS << ": "; + } + OS << Message; + + if (auto *ND = dyn_cast_or_null(TheDecl)) { + OS << " '"; + ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); + OS << "'"; + } + + OS << '\n'; +} + // Defined here so that it can be inlined into its direct callers. bool Decl::isOutOfLine() const { return !getLexicalDeclContext()->Equals(getDeclContext()); Index: lib/Frontend/CompilerInstance.cpp =================================================================== --- lib/Frontend/CompilerInstance.cpp +++ lib/Frontend/CompilerInstance.cpp @@ -1195,6 +1195,11 @@ llvm::CrashRecoveryContext CRC; CRC.RunSafelyOnThread( [&]() { + SmallString<64> CrashInfoMessage("While building module for '"); + CrashInfoMessage += ModuleName; + CrashInfoMessage += "'"; + llvm::PrettyStackTraceString CrashInfo(CrashInfoMessage.c_str()); + // FIXME: I have no idea what the best way to do this is, but it's // probably not this. Interfaces changed upstream. std::unique_ptr Action( Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -15,6 +15,7 @@ #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" @@ -22,7 +23,6 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/Optional.h" @@ -3940,7 +3940,7 @@ /// void Parser::ParseStructUnionBody(SourceLocation RecordLoc, unsigned TagType, Decl *TagDecl) { - PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, "parsing struct/union body"); assert(!getLangOpts().CPlusPlus && "C++ declarations not supported"); Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -14,6 +14,7 @@ #include "clang/Parse/Parser.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/OperatorKinds.h" @@ -22,7 +23,6 @@ #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/ParsedTemplate.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/SmallString.h" @@ -188,8 +188,8 @@ IdentLoc, Ident, T.getOpenLocation(), attrs.getList(), ImplicitUsingDirectiveDecl); - PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc, - "parsing namespace"); + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl, + NamespaceLoc, "parsing namespace"); // Parse the contents of the namespace. This includes parsing recovery on // any improperly nested namespaces. @@ -3112,7 +3112,7 @@ TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) && "Invalid TagType!"); - PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, "parsing struct/union/class body"); // Determine whether this is a non-nested class. Note that local Index: lib/Parse/ParseObjc.cpp =================================================================== --- lib/Parse/ParseObjc.cpp +++ lib/Parse/ParseObjc.cpp @@ -13,11 +13,11 @@ #include "clang/Parse/Parser.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/CharInfo.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -2683,7 +2683,7 @@ Decl *Parser::ParseObjCMethodDefinition() { Decl *MDecl = ParseObjCMethodPrototype(); - PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(), + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, MDecl, Tok.getLocation(), "parsing Objective-C method"); // parse optional ';' Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/LoopHint.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "clang/Sema/TypoCorrection.h" using namespace clang; @@ -1957,7 +1957,7 @@ assert(Tok.is(tok::l_brace)); SourceLocation LBraceLoc = Tok.getLocation(); - PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc, + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, LBraceLoc, "parsing function body"); // Save and reset current vtordisp stack if we have entered a C++ method body. @@ -1990,7 +1990,7 @@ assert(Tok.is(tok::kw_try) && "Expected 'try'"); SourceLocation TryLoc = ConsumeToken(); - PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc, + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, Decl, TryLoc, "parsing function try block"); // Constructor initializer list? Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -19,6 +19,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/AST/StmtCXX.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/PartialDiagnostic.h" @@ -31,7 +32,6 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/MultiplexExternalSemaSource.h" #include "clang/Sema/ObjCMethodList.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaConsumer.h" @@ -1507,24 +1507,6 @@ void ExternalSemaSource::ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector, 4>> &) {} -void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const { - SourceLocation Loc = this->Loc; - if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation(); - if (Loc.isValid()) { - Loc.print(OS, S.getSourceManager()); - OS << ": "; - } - OS << Message; - - if (auto *ND = dyn_cast_or_null(TheDecl)) { - OS << " '"; - ND->getNameForDiagnostic(OS, ND->getASTContext().getPrintingPolicy(), true); - OS << "'"; - } - - OS << '\n'; -} - /// \brief Figure out if an expression could be turned into a call. /// /// Use this when trying to recover from an error where the programmer may have Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -18,11 +18,11 @@ #include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/LangOptions.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" @@ -2011,7 +2011,7 @@ if (Inst.isInvalid()) return true; assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller"); - PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(), "instantiating class definition"); // Enter the scope of this instantiation. We don't use @@ -2238,7 +2238,7 @@ return true; if (Inst.isAlreadyInstantiating()) return false; - PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(), "instantiating enum definition"); // The instantiation is visible here, even if it was first declared in an @@ -2314,7 +2314,7 @@ << Instantiation; return true; } - PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(), "instantiating default member init"); // Enter the scope of this instantiation. We don't use PushDeclContext because Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -18,10 +18,10 @@ #include "clang/AST/DependentDiagnostic.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/AST/TypeLoc.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Template.h" using namespace clang; @@ -3912,7 +3912,7 @@ InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; - PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Function, SourceLocation(), "instantiating function definition"); // The instantiation is visible here, even if it was first declared in an @@ -4321,7 +4321,7 @@ InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable initializer"); // The instantiation is visible here, even if it was first declared in an @@ -4434,7 +4434,7 @@ InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable definition"); // If we're performing recursive template instantiation, create our own @@ -5238,7 +5238,7 @@ break; } - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable definition"); bool DefinitionRequired = Var->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; Index: lib/Serialization/ASTWriterDecl.cpp =================================================================== --- lib/Serialization/ASTWriterDecl.cpp +++ lib/Serialization/ASTWriterDecl.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/Expr.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/SourceManager.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" @@ -2215,6 +2216,9 @@ } void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { + PrettyDeclStackTraceEntry CrashInfo(Context, D, SourceLocation(), + "serializing"); + // Determine the ID for this declaration. serialization::DeclID ID; assert(!D->isFromASTFile() && "should not be emitting imported decl");