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/CGRTTI.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/CGRTTI.cpp')
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 1cca97702d..0724fdfba3 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -244,11 +244,9 @@ static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) { return TypeInfoIsInStandardLibrary(BuiltinTy); } -/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for -/// the given type exists somewhere else, and that we should not emit the type -/// information in this translation unit. -static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context, - QualType Ty) { +/// IsStandardLibraryRTTIDescriptor - Returns whether the type +/// information for the given type exists in the standard library. +static bool IsStandardLibraryRTTIDescriptor(QualType Ty) { // Type info for builtin types is defined in the standard library. if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty)) return TypeInfoIsInStandardLibrary(BuiltinTy); @@ -258,6 +256,15 @@ static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context, if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) return TypeInfoIsInStandardLibrary(PointerTy); + return false; +} + +/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for +/// the given type exists somewhere else, and that we should not emit the type +/// information in this translation unit. Assumes that it is not a +/// standard-library type. +static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context, + QualType Ty) { // If RTTI is disabled, don't consider key functions. if (!Context.getLangOptions().RTTI) return false; @@ -456,8 +463,7 @@ void RTTIBuilder::BuildVTablePointer(const Type *Ty) { Fields.push_back(VTable); } -llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, - bool Force) { +llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { // We want to operate on the canonical type. Ty = CGM.getContext().getCanonicalType(Ty); @@ -469,19 +475,26 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name); if (OldGV && !OldGV->isDeclaration()) return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy); - + // Check if there is already an external RTTI descriptor for this type. - if (!Force && ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty)) + bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty); + if (!Force && + (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty))) return GetAddrOfExternalRTTIDescriptor(Ty); - llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty); + // Emit the standard library with external linkage. + llvm::GlobalVariable::LinkageTypes Linkage; + if (IsStdLib) + Linkage = llvm::GlobalValue::ExternalLinkage; + else + Linkage = getTypeInfoLinkage(Ty); // Add the vtable pointer. BuildVTablePointer(cast<Type>(Ty)); // And the name. Fields.push_back(BuildName(Ty, DecideHidden(Ty), Linkage)); - + switch (Ty->getTypeClass()) { default: assert(false && "Unhandled type class!"); @@ -551,7 +564,15 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, OldGV->replaceAllUsesWith(NewPtr); OldGV->eraseFromParent(); } - + + // GCC only relies on the uniqueness of the type names, not the + // type_infos themselves, so we can emit these as hidden symbols. + if (const RecordType *RT = dyn_cast<RecordType>(Ty)) + CGM.setTypeVisibility(GV, cast<CXXRecordDecl>(RT->getDecl()), + /*ForRTTI*/ true); + else if (Linkage == llvm::GlobalValue::WeakODRLinkage) + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); + return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy); } |