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" @@ -40,6 +41,11 @@ using namespace CodeGen; namespace { +struct TypeInfoOptions { + bool DLLExport; + llvm::GlobalValue::VisibilityTypes Visibility; +}; + class ItaniumCXXABI : public CodeGen::CGCXXABI { /// VTables - All the vtables which have been defined. llvm::DenseMap VTables; @@ -181,8 +187,9 @@ emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn) override; - void EmitFundamentalRTTIDescriptor(QualType Type, bool DLLExport); - void EmitFundamentalRTTIDescriptors(bool DLLExport); + void EmitFundamentalRTTIDescriptor(QualType Type, + const TypeInfoOptions *Options); + void EmitFundamentalRTTIDescriptors(const TypeInfoOptions *Options); llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, @@ -1612,8 +1619,12 @@ RD->getIdentifier()->isStr("__fundamental_type_info") && isa(DC) && cast(DC)->getIdentifier() && cast(DC)->getIdentifier()->isStr("__cxxabiv1") && - DC->getParent()->isTranslationUnit()) - EmitFundamentalRTTIDescriptors(RD->hasAttr()); + DC->getParent()->isTranslationUnit()) { + TypeInfoOptions options; + options.DLLExport = RD->hasAttr(); + options.Visibility = CodeGenModule::GetLLVMVisibility(RD->getVisibility()); + EmitFundamentalRTTIDescriptors(&options); + } if (!VTable->isDeclarationForLinker()) CGM.EmitVTableTypeMetadata(VTable, VTLayout); @@ -2698,12 +2709,21 @@ BCTI_Public = 0x2 }; - /// BuildTypeInfo - Build the RTTI type info struct for the given type. + /// BuildTypeInfo - Build the RTTI type info struct for the given type, or + /// link to an existing RTTI descriptor if one already exists. /// /// \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); + /// \param Options - options for the generated type info + llvm::Constant *BuildTypeInfo(QualType Ty, + bool Force = false, + const TypeInfoOptions *Options = nullptr); + + /// BuildTypeInfo - Build the RTTI type info struct for the given type. + llvm::Constant *BuildTypeInfo( + QualType Ty, + llvm::GlobalVariable::LinkageTypes Linkage, + llvm::GlobalValue::VisibilityTypes Visibility, + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass); }; } @@ -3172,8 +3192,8 @@ llvm_unreachable("Invalid linkage!"); } -llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, - bool DLLExport) { +llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( + QualType Ty, bool Force, const TypeInfoOptions *Options) { // We want to operate on the canonical type. Ty = Ty.getCanonicalType(); @@ -3202,6 +3222,41 @@ else Linkage = getTypeInfoLinkage(CGM, Ty); + // Give the type_info object and name the formal visibility of the + // type itself. + llvm::GlobalValue::VisibilityTypes llvmVisibility; + if (Options) + llvmVisibility = Options->Visibility; + else 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 + llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility()); + + llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass = + llvm::GlobalValue::DefaultStorageClass; + if (CGM.getTriple().isWindowsItaniumEnvironment()) { + auto RD = Ty->getAsCXXRecordDecl(); + if ((Options && Options->DLLExport) || + (RD && RD->hasAttr())) { + DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass; + } else if (RD && RD->hasAttr() && + ShouldUseExternalRTTIDescriptor(CGM, Ty)) { + DLLStorageClass = llvm::GlobalValue::DLLImportStorageClass; + } + } + + 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,12 +3370,16 @@ 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 *GV = new llvm::GlobalVariable(M, Init->getType(), /*Constant=*/true, Linkage, Init, Name); // If there's already an old global variable, replace it with the new one. + llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name); if (OldGV) { GV->takeName(OldGV); llvm::Constant *NewPtr = @@ -3347,33 +3406,16 @@ // 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); - + TypeName->setDLLStorageClass(DLLStorageClass); + GV->setDLLStorageClass(DLLStorageClass); + if (DLLStorageClass == 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. @@ -3655,18 +3697,18 @@ return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty); } -void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type, - bool DLLExport) { +void ItaniumCXXABI::EmitFundamentalRTTIDescriptor( + QualType Type, const TypeInfoOptions *Options) { 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(Type, /*Force=*/true, Options); + ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, /*Force=*/true, Options); ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, /*Force=*/true, - DLLExport); + Options); } -void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(bool DLLExport) { +void ItaniumCXXABI::EmitFundamentalRTTIDescriptors( + const TypeInfoOptions* Options) { // Types added here must also be added to TypeInfoIsInStandardLibrary. QualType FundamentalTypes[] = { getContext().VoidTy, getContext().NullPtrTy, @@ -3684,7 +3726,7 @@ getContext().Char32Ty }; for (const QualType &FundamentalType : FundamentalTypes) - EmitFundamentalRTTIDescriptor(FundamentalType, DLLExport); + EmitFundamentalRTTIDescriptor(FundamentalType, Options); } /// What sort of uniqueness rules should we use for the RTTI for the