diff options
author | John McCall <rjmccall@apple.com> | 2010-08-04 08:34:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-04 08:34:44 +0000 |
commit | cbfe50224b19119e759802bd0c1463269dffd09e (patch) | |
tree | e7d15b5599d9f22a0502f085031bd854574cf50b /lib/CodeGen/CodeGenModule.cpp | |
parent | 72905cfa81cfd126f322c4173f56d332aac5539e (diff) |
Emit standard-library RTTI with external linkage, not weak_odr.
Apply hidden visibility to most RTTI; libstdc++ does not rely on exact
pointer equality for the type info (just the type info names). Apply
the same optimization to RTTI that we do to vtables.
Fixes PR5962.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110192 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 63d79132b1..d2be5af14a 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -216,6 +216,57 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV, } } +/// Set the symbol visibility of type information (vtable and RTTI) +/// associated with the given type. +void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV, + const CXXRecordDecl *RD, + bool IsForRTTI) const { + setGlobalVisibility(GV, RD); + + // We want to drop the visibility to hidden for weak type symbols. + // This isn't possible if there might be unresolved references + // elsewhere that rely on this symbol being visible. + + // Preconditions. + if (GV->getLinkage() != llvm::GlobalVariable::WeakODRLinkage || + GV->getVisibility() != llvm::GlobalVariable::DefaultVisibility) + return; + + // Don't override an explicit visibility attribute. + if (RD->hasAttr<VisibilityAttr>()) + return; + + switch (RD->getTemplateSpecializationKind()) { + // 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: + return; + + // Every use of a non-template or explicitly-specialized class's + // type information has to emit it. + case TSK_ExplicitSpecialization: + case TSK_Undeclared: + break; + + // 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: + break; + } + + // If there's a key function, there may be translation units + // that don't have the key function's definition. But ignore + // this if we're emitting RTTI under -fno-rtti. + if (!IsForRTTI || Features.RTTI) + if (Context.getKeyFunction(RD)) + return; + + // Otherwise, drop the visibility to hidden. + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); +} + llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) { const NamedDecl *ND = cast<NamedDecl>(GD.getDecl()); |