FunctionDecl::getBody() is getting an ASTContext argument for use in
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
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index d733c8c..5d49d70 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -320,7 +320,8 @@
 }
 
 
-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 @@
   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 3ffcc49..81fdae2 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -477,11 +477,11 @@
   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 @@
   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 5236154..46dce59 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -399,8 +399,12 @@
 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 566c197..9047d9d 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -525,7 +525,7 @@
           
           // 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 01f5e81..7e7132a 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -140,7 +140,7 @@
                                             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 @@
   BugReport& getReport() { return *R; }
   GRBugReporter& getBugReporter() { return BR; }
   GRStateManager& getStateManager() { return BR.getStateManager(); }
-  
+
   PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
   
   PathDiagnosticLocation
@@ -189,7 +189,7 @@
   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 cfeabd0..7443c52 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -2903,7 +2903,8 @@
   }
   
   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 a14ae26..0d6e7e4 100644
--- a/lib/Analysis/CheckObjCDealloc.cpp
+++ b/lib/Analysis/CheckObjCDealloc.cpp
@@ -172,7 +172,7 @@
   }
   
   // 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 @@
               
     // 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 658a6b1..57fad8d 100644
--- a/lib/Analysis/CheckObjCUnusedIVars.cpp
+++ b/lib/Analysis/CheckObjCUnusedIVars.cpp
@@ -85,7 +85,7 @@
   // 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 da007c1..1d00727 100644
--- a/lib/Analysis/PathDiagnostic.cpp
+++ b/lib/Analysis/PathDiagnostic.cpp
@@ -171,8 +171,13 @@
     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 808add7..147155e 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -131,8 +131,8 @@
   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 4bdebfe..45c7d0a 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -225,7 +225,7 @@
                                     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 4cb1b43..df62f0e 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -971,7 +971,7 @@
   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 @@
   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 64bf383..d7f0cd3 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -241,13 +241,15 @@
     : 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 @@
   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 @@
 
   // 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 3a264d4..619d08c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2824,7 +2824,7 @@
 
   // 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 cafa67f..f16d343 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -771,7 +771,7 @@
   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 e0d28fa..20a150f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2417,7 +2417,7 @@
       // 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();
     }