[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