diff options
author | John McCall <rjmccall@apple.com> | 2010-08-03 07:24:12 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-03 07:24:12 +0000 |
commit | 3d640e606165daf2eaf18d52c0697f68daec106a (patch) | |
tree | 18ecf011d07fa3119666f94012814d1a999ca880 | |
parent | e3273e78da4716f9c999ae207f6898f376a6e1a4 (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.cpp | 16 | ||||
-rw-r--r-- | test/CodeGenCXX/key-function-vtable.cpp | 8 | ||||
-rw-r--r-- | test/CodeGenCXX/virt-template-vtable.cpp | 9 | ||||
-rw-r--r-- | test/CodeGenCXX/vtable-key-function.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/vtable-linkage.cpp | 5 |
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 |