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:
Chris Lattner 2009-03-05 01:25:28 +00:00
parent 626aecc4be
commit 03b5394da7
5 changed files with 56 additions and 2 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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.

View File

@ -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){

View File

@ -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.
///