rename PrettyStackTraceDecl -> PrettyStackTraceActionsDecl.
Introduce a new PrettyStackTraceDecl. Use it to add the top level LLVM IR generation stuff in Backend.cpp to stack traces. We now get crashes like: Stack dump: 0. Program arguments: clang t.c -emit-llvm 1. <eof> parser at end of file 2. t.c:1:5: LLVM IR generation of declaration 'a' Abort for IR generation crashes. llvm-svn: 66153
This commit is contained in:
parent
1d09f6a221
commit
eae6cb6154
|
@ -39,12 +39,13 @@ using namespace clang;
|
|||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class VISIBILITY_HIDDEN BackendConsumer : public ASTConsumer {
|
||||
class VISIBILITY_HIDDEN BackendConsumer : public ASTConsumer {
|
||||
BackendAction Action;
|
||||
CompileOptions CompileOpts;
|
||||
const std::string &InputFile;
|
||||
std::string OutputFile;
|
||||
bool GenerateDebugInfo;
|
||||
ASTContext *Context;
|
||||
|
||||
Timer LLVMIRGeneration;
|
||||
Timer CodeGenerationTime;
|
||||
|
@ -78,8 +79,8 @@ namespace {
|
|||
public:
|
||||
BackendConsumer(BackendAction action, Diagnostic &Diags,
|
||||
const LangOptions &langopts, const CompileOptions &compopts,
|
||||
const std::string& infile, const std::string& outfile,
|
||||
bool debug) :
|
||||
const std::string &infile, const std::string &outfile,
|
||||
bool debug) :
|
||||
Action(action),
|
||||
CompileOpts(compopts),
|
||||
InputFile(infile),
|
||||
|
@ -105,6 +106,7 @@ namespace {
|
|||
}
|
||||
|
||||
virtual void InitializeTU(TranslationUnit& TU) {
|
||||
Context = &TU.getContext();
|
||||
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.startTimer();
|
||||
|
@ -121,6 +123,9 @@ namespace {
|
|||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D) {
|
||||
PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
|
||||
Context->getSourceManager(),
|
||||
"LLVM IR generation of declaration");
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.startTimer();
|
||||
|
||||
|
@ -131,15 +136,18 @@ namespace {
|
|||
}
|
||||
|
||||
virtual void HandleTranslationUnit(TranslationUnit& TU) {
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.startTimer();
|
||||
{
|
||||
PrettyStackTraceString CrashInfo("per-file LLVM IR generation");
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.startTimer();
|
||||
|
||||
Gen->HandleTranslationUnit(TU);
|
||||
Gen->HandleTranslationUnit(TU);
|
||||
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.stopTimer();
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.stopTimer();
|
||||
}
|
||||
|
||||
// EmitAssembly times itself.
|
||||
// EmitAssembly times and registers crash info itself.
|
||||
EmitAssembly();
|
||||
|
||||
// Force a flush here in case we never get released.
|
||||
|
@ -148,6 +156,9 @@ namespace {
|
|||
}
|
||||
|
||||
virtual void HandleTagDeclDefinition(TagDecl *D) {
|
||||
PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
|
||||
Context->getSourceManager(),
|
||||
"LLVM IR generation of declaration");
|
||||
Gen->HandleTagDeclDefinition(D);
|
||||
}
|
||||
};
|
||||
|
@ -359,7 +370,6 @@ void BackendConsumer::EmitAssembly() {
|
|||
return;
|
||||
|
||||
|
||||
|
||||
TimeRegion Region(CompileOpts.TimePasses ? &CodeGenerationTime : 0);
|
||||
|
||||
// Make sure IR generation is happy with the module. This is
|
||||
|
@ -388,6 +398,8 @@ void BackendConsumer::EmitAssembly() {
|
|||
// would like to have the option of streaming code generation.
|
||||
|
||||
if (PerFunctionPasses) {
|
||||
PrettyStackTraceString CrashInfo("per-function optimization");
|
||||
|
||||
PerFunctionPasses->doInitialization();
|
||||
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
if (!I->isDeclaration())
|
||||
|
@ -395,10 +407,13 @@ void BackendConsumer::EmitAssembly() {
|
|||
PerFunctionPasses->doFinalization();
|
||||
}
|
||||
|
||||
if (PerModulePasses)
|
||||
if (PerModulePasses) {
|
||||
PrettyStackTraceString CrashInfo("per-module optimization passes");
|
||||
PerModulePasses->run(*M);
|
||||
}
|
||||
|
||||
if (CodeGenPasses) {
|
||||
PrettyStackTraceString CrashInfo("code generation");
|
||||
CodeGenPasses->doInitialization();
|
||||
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
if (!I->isDeclaration())
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/AST/Type.h"
|
||||
// FIXME: Layering violation
|
||||
#include "clang/Parse/AccessSpecifier.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
|
||||
namespace clang {
|
||||
class DeclContext;
|
||||
|
@ -327,6 +328,22 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
|
||||
/// doing something to a specific decl.
|
||||
class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
|
||||
Decl *TheDecl;
|
||||
SourceLocation Loc;
|
||||
SourceManager &SM;
|
||||
const char *Message;
|
||||
public:
|
||||
PrettyStackTraceDecl(Decl *theDecl, SourceLocation L,
|
||||
SourceManager &sm, const char *Msg)
|
||||
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
|
||||
|
||||
virtual void print(llvm::raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
|
||||
/// DeclContext - This is used only as base class of specific decl types that
|
||||
/// can act as declaration contexts. These decls are (only the top classes
|
||||
/// that directly derive from DeclContext are mentioned, not their subclasses):
|
||||
|
|
|
@ -1516,16 +1516,19 @@ public:
|
|||
AttributeList *AttrList);
|
||||
};
|
||||
|
||||
|
||||
class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
|
||||
/// PrettyStackTraceActionsDecl - If a crash occurs in the parser while parsing
|
||||
/// something related to a virtualized decl, include that virtualized decl in
|
||||
/// the stack trace.
|
||||
class PrettyStackTraceActionsDecl : public llvm::PrettyStackTraceEntry {
|
||||
Action::DeclTy *TheDecl;
|
||||
SourceLocation Loc;
|
||||
Action &Actions;
|
||||
SourceManager &SM;
|
||||
const char *Message;
|
||||
public:
|
||||
PrettyStackTraceDecl(Action::DeclTy *Decl, SourceLocation L,
|
||||
Action &actions, SourceManager &sm, const char *Msg)
|
||||
PrettyStackTraceActionsDecl(Action::DeclTy *Decl, SourceLocation L,
|
||||
Action &actions, SourceManager &sm,
|
||||
const char *Msg)
|
||||
: TheDecl(Decl), Loc(L), Actions(actions), SM(sm), Message(Msg) {}
|
||||
|
||||
virtual void print(llvm::raw_ostream &OS) const;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
|
@ -91,6 +92,27 @@ void Decl::addDeclKind(Kind k) {
|
|||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PrettyStackTraceDecl Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
|
||||
SourceLocation TheLoc = Loc;
|
||||
if (TheLoc.isInvalid() && TheDecl)
|
||||
TheLoc = TheDecl->getLocation();
|
||||
|
||||
if (TheLoc.isValid()) {
|
||||
TheLoc.print(OS, SM);
|
||||
OS << ": ";
|
||||
}
|
||||
|
||||
OS << Message;
|
||||
|
||||
if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
|
||||
OS << " '" << DN->getQualifiedNameAsString() << '\'';
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Decl Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -42,7 +42,7 @@ Action::DeclTy *Action::ActOnUsingDirective(Scope *CurScope,
|
|||
}
|
||||
|
||||
|
||||
void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
|
||||
void PrettyStackTraceActionsDecl::print(llvm::raw_ostream &OS) const {
|
||||
if (Loc.isValid()) {
|
||||
Loc.print(OS, SM);
|
||||
OS << ": ";
|
||||
|
|
|
@ -1096,9 +1096,9 @@ ParseStructDeclaration(DeclSpec &DS,
|
|||
///
|
||||
void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
||||
unsigned TagType, DeclTy *TagDecl) {
|
||||
PrettyStackTraceDecl CrashInfo(TagDecl, RecordLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing struct/union body");
|
||||
PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing struct/union body");
|
||||
|
||||
SourceLocation LBraceLoc = ConsumeBrace();
|
||||
|
||||
|
|
|
@ -73,9 +73,9 @@ Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
|
|||
DeclTy *NamespcDecl =
|
||||
Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
|
||||
|
||||
PrettyStackTraceDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing namespace");
|
||||
PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing namespace");
|
||||
|
||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
|
||||
ParseExternalDeclaration();
|
||||
|
@ -793,9 +793,9 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
|||
TagType == DeclSpec::TST_union ||
|
||||
TagType == DeclSpec::TST_class) && "Invalid TagType!");
|
||||
|
||||
PrettyStackTraceDecl CrashInfo(TagDecl, RecordLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing struct/union/class body");
|
||||
PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing struct/union/class body");
|
||||
|
||||
SourceLocation LBraceLoc = ConsumeBrace();
|
||||
|
||||
|
|
|
@ -1356,9 +1356,9 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
|||
Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
|
||||
DeclTy *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
|
||||
|
||||
PrettyStackTraceDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing Objective-C method");
|
||||
PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing Objective-C method");
|
||||
|
||||
// parse optional ';'
|
||||
if (Tok.is(tok::semi))
|
||||
|
|
|
@ -1288,9 +1288,9 @@ Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl) {
|
|||
assert(Tok.is(tok::l_brace));
|
||||
SourceLocation LBraceLoc = Tok.getLocation();
|
||||
|
||||
PrettyStackTraceDecl CrashInfo(Decl, LBraceLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing function body");
|
||||
PrettyStackTraceActionsDecl CrashInfo(Decl, LBraceLoc, Actions,
|
||||
PP.getSourceManager(),
|
||||
"parsing function body");
|
||||
|
||||
// Do not enter a scope for the brace, as the arguments are in the same scope
|
||||
// (the function body) as the body itself. Instead, just read the statement
|
||||
|
|
Loading…
Reference in New Issue