summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-05 21:40:05 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-05 21:40:05 +0000
commit1a68ab6c83e5fdd1a4d75fd4bdfc216498831735 (patch)
tree6c94b3bb2a1caa439cc485e99c5d0c26b987cafb /clang/test
parentaee326860c6f6ab8fdb7485dfb8841df8f925f74 (diff)
downloadbcm5719-llvm-1a68ab6c83e5fdd1a4d75fd4bdfc216498831735.tar.gz
bcm5719-llvm-1a68ab6c83e5fdd1a4d75fd4bdfc216498831735.zip
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. llvm-svn: 92779
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGenCXX/vtable-linkage.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/vtable-linkage.cpp b/clang/test/CodeGenCXX/vtable-linkage.cpp
index 23d78aadf7e..57380070418 100644
--- a/clang/test/CodeGenCXX/vtable-linkage.cpp
+++ b/clang/test/CodeGenCXX/vtable-linkage.cpp
@@ -30,6 +30,7 @@ void D::f() { }
static struct : D { } e;
+// The destructor is the key function.
template<typename T>
struct E {
virtual ~E();
@@ -37,6 +38,7 @@ struct E {
template<typename T> E<T>::~E() { }
+// Anchor is the key function
template<>
struct E<char> {
virtual void anchor();
@@ -54,6 +56,29 @@ void use_E() {
(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 @@ void use_E() {
// 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 @@ void use_E() {
// 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.
OpenPOWER on IntegriCloud