Skip to content

Commit

Permalink
CodeGen: export typeinfo and typeinfo name on itanium
Browse files Browse the repository at this point in the history
When a C++ record is marked with dllexport mark both the typeinfo and the
typeinfo name as being exported.  Handle dllimport as the inverse.  This applies
to the itanium environment and not the MinGW environment.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288546 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
compnerd committed Dec 2, 2016
1 parent faa7188 commit b4af165
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
30 changes: 24 additions & 6 deletions lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}
Expand Down
21 changes: 20 additions & 1 deletion test/CodeGenCXX/windows-itanium-type-info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,24 @@ class __declspec(dllexport) __fundamental_type_info {
__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

0 comments on commit b4af165

Please sign in to comment.