[cfe-commits] r107768 - in /cfe/trunk: include/clang/AST/ lib/AST/ lib/Checker/ lib/CodeGen/ lib/Sema/

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Jul 7 04:31:19 PDT 2010


Author: akirtzidis
Date: Wed Jul  7 06:31:19 2010
New Revision: 107768

URL: http://llvm.org/viewvc/llvm-project?rev=107768&view=rev
Log:
Introduce Decl::hasBody() and FunctionDecl::hasBody() and use them instead of getBody() when we are just checking the existence of a body, to avoid de-serialization of the body from PCH.

Makes de-serialization of the function body even more "lazier".

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Checker/AnalysisConsumer.cpp
    cfe/trunk/lib/Checker/CallInliner.cpp
    cfe/trunk/lib/Checker/GRExprEngine.cpp
    cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGVTables.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Jul  7 06:31:19 2010
@@ -1227,11 +1227,25 @@
     EndRangeLoc = E;
   }
 
+  /// \brief Returns true if the function has a body (definition). The
+  /// function body might be in any of the (re-)declarations of this
+  /// function. The variant that accepts a FunctionDecl pointer will
+  /// set that function declaration to the actual declaration
+  /// containing the body (if there is one).
+  bool hasBody(const FunctionDecl *&Definition) const;
+
+  virtual bool hasBody() const {
+    const FunctionDecl* Definition;
+    return hasBody(Definition);
+  }
+
   /// getBody - Retrieve the body (definition) of the function. The
   /// function body might be in any of the (re-)declarations of this
   /// function. The variant that accepts a FunctionDecl pointer will
   /// set that function declaration to the actual declaration
   /// containing the body (if there is one).
+  /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
+  /// unnecessary PCH de-serialization of the body.
   Stmt *getBody(const FunctionDecl *&Definition) const;
 
   virtual Stmt *getBody() const {

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Jul  7 06:31:19 2010
@@ -488,6 +488,10 @@
   ///  top-level Stmt* of that body.  Otherwise this method returns null.
   virtual Stmt* getBody() const { return 0; }
 
+  /// \brief Returns true if this Decl represents a declaration for a body of
+  /// code, such as a function or method definition.
+  virtual bool hasBody() const { return getBody() != 0; }
+
   /// getCompoundBody - Returns getBody(), dyn_casted to a CompoundStmt.
   CompoundStmt* getCompoundBody() const;
 

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Jul  7 06:31:19 2010
@@ -953,6 +953,17 @@
   return false;
 }
 
+bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if (I->Body) {
+      Definition = *I;
+      return true;
+    }
+  }
+
+  return false;
+}
+
 Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
   for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
     if (I->Body) {
@@ -1153,11 +1164,11 @@
   }
 
   const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
-  Stmt *Pattern = 0;
+  bool HasPattern = false;
   if (PatternDecl)
-    Pattern = PatternDecl->getBody(PatternDecl);
+    HasPattern = PatternDecl->hasBody(PatternDecl);
   
-  if (Pattern && PatternDecl)
+  if (HasPattern && PatternDecl)
     return PatternDecl->isInlined();
   
   return false;
@@ -1302,15 +1313,15 @@
 
   // Find the actual template from which we will instantiate.
   const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
-  Stmt *Pattern = 0;
+  bool HasPattern = false;
   if (PatternDecl)
-    Pattern = PatternDecl->getBody(PatternDecl);
+    HasPattern = PatternDecl->hasBody(PatternDecl);
   
   // C++0x [temp.explicit]p9:
   //   Except for inline functions, other explicit instantiation declarations
   //   have the effect of suppressing the implicit instantiation of the entity
   //   to which they refer. 
-  if (!Pattern || !PatternDecl)
+  if (!HasPattern || !PatternDecl) 
     return true;
 
   return PatternDecl->isInlined();
@@ -1514,7 +1525,7 @@
   // class template, check whether that member function was defined out-of-line.
   if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) {
     const FunctionDecl *Definition;
-    if (FD->getBody(Definition))
+    if (FD->hasBody(Definition))
       return Definition->isOutOfLine();
   }
   
@@ -1522,7 +1533,7 @@
   // check whether that function template was defined out-of-line.
   if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) {
     const FunctionDecl *Definition;
-    if (FunTmpl->getTemplatedDecl()->getBody(Definition))
+    if (FunTmpl->getTemplatedDecl()->hasBody(Definition))
       return Definition->isOutOfLine();
   }
   

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Jul  7 06:31:19 2010
@@ -452,6 +452,15 @@
 }
 
 SourceLocation Decl::getBodyRBrace() const {
+  // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
+  // FunctionDecl stores EndRangeLoc for this purpose.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) {
+    const FunctionDecl *Definition;
+    if (FD->hasBody(Definition))
+      return Definition->getSourceRange().getEnd();
+    return SourceLocation();
+  }
+
   Stmt *Body = getBody();
   if (!Body)
     return SourceLocation();

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Jul  7 06:31:19 2010
@@ -743,7 +743,7 @@
     CheckFn = this;
   
   const FunctionDecl *fn;
