diff options
author | John McCall <rjmccall@apple.com> | 2010-08-04 06:38:15 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-04 06:38:15 +0000 |
commit | 0c7d32bde03ae90367cb0666cf8614d425290aa3 (patch) | |
tree | 8f1e13f1433f379b9db852c2670777f4715fd7e7 | |
parent | 0b2517299415ab1c28b9cb87d536ccea84317a10 (diff) |
Extend the hidden-visibility vtables optimization to template classes that
haven't been explicitly instantiated.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110189 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGVTables.cpp | 36 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-subst-std.cpp | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/virt-template-vtable.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/vtable-linkage.cpp | 16 |
4 files changed, 42 insertions, 18 deletions
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 052a6fdca3..9cb64c6d5b 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2929,18 +2929,34 @@ CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, // 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 + // possible that there might be unresolved references elsewhere + // which can only be resolved by this emission. 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); + !RD->hasAttr<VisibilityAttr>()) { + switch (RD->getTemplateSpecializationKind()) { + + // Every use of a non-template or explicitly-specialized class's + // vtable has to emit it. + case TSK_ExplicitSpecialization: + case TSK_Undeclared: + // Implicit instantiations can ignore the possibility of an + // explicit instantiation declaration because there necessarily + // must be an EI definition somewhere with default visibility. + case TSK_ImplicitInstantiation: + // If there's a key function, there may be translation units + // that don't have the key function's definition. + if (!CGM.Context.getKeyFunction(RD)) + // Otherwise, drop the visibility to hidden. + VTable->setVisibility(llvm::GlobalValue::HiddenVisibility); + break; + + // We have to disable the optimization if this is an EI definition + // because there might be EI declarations in other shared objects. + case TSK_ExplicitInstantiationDefinition: + case TSK_ExplicitInstantiationDeclaration: + break; + } } } diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index 9c1e978294..b08b12c91e 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -3,13 +3,13 @@ // Check mangling of Vtables, VTTs, and construction vtables that // involve standard substitutions. -// CHECK: @_ZTVSd = weak_odr constant +// CHECK: @_ZTVSd = weak_odr hidden constant // CHECK: @_ZTCSd0_Si = internal constant // CHECK: @_ZTCSd16_So = internal constant // CHECK: @_ZTTSd = weak_odr constant -// CHECK: @_ZTVSo = weak_odr constant +// CHECK: @_ZTVSo = weak_odr hidden constant // CHECK: @_ZTTSo = weak_odr constant -// CHECK: @_ZTVSi = weak_odr constant +// CHECK: @_ZTVSi = weak_odr hidden constant // CHECK: @_ZTTSi = weak_odr constant namespace std { struct A { A(); }; diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp index b955828312..ab406fd998 100644 --- a/test/CodeGenCXX/virt-template-vtable.cpp +++ b/test/CodeGenCXX/virt-template-vtable.cpp @@ -19,4 +19,4 @@ 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 +// CHECK: @_ZTV1AIiE = weak_odr hidden constant diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp index a4808d0b76..9b93a316be 100644 --- a/test/CodeGenCXX/vtable-linkage.cpp +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -11,6 +11,7 @@ // RUN: FileCheck --check-prefix=CHECK-10 %s < %t // RUN: FileCheck --check-prefix=CHECK-11 %s < %t // RUN: FileCheck --check-prefix=CHECK-12 %s < %t +// RUN: FileCheck --check-prefix=CHECK-13 %s < %t namespace { struct A { @@ -83,12 +84,13 @@ struct F<char> { template struct F<short>; extern template struct F<int>; -void use_F(F<char> &fc) { +void use_F() { + F<char> fc; + fc.foo(); F<int> fi; fi.foo(); F<long> fl; (void)fl; - fc.foo(); } // B has a key function that is not defined in this translation unit so its vtable @@ -135,8 +137,8 @@ void use_F(F<char> &fc) { // CHECK-7: @_ZTI1EIlE = weak_odr constant // F<long> is an implicit template instantiation with no key function, -// so its vtable should have weak_odr linkage. -// CHECK-8: @_ZTV1FIlE = weak_odr constant +// so its vtable should have weak_odr linkage and hidden visibility. +// CHECK-8: @_ZTV1FIlE = weak_odr hidden constant // CHECK-8: @_ZTS1FIlE = weak_odr constant // CHECK-8: @_ZTI1FIlE = weak_odr constant @@ -161,6 +163,12 @@ void use_F(F<char> &fc) { // CHECK-12: @_ZTSN12_GLOBAL__N_11AE = internal constant // CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal constant +// F<char> is an explicit specialization without a key function, so +// its vtable should have weak_odr linkage and hidden visibility. +// CHECK-13: @_ZTV1FIcE = weak_odr hidden constant +// CHECK-13: @_ZTS1FIcE = weak_odr constant +// CHECK-13: @_ZTI1FIcE = weak_odr constant + // RUN: FileCheck --check-prefix=CHECK-G %s < %t // // CHECK-G: @_ZTV1GIiE = weak_odr constant |