]> granicus.if.org Git - clang/commitdiff
Fix a bug where an explicit instantiation declaration of a class template
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Mar 2014 23:54:09 +0000 (23:54 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Mar 2014 23:54:09 +0000 (23:54 +0000)
specialization would make us think it might have a key function.

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

lib/AST/RecordLayoutBuilder.cpp
test/CodeGenCXX/template-instantiation.cpp

index 0c21bde38204b26ed4e78f9a1cae72dfcdfb1d7d..ce55d2e49abcdce5eae0c69102e7f2d326b07fdb 100644 (file)
@@ -1957,10 +1957,11 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
   if (!RD->isExternallyVisible())
     return 0;
 
-  // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6.
+  // Template instantiations don't have key functions per Itanium C++ ABI 5.2.6.
   // Same behavior as GCC.
   TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
   if (TSK == TSK_ImplicitInstantiation ||
+      TSK == TSK_ExplicitInstantiationDeclaration ||
       TSK == TSK_ExplicitInstantiationDefinition)
     return 0;
 
index 80283a1edd047f1af37a6a353c9a9e75a4a2fbe6..3baa946b0b1c9d452221a960f045684aadaf0105 100644 (file)
@@ -5,11 +5,15 @@
 //
 // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
 // CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
-// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant
+// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
+// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
+// CHECK:     @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
 
 // CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32]
 // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A
 
+// CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
+
 // CHECK-NOT: _ZTVN5test31SIiEE
 // CHECK-NOT: _ZTSN5test31SIiEE
 
@@ -39,11 +43,21 @@ namespace test0 {
     virtual void      xsgetn();
   };
 
-  // This specialization should cause the vtable to be emitted, even with
-  // the following extern template declaration.
-  template<> void stdio_sync_filebuf<wchar_t>::xsgetn()  {
+  // This specialization is not a key function, so doesn't cause the vtable to
+  // be instantiated unless we're instantiating a class definition anyway.
+  template<> void stdio_sync_filebuf<int[1]>::xsgetn()  {
+  }
+  template<> void stdio_sync_filebuf<int[2]>::xsgetn()  {
+  }
+  template<> void stdio_sync_filebuf<int[3]>::xsgetn()  {
   }
-  extern template class stdio_sync_filebuf<wchar_t>;
+  template<> void stdio_sync_filebuf<int[4]>::xsgetn()  {
+  }
+  extern template class stdio_sync_filebuf<int[2]>;
+
+  // These two both cause vtables to be emitted.
+  template class stdio_sync_filebuf<int[3]>;
+  stdio_sync_filebuf<int[4]> implicit_instantiation;
 }
 
 namespace test1 {