-  return CheckFn->getBody(fn) && !fn->isOutOfLine();
+  return CheckFn->hasBody(fn) && !fn->isOutOfLine();
 }
 
 CXXBaseOrMemberInitializer::

Modified: cfe/trunk/lib/Checker/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/AnalysisConsumer.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/Checker/AnalysisConsumer.cpp Wed Jul  7 06:31:19 2010
@@ -180,7 +180,7 @@
   }
 
   virtual void HandleTranslationUnit(ASTContext &C);
-  void HandleCode(Decl *D, Stmt* Body, Actions& actions);
+  void HandleCode(Decl *D, Actions& actions);
 };
 } // end anonymous namespace
 
@@ -209,7 +209,7 @@
             FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
           break;
         DisplayFunction(FD);
-        HandleCode(FD, FD->getBody(), FunctionActions);
+        HandleCode(FD, FunctionActions);
       }
       break;
     }
@@ -222,14 +222,14 @@
             Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
           break;
         DisplayFunction(MD);
-        HandleCode(MD, MD->getBody(), ObjCMethodActions);
+        HandleCode(MD, ObjCMethodActions);
       }
       break;
     }
 
     case Decl::ObjCImplementation: {
       ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
-      HandleCode(ID, 0, ObjCImplementationActions);
+      HandleCode(ID, ObjCImplementationActions);
 
       for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(), 
              ME = ID->meth_end(); MI != ME; ++MI) {
@@ -237,7 +237,7 @@
           if (!Opts.AnalyzeSpecificFunction.empty() &&
              Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
             break;
-          HandleCode(*MI, (*MI)->getBody(), ObjCMethodActions);
+          HandleCode(*MI, ObjCMethodActions);
         }
       }
       break;
@@ -270,7 +270,7 @@
       FindBlocks(DC, WL);
 }
 
-void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
+void AnalysisConsumer::HandleCode(Decl *D, Actions& actions) {
 
   // Don't run the actions if an error has occured with parsing the file.
   Diagnostic &Diags = PP.getDiagnostics();
@@ -291,7 +291,7 @@
   llvm::SmallVector<Decl*, 10> WL;
   WL.push_back(D);
 
-  if (Body && Opts.AnalyzeNestedBlocks)
+  if (D->hasBody() && Opts.AnalyzeNestedBlocks)
     FindBlocks(cast<DeclContext>(D), WL);
 
   for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)

Modified: cfe/trunk/lib/Checker/CallInliner.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CallInliner.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CallInliner.cpp (original)
+++ cfe/trunk/lib/Checker/CallInliner.cpp Wed Jul  7 06:31:19 2010
@@ -42,7 +42,7 @@
   if (!FD)
     return false;
 
-  if (!FD->getBody(FD))
+  if (!FD->hasBody(FD))
     return false;
 
   // Now we have the definition of the callee, create a CallEnter node.

Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Wed Jul  7 06:31:19 2010
@@ -1885,7 +1885,7 @@
   if (!FD)
     return false;
 
-  if (!FD->getBody(FD))
+  if (!FD->hasBody(FD))
     return false;
 
   // Now we have the definition of the callee, create a CallEnter node.

Modified: cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp (original)
+++ cfe/trunk/lib/Checker/LLVMConventionsChecker.cpp Wed Jul  7 06:31:19 2010
@@ -294,7 +294,7 @@
 
     Decl *D = *I;
 
-    if (D->getBody())
+    if (D->hasBody())
       CheckStringRefAssignedTemporary(D, BR);
 
     if (CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(D))

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Wed Jul  7 06:31:19 2010
@@ -98,7 +98,7 @@
   /// emit.  We can't emit aliases to declarations; that's just not
   /// how aliases work.
   const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
-  if (!BaseD->isImplicit() && !BaseD->getBody())
+  if (!BaseD->isImplicit() && !BaseD->hasBody())
     return true;
 
   // If the base is at a non-zero offset, give up.

Modified: cfe/trunk/lib/CodeGen/CGVTables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.h (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.h Wed Jul  7 06:31:19 2010
@@ -301,7 +301,7 @@
 				       const CXXRecordDecl *RD) {
     assert (RD->isDynamicClass() && "Non dynamic classes have no key.");
     const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
-    return KeyFunction && !KeyFunction->getBody();
+    return KeyFunction && !KeyFunction->hasBody();
   }
 
   /// needsVTTParameter - Return whether the given global decl needs a VTT

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Jul  7 06:31:19 2010
@@ -1085,7 +1085,7 @@
     // If this class has a key function, use that to determine the linkage of
     // the vtable.
     const FunctionDecl *Def = 0;
