diff options
30 files changed, 107 insertions, 64 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 3f4ea122bd..083f6c6363 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -16,6 +16,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/ExternalASTSource.h" namespace clang { class Expr; @@ -564,7 +565,7 @@ private: /// FunctionDecl object to save an allocation like FunctionType does. ParmVarDecl **ParamInfo; - Stmt *Body; // Null if a prototype. + Stmt *Body; /// PreviousDeclaration - A link to the previous declaration of this /// same function, NULL if this is the first declaration. For @@ -596,7 +597,7 @@ protected: SourceLocation TSSL = SourceLocation()) : ValueDecl(DK, DC, L, N, T), DeclContext(DK), - ParamInfo(0), Body(0), PreviousDeclaration(0), + ParamInfo(0), Body(), PreviousDeclaration(0), SClass(S), IsInline(isInline), IsVirtual(false), IsPure(false), InheritedPrototype(false), HasPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL) {} @@ -619,20 +620,25 @@ public: /// function. The variant that accepts a FunctionDecl pointer will /// set that function declaration to the actual declaration /// containing the body (if there is one). - CompoundStmt *getBody(const FunctionDecl *&Definition) const; + CompoundStmt *getBody(ASTContext &Context, + const FunctionDecl *&Definition) const; - virtual CompoundStmt *getBody() const { + virtual CompoundStmt *getBody(ASTContext &Context) const { const FunctionDecl* Definition; - return getBody(Definition); + return getBody(Context, Definition); } - + + /// \brief If the function has a body that is immediately available, + /// return it. + CompoundStmt *getBodyIfAvailable() const; + /// isThisDeclarationADefinition - Returns whether this specific /// declaration of the function is also a definition. This does not /// determine whether the function has been defined (e.g., in a /// previous definition); for that information, use getBody. /// FIXME: Should return true if function is deleted or defaulted. However, /// CodeGenModule.cpp uses it, and I don't know if this would break it. - bool isThisDeclarationADefinition() const { return Body != 0; } + bool isThisDeclarationADefinition() const { return Body; } void setBody(CompoundStmt *B) { Body = (Stmt*) B; } @@ -1258,6 +1264,7 @@ public: SourceLocation getCaretLocation() const { return getLocation(); } CompoundStmt *getBody() const { return (CompoundStmt*) Body; } + CompoundStmt *getBody(ASTContext &C) const { return (CompoundStmt*) Body; } void setBody(CompoundStmt *B) { Body = (Stmt*) B; } // Iterator access to formal parameters. diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 7f427e3eb3..434780baa0 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -281,7 +281,7 @@ public: // getBody - If this Decl represents a declaration for a body of code, // such as a function or method definition, this method returns the top-level // Stmt* of that body. Otherwise this method returns null. - virtual CompoundStmt* getBody() const { return 0; } + virtual CompoundStmt* getBody(ASTContext &Context) const { return 0; } // global temp stats (until we have a per-module visitor) static void addDeclKind(Kind k); diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 26f8f1a75f..4dbfe4db0b 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -676,8 +676,8 @@ public: /// defined. If false, then this constructor was defined by the /// user. This operation can only be invoked if the constructor has /// already been defined. - bool isImplicitlyDefined() const { - assert(getBody() != 0 && + bool isImplicitlyDefined(ASTContext &C) const { + assert(isThisDeclarationADefinition() && "Can only get the implicit-definition flag once the constructor has been defined"); return ImplicitlyDefined; } @@ -685,7 +685,7 @@ public: /// setImplicitlyDefined - Set whether this constructor was /// implicitly defined or not. void setImplicitlyDefined(bool ID) { - assert(getBody() != 0 && + assert(isThisDeclarationADefinition() && "Can only set the implicit-definition flag once the constructor has been defined"); ImplicitlyDefined = ID; } @@ -773,7 +773,7 @@ public: /// user. This operation can only be invoked if the destructor has /// already been defined. bool isImplicitlyDefined() const { - assert(getBody() != 0 && + assert(isThisDeclarationADefinition() && "Can only get the implicit-definition flag once the destructor has been defined"); return ImplicitlyDefined; } @@ -781,7 +781,7 @@ public: /// setImplicitlyDefined - Set whether this destructor was /// implicitly defined or not. void setImplicitlyDefined(bool ID) { - assert(getBody() != 0 && + assert(isThisDeclarationADefinition() && "Can only set the implicit-definition flag once the destructor has been defined"); ImplicitlyDefined = ID; } diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 62cd01ee8b..7b02bb29fd 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -225,7 +225,10 @@ public: return ImplementationControl(DeclImplementation); } - virtual CompoundStmt *getBody() const { return (CompoundStmt*) Body; } + virtual CompoundStmt *getBody(ASTContext &C) const { + return (CompoundStmt*) Body; + } + CompoundStmt *getBody() { return (CompoundStmt*)Body; } void setBody(CompoundStmt *B) { Body = (Stmt*) B; } // Implement isa/cast/dyncast/etc. diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index c8599ea587..3b9b6273b1 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -2505,6 +2505,9 @@ public: const Stmt *getBody() const; Stmt *getBody(); + const Stmt *getBody(ASTContext &C) const { return getBody(); } + Stmt *getBody(ASTContext &C) { return getBody(); } + virtual SourceRange getSourceRange() const { return SourceRange(getCaretLocation(), getBody()->getLocEnd()); } diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 2ec29d80ec..d5499d7b05 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -16,11 +16,13 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "llvm/ADT/SmallVector.h" +#include <cassert> namespace clang { class ASTConsumer; class Decl; class DeclContext; +class Stmt; /// \brief The deserialized representation of a set of declarations /// with the same name that are visible in a given context. diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 1352908ef1..c4f90a3c79 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -273,6 +273,9 @@ public: /// supplements. ASTContext &getContext() { return Context; } + /// \brief Retrieve the stream that this PCH reader is reading from. + llvm::BitstreamReader &getStream() { return Stream; } + /// \brief Record that the given ID maps to the given switch-case /// statement. void RecordSwitchCaseID(SwitchCase *SC, unsigned ID); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index d733c8c929..5d49d706d7 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -320,7 +320,8 @@ void FunctionDecl::Destroy(ASTContext& C) { } -CompoundStmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { +CompoundStmt *FunctionDecl::getBody(ASTContext &Context, + const FunctionDecl *&Definition) const { for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) { if (FD->Body) { Definition = FD; @@ -331,6 +332,15 @@ CompoundStmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { return 0; } +CompoundStmt *FunctionDecl::getBodyIfAvailable() const { + for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) { + if (FD->Body) + return cast<CompoundStmt>(FD->Body); + } + + return 0; +} + bool FunctionDecl::isMain() const { return getDeclContext()->getLookupContext()->isTranslationUnit() && getIdentifier() && getIdentifier()->isStr("main"); diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index 3ffcc49c36..81fdae2edc 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -477,11 +477,11 @@ void FunctionDecl::EmitImpl(Serializer& S) const { if (ParamInfo != NULL) { S.EmitBool(true); S.EmitInt(getNumParams()); - S.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body); + // FIXME: S.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body); } else { S.EmitBool(false); - S.EmitOwnedPtr(Body); + // FIXME: S.EmitOwnedPtr(Body); } } @@ -508,7 +508,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) { if (hasParamDecls) D.BatchReadOwnedPtrs(numParams, reinterpret_cast<Decl**>(&decl->ParamInfo[0]), - decl->Body, C); + /*FIXME: decl->Body,*/ C); else decl->Body = D.ReadOwnedPtr<Stmt>(C); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 523615491d..46dce59d3e 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -399,8 +399,12 @@ const FunctionType *BlockExpr::getFunctionType() const { SourceLocation BlockExpr::getCaretLocation() const { return TheBlock->getCaretLocation(); } -const Stmt *BlockExpr::getBody() const { return TheBlock->getBody(); } -Stmt *BlockExpr::getBody() { return TheBlock->getBody(); } +const Stmt *BlockExpr::getBody() const { + return TheBlock->getBody(); +} +Stmt *BlockExpr::getBody() { + return TheBlock->getBody(); +} //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 566c1971b7..9047d9d8a9 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -525,7 +525,7 @@ Store BasicStoreManager::getInitialStore() { // Scan the method for ivar references. While this requires an // entire AST scan, the cost should not be high in practice. - St = scanForIvars(MD->getBody(), PD, St); + St = scanForIvars(MD->getBody(getContext()), PD, St); } } } diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 01f5e81bf5..7e7132aaab 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -140,7 +140,7 @@ public: const ExplodedNode<GRState>* N); ParentMap& getParentMap() { - if (PM.get() == 0) PM.reset(new ParentMap(CodeDecl.getBody())); + if (PM.get() == 0) PM.reset(new ParentMap(CodeDecl.getBody(getContext()))); return *PM.get(); } @@ -163,7 +163,7 @@ public: BugReport& getReport() { return *R; } GRBugReporter& getBugReporter() { return BR; } GRStateManager& getStateManager() { return BR.getStateManager(); } - + PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S); PathDiagnosticLocation @@ -189,7 +189,7 @@ PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N) { if (Stmt *S = GetNextStmt(N)) return PathDiagnosticLocation(S, SMgr); - return FullSourceLoc(CodeDecl.getBody()->getRBracLoc(), SMgr); + return FullSourceLoc(CodeDecl.getBody(getContext())->getRBracLoc(), SMgr); } PathDiagnosticLocation diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index cfeabd0cb1..7443c521b3 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -2903,7 +2903,8 @@ CFRefLeakReport::getEndPath(BugReporter& br, const ExplodedNode<GRState>* EndN){ } if (!L.isValid()) { - CompoundStmt *CS = BR.getStateManager().getCodeDecl().getBody(); + CompoundStmt *CS + = BR.getStateManager().getCodeDecl().getBody(BR.getContext()); L = PathDiagnosticLocation(CS->getRBracLoc(), SMgr); } diff --git a/lib/Analysis/CheckObjCDealloc.cpp b/lib/Analysis/CheckObjCDealloc.cpp index a14ae26512..0d6e7e46a0 100644 --- a/lib/Analysis/CheckObjCDealloc.cpp +++ b/lib/Analysis/CheckObjCDealloc.cpp @@ -172,7 +172,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D, } // dealloc found. Scan for missing [super dealloc]. - if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) { + if (MD->getBody(Ctx) && !scan_dealloc(MD->getBody(Ctx), S)) { const char* name = LOpts.getGCMode() == LangOptions::NonGC ? "missing [super dealloc]" @@ -223,7 +223,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D, // ivar must be released if and only if the kind of setter was not 'assign' bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign; - if(scan_ivar_release(MD->getBody(), ID, PD, RS, SelfII, Ctx) + if(scan_ivar_release(MD->getBody(Ctx), ID, PD, RS, SelfII, Ctx) != requiresRelease) { const char *name; const char* category = "Memory (Core Foundation/Objective-C)"; diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp index 658a6b189a..57fad8d86b 100644 --- a/lib/Analysis/CheckObjCUnusedIVars.cpp +++ b/lib/Analysis/CheckObjCUnusedIVars.cpp @@ -85,7 +85,7 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) { // Now scan the methods for accesses. for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(), E = D->instmeth_end(); I!=E; ++I) - Scan(M, (*I)->getBody()); + Scan(M, (*I)->getBody(BR.getContext())); // Scan for @synthesized property methods that act as setters/getters // to an ivar. diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index da007c16ec..1d00727d0a 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -171,8 +171,13 @@ SourceRange PathDiagnosticLocation::asRange() const { case DeclK: if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) return MD->getSourceRange(); - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - return FD->getBody()->getSourceRange(); + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + // FIXME: We would like to always get the function body, even + // when it needs to be de-serialized, but getting the + // ASTContext here requires significant changes. + if (CompoundStmt *Body = FD->getBodyIfAvailable()) + return Body->getSourceRange(); + } else { SourceLocation L = D->getLocation(); return SourceRange(L, L); diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 808add74f7..147155ea1a 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -131,8 +131,8 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { if (CGM.getDebugInfo() && !OMD->hasAttr<NodebugAttr>()) DebugInfo = CGM.getDebugInfo(); StartObjCMethod(OMD, OMD->getClassInterface()); - EmitStmt(OMD->getBody()); - FinishFunction(cast<CompoundStmt>(OMD->getBody())->getRBracLoc()); + EmitStmt(OMD->getBody(getContext())); + FinishFunction(cast<CompoundStmt>(OMD->getBody(getContext()))->getRBracLoc()); } // FIXME: I wasn't sure about the synthesis approach. If we end up diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 4bdebfe431..45c7d0aa27 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -225,7 +225,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD, FProto->getArgType(i))); } - const CompoundStmt *S = FD->getBody(); + const CompoundStmt *S = FD->getBody(getContext()); StartFunction(FD, FD->getResultType(), Fn, Args, S->getLBracLoc()); EmitStmt(S); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 4cb1b43ba5..df62f0e918 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -971,7 +971,7 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { if (D->hasAttr<DLLExportAttr>()) { if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { // The dllexport attribute is ignored for undefined symbols. - if (FD->getBody()) + if (FD->getBody(getContext())) GA->setLinkage(llvm::Function::DLLExportLinkage); } else { GA->setLinkage(llvm::Function::DLLExportLinkage); @@ -1403,7 +1403,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::ObjCMethod: { ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D); // If this is not a prototype, emit the body. - if (OMD->getBody()) + if (OMD->getBody(getContext())) CodeGenFunction(*this).GenerateObjCMethod(OMD); break; } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 64bf3833b4..d7f0cd3497 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -241,13 +241,15 @@ namespace { : public DeclVisitor<PCHDeclWriter, void> { PCHWriter &Writer; + ASTContext &Context; PCHWriter::RecordData &Record; public: pch::DeclCode Code; - PCHDeclWriter(PCHWriter &Writer, PCHWriter::RecordData &Record) - : Writer(Writer), Record(Record) { } + PCHDeclWriter(PCHWriter &Writer, ASTContext &Context, + PCHWriter::RecordData &Record) + : Writer(Writer), Context(Context), Record(Record) { } void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *D); @@ -340,7 +342,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) { VisitValueDecl(D); Record.push_back(D->isThisDeclarationADefinition()); if (D->isThisDeclarationADefinition()) - Writer.AddStmt(D->getBody()); + Writer.AddStmt(D->getBody(Context)); Writer.AddDeclRef(D->getPreviousDeclaration(), Record); Record.push_back(D->getStorageClass()); // FIXME: stable encoding Record.push_back(D->isInline()); @@ -1474,7 +1476,7 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) { // Emit all of the declarations. RecordData Record; - PCHDeclWriter W(*this, Record); + PCHDeclWriter W(*this, Context, Record); while (!DeclsToEmit.empty()) { // Pull the next declaration off the queue Decl *D = DeclsToEmit.front(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 3a264d4449..619d08c758 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2824,7 +2824,7 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { // See if this is a redefinition. const FunctionDecl *Definition; - if (FD->getBody(Definition)) { + if (FD->getBody(Context, Definition)) { Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); Diag(Definition->getLocation(), diag::note_previous_definition); } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index cafa67fde7..f16d343dd0 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -771,7 +771,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { if (VarDecl *VD = dyn_cast<VarDecl>(D)) { isDef = (!VD->hasExternalStorage() || VD->getInit()); } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { - isDef = FD->getBody(); + isDef = FD->getBody(S.Context); } else if (isa<ObjCPropertyDecl>(D)) { // We ignore weak import on properties return; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e0d28fa140..20a150fad6 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2417,7 +2417,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, // Check if we have too few/too many template arguments, based // on our knowledge of the function definition. const FunctionDecl *Def = 0; - if (FDecl->getBody(Def) && NumArgs != Def->param_size()) + if (FDecl->getBody(Context, Def) && NumArgs != Def->param_size()) Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments) << (NumArgs > Def->param_size()) << FDecl << Fn->getSourceRange(); } diff --git a/test/PCH/blocks.c b/test/PCH/blocks.c index 0e5065ccee..27286b1961 100644 --- a/test/PCH/blocks.c +++ b/test/PCH/blocks.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -fblocks -include %S/blocks.h -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -fblocks -include %S/blocks.h -fsyntax-only -emit-llvm -o - %s // Test with pch. // RUN: clang-cc -emit-pch -fblocks -o %t %S/blocks.h && -// RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -emit-llvm -o - %s int do_add(int x, int y) { return add(x, y); } diff --git a/test/PCH/stmts.c b/test/PCH/stmts.c index f376a1dd37..9979d10d33 100644 --- a/test/PCH/stmts.c +++ b/test/PCH/stmts.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -include %S/stmts.h -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -include %S/stmts.h -fsyntax-only -emit-llvm -o - %s // Test with pch. // RUN: clang-cc -emit-pch -o %t %S/stmts.h && -// RUN: clang-cc -include-pch %t -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -include-pch %t -fsyntax-only -emit-llvm -o - %s void g0(void) { f0(5); } int g1(int x) { return f1(x); } diff --git a/test/PCH/va_arg.c b/test/PCH/va_arg.c index 796be03b07..aec55acbeb 100644 --- a/test/PCH/va_arg.c +++ b/test/PCH/va_arg.c @@ -1,10 +1,11 @@ // Test this without pch. -// RUN: clang-cc -triple=x86_64-unknown-freebsd7.0 -include %S/va_arg.h -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -triple=x86_64-unknown-freebsd7.0 -include %S/va_arg.h %s // Test with pch. -// RUN: clang-cc -triple=x86_64-unknown-freebsd7.0 -emit-pch -o %t %S/va_arg.h && -// RUN: clang-cc -triple=x86_64-unknown-freebsd7.0 -include-pch %t -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -triple=x86_64-unknown-freebsd7.0 -o %t %S/va_arg.h && +// RUN: clang-cc -triple=x86_64-unknown-freebsd7.0 -include-pch %t %s +// FIXME: Crash when emitting LLVM bitcode using PCH! char *g0(char** argv, int argc) { return argv[argc]; } char *g(char **argv) { diff --git a/tools/clang-cc/ASTConsumers.cpp b/tools/clang-cc/ASTConsumers.cpp index 61a9e4460a..aabbf2ab4a 100644 --- a/tools/clang-cc/ASTConsumers.cpp +++ b/tools/clang-cc/ASTConsumers.cpp @@ -80,9 +80,10 @@ void DeclPrinter:: PrintDecl(Decl *D) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { PrintFunctionDeclStart(FD); - if (FD->getBody()) { + // FIXME: Pass a context here so we can use getBody() + if (FD->getBodyIfAvailable()) { Out << ' '; - FD->getBody()->printPretty(Out, 0, Indentation, true); + FD->getBodyIfAvailable()->printPretty(Out, 0, Indentation, true); Out << '\n'; } } else if (isa<ObjCMethodDecl>(D)) { @@ -221,7 +222,8 @@ void DeclPrinter::Print(NamespaceDecl *NS) { } void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) { - bool HasBody = FD->getBody(); + // FIXME: pass a context so that we can use getBody. + bool HasBody = FD->getBodyIfAvailable(); Out << '\n'; @@ -264,7 +266,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) { AFT->getResultType().getAsStringInternal(Proto); Out << Proto; - if (!FD->getBody()) + if (!FD->getBodyIfAvailable()) Out << ";\n"; // Doesn't print the body. } @@ -596,10 +598,10 @@ void ASTDumper::HandleTopLevelSingleDecl(Decl *D) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { PrintFunctionDeclStart(FD); - if (FD->getBody()) { + if (FD->getBodyIfAvailable()) { Out << '\n'; // FIXME: convert dumper to use std::ostream? - FD->getBody()->dumpAll(*SM); + FD->getBodyIfAvailable()->dumpAll(*SM); Out << '\n'; } } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { @@ -664,9 +666,9 @@ void ASTViewer::HandleTopLevelSingleDecl(Decl *D) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { DeclPrinter().PrintFunctionDeclStart(FD); - if (FD->getBody()) { + if (FD->getBodyIfAvailable()) { llvm::cerr << '\n'; - FD->getBody()->viewAST(); + FD->getBodyIfAvailable()->viewAST(); llvm::cerr << '\n'; } return; diff --git a/tools/clang-cc/AnalysisConsumer.cpp b/tools/clang-cc/AnalysisConsumer.cpp index c39b1bcf3f..b1fb741782 100644 --- a/tools/clang-cc/AnalysisConsumer.cpp +++ b/tools/clang-cc/AnalysisConsumer.cpp @@ -425,7 +425,7 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { AnalyzeSpecificFunction != FD->getIdentifier()->getName()) break; - Stmt* Body = FD->getBody(); + Stmt* Body = FD->getBody(*Ctx); if (Body) HandleCode(FD, Body, FunctionActions); break; } diff --git a/tools/clang-cc/RewriteBlocks.cpp b/tools/clang-cc/RewriteBlocks.cpp index f1f53e41c5..a9324e6666 100644 --- a/tools/clang-cc/RewriteBlocks.cpp +++ b/tools/clang-cc/RewriteBlocks.cpp @@ -1092,7 +1092,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) { // definitions using the same code. RewriteFunctionProtoType(FD->getType(), FD); - if (CompoundStmt *Body = FD->getBody()) { + if (CompoundStmt *Body = FD->getBody(*Context)) { CurFunctionDef = FD; FD->setBody(cast_or_null<CompoundStmt>(RewriteFunctionBody(Body))); // This synthesizes and inserts the block "impl" struct, invoke function, @@ -1104,7 +1104,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) { } if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { RewriteMethodDecl(MD); - if (Stmt *Body = MD->getBody()) { + if (Stmt *Body = MD->getBody(*Context)) { CurMethodDef = MD; RewriteFunctionBody(Body); InsertBlockLiteralsWithinMethod(MD); @@ -1116,7 +1116,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) { RewriteBlockPointerDecl(VD); if (VD->getInit()) { if (BlockExpr *CBE = dyn_cast<BlockExpr>(VD->getInit())) { - RewriteFunctionBody(CBE->getBody()); + RewriteFunctionBody(CBE->getBody(*Context)); // We've just rewritten the block body in place. // Now we snarf the rewritten text and stash it away for later use. diff --git a/tools/clang-cc/RewriteObjC.cpp b/tools/clang-cc/RewriteObjC.cpp index 41f532b287..46f8e7ead3 100644 --- a/tools/clang-cc/RewriteObjC.cpp +++ b/tools/clang-cc/RewriteObjC.cpp @@ -994,7 +994,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) { ObjCMethodDecl *OMD = *I; RewriteObjCMethodDecl(OMD, ResultStr); SourceLocation LocStart = OMD->getLocStart(); - SourceLocation LocEnd = OMD->getBody()->getLocStart(); + SourceLocation LocEnd = OMD->getBody(*Context)->g |