aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-03 07:24:12 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-03 07:24:12 +0000
commit3d640e606165daf2eaf18d52c0697f68daec106a (patch)
tree18ecf011d07fa3119666f94012814d1a999ca880
parente3273e78da4716f9c999ae207f6898f376a6e1a4 (diff)
Emit weak vtables of non-template classes with hidden visibility.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110107 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGVTables.cpp16
-rw-r--r--test/CodeGenCXX/key-function-vtable.cpp8
-rw-r--r--test/CodeGenCXX/virt-template-vtable.cpp9
-rw-r--r--test/CodeGenCXX/vtable-key-function.cpp2
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp5
5 files changed, 33 insertions, 7 deletions
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index f597a1338c..052a6fdca3 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -2926,6 +2926,22 @@ CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,
// Set the right visibility.
CGM.setGlobalVisibility(VTable, RD);
+
+ // It's okay to have multiple copies of a vtable, so don't make the
+ // dynamic linker unique them. Suppress this optimization if it's
+ // possible that there might be unresolved references elsewhere,
+ // which can happen if
+ // - there's a key function and the vtable is getting emitted weak
+ // anyway for whatever reason
+ // - there might be an explicit instantiation declaration somewhere,
+ // i.e. if it's a template at all
+ if (Linkage == llvm::GlobalVariable::WeakODRLinkage &&
+ VTable->getVisibility() == llvm::GlobalVariable::DefaultVisibility &&
+ !RD->hasAttr<VisibilityAttr>() &&
+ RD->getTemplateSpecializationKind() == TSK_Undeclared &&
+ !CGM.Context.getKeyFunction(RD)) {
+ VTable->setVisibility(llvm::GlobalVariable::HiddenVisibility);
+ }
}
llvm::GlobalVariable *
diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp
index 1cfeb0c502..e71fba692f 100644
--- a/test/CodeGenCXX/key-function-vtable.cpp
+++ b/test/CodeGenCXX/key-function-vtable.cpp
@@ -12,11 +12,11 @@ testb *testbvar = new testb;
struct testc { virtual void a(); };
inline void testc::a() {}
-// Key functions with inline specifier (PR5705)
+// Functions with inline specifier are not key functions (PR5705)
struct testd { inline virtual void a(); };
void testd::a() {}
-// Key functions with inline specifier (PR5705)
+// Functions with inline specifier are not key functions (PR5705)
struct teste { inline virtual void a(); };
teste *testevar = new teste;
@@ -47,5 +47,5 @@ void use_X1(X1 *x1) { x1->f(); }
// CHECK: @_ZTV5testa = constant [3 x i8*] [i8* null
// CHECK: @_ZTV5testc = weak_odr constant [3 x i8*] [i8* null
// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5teste = weak_odr constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5testb = weak_odr constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5teste = weak_odr hidden constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5testb = weak_odr hidden constant [3 x i8*] [i8* null
diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp
index b968f38c82..b955828312 100644
--- a/test/CodeGenCXX/virt-template-vtable.cpp
+++ b/test/CodeGenCXX/virt-template-vtable.cpp
@@ -10,4 +10,13 @@ class B : A<int> {
};
B::B() {}
+template class A<long>;
+
+extern template class A<short>;
+template class A<short>;
+
+
+// CHECK: @_ZTV1B = weak_odr hidden constant
+// CHECK: @_ZTV1AIlE = weak_odr constant
+// CHECK: @_ZTV1AIsE = weak_odr constant
// CHECK: @_ZTV1AIiE = weak_odr constant
diff --git a/test/CodeGenCXX/vtable-key-function.cpp b/test/CodeGenCXX/vtable-key-function.cpp
index 97a546f8c9..bdcab230c6 100644
--- a/test/CodeGenCXX/vtable-key-function.cpp
+++ b/test/CodeGenCXX/vtable-key-function.cpp
@@ -9,7 +9,7 @@ struct A {
// A does not have a key function, so the first constructor we emit should
// cause the vtable to be defined (without assertions.)
-// CHECK: @_ZTVN6PR56971AE = weak_odr constant
+// CHECK: @_ZTVN6PR56971AE = weak_odr hidden constant
A::A() { }
A::A(int) { }
}
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index b3b68703c6..a4808d0b76 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -95,8 +95,9 @@ void use_F(F<char> &fc) {
// has external linkage.
// CHECK-1: @_ZTV1B = external constant
-// C has no key function, so its vtable should have weak_odr linkage.
-// CHECK-2: @_ZTV1C = weak_odr constant
+// C has no key function, so its vtable should have weak_odr linkage
+// and hidden visibility (rdar://problem/7523229).
+// CHECK-2: @_ZTV1C = weak_odr hidden constant
// CHECK-2: @_ZTS1C = weak_odr constant
// CHECK-2: @_ZTI1C = weak_odr constant