Include information about compound statements when crashing in sema or the

parser.  For example, we now print out:

0.	t.c:5:10: in compound statement {}
1.	t.c:3:12: in compound statement {}
2.	clang t.c -fsyntax-only

llvm-svn: 66108
This commit is contained in:
Chris Lattner 2009-03-05 00:00:31 +00:00
parent 00dfe30409
commit bd61a95481
5 changed files with 85 additions and 17 deletions

View File

@ -0,0 +1,37 @@
//===- clang/Basic/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the PrettyStackTraceEntry class, which is used to make
// crashes give more contextual information about what the program was doing
// when it crashed.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_BASIC_PRETTYSTACKTRACE_H
#define CLANG_BASIC_PRETTYSTACKTRACE_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/PrettyStackTrace.h"
namespace clang {
/// PrettyStackTraceLoc - If a crash happens while one of these objects are
/// live, .
class PrettyStackTraceLoc : public llvm::PrettyStackTraceEntry {
SourceManager &SM;
SourceLocation Loc;
const char *Message;
public:
PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg)
: SM(sm), Loc(L), Message(Msg) {}
virtual void print(llvm::raw_ostream &OS) const;
};
}
#endif

View File

@ -14,12 +14,13 @@
#ifndef LLVM_CLANG_SOURCELOCATION_H
#define LLVM_CLANG_SOURCELOCATION_H
#include <cassert>
#include "llvm/Bitcode/SerializationFwd.h"
#include <utility>
#include <cassert>
namespace llvm {
class MemoryBuffer;
class raw_ostream;
template <typename T> struct DenseMapInfo;
}
@ -134,7 +135,8 @@ public:
/// ReadVal - Read a SourceLocation object from Bitcode.
static SourceLocation ReadVal(llvm::Deserializer& D);
void print(llvm::raw_ostream &OS, const SourceManager &SM) const;
void dump(const SourceManager &SM) const;
};

View File

@ -13,14 +13,31 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
using namespace clang;
//===----------------------------------------------------------------------===//
// PrettyStackTraceLoc
//===----------------------------------------------------------------------===//
void PrettyStackTraceLoc::print(llvm::raw_ostream &OS) const {
if (Loc.isValid()) {
Loc.print(OS, SM);
OS << ": ";
}
OS << Message << '\n';
}
//===----------------------------------------------------------------------===//
// SourceLocation
//===----------------------------------------------------------------------===//
void SourceLocation::Emit(llvm::Serializer& S) const {
S.EmitInt(getRawEncoding());
}
@ -29,28 +46,31 @@ SourceLocation SourceLocation::ReadVal(llvm::Deserializer& D) {
return SourceLocation::getFromRawEncoding(D.ReadInt());
}
void SourceLocation::dump(const SourceManager &SM) const {
void SourceLocation::print(llvm::raw_ostream &OS, const SourceManager &SM)const{
if (!isValid()) {
fprintf(stderr, "<invalid loc>");
OS << "<invalid loc>";
return;
}
if (isFileID()) {
PresumedLoc PLoc = SM.getPresumedLoc(*this);
// The instantiation and spelling pos is identical for file locs.
fprintf(stderr, "%s:%d:%d",
PLoc.getFilename(), PLoc.getLine(), PLoc.getColumn());
OS << PLoc.getFilename() << ':' << PLoc.getLine()
<< ':' << PLoc.getColumn();
return;
}
SM.getInstantiationLoc(*this).dump(SM);
fprintf(stderr, " <Spelling=");
SM.getSpellingLoc(*this).dump(SM);
fprintf(stderr, ">");
SM.getInstantiationLoc(*this).print(OS, SM);
OS << " <Spelling=";
SM.getSpellingLoc(*this).print(OS, SM);
OS << '>';
}
void SourceLocation::dump(const SourceManager &SM) const {
print(llvm::errs(), SM);
llvm::errs().flush();
}
void SourceRange::Emit(llvm::Serializer& S) const {
B.Emit(S);
@ -63,6 +83,10 @@ SourceRange SourceRange::ReadVal(llvm::Deserializer& D) {
return SourceRange(A,B);
}
//===----------------------------------------------------------------------===//
// FullSourceLoc
//===----------------------------------------------------------------------===//
FileID FullSourceLoc::getFileID() const {
assert(isValid());
return SrcMgr->getFileID(*this);

View File

@ -1848,7 +1848,6 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
// If we reached this point, we are either in C/ObjC or the token didn't
// satisfy any of the C++-specific checks.
if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
assert(!getLang().CPlusPlus &&
"There's a C++-specific check for tok::identifier above");
@ -2080,7 +2079,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
// Enter function-declaration scope, limiting any declarators to the
// function prototype scope, including parameter declarators.
ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope|Scope::DeclScope);
ParseScope PrototypeScope(this,
Scope::FunctionPrototypeScope|Scope::DeclScope);
bool IsVariadic = false;
SourceLocation EllipsisLoc;

View File

@ -15,10 +15,11 @@
#include "clang/Parse/Parser.h"
#include "ExtensionRAIIObject.h"
#include "AstGuard.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/SourceManager.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@ -409,6 +410,10 @@ Parser::OwningStmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
/// consume the '}' at the end of the block. It does not manipulate the scope
/// stack.
Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
Tok.getLocation(),
"in compound statement ('{}')");
SourceLocation LBraceLoc = ConsumeBrace(); // eat the '{'.
// TODO: "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are