]> granicus.if.org Git - clang/commitdiff
FunctionDecl::getBody() is getting an ASTContext argument for use in
authorDouglas Gregor <dgregor@apple.com>
Sat, 18 Apr 2009 00:02:19 +0000 (00:02 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 18 Apr 2009 00:02:19 +0000 (00:02 +0000)
lazy PCH deserialization. Propagate that argument wherever it needs to
be. No functionality change, except that I've tightened up a few PCH
tests in preparation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69406 91177308-0d34-0410-b5e6-96231b3b80d8

30 files changed:
include/clang/AST/Decl.h
include/clang/AST/DeclBase.h
include/clang/AST/DeclCXX.h
include/clang/AST/DeclObjC.h
include/clang/AST/Expr.h
include/clang/AST/ExternalASTSource.h
include/clang/Frontend/PCHReader.h
lib/AST/Decl.cpp
lib/AST/DeclSerialization.cpp
lib/AST/Expr.cpp
lib/Analysis/BasicStore.cpp
lib/Analysis/BugReporter.cpp
lib/Analysis/CFRefCount.cpp
lib/Analysis/CheckObjCDealloc.cpp
lib/Analysis/CheckObjCUnusedIVars.cpp
lib/Analysis/PathDiagnostic.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenModule.cpp
lib/Frontend/PCHWriter.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp
test/PCH/blocks.c
test/PCH/stmts.c
test/PCH/va_arg.c
tools/clang-cc/ASTConsumers.cpp
tools/clang-cc/AnalysisConsumer.cpp
tools/clang-cc/RewriteBlocks.cpp
tools/clang-cc/RewriteObjC.cpp

index 3f4ea122bdbbf72cc409cb64f9f3c445da818a6c..083f6c6363813af6c0dd797b77a9f217f17c7528 100644 (file)
@@ -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.
index 7f427e3eb3a68444550043d72c81b32158ecd21f..434780baa0288179689ecc36a4256c909de2b414 100644 (file)
@@ -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);
index 26f8f1a75f020bce980c49bce46899ce1a3e97d5..4dbfe4db0bd89e5c778cd1bf6699cde6e0263905 100644 (file)
@@ -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; 
   }
index 62cd01ee8b5a8d48e494e203686b24916fc57c67..7b02bb29fd4e17b2412a553fda1b892b28c1f5e2 100644 (file)
@@ -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.
index c8599ea587757e6cdcd4406174d2c827339adea8..3b9b6273b15918e4eabeb0c3fc588b0b70ac7352 100644 (file)
@@ -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());
   }
index 2ec29d80ec04f0461ff614d730afb2207d3ffc2e..d5499d7b05f41e7e82d03aefab1caf19f05036bd 100644 (file)
 #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.
index 1352908ef185bdef0dbcf7a81a315b632eae7b0d..c4f90a3c794714d70713a75f616dc050b88f95bd 100644 (file)
@@ -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);
index d733c8c929fb3b62b118d97da1b719fe6507de26..5d49d706d7ecd72e0b618af56ab24d45e66b3bea 100644 (file)
@@ -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");
index 3ffcc49c363bc916b07997c48d57ded84ac85e4b..81fdae2edc79d414c4d7788a664deba9305bb381 100644 (file)
@@ -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);
   
index 523615491d5367ef6b1ffc8ae30592937f068e1a..46dce59d3e9d1536108cba04f05df86920f9d101 100644 (file)
@@ -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(); 
+}
 
 
 //===----------------------------------------------------------------------===//
index 566c1971b7d778abd49e835c9f0a52d8a5f26b96..9047d9d8a950976d17f1e6064352efda800d079e 100644 (file)
@@ -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);
         }
       }
     }
index 01f5e81bf58a9e6f7ffc43c98db1263b5d7e0e50..7e7132aaab70086204e089d9b244fdd01a55872a 100644 (file)
@@ -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
index cfeabd0cb1b06c06b07e7f578f0b0aa7fa43ead3..7443c521b3bc4794cb62108bdba38539550e6a03 100644 (file)
@@ -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);
   }
 
