[cfe-commits] r84216 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/extern-templates.cpp test/SemaTemplate/variadic-class-template-2.cpp

Douglas Gregor dgregor at apple.com
Thu Oct 15 15:53:22 PDT 2009


Author: dgregor
Date: Thu Oct 15 17:53:21 2009
New Revision: 84216

URL: http://llvm.org/viewvc/llvm-project?rev=84216&view=rev
Log:
Make the remaining explicit-instantiation semantic action use
CheckSpecializationInstantiationRedecl to check for
redeclarations/instantiations. Also fixes a longstanding issue where
our explicit-instantiation location information wasn't as good as it
could have been.

Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaTemplate/extern-templates.cpp
    cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=84216&r1=84215&r2=84216&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Oct 15 17:53:21 2009
@@ -3630,54 +3630,18 @@
   
   ClassTemplateSpecializationDecl *Specialization = 0;
 
-  bool SpecializationRequiresInstantiation = true;
   if (PrevDecl) {
-    if (PrevDecl->getSpecializationKind()
-          == TSK_ExplicitInstantiationDefinition) {
-      // This particular specialization has already been declared or
-      // instantiated. We cannot explicitly instantiate it.
-      Diag(TemplateNameLoc, diag::err_explicit_instantiation_duplicate)
-        << Context.getTypeDeclType(PrevDecl);
-      Diag(PrevDecl->getLocation(),
-           diag::note_previous_explicit_instantiation);
+    bool SuppressNew = false;
+    if (CheckSpecializationInstantiationRedecl(*this, TemplateNameLoc, TSK,
+                                               PrevDecl, 
+                                              PrevDecl->getSpecializationKind(), 
+                                            PrevDecl->getPointOfInstantiation(),
+                                               SuppressNew))
       return DeclPtrTy::make(PrevDecl);
-    }
 
-    if (PrevDecl->getSpecializationKind() == TSK_ExplicitSpecialization) {
-      // C++ DR 259, C++0x [temp.explicit]p4:
-      //   For a given set of template parameters, if an explicit
-      //   instantiation of a template appears after a declaration of
-      //   an explicit specialization for that template, the explicit
-      //   instantiation has no effect.
-      if (!getLangOptions().CPlusPlus0x) {
-        Diag(TemplateNameLoc,
-             diag::ext_explicit_instantiation_after_specialization)
-          << Context.getTypeDeclType(PrevDecl);
-        Diag(PrevDecl->getLocation(),
-             diag::note_previous_template_specialization);
-      }
-
-      // Create a new class template specialization declaration node
-      // for this explicit specialization. This node is only used to
-      // record the existence of this explicit instantiation for
-      // accurate reproduction of the source code; we don't actually
-      // use it for anything, since it is semantically irrelevant.
-      Specialization
-        = ClassTemplateSpecializationDecl::Create(Context,
-                                             ClassTemplate->getDeclContext(),
-                                                  TemplateNameLoc,
-                                                  ClassTemplate,
-                                                  Converted, 0);
-      Specialization->setLexicalDeclContext(CurContext);
-      CurContext->addDecl(Specialization);
+    if (SuppressNew)
       return DeclPtrTy::make(PrevDecl);
-    }
-
-    // If we have already (implicitly) instantiated this
-    // specialization, there is less work to do.
-    if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation)
-      SpecializationRequiresInstantiation = false;
-
+    
     if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation ||
         PrevDecl->getSpecializationKind() == TSK_Undeclared) {
       // Since the only prior class template specialization with these
@@ -3688,7 +3652,7 @@
       Specialization->setLocation(TemplateNameLoc);
       PrevDecl = 0;
     }
-  } 
+  }
   
   if (!Specialization) {
     // Create a new class template specialization declaration node for
@@ -3741,11 +3705,13 @@
   //
   // This check comes when we actually try to perform the
   // instantiation.
-  if (SpecializationRequiresInstantiation)
+  ClassTemplateSpecializationDecl *Def
+    = cast_or_null<ClassTemplateSpecializationDecl>(
+                                        Specialization->getDefinition(Context));
+  if (!Def)
     InstantiateClassTemplateSpecialization(Specialization, TSK);
   else // Instantiate the members of this class template specialization.
-    InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization,
-                                                  TSK);
+    InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
 
   return DeclPtrTy::make(Specialization);
 }
@@ -3836,7 +3802,9 @@
       return TagD;
   }
   
-  if (!Record->getDefinition(Context)) {
+  CXXRecordDecl *RecordDef
+    = cast_or_null<CXXRecordDecl>(Record->getDefinition(Context));
+  if (!RecordDef) {
     // C++ [temp.explicit]p3:
     //   A definition of a member class of a class template shall be in scope 
     //   at the point of an explicit instantiation of the member class.
@@ -3848,12 +3816,12 @@
       Diag(Pattern->getLocation(), diag::note_forward_declaration)
         << Pattern;
       return true;
-    } else if (InstantiateClass(TemplateLoc, Record, Def,
+    } else if (InstantiateClass(NameLoc, Record, Def,
                                 getTemplateInstantiationArgs(Record),
                                 TSK))
       return true;
   } else // Instantiate all of the members of the class.
-    InstantiateClassMembers(TemplateLoc, Record,
+    InstantiateClassMembers(NameLoc, RecordDef,
                             getTemplateInstantiationArgs(Record), TSK);
 
   // FIXME: We don't have any representation for explicit instantiations of

Modified: cfe/trunk/test/SemaTemplate/extern-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/extern-templates.cpp?rev=84216&r1=84215&r2=84216&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/extern-templates.cpp (original)
+++ cfe/trunk/test/SemaTemplate/extern-templates.cpp Thu Oct 15 17:53:21 2009
@@ -29,16 +29,14 @@
   xii.g(0);
 }
 
-// FIXME: we would like the notes to point to the explicit instantiation at the
-// bottom.
-extern template class X0<long*>; // expected-note 2{{instantiation}}
+extern template class X0<long*>; 
 
 void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
   xl.f(0);
   xli.g(0);
 }
 
-template class X0<long*>;
+template class X0<long*>; // expected-note 2{{instantiation}}
 
 template<typename T>
 class X1 {

Modified: cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp?rev=84216&r1=84215&r2=84216&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp (original)
+++ cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp Thu Oct 15 17:53:21 2009
@@ -14,6 +14,6 @@
 
 template <typename = int, typename ...> struct TS3 {}; // expected-note{{template parameter is declared here}}
 template struct TS3<>; // expected-note{{previous explicit instantiation is here}}
-template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3<>'}}
+template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3}}
 template struct TS3<int, int>;
 template struct TS3<10>; // expected-error{{template argument for template type parameter must be a type}}





More information about the cfe-commits mailing list