[cfe-commits] r92779 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-linkage.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 5 13:40:05 PST 2010


Author: dgregor
Date: Tue Jan  5 15:40:05 2010
New Revision: 92779

URL: http://llvm.org/viewvc/llvm-project?rev=92779&view=rev
Log:
Make use of available_externally linkage for vtables when the
non-inline key function of a class template instantiation, when no key
function is present, the class template instantiation itself was
instantiated with an explicit instantiation declaration (aka extern
template). I'm fairly certain that the C++0x specification gives us
this lattitude, although GCC doesn't take advantage of it.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=92779&r1=92778&r2=92779&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Tue Jan  5 15:40:05 2010
@@ -1501,16 +1501,31 @@
       break;
 
     case TSK_ImplicitInstantiation:
-    case TSK_ExplicitInstantiationDeclaration:
-      // FIXME: could an explicit instantiation declaration imply
-      // available_externally linkage?
     case TSK_ExplicitInstantiationDefinition:
       Linkage = llvm::GlobalVariable::WeakODRLinkage;
       break;
+
+    case TSK_ExplicitInstantiationDeclaration:
+      Linkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+      break;
     }
   }
-  else
+  else if (KeyFunction)
     Linkage = llvm::GlobalVariable::WeakODRLinkage;
+  else {
+    switch (RD->getTemplateSpecializationKind()) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+    case TSK_ImplicitInstantiation:
+    case TSK_ExplicitInstantiationDefinition:
+      Linkage = llvm::GlobalVariable::WeakODRLinkage;
+      break;
+
+    case TSK_ExplicitInstantiationDeclaration:
+      Linkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+      break;
+    }
+  }
   
   // Emit the data.
   GenerateClassData(Linkage, RD);

Modified: cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp?rev=92779&r1=92778&r2=92779&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp Tue Jan  5 15:40:05 2010
@@ -30,6 +30,7 @@
 
 static struct : D { } e;
 
+// The destructor is the key function.
 template<typename T>
 struct E {
   virtual ~E();
@@ -37,6 +38,7 @@
 
 template<typename T> E<T>::~E() { }
 
+// Anchor is the key function
 template<>
 struct E<char> {
   virtual void anchor();
@@ -54,6 +56,29 @@
   (void)el;
 }
 
+// No key function
+template<typename T>
+struct F {
+  virtual void foo() { }
+};
+
+// No key function
+template<>
+struct F<char> {
+  virtual void foo() { }
+};
+
+template struct F<short>;
+extern template struct F<int>;
+
+void use_F(F<char> &fc) {
+  F<int> fi;
+  (void)fi;
+  F<long> fl;
+  (void)fl;
+  fc.foo();
+}
+
 // B has a key function that is not defined in this translation unit so its vtable
 // has external linkage.
 // CHECK: @_ZTV1B = external constant
@@ -79,6 +104,10 @@
 // weak_odr linkage.
 // CHECK: @_ZTV1EIsE = weak_odr constant
 
+// F<short> is an explicit template instantiation without a key
+// function, so its vtable should have weak_odr linkage
+// CHECK: @_ZTV1FIsE = weak_odr constant
+
 // E<long> is an implicit template instantiation with a key function
 // defined in this translation unit, so its vtable should have
 // weak_odr linkage.
@@ -90,6 +119,14 @@
 // CHECK: @"_ZTI3$_0" = internal constant
 // CHECK: @"_ZTV3$_0" = internal constant
 
+// F<long> is an implicit template instantiation with no key function,
+// so its vtable should have weak_odr linkage.
+// CHECK: @_ZTV1FIlE = weak_odr constant
+
+// F<int> is an explicit template instantiation declaration without a
+// key function, so its vtable should have weak_odr linkage.
+// CHECK: @_ZTV1FIiE = available_externally constant
+
 // E<int> is an explicit template instantiation declaration. It has a
 // key function that is not instantiation, so we should only reference
 // its vtable, not define it.





More information about the cfe-commits mailing list