r191418 - If a partial specialization of a member template is declared within a class

Richard Smith richard-llvm at metafoo.co.uk
Wed Sep 25 20:49:48 PDT 2013


Author: rsmith
Date: Wed Sep 25 22:49:48 2013
New Revision: 191418

URL: http://llvm.org/viewvc/llvm-project?rev=191418&view=rev
Log:
If a partial specialization of a member template is declared within a class
template and defined outside it, don't instantiate it twice when instantiating
the surrounding class template specialization. That would cause us to reject
the code because we think two partial specializations instantiated to produce
the same signature.

Added:
    cfe/trunk/test/SemaTemplate/instantiate-partial-spec.cpp
Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=191418&r1=191417&r2=191418&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Sep 25 22:49:48 2013
@@ -2142,13 +2142,25 @@ Sema::InstantiateClass(SourceLocation Po
 
     // Instantiate any out-of-line class template partial
     // specializations now.
-    for (TemplateDeclInstantiator::delayed_partial_spec_iterator 
+    for (TemplateDeclInstantiator::delayed_partial_spec_iterator
               P = Instantiator.delayed_partial_spec_begin(),
            PEnd = Instantiator.delayed_partial_spec_end();
          P != PEnd; ++P) {
       if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
-                                                                P->first,
-                                                                P->second)) {
+              P->first, P->second)) {
+        Instantiation->setInvalidDecl();
+        break;
+      }
+    }
+
+    // Instantiate any out-of-line variable template partial
+    // specializations now.
+    for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
+              P = Instantiator.delayed_var_partial_spec_begin(),
+           PEnd = Instantiator.delayed_var_partial_spec_end();
+         P != PEnd; ++P) {
+      if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
+              P->first, P->second)) {
         Instantiation->setInvalidDecl();
         break;
       }

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=191418&r1=191417&r2=191418&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Sep 25 22:49:48 2013
@@ -923,7 +923,7 @@ Decl *TemplateDeclInstantiator::VisitCla
     SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
     D->getPartialSpecializations(PartialSpecs);
     for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
-      if (PartialSpecs[I]->isOutOfLine())
+      if (PartialSpecs[I]->getFirstDeclaration()->isOutOfLine())
         OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I]));
   }
 
@@ -1004,7 +1004,7 @@ Decl *TemplateDeclInstantiator::VisitVar
     SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs;
     D->getPartialSpecializations(PartialSpecs);
     for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
-      if (PartialSpecs[I]->isOutOfLine())
+      if (PartialSpecs[I]->getFirstDeclaration()->isOutOfLine())
         OutOfLineVarPartialSpecs.push_back(
             std::make_pair(Inst, PartialSpecs[I]));
   }

Added: cfe/trunk/test/SemaTemplate/instantiate-partial-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-partial-spec.cpp?rev=191418&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-partial-spec.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-partial-spec.cpp Wed Sep 25 22:49:48 2013
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++1y -verify %s
+// expected-no-diagnostics
+
+template<typename T> struct A {
+  template<typename U> struct B;
+  template<typename U> struct B<U*>;
+};
+template<typename T> template<typename U> struct A<T>::B<U*> {};
+template struct A<int>;
+A<int>::B<int*> b;
+
+
+template<typename T> struct B {
+  template<typename U> static const int var1;
+  template<typename U> static const int var1<U*>;
+
+  template<typename U> static const int var2;
+};
+template<typename T> template<typename U> const int B<T>::var1<U*> = 1;
+template<typename T> template<typename U> const int B<T>::var2<U*> = 1;
+template struct B<int>;
+int b_test1[B<int>::var1<int*>];
+int b_test2[B<int>::var2<int*>];





More information about the cfe-commits mailing list