[cfe-commits] r102693 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp

Douglas Gregor dgregor at apple.com
Thu Apr 29 22:56:51 PDT 2010


Author: dgregor
Date: Fri Apr 30 00:56:50 2010
New Revision: 102693

URL: http://llvm.org/viewvc/llvm-project?rev=102693&view=rev
Log:
Introduce a sequence number into class template partial
specializations, which keeps track of the order in which they were
originally declared. We use this number so that we can always walk the
list of partial specializations in a predictable order during matching
or template instantiation. This also fixes a failure in Boost.Proto,
where SourceManager::isBeforeInTranslationUnit was behaving
poorly in inconsistent ways.

Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.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=102693&r1=102692&r2=102693&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Fri Apr 30 00:56:50 2010
@@ -1011,6 +1011,11 @@
   TemplateArgumentLoc *ArgsAsWritten;
   unsigned NumArgsAsWritten;
 
+  /// \brief Sequence number indicating when this class template partial
+  /// specialization was added to the set of partial specializations for
+  /// its owning class template.
+  unsigned SequenceNumber;
+    
   /// \brief The class template partial specialization from which this 
   /// class template partial specialization was instantiated.
   ///
@@ -1026,13 +1031,15 @@
                                          TemplateArgumentListBuilder &Builder,
                                          TemplateArgumentLoc *ArgInfos,
                                          unsigned NumArgInfos,
-                               ClassTemplatePartialSpecializationDecl *PrevDecl)
+                               ClassTemplatePartialSpecializationDecl *PrevDecl,
+                                         unsigned SequenceNumber)
     : ClassTemplateSpecializationDecl(Context,
                                       ClassTemplatePartialSpecialization,
                                       DC, L, SpecializedTemplate, Builder,
                                       PrevDecl),
       TemplateParams(Params), ArgsAsWritten(ArgInfos),
-      NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
+      NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+      InstantiatedFromMember(0, false) { }
 
 public:
   static ClassTemplatePartialSpecializationDecl *
@@ -1042,7 +1049,8 @@
          TemplateArgumentListBuilder &Builder,
          const TemplateArgumentListInfo &ArgInfos,
          QualType CanonInjectedType,
-         ClassTemplatePartialSpecializationDecl *PrevDecl);
+         ClassTemplatePartialSpecializationDecl *PrevDecl,
+         unsigned SequenceNumber);
 
   /// Get the list of template parameters
   TemplateParameterList *getTemplateParameters() const {
@@ -1059,6 +1067,10 @@
     return NumArgsAsWritten;
   }
 
+  /// \brief Get the sequence number for this class template partial
+  /// specialization.
+  unsigned getSequenceNumber() const { return SequenceNumber; }
+    
   /// \brief Retrieve the member class template partial specialization from
   /// which this particular class template partial specialization was
   /// instantiated.
@@ -1226,6 +1238,10 @@
     return CommonPtr->PartialSpecializations;
   }
 
+  /// \brief Retrieve the partial specializations as an ordered list.
+  void getPartialSpecializations(
+          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+  
   /// \brief Find a class template partial specialization with the given
   /// type T.
   ///

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=102693&r1=102692&r2=102693&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Fri Apr 30 00:56:50 2010
@@ -178,6 +178,20 @@
   C.Deallocate((void*)this);
 }
 
+void ClassTemplateDecl::getPartialSpecializations(
+          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
+  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
+    = CommonPtr->PartialSpecializations;
+  PS.clear();
+  PS.resize(PartialSpecs.size());
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+       P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
+       P != PEnd; ++P) {
+    assert(!PS[P->getSequenceNumber()]);
+    PS[P->getSequenceNumber()] = &*P;
+  }
+}
+
 ClassTemplatePartialSpecializationDecl *
 ClassTemplateDecl::findPartialSpecialization(QualType T) {
   ASTContext &Context = getASTContext();
@@ -456,7 +470,8 @@
        TemplateArgumentListBuilder &Builder,
        const TemplateArgumentListInfo &ArgInfos,
        QualType CanonInjectedType,
-       ClassTemplatePartialSpecializationDecl *PrevDecl) {
+       ClassTemplatePartialSpecializationDecl *PrevDecl,
+       unsigned SequenceNumber) {
   unsigned N = ArgInfos.size();
   TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
   for (unsigned I = 0; I != N; ++I)
@@ -468,7 +483,8 @@
                                                           SpecializedTemplate,
                                                           Builder,
                                                           ClonedArgs, N,
-                                                          PrevDecl);
+                                                          PrevDecl,
+                                                          SequenceNumber);
   Result->setSpecializationKind(TSK_ExplicitSpecialization);
 
   Context.getInjectedClassNameType(Result, CanonInjectedType);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=102693&r1=102692&r2=102693&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Apr 30 00:56:50 2010
