diff options
| -rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 30 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/windows-itanium-type-info.cpp | 21 |
2 files changed, 44 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 088454647c7..48d47d23599 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2911,16 +2911,18 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, case VisibleNoLinkage: case ExternalLinkage: - if (!CGM.getLangOpts().RTTI) { - // RTTI is not enabled, which means that this type info struct is going - // to be used for exception handling. Give it linkonce_odr linkage. + // 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>()) + return llvm::GlobalValue::ExternalLinkage; if (RD->isDynamicClass()) { llvm::GlobalValue::LinkageTypes LT = CGM.getVTableLinkage(RD); // MinGW won't export the RTTI information when there is a key function. @@ -3122,10 +3124,26 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, llvmVisibility = llvm::GlobalValue::HiddenVisibility; else llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility()); + TypeName->setVisibility(llvmVisibility); GV->setVisibility(llvmVisibility); - if (DLLExport) - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + + if (CGM.getTriple().isWindowsItaniumEnvironment()) { + auto RD = Ty->getAsCXXRecordDecl(); + if (DLLExport || (RD && RD->hasAttr<DLLExportAttr>())) { + TypeName->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + } else if (RD && RD->hasAttr<DLLImportAttr>()) { + 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); + } + } return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); } diff --git a/clang/test/CodeGenCXX/windows-itanium-type-info.cpp b/clang/test/CodeGenCXX/windows-itanium-type-info.cpp index 206e7c3e2f9..ecc227d5b63 100644 --- a/clang/test/CodeGenCXX/windows-itanium-type-info.cpp +++ b/clang/test/CodeGenCXX/windows-itanium-type-info.cpp @@ -9,5 +9,24 @@ public: __fundamental_type_info::~__fundamental_type_info() {} } -// CHECK: @_ZTIi = dllexport constant +struct __declspec(dllimport) base { + virtual void method(); +}; +struct __declspec(dllexport) derived : base { + virtual ~derived(); +}; +derived::~derived() { + method(); +} + +// CHECK-DAG: @_ZTIi = dllexport constant +// CHECK-DAG: @_ZTSi = dllexport constant + +// CHECK-DAG: @_ZTI7derived = dllexport constant +// CHECK-DAG: @_ZTS7derived = dllexport constant +// CHECK-DAG: @_ZTV7derived = dllexport unnamed_addr constant + +// CHECK-DAG: @_ZTI4base = external dllimport constant +// CHECK-DAG: @_ZTS4base = external dllimport constant +// CHECK-NOT: @_ZTV4base = external dllimport constant |

