diff options
Diffstat (limited to 'clang/lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 121 |
1 files changed, 63 insertions, 58 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 168dbcb2893..e7d4d8ac295 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3008,8 +3008,46 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) { /// Return the linkage that the type info and type info name constants /// should have for the given type. -static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, - QualType Ty) { +static std::pair<llvm::GlobalVariable::LinkageTypes, + llvm::GlobalVariable::LinkageTypes> +getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) { + llvm::GlobalValue::LinkageTypes TypeLinkage = [&]() { + switch (Ty->getLinkage()) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: + return llvm::GlobalValue::InternalLinkage; + + case VisibleNoLinkage: + case ModuleInternalLinkage: + case ModuleLinkage: + case ExternalLinkage: + // RTTI is not enabled, which means that this type info struct is going + // to be used for exception handling. Give it linkonce_odr linkage. + if (!CGM.getLangOpts().RTTI) + return llvm::GlobalValue::LinkOnceODRLinkage; + + if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { + const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); + if (RD->hasAttr<WeakAttr>()) + return llvm::GlobalValue::WeakODRLinkage; + if (CGM.getTriple().isWindowsItaniumEnvironment()) + if (RD->hasAttr<DLLImportAttr>() && + ShouldUseExternalRTTIDescriptor(CGM, Ty)) + return llvm::GlobalValue::ExternalLinkage; + // MinGW always uses LinkOnceODRLinkage for type info. + if (RD->isCompleteDefinition() && RD->isDynamicClass() && + !CGM.getContext() + .getTargetInfo() + .getTriple() + .isWindowsGNUEnvironment()) + return CGM.getVTableLinkage(RD); + } + + return llvm::GlobalValue::LinkOnceODRLinkage; + } + llvm_unreachable("Invalid linkage!"); + }(); // Itanium C++ ABI 2.9.5p7: // In addition, it and all of the intermediate abi::__pointer_type_info // structs in the chain down to the abi::__class_type_info for the @@ -3020,44 +3058,8 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, // complete class RTTI (because the latter need not exist), possibly by // making it a local static object. if (ContainsIncompleteClassType(Ty)) - return llvm::GlobalValue::InternalLinkage; - - switch (Ty->getLinkage()) { - case NoLinkage: - case InternalLinkage: - case UniqueExternalLinkage: - return llvm::GlobalValue::InternalLinkage; - - case VisibleNoLinkage: - case ModuleInternalLinkage: - case ModuleLinkage: - case ExternalLinkage: - // RTTI is not enabled, which means that this type info struct is going - // to be used for exception handling. Give it linkonce_odr linkage. - if (!CGM.getLangOpts().RTTI) - return llvm::GlobalValue::LinkOnceODRLinkage; - - if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { - const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); - if (RD->hasAttr<WeakAttr>()) - return llvm::GlobalValue::WeakODRLinkage; - if (CGM.getTriple().isWindowsItaniumEnvironment()) - if (RD->hasAttr<DLLImportAttr>() && - ShouldUseExternalRTTIDescriptor(CGM, Ty)) - return llvm::GlobalValue::ExternalLinkage; - // MinGW always uses LinkOnceODRLinkage for type info. - if (RD->isDynamicClass() && - !CGM.getContext() - .getTargetInfo() - .getTriple() - .isWindowsGNUEnvironment()) - return CGM.getVTableLinkage(RD); - } - - return llvm::GlobalValue::LinkOnceODRLinkage; - } - - llvm_unreachable("Invalid linkage!"); + return {llvm::GlobalValue::InternalLinkage, TypeLinkage}; + return {TypeLinkage, TypeLinkage}; } llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, @@ -3084,23 +3086,25 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, return GetAddrOfExternalRTTIDescriptor(Ty); // Emit the standard library with external linkage. - llvm::GlobalVariable::LinkageTypes Linkage; + llvm::GlobalVariable::LinkageTypes InfoLinkage, NameLinkage; if (IsStdLib) - Linkage = llvm::GlobalValue::ExternalLinkage; - else - Linkage = getTypeInfoLinkage(CGM, Ty); - + InfoLinkage = NameLinkage = llvm::GlobalValue::ExternalLinkage; + else { + auto LinkagePair = getTypeInfoLinkage(CGM, Ty); + InfoLinkage = LinkagePair.first; + NameLinkage = LinkagePair.second; + } // Add the vtable pointer. BuildVTablePointer(cast<Type>(Ty)); // And the name. - llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage); + llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, NameLinkage); llvm::Constant *TypeNameField; // If we're supposed to demote the visibility, be sure to set a flag // to use a string comparison for type_info comparisons. ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness = - CXXABI.classifyRTTIUniqueness(Ty, Linkage); + CXXABI.classifyRTTIUniqueness(Ty, NameLinkage); if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) { // The flag is the sign bit, which on ARM64 is defined to be clear // for global pointers. This is very ARM64-specific. @@ -3206,7 +3210,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, llvm::Module &M = CGM.getModule(); llvm::GlobalVariable *GV = new llvm::GlobalVariable(M, Init->getType(), - /*Constant=*/true, Linkage, Init, Name); + /*Constant=*/true, InfoLinkage, Init, Name); // If there's already an old global variable, replace it with the new one. if (OldGV) { @@ -3237,19 +3241,20 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, // 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()); + auto computeVisibility = [&](llvm::GlobalValue::LinkageTypes Linkage) { + if (llvm::GlobalValue::isLocalLinkage(Linkage)) + // If the linkage is local, only default visibility makes sense. + return llvm::GlobalValue::DefaultVisibility; + else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden) + return llvm::GlobalValue::HiddenVisibility; + else + return CodeGenModule::GetLLVMVisibility(Ty->getVisibility()); + }; - TypeName->setVisibility(llvmVisibility); + TypeName->setVisibility(computeVisibility(NameLinkage)); CGM.setDSOLocal(TypeName); - GV->setVisibility(llvmVisibility); + GV->setVisibility(computeVisibility(InfoLinkage)); CGM.setDSOLocal(GV); if (CGM.getTriple().isWindowsItaniumEnvironment()) { |