index a14ae265128b9c048f589f10e9092aca710a493e..0d6e7e46a0b74618f9235b3666daccfb25110044 100644 (file)
@@ -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)";
index 658a6b189aaf091fccd805567db8bd9e921b7e60..57fad8d86b652c2d031193904b4a981c304cf5a7 100644 (file)
@@ -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.
index da007c16ec47ff1b3e9358df78fbb30d0cebea6e..1d00727d0a2acee2bf1e0065a31f02a3bf7b296a 100644 (file)
@@ -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);
index 808add74f76489babe2a9659c716a86e6fb2cc70..147155ea1ac644f3e9e2bc241b4deb2e9e8cf8df 100644 (file)
@@ -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
index 4bdebfe43157d533b1cf25a387f351f40167f083..45c7d0aa27a1f593a663b0c8ea1bb6c47e86765d 100644 (file)
@@ -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);
index 4cb1b43ba53d36ca7e7748f1cb39d2087321589c..df62f0e918b28727f825e30a6fbb3fa2937247d6 100644 (file)
@@ -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;
   }
index 64bf3833b4f195a191812f9b251acce68a1398a2..d7f0cd3497fd6f774bea2c23d762f63514b8b6a2 100644 (file)
@@ -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();
index 3a264d4449e9610efd958ed5dde1d028ca4b4400..619d08c7580531c951e38c45c95215ff81783230 100644 (file)
@@ -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);
   }
index cafa67fde7518afabbf2596e314392d9d14116f7..f16d343dd0475000f14623d9c845801d592a67f6 100644 (file)
@@ -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;
index e0d28fa140ed0dceba11cf1925a9325281ff8fb2..20a150fad60776f810072cb3b450ee3753e65ad8 100644 (file)
@@ -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();
     }
index 0e5065cceedc24bc9b8a1fa19bb75aaa4ce14416..27286b19618b27221866d7c2f0887691d5ff7f7b 100644 (file)
@@ -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); }
 
index f376a1dd37f59636e378ef320726bf27d98be516..9979d10d3304f3e7bb1773aff6495726c5000563 100644 (file)
@@ -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); }
index 796be03b07546e4ea527ba47a1d2dda96d878915..aec55acbebeddb5e6fd7b5ad17edd970d7d2bffb 100644 (file)
@@ -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) {
index 61a9e4460abd9e34051aed9b12fa13c40f5053ec..aabbf2ab4a367ffd50096a401c27f97192e4e4bb 100644 (file)
@@ -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;
index c39b1bcf3ff700623a6bdfd07325429ef8a54500..b1fb7417825fd760d5d0914d207e382fd543b6fc 100644 (file)
@@ -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;
     }
index f1f53e41c54002d08e912ee0aa7e764fad6293f5..a9324e666698ae16a6b891a6c0bc2a298918ce0c 100644 (file)
@@ -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.
index 41f532b2873fcea7949e185e8529be9fc55976e9..46f8e7ead38161098ca32f428b0301391cb23d85 100644 (file)
@@ -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)->getLocStart();
     
     const char *startBuf = SM->getCharacterData(LocStart);
     const char *endBuf = SM->getCharacterData(LocEnd);
@@ -1009,7 +1009,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)->getLocStart();
     
     const char *startBuf = SM->getCharacterData(LocStart);
     const char *endBuf = SM->getCharacterData(LocEnd);
@@ -4445,7 +4445,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
     // definitions using the same code.
     RewriteBlocksInFunctionProtoType(FD->getType(), FD);
 
-    if (CompoundStmt *Body = FD->getBody()) {
+    if (CompoundStmt *Body = FD->getBody(*Context)) {
       CurFunctionDef = FD;
       CollectPropertySetters(Body);
       CurrentBody = Body;