From: Jordan Rose Date: Fri, 23 Mar 2018 00:07:18 +0000 (+0000) Subject: Sink PrettyDeclStackTrace down to the AST library X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5fe5d44d7f265c60c1faa0bb6b8506412dfbbc64;p=clang Sink PrettyDeclStackTrace down to the AST library ...and add some very basic stack trace entries for module building. This would have helped track down rdar://problem/38434694 sooner. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328276 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/AST/PrettyDeclStackTrace.h similarity index 81% rename from include/clang/Sema/PrettyDeclStackTrace.h rename to include/clang/AST/PrettyDeclStackTrace.h index ca22e640de..8eb519eae2 100644 --- a/include/clang/Sema/PrettyDeclStackTrace.h +++ b/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; }; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 35364d6abc..ed80dd8fca 100644 --- a/lib/AST/Decl.cpp +++ b/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 @@ Decl *clang::getPrimaryMergedDecl(Decl *D) { 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()); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index bb8b8572fa..1ed254d6ae 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -1170,6 +1170,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, llvm::CrashRecoveryContext CRC; CRC.RunSafelyOnThread( [&]() { + SmallString<64> CrashInfoMessage("While building module for '"); + CrashInfoMessage += ModuleName; + CrashInfoMessage += "'"; + llvm::PrettyStackTraceString CrashInfo(CrashInfoMessage.c_str()); + GenerateModuleFromModuleMapAction Action; Instance.ExecuteAction(Action); }, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index deefcaf325..f19bcaadf0 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/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" @@ -3908,7 +3908,7 @@ void Parser::ParseStructDeclaration( /// 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"); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 172950fc67..207047b03c 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/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 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context, 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. @@ -3110,7 +3110,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 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 diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 13f968fa5e..0ac418ad70 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/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" @@ -2680,7 +2680,7 @@ void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) { 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 ';' diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index b63c69db48..f72fd3221c 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/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 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { 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 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { 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? diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index c61e2fdcab..171b3ec5f8 100644 --- a/lib/Sema/Sema.cpp +++ b/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" @@ -1525,24 +1525,6 @@ void ExternalSemaSource::ReadUndefinedButUsed( 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 diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index bcc1e66fb0..5b6eb39e6b 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/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" #include "clang/Sema/TemplateInstCallback.h" @@ -2026,7 +2026,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, 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 @@ -2253,7 +2253,7 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation, 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 @@ -2329,7 +2329,7 @@ bool Sema::InstantiateInClassInitializer( << 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 diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 3cc37d086a..ebfad36d36 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/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" #include "clang/Sema/TemplateInstCallback.h" @@ -3895,7 +3895,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, 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 @@ -4306,7 +4306,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, 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 @@ -4419,7 +4419,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, 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 @@ -5223,7 +5223,7 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) { break; } - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable definition"); bool DefinitionRequired = Var->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 6a426036a2..d70debaf85 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/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" @@ -2227,6 +2228,9 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context, } 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");