]> granicus.if.org Git - clang/commitdiff
Skip implicit instantiation of templated variables where a more recent
authorChandler Carruth <chandlerc@gmail.com>
Sat, 13 Feb 2010 10:17:50 +0000 (10:17 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 13 Feb 2010 10:17:50 +0000 (10:17 +0000)
redeclaration provides an explicit instantiation or is invalid.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96097 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/explicit-instantiation.cpp

index caeea5847068640b2445ebe735af0292af48cb3a..a55193aa74f25478ccf3cce7e8e1ae68d957a0e0 100644 (file)
@@ -2323,6 +2323,24 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
     VarDecl *Var = cast<VarDecl>(Inst.first);
     assert(Var->isStaticDataMember() && "Not a static data member?");
 
+    // Don't try to instantiate declarations if the most recent redeclaration
+    // is invalid.
+    if (Var->getMostRecentDeclaration()->isInvalidDecl())
+      continue;
+
+    // Check if the most recent declaration has changed the specialization kind
+    // and removed the need for implicit instantiation.
+    switch (Var->getMostRecentDeclaration()->getTemplateSpecializationKind()) {
+    case TSK_Undeclared:
+      assert(false && "Cannot instantitiate an undeclared specialization.");
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+    case TSK_ExplicitSpecialization:
+      continue;  // No longer need implicit instantiation.
+    case TSK_ImplicitInstantiation:
+      break;
+    }
+
     PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var),
                                           Var->getLocation(), *this,
                                           Context.getSourceManager(),
index 227856f1a8e22d08ec019a8f45cc33d5327f4757..de51f0992baa3ae01bac2d8b922e75a36eb24328 100644 (file)
@@ -76,3 +76,10 @@ template void print_type<double>(double*);
 // PR5069
 template<int I> void foo0 (int (&)[I + 1]) { }
 template void foo0<2> (int (&)[3]);
+
+namespace explicit_instantiation_after_implicit_instantiation {
+  template <int I> struct X0 { static int x; };
+  template <int I> int X0<I>::x;
+  void test1() { (void)&X0<1>::x; }
+  template struct X0<1>;
+}