[cfe-commits] r108834 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/Decl.cpp lib/AST/DeclTemplate.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Jul 20 06:59:58 PDT 2010


Author: akirtzidis
Date: Tue Jul 20 08:59:58 2010
New Revision: 108834

URL: http://llvm.org/viewvc/llvm-project?rev=108834&view=rev
Log:
Hide FunctionTemplateDecl's specializations folding set as implementation detail and introduce
FunctionTemplateDecl::findSpecialization.

Redeclarations of specializations will not cause the previous decl to be removed from the set,
the set will keep the canonical decl. findSpecialization will return the most recent redeclaration.

Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=108834&r1=108833&r2=108834&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Tue Jul 20 08:59:58 2010
@@ -522,6 +522,20 @@
   /// may implicitly allocate memory for the common pointer.
   Common *getCommonPtr();
 
+  /// \brief Retrieve the set of function template specializations of this
+  /// function template.
+  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+    return getCommonPtr()->Specializations;
+  }
+  
+  friend void FunctionDecl::setFunctionTemplateSpecialization(
+                                       FunctionTemplateDecl *Template,
+                                       const TemplateArgumentList *TemplateArgs,
+                                       void *InsertPos,
+                                       TemplateSpecializationKind TSK,
+                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
+                                       SourceLocation PointOfInstantiation);
+
   FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
                        TemplateParameterList *Params, NamedDecl *Decl)
     : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
@@ -535,11 +549,10 @@
     return static_cast<FunctionDecl*>(TemplatedDecl);
   }
 
-  /// \brief Retrieve the set of function template specializations of this
-  /// function template.
-  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
-    return getCommonPtr()->Specializations;
-  }
+  /// \brief Return the specialization with the provided arguments if it exists,
+  /// otherwise return the insertion point.
+  FunctionDecl *findSpecialization(const TemplateArgument *Args,
+                                   unsigned NumArgs, void *&InsertPos);
 
   /// \brief Retrieve the previous declaration of this function template, or
   /// NULL if no such declaration exists.

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=108834&r1=108833&r2=108834&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Jul 20 08:59:58 2010
@@ -1400,14 +1400,15 @@
   if (InsertPos)
     Template->getSpecializations().InsertNode(Info, InsertPos);
   else {
-    // Try to insert the new node. If there is an existing node, remove it 
-    // first.
+    // Try to insert the new node. If there is an existing node, leave it, the
+    // set will contain the canonical decls while
+    // FunctionTemplateDecl::findSpecialization will return
+    // the most recent redeclarations.
     FunctionTemplateSpecializationInfo *Existing
       = Template->getSpecializations().GetOrInsertNode(Info);
-    if (Existing) {
-      Template->getSpecializations().RemoveNode(Existing);
-      Template->getSpecializations().GetOrInsertNode(Info);
-    }
+    (void)Existing;
+    assert((!Existing || Existing->Function->isCanonicalDecl()) &&
+           "Set is supposed to only contain canonical decls");
   }
 }
 

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=108834&r1=108833&r2=108834&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Tue Jul 20 08:59:58 2010
@@ -119,6 +119,16 @@
   Decl::Destroy(C);
 }
 
+FunctionDecl *
+FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
+                                         unsigned NumArgs, void *&InsertPos) {
+  llvm::FoldingSetNodeID ID;
+  FunctionTemplateSpecializationInfo::Profile(ID,Args,NumArgs, getASTContext());
+  FunctionTemplateSpecializationInfo *Info
+      = getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+  return Info ? Info->Function->getMostRecentDeclaration() : 0;
+}
+
 FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
   FunctionTemplateDecl *FunTmpl = this;
   while (FunTmpl->getPreviousDeclaration())

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=108834&r1=108833&r2=108834&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Tue Jul 20 08:59:58 2010
@@ -254,11 +254,12 @@
     
     SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
 
-    FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
-                                          TemplArgs.data(), TSK,
-                                          TemplArgLocs.size(),
-                                          TemplArgLocs.data(),
-                                          LAngleLoc, RAngleLoc, POI);
+    if (FD->isCanonicalDecl()) // if canonical add to template's set.
+      FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
+                                            TemplArgs.data(), TSK,
+                                            TemplArgLocs.size(),
+                                            TemplArgLocs.data(),
+                                            LAngleLoc, RAngleLoc, POI);
     break;
   }
   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=108834&r1=108833&r2=108834&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Tue Jul 20 08:59:58 2010
@@ -929,8 +929,11 @@
     Record.push_back(D->getSpecializations().size());
     for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
            I = D->getSpecializations().begin(),
-           E = D->getSpecializations().end()   ; I != E; ++I)
+           E = D->getSpecializations().end()   ; I != E; ++I) {
+      assert(I->Function->isCanonicalDecl() &&
+             "Expected only canonical decls in set");
       Writer.AddDeclRef(I->Function, Record);
+    }
 
     Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
     if (D->getInstantiatedFromMemberTemplate())

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=108834&r1=108833&r2=108834&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Jul 20 08:59:58 2010
@@ -968,20 +968,16 @@
   FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
   void *InsertPos = 0;
   if (FunctionTemplate && !TemplateParams) {
-    llvm::FoldingSetNodeID ID;
     std::pair<const TemplateArgument *, unsigned> Innermost 
       = TemplateArgs.getInnermost();
-    FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
-                                                Innermost.second,
-                                                SemaRef.Context);
-
-    FunctionTemplateSpecializationInfo *Info
-      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
-                                                                   InsertPos);
+
+    FunctionDecl *SpecFunc
+      = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+                                             InsertPos);
 
     // If we already have a function template specialization, return it.
-    if (Info)
-      return Info->Function;
+    if (SpecFunc)
+      return SpecFunc;
   }
 
   bool isFriend;
@@ -1222,20 +1218,16 @@
     // We are creating a function template specialization from a function
     // template. Check whether there is already a function template
     // specialization for this particular set of template arguments.
-    llvm::FoldingSetNodeID ID;
     std::pair<const TemplateArgument *, unsigned> Innermost 
       = TemplateArgs.getInnermost();
-    FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
-                                                Innermost.second,
-                                                SemaRef.Context);
-
-    FunctionTemplateSpecializationInfo *Info
-      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
-                                                                   InsertPos);
+
+    FunctionDecl *SpecFunc
+      = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+                                             InsertPos);
 
     // If we already have a function template specialization, return it.
-    if (Info)
-      return Info->Function;
+    if (SpecFunc)
+      return SpecFunc;
   }
 
   bool isFriend;





More information about the cfe-commits mailing list