Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -31,6 +31,7 @@ #include "clang/AST/StmtCXX.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Value.h" @@ -181,8 +182,7 @@ emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn) override; - void EmitFundamentalRTTIDescriptor(QualType Type, bool DLLExport); - void EmitFundamentalRTTIDescriptors(bool DLLExport); + void EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD); llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, @@ -1613,7 +1613,7 @@ isa(DC) && cast(DC)->getIdentifier() && cast(DC)->getIdentifier()->isStr("__cxxabiv1") && DC->getParent()->isTranslationUnit()) - EmitFundamentalRTTIDescriptors(RD->hasAttr()); + EmitFundamentalRTTIDescriptors(RD); if (!VTable->isDeclarationForLinker()) CGM.EmitVTableTypeMetadata(VTable, VTLayout); @@ -2698,12 +2698,16 @@ BCTI_Public = 0x2 }; + /// BuildTypeInfo - Build the RTTI type info struct for the given type, or + /// link to an existing RTTI descriptor if one already exists. + llvm::Constant *BuildTypeInfo(QualType Ty); + /// BuildTypeInfo - Build the RTTI type info struct for the given type. - /// - /// \param Force - true to force the creation of this RTTI value - /// \param DLLExport - true to mark the RTTI value as DLLExport - llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false, - bool DLLExport = false); + llvm::Constant *BuildTypeInfo( + QualType Ty, + llvm::GlobalVariable::LinkageTypes Linkage, + llvm::GlobalValue::VisibilityTypes Visibility, + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass); }; } @@ -3172,8 +3176,7 @@ llvm_unreachable("Invalid linkage!"); } -llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, - bool DLLExport) { +llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) { // We want to operate on the canonical type. Ty = Ty.getCanonicalType(); @@ -3191,17 +3194,41 @@ } // Check if there is already an external RTTI descriptor for this type. - bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty); - if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty))) + if (IsStandardLibraryRTTIDescriptor(Ty) || + ShouldUseExternalRTTIDescriptor(CGM, Ty)) return GetAddrOfExternalRTTIDescriptor(Ty); // Emit the standard library with external linkage. - llvm::GlobalVariable::LinkageTypes Linkage; - if (IsStdLib) - Linkage = llvm::GlobalValue::ExternalLinkage; + llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty); + + // Give the type_info object and name the formal visibility of the + // type itself. + llvm::GlobalValue::VisibilityTypes llvmVisibility; + if (llvm::GlobalValue::isLocalLinkage(Linkage)) + // If the linkage is local, only default visibility makes sense. + llvmVisibility = llvm::GlobalValue::DefaultVisibility; + else if (CXXABI.classifyRTTIUniqueness(Ty, Linkage) == + ItaniumCXXABI::RUK_NonUniqueHidden) + llvmVisibility = llvm::GlobalValue::HiddenVisibility; else - Linkage = getTypeInfoLinkage(CGM, Ty); + llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility()); + + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass = + llvm::GlobalValue::DefaultStorageClass; + if (CGM.getTriple().isWindowsItaniumEnvironment()) { + auto RD = Ty->getAsCXXRecordDecl(); + if (RD && RD->hasAttr()) + DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass; + } + return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass); +} + +llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( + QualType Ty, + llvm::GlobalVariable::LinkageTypes Linkage, + llvm::GlobalValue::VisibilityTypes Visibility, + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) { // Add the vtable pointer. BuildVTablePointer(cast(Ty)); @@ -3315,7 +3342,11 @@ llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields); + SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out); llvm::Module &M = CGM.getModule(); + llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name); llvm::GlobalVariable *GV = new llvm::GlobalVariable(M, Init->getType(), /*Constant=*/true, Linkage, Init, Name); @@ -3347,40 +3378,14 @@ // All of this is to say that it's important that both the type_info // object and the type_info name be uniqued when weakly emitted. - // Give the type_info object and name the formal visibility of the - // type itself. - llvm::GlobalValue::VisibilityTypes llvmVisibility; - if (llvm::GlobalValue::isLocalLinkage(Linkage)) - // If the linkage is local, only default visibility makes sense. - llvmVisibility = llvm::GlobalValue::DefaultVisibility; - else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden) - llvmVisibility = llvm::GlobalValue::HiddenVisibility; - else - llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility()); - - TypeName->setVisibility(llvmVisibility); + TypeName->setVisibility(Visibility); CGM.setDSOLocal(TypeName); - GV->setVisibility(llvmVisibility); + GV->setVisibility(Visibility); CGM.setDSOLocal(GV); - if (CGM.getTriple().isWindowsItaniumEnvironment()) { - auto RD = Ty->getAsCXXRecordDecl(); - if (DLLExport || (RD && RD->hasAttr())) { - TypeName->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - } else if (RD && RD->hasAttr() && - ShouldUseExternalRTTIDescriptor(CGM, Ty)) { - TypeName->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - - // Because the typename and the typeinfo are DLL import, convert them to - // declarations rather than definitions. The initializers still need to - // be constructed to calculate the type for the declarations. - TypeName->setInitializer(nullptr); - GV->setInitializer(nullptr); - } - } + TypeName->setDLLStorageClass(DLLStorageClass); + GV->setDLLStorageClass(DLLStorageClass); return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); } @@ -3655,18 +3660,7 @@ return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty); } -void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type, - bool DLLExport) { - QualType PointerType = getContext().getPointerType(Type); - QualType PointerTypeConst = getContext().getPointerType(Type.withConst()); - ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, /*Force=*/true, DLLExport); - ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, /*Force=*/true, - DLLExport); - ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, /*Force=*/true, - DLLExport); -} - -void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(bool DLLExport) { +void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) { // Types added here must also be added to TypeInfoIsInStandardLibrary. QualType FundamentalTypes[] = { getContext().VoidTy, getContext().NullPtrTy, @@ -3683,8 +3677,21 @@ getContext().Char8Ty, getContext().Char16Ty, getContext().Char32Ty }; - for (const QualType &FundamentalType : FundamentalTypes) - EmitFundamentalRTTIDescriptor(FundamentalType, DLLExport); + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass = + RD->hasAttr() + ? llvm::GlobalValue::DLLExportStorageClass + : llvm::GlobalValue::DefaultStorageClass; + llvm::GlobalValue::VisibilityTypes Visibility = + CodeGenModule::GetLLVMVisibility(RD->getVisibility()); + for (const QualType &FundamentalType : FundamentalTypes) { + QualType PointerType = getContext().getPointerType(FundamentalType); + QualType PointerTypeConst = getContext().getPointerType( + FundamentalType.withConst()); + for (QualType Type : {FundamentalType, PointerType, PointerTypeConst}) + ItaniumRTTIBuilder(*this).BuildTypeInfo( + Type, llvm::GlobalValue::ExternalLinkage, + Visibility, DLLStorageClass); + } } /// What sort of uniqueness rules should we use for the RTTI for the Index: test/CodeGenCXX/rtti-fundamental.cpp =================================================================== --- test/CodeGenCXX/rtti-fundamental.cpp +++ test/CodeGenCXX/rtti-fundamental.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -fvisibility hidden -o - | FileCheck %s -check-prefix=CHECK-HIDDEN #include @@ -16,116 +17,184 @@ // void // CHECK: @_ZTIv = constant +// CHECK-HIDDEN: @_ZTIv = hidden constant // CHECK: @_ZTIPv = constant +// CHECK-HIDDEN: @_ZTIPv = hidden constant // CHECK: @_ZTIPKv = constant +// CHECK-HIDDEN: @_ZTIPKv = hidden constant // std::nullptr_t // CHECK: @_ZTIDn = constant +// CHECK-HIDDEN: @_ZTIDn = hidden constant // CHECK: @_ZTIPDn = constant +// CHECK-HIDDEN: @_ZTIPDn = hidden constant // CHECK: @_ZTIPKDn = constant +// CHECK-HIDDEN: @_ZTIPKDn = hidden constant // bool // CHECK: @_ZTIb = constant +// CHECK-HIDDEN: @_ZTIb = hidden constant // CHECK: @_ZTIPb = constant +// CHECK-HIDDEN: @_ZTIPb = hidden constant // CHECK: @_ZTIPKb = constant +// CHECK-HIDDEN: @_ZTIPKb = hidden constant // wchar_t // CHECK: @_ZTIw = constant +// CHECK-HIDDEN: @_ZTIw = hidden constant // CHECK: @_ZTIPw = constant +// CHECK-HIDDEN: @_ZTIPw = hidden constant // CHECK: @_ZTIPKw = constant +// CHECK-HIDDEN: @_ZTIPKw = hidden constant // char // CHECK: @_ZTIc = constant +// CHECK-HIDDEN: @_ZTIc = hidden constant // CHECK: @_ZTIPc = constant +// CHECK-HIDDEN: @_ZTIPc = hidden constant // CHECK: @_ZTIPKc = constant +// CHECK-HIDDEN: @_ZTIPKc = hidden constant // unsigned char // CHECK: @_ZTIh = constant +// CHECK-HIDDEN: @_ZTIh = hidden constant // CHECK: @_ZTIPh = constant +// CHECK-HIDDEN: @_ZTIPh = hidden constant // CHECK: @_ZTIPKh = constant +// CHECK-HIDDEN: @_ZTIPKh = hidden constant // signed char // CHECK: @_ZTIa = constant +// CHECK-HIDDEN: @_ZTIa = hidden constant // CHECK: @_ZTIPa = constant +// CHECK-HIDDEN: @_ZTIPa = hidden constant // CHECK: @_ZTIPKa = constant +// CHECK-HIDDEN: @_ZTIPKa = hidden constant // short // CHECK: @_ZTIs = constant +// CHECK-HIDDEN: @_ZTIs = hidden constant // CHECK: @_ZTIPs = constant +// CHECK-HIDDEN: @_ZTIPs = hidden constant // CHECK: @_ZTIPKs = constant +// CHECK-HIDDEN: @_ZTIPKs = hidden constant // unsigned short // CHECK: @_ZTIt = constant +// CHECK-HIDDEN: @_ZTIt = hidden constant // CHECK: @_ZTIPt = constant +// CHECK-HIDDEN: @_ZTIPt = hidden constant // CHECK: @_ZTIPKt = constant +// CHECK-HIDDEN: @_ZTIPKt = hidden constant // int // CHECK: @_ZTIi = constant +// CHECK-HIDDEN: @_ZTIi = hidden constant // CHECK: @_ZTIPi = constant +// CHECK-HIDDEN: @_ZTIPi = hidden constant // CHECK: @_ZTIPKi = constant +// CHECK-HIDDEN: @_ZTIPKi = hidden constant // unsigned int // CHECK: @_ZTIj = constant +// CHECK-HIDDEN: @_ZTIj = hidden constant // CHECK: @_ZTIPj = constant +// CHECK-HIDDEN: @_ZTIPj = hidden constant // CHECK: @_ZTIPKj = constant +// CHECK-HIDDEN: @_ZTIPKj = hidden constant // long // CHECK: @_ZTIl = constant +// CHECK-HIDDEN: @_ZTIl = hidden constant // CHECK: @_ZTIPl = constant +// CHECK-HIDDEN: @_ZTIPl = hidden constant // CHECK: @_ZTIPKl = constant +// CHECK-HIDDEN: @_ZTIPKl = hidden constant // unsigned long // CHECK: @_ZTIm = constant +// CHECK-HIDDEN: @_ZTIm = hidden constant // CHECK: @_ZTIPm = constant +// CHECK-HIDDEN: @_ZTIPm = hidden constant // CHECK: @_ZTIPKm = constant +// CHECK-HIDDEN: @_ZTIPKm = hidden constant // long long // CHECK: @_ZTIx = constant +// CHECK-HIDDEN: @_ZTIx = hidden constant // CHECK: @_ZTIPx = constant +// CHECK-HIDDEN: @_ZTIPx = hidden constant // CHECK: @_ZTIPKx = constant +// CHECK-HIDDEN: @_ZTIPKx = hidden constant // unsigned long long // CHECK: @_ZTIy = constant +// CHECK-HIDDEN: @_ZTIy = hidden constant // CHECK: @_ZTIPy = constant +// CHECK-HIDDEN: @_ZTIPy = hidden constant // CHECK: @_ZTIPKy = constant +// CHECK-HIDDEN: @_ZTIPKy = hidden constant // __int128 // CHECK: @_ZTIn = constant +// CHECK-HIDDEN: @_ZTIn = hidden constant // CHECK: @_ZTIPn = constant +// CHECK-HIDDEN: @_ZTIPn = hidden constant // CHECK: @_ZTIPKn = constant +// CHECK-HIDDEN: @_ZTIPKn = hidden constant // unsigned __int128 // CHECK: @_ZTIo = constant +// CHECK-HIDDEN: @_ZTIo = hidden constant // CHECK: @_ZTIPo = constant +// CHECK-HIDDEN: @_ZTIPo = hidden constant // CHECK: @_ZTIPKo = constant +// CHECK-HIDDEN: @_ZTIPKo = hidden constant // half // CHECK: @_ZTIDh = constant +// CHECK-HIDDEN: @_ZTIDh = hidden constant // CHECK: @_ZTIPDh = constant +// CHECK-HIDDEN: @_ZTIPDh = hidden constant // CHECK: @_ZTIPKDh = constant +// CHECK-HIDDEN: @_ZTIPKDh = hidden constant // float // CHECK: @_ZTIf = constant +// CHECK-HIDDEN: @_ZTIf = hidden constant // CHECK: @_ZTIPf = constant +// CHECK-HIDDEN: @_ZTIPf = hidden constant // CHECK: @_ZTIPKf = constant +// CHECK-HIDDEN: @_ZTIPKf = hidden constant // double // CHECK: @_ZTId = constant +// CHECK-HIDDEN: @_ZTId = hidden constant // CHECK: @_ZTIPd = constant +// CHECK-HIDDEN: @_ZTIPd = hidden constant // CHECK: @_ZTIPKd = constant +// CHECK-HIDDEN: @_ZTIPKd = hidden constant // long double // CHECK: @_ZTIe = constant +// CHECK-HIDDEN: @_ZTIe = hidden constant // CHECK: @_ZTIPe = constant +// CHECK-HIDDEN: @_ZTIPe = hidden constant // CHECK: @_ZTIPKe = constant +// CHECK-HIDDEN: @_ZTIPKe = hidden constant // char16_t // CHECK: @_ZTIDs = constant +// CHECK-HIDDEN: @_ZTIDs = hidden constant // CHECK: @_ZTIPDs = constant +// CHECK-HIDDEN: @_ZTIPDs = hidden constant // CHECK: @_ZTIPKDs = constant +// CHECK-HIDDEN: @_ZTIPKDs = hidden constant // char32_t // CHECK: @_ZTIDi = constant +// CHECK-HIDDEN: @_ZTIDi = hidden constant // CHECK: @_ZTIPDi = constant +// CHECK-HIDDEN: @_ZTIPDi = hidden constant // CHECK: @_ZTIPKDi = constant - +// CHECK-HIDDEN: @_ZTIPKDi = hidden constant