@@ -3781,6 +3781,8 @@
     // Create a new class template partial specialization declaration node.
     ClassTemplatePartialSpecializationDecl *PrevPartial
       = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
+    unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber()
+                            : ClassTemplate->getPartialSpecializations().size();
     ClassTemplatePartialSpecializationDecl *Partial
       = ClassTemplatePartialSpecializationDecl::Create(Context,
                                              ClassTemplate->getDeclContext(),
@@ -3790,7 +3792,8 @@
                                                        Converted,
                                                        TemplateArgs,
                                                        CanonType,
-                                                       PrevPartial);
+                                                       PrevPartial,
+                                                       SequenceNumber);
     SetNestedNameSpecifier(Partial, SS);
 
     if (PrevPartial) {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=102693&r1=102692&r2=102693&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri Apr 30 00:56:50 2010
@@ -1278,21 +1278,20 @@
   typedef std::pair<ClassTemplatePartialSpecializationDecl *,
                     TemplateArgumentList *> MatchResult;
   llvm::SmallVector<MatchResult, 4> Matched;
-  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
-         Partial = Template->getPartialSpecializations().begin(),
-         PartialEnd = Template->getPartialSpecializations().end();
-       Partial != PartialEnd;
-       ++Partial) {
+  llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+  Template->getPartialSpecializations(PartialSpecs);
+  for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
+    ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
     TemplateDeductionInfo Info(Context, PointOfInstantiation);
     if (TemplateDeductionResult Result
-          = DeduceTemplateArguments(&*Partial,
+          = DeduceTemplateArguments(Partial,
                                     ClassTemplateSpec->getTemplateArgs(),
                                     Info)) {
       // FIXME: Store the failed-deduction information for use in
       // diagnostics, later.
       (void)Result;
     } else {
-      Matched.push_back(std::make_pair(&*Partial, Info.take()));
+      Matched.push_back(std::make_pair(Partial, Info.take()));
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=102693&r1=102692&r2=102693&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Apr 30 00:56:50 2010
@@ -620,21 +620,6 @@
   return 0;
 }
 
-namespace {
-  class SortDeclByLocation {
-    SourceManager &SourceMgr;
-    
-  public:
-    explicit SortDeclByLocation(SourceManager &SourceMgr) 
-      : SourceMgr(SourceMgr) { }
-    
-    bool operator()(const Decl *X, const Decl *Y) const {
-      return SourceMgr.isBeforeInTranslationUnit(X->getLocation(),
-                                                 Y->getLocation());
-    }
-  };
-}
-
 Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
 
@@ -791,19 +776,10 @@
   
   Owner->addDecl(Inst);
   
-  // First, we sort the partial specializations by location, so 
-  // that we instantiate them in the order they were declared.
-  llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
-  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
-         P = D->getPartialSpecializations().begin(), 
-         PEnd = D->getPartialSpecializations().end();
-       P != PEnd; ++P)
-    PartialSpecs.push_back(&*P);
-  std::sort(PartialSpecs.begin(), PartialSpecs.end(),
-            SortDeclByLocation(SemaRef.SourceMgr));
-  
   // Instantiate all of the partial specializations of this member class 
   // template.
+  llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+  D->getPartialSpecializations(PartialSpecs);
   for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
     InstantiateClassTemplatePartialSpecialization(Inst, PartialSpecs[I]);
   
@@ -1768,7 +1744,8 @@
                                                      Converted,
                                                      InstTemplateArgs,
                                                      CanonType,
-                                                     0);
+                                                     0,
+                             ClassTemplate->getPartialSpecializations().size());
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(PartialSpec, InstPartialSpec))
     return 0;





More information about the cfe-commits mailing list