-    if (KeyFunction->getBody(Def))
+    if (KeyFunction->hasBody(Def))
       KeyFunction = cast<CXXMethodDecl>(Def);
     
     switch (KeyFunction->getTemplateSpecializationKind()) {
@@ -1453,7 +1453,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->hasBody())
         GA->setLinkage(llvm::Function::DLLExportLinkage);
     } else {
       GA->setLinkage(llvm::Function::DLLExportLinkage);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jul  7 06:31:19 2010
@@ -3488,7 +3488,7 @@
   if (Redeclaration && Previous.isSingleResult()) {
     const FunctionDecl *Def;
     FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
-    if (PrevFD && PrevFD->getBody(Def) && D.hasAttributes()) {
+    if (PrevFD && PrevFD->hasBody(Def) && D.hasAttributes()) {
       Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition);
       Diag(Def->getLocation(), diag::note_previous_definition);
     }
@@ -4530,7 +4530,7 @@
   // But don't complain if we're in GNU89 mode and the previous definition
   // was an extern inline function.
   const FunctionDecl *Definition;
-  if (FD->getBody(Definition) &&
+  if (FD->hasBody(Definition) &&
       !canRedefineFunction(Definition, getLangOptions())) {
     Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
     Diag(Definition->getLocation(), diag::note_previous_definition);
@@ -5917,7 +5917,7 @@
       typedef CXXRecordDecl::ctor_iterator ctor_iter;
       for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){
         const FunctionDecl *body = 0;
-        ci->getBody(body);
+        ci->hasBody(body);
         if (!body || !cast<CXXConstructorDecl>(body)->isImplicitlyDefined()) {
           SourceLocation CtorLoc = ci->getLocation();
           Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member;

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jul  7 06:31:19 2010
@@ -913,7 +913,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->hasBody();
   } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
     // We ignore weak import on properties and methods
     return;

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jul  7 06:31:19 2010
@@ -6652,7 +6652,7 @@
     if (const CXXMethodDecl *KeyFunction
                              = Context.getKeyFunction(DynamicClasses[I])) {
       const FunctionDecl *Definition = 0;
-      if (KeyFunction->getBody(Definition))
+      if (KeyFunction->hasBody(Definition))
         MarkVTableUsed(Definition->getLocation(), DynamicClasses[I], true);
     }
   }
@@ -6675,7 +6675,7 @@
     // defined in another translation unit, we don't need to emit the
     // vtable even though we're using it.
     const CXXMethodDecl *KeyFunction = Context.getKeyFunction(Class);
-    if (KeyFunction && !KeyFunction->getBody()) {
+    if (KeyFunction && !KeyFunction->hasBody()) {
       switch (KeyFunction->getTemplateSpecializationKind()) {
       case TSK_Undeclared:
       case TSK_ExplicitSpecialization:
@@ -6723,7 +6723,7 @@
     // Optionally warn if we're emitting a weak vtable.
     if (Class->getLinkage() == ExternalLinkage &&
         Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
-      if (!KeyFunction || (KeyFunction->getBody() && KeyFunction->isInlined()))
+      if (!KeyFunction || (KeyFunction->hasBody() && KeyFunction->isInlined()))
         Diag(Class->getLocation(), diag::warn_weak_vtable) << Class;
     }
   }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Jul  7 06:31:19 2010
@@ -3676,7 +3676,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->hasBody(Def) && NumArgs != Def->param_size()) {
         const FunctionProtoType *Proto =
             Def->getType()->getAs<FunctionProtoType>();
         if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Jul  7 06:31:19 2010
@@ -1442,7 +1442,7 @@
             SuppressNew)
           continue;
         
-        if (Function->getBody())
+        if (Function->hasBody())
           continue;
 
         if (TSK == TSK_ExplicitInstantiationDefinition) {
@@ -1452,7 +1452,7 @@
           //   specialization and is only an explicit instantiation definition 
           //   of members whose definition is visible at the point of 
           //   instantiation.
-          if (!Pattern->getBody())
+          if (!Pattern->hasBody())
             continue;
         
           Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=107768&r1=107767&r2=107768&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Jul  7 06:31:19 2010
@@ -1181,7 +1181,7 @@
         D->isThisDeclarationADefinition()) {
       // Check for a function body.
       const FunctionDecl *Definition = 0;
-      if (Function->getBody(Definition) &&
+      if (Function->hasBody(Definition) &&
           Definition->getTemplateSpecializationKind() == TSK_Undeclared) {
         SemaRef.Diag(Function->getLocation(), diag::err_redefinition) 
           << Function->getDeclName();
@@ -1197,7 +1197,7 @@
             ((*R)->getFriendObjectKind() != Decl::FOK_None)) {
           if (const FunctionDecl *RPattern
               = (*R)->getTemplateInstantiationPattern())
-            if (RPattern->getBody(RPattern)) {
+            if (RPattern->hasBody(RPattern)) {
               SemaRef.Diag(Function->getLocation(), diag::err_redefinition) 
                 << Function->getDeclName();
               SemaRef.Diag((*R)->getLocation(), diag::note_previous_definition);
@@ -2040,7 +2040,7 @@
                                          FunctionDecl *Function,
                                          bool Recursive,
                                          bool DefinitionRequired) {
-  if (Function->isInvalidDecl() || Function->getBody())
+  if (Function->isInvalidDecl() || Function->hasBody())
     return;
 
   // Never instantiate an explicit specialization.





More information about the cfe-commits mailing list