When parsing a function body, add it to the crash stack, giving us something
like: Stack dump: 0. t.c:5:10: in compound statement ('{}') 1. t.c:3:12: in compound statement ('{}') 2. t.c:3:12: parsing function body 'foo' 3. clang t.c Abort llvm-svn: 66118
This commit is contained in:
parent
626aecc4be
commit
03b5394da7
|
@ -20,6 +20,7 @@
|
|||
#include "clang/Basic/TypeTraits.h"
|
||||
#include "clang/Parse/AccessSpecifier.h"
|
||||
#include "clang/Parse/Ownership.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
|
||||
namespace clang {
|
||||
// Semantic.
|
||||
|
@ -118,6 +119,11 @@ public:
|
|||
|
||||
/// Statistics.
|
||||
virtual void PrintStats() const {}
|
||||
|
||||
/// getDeclName - Return a pretty name for the specified decl if possible, or
|
||||
/// an empty string if not. This is used for pretty crash reporting.
|
||||
virtual std::string getDeclName(DeclTy *D) { return ""; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Declaration Tracking Callbacks.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -266,8 +272,8 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
/// ActOnFinishFunctionBody - This is called when a function body has completed
|
||||
/// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
|
||||
/// ActOnFinishFunctionBody - This is called when a function body has
|
||||
/// completed parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
|
||||
virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtArg Body) {
|
||||
return Decl;
|
||||
}
|
||||
|
@ -1510,6 +1516,21 @@ public:
|
|||
AttributeList *AttrList);
|
||||
};
|
||||
|
||||
|
||||
class PrettyStackTraceDecl : 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)
|
||||
: TheDecl(Decl), Loc(L), Actions(actions), SM(sm), Message(Msg) {}
|
||||
|
||||
virtual void print(llvm::raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,8 +16,23 @@
|
|||
#include "clang/Parse/Scope.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/RecyclingAllocator.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace clang;
|
||||
|
||||
void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
|
||||
if (Loc.isValid()) {
|
||||
Loc.print(OS, SM);
|
||||
OS << ": ";
|
||||
}
|
||||
OS << Message;
|
||||
|
||||
std::string Name = Actions.getDeclName(TheDecl);
|
||||
if (!Name.empty())
|
||||
OS << " '" << Name << '\'';
|
||||
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
/// TypeNameInfo - A link exists here for each scope that an identifier is
|
||||
/// defined.
|
||||
namespace {
|
||||
|
|
|
@ -1288,6 +1288,10 @@ 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");
|
||||
|
||||
// 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
|
||||
// list and put it into a CompoundStmt for safe keeping.
|
||||
|
|
|
@ -290,6 +290,11 @@ public:
|
|||
//===--------------------------------------------------------------------===//
|
||||
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
|
||||
//
|
||||
|
||||
/// getDeclName - Return a pretty name for the specified decl if possible, or
|
||||
/// an empty string if not. This is used for pretty crash reporting.
|
||||
virtual std::string getDeclName(DeclTy *D);
|
||||
|
||||
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
|
||||
Scope *S, const CXXScopeSpec *SS);
|
||||
virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup){
|
||||
|
|
|
@ -30,6 +30,15 @@
|
|||
#include <functional>
|
||||
using namespace clang;
|
||||
|
||||
/// getDeclName - Return a pretty name for the specified decl if possible, or
|
||||
/// an empty string if not. This is used for pretty crash reporting.
|
||||
std::string Sema::getDeclName(DeclTy *d) {
|
||||
Decl *D = static_cast<Decl *>(d);
|
||||
if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(D))
|
||||
return DN->getQualifiedNameAsString();
|
||||
return "";
|
||||
}
|
||||
|
||||
/// \brief If the identifier refers to a type name within this scope,
|
||||
/// return the declaration of that type.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue