31
31
#include " clang/AST/StmtCXX.h"
32
32
#include " llvm/IR/CallSite.h"
33
33
#include " llvm/IR/DataLayout.h"
34
+ #include " llvm/IR/GlobalValue.h"
34
35
#include " llvm/IR/Instructions.h"
35
36
#include " llvm/IR/Intrinsics.h"
36
37
#include " llvm/IR/Value.h"
@@ -181,8 +182,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
181
182
emitTerminateForUnexpectedException (CodeGenFunction &CGF,
182
183
llvm::Value *Exn) override ;
183
184
184
- void EmitFundamentalRTTIDescriptor (QualType Type, bool DLLExport);
185
- void EmitFundamentalRTTIDescriptors (bool DLLExport);
185
+ void EmitFundamentalRTTIDescriptors (const CXXRecordDecl *RD);
186
186
llvm::Constant *getAddrOfRTTIDescriptor (QualType Ty) override ;
187
187
CatchTypeInfo
188
188
getAddrOfCXXCatchHandlerType (QualType Ty,
@@ -1613,7 +1613,7 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1613
1613
isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier () &&
1614
1614
cast<NamespaceDecl>(DC)->getIdentifier ()->isStr (" __cxxabiv1" ) &&
1615
1615
DC->getParent ()->isTranslationUnit ())
1616
- EmitFundamentalRTTIDescriptors (RD-> hasAttr <DLLExportAttr>() );
1616
+ EmitFundamentalRTTIDescriptors (RD);
1617
1617
1618
1618
if (!VTable->isDeclarationForLinker ())
1619
1619
CGM.EmitVTableTypeMetadata (VTable, VTLayout);
@@ -2698,12 +2698,16 @@ class ItaniumRTTIBuilder {
2698
2698
BCTI_Public = 0x2
2699
2699
};
2700
2700
2701
+ // / BuildTypeInfo - Build the RTTI type info struct for the given type, or
2702
+ // / link to an existing RTTI descriptor if one already exists.
2703
+ llvm::Constant *BuildTypeInfo (QualType Ty);
2704
+
2701
2705
// / BuildTypeInfo - Build the RTTI type info struct for the given type.
2702
- // /
2703
- // / \param Force - true to force the creation of this RTTI value
2704
- // / \param DLLExport - true to mark the RTTI value as DLLExport
2705
- llvm::Constant * BuildTypeInfo (QualType Ty, bool Force = false ,
2706
- bool DLLExport = false );
2706
+ llvm::Constant * BuildTypeInfo (
2707
+ QualType Ty,
2708
+ llvm::GlobalVariable::LinkageTypes Linkage,
2709
+ llvm::GlobalValue::VisibilityTypes Visibility ,
2710
+ llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass );
2707
2711
};
2708
2712
}
2709
2713
@@ -3172,8 +3176,7 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
3172
3176
llvm_unreachable (" Invalid linkage!" );
3173
3177
}
3174
3178
3175
- llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo (QualType Ty, bool Force,
3176
- bool DLLExport) {
3179
+ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo (QualType Ty) {
3177
3180
// We want to operate on the canonical type.
3178
3181
Ty = Ty.getCanonicalType ();
3179
3182
@@ -3191,17 +3194,41 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force,
3191
3194
}
3192
3195
3193
3196
// Check if there is already an external RTTI descriptor for this type.
3194
- bool IsStdLib = IsStandardLibraryRTTIDescriptor (Ty);
3195
- if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor (CGM, Ty) ))
3197
+ if ( IsStandardLibraryRTTIDescriptor (Ty) ||
3198
+ ShouldUseExternalRTTIDescriptor (CGM, Ty))
3196
3199
return GetAddrOfExternalRTTIDescriptor (Ty);
3197
3200
3198
3201
// Emit the standard library with external linkage.
3199
- llvm::GlobalVariable::LinkageTypes Linkage;
3200
- if (IsStdLib)
3201
- Linkage = llvm::GlobalValue::ExternalLinkage;
3202
+ llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage (CGM, Ty);
3203
+
3204
+ // Give the type_info object and name the formal visibility of the
3205
+ // type itself.
3206
+ llvm::GlobalValue::VisibilityTypes llvmVisibility;
3207
+ if (llvm::GlobalValue::isLocalLinkage (Linkage))
3208
+ // If the linkage is local, only default visibility makes sense.
3209
+ llvmVisibility = llvm::GlobalValue::DefaultVisibility;
3210
+ else if (CXXABI.classifyRTTIUniqueness (Ty, Linkage) ==
3211
+ ItaniumCXXABI::RUK_NonUniqueHidden)
3212
+ llvmVisibility = llvm::GlobalValue::HiddenVisibility;
3202
3213
else
3203
- Linkage = getTypeInfoLinkage (CGM, Ty);
3214
+ llvmVisibility = CodeGenModule::GetLLVMVisibility (Ty->getVisibility ());
3215
+
3216
+ llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3217
+ llvm::GlobalValue::DefaultStorageClass;
3218
+ if (CGM.getTriple ().isWindowsItaniumEnvironment ()) {
3219
+ auto RD = Ty->getAsCXXRecordDecl ();
3220
+ if (RD && RD->hasAttr <DLLExportAttr>())
3221
+ DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3222
+ }
3204
3223
3224
+ return BuildTypeInfo (Ty, Linkage, llvmVisibility, DLLStorageClass);
3225
+ }
3226
+
3227
+ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo (
3228
+ QualType Ty,
3229
+ llvm::GlobalVariable::LinkageTypes Linkage,
3230
+ llvm::GlobalValue::VisibilityTypes Visibility,
3231
+ llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3205
3232
// Add the vtable pointer.
3206
3233
BuildVTablePointer (cast<Type>(Ty));
3207
3234
@@ -3315,7 +3342,11 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force,
3315
3342
3316
3343
llvm::Constant *Init = llvm::ConstantStruct::getAnon (Fields);
3317
3344
3345
+ SmallString<256 > Name;
3346
+ llvm::raw_svector_ostream Out (Name);
3347
+ CGM.getCXXABI ().getMangleContext ().mangleCXXRTTI (Ty, Out);
3318
3348
llvm::Module &M = CGM.getModule ();
3349
+ llvm::GlobalVariable *OldGV = M.getNamedGlobal (Name);
3319
3350
llvm::GlobalVariable *GV =
3320
3351
new llvm::GlobalVariable (M, Init->getType (),
3321
3352
/* Constant=*/ true , Linkage, Init, Name);
@@ -3347,40 +3378,14 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force,
3347
3378
// All of this is to say that it's important that both the type_info
3348
3379
// object and the type_info name be uniqued when weakly emitted.
3349
3380
3350
- // Give the type_info object and name the formal visibility of the
3351
- // type itself.
3352
- llvm::GlobalValue::VisibilityTypes llvmVisibility;
3353
- if (llvm::GlobalValue::isLocalLinkage (Linkage))
3354
- // If the linkage is local, only default visibility makes sense.
3355
- llvmVisibility = llvm::GlobalValue::DefaultVisibility;
3356
- else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
3357
- llvmVisibility = llvm::GlobalValue::HiddenVisibility;
3358
- else
3359
- llvmVisibility = CodeGenModule::GetLLVMVisibility (Ty->getVisibility ());
3360
-
3361
- TypeName->setVisibility (llvmVisibility);
3381
+ TypeName->setVisibility (Visibility);
3362
3382
CGM.setDSOLocal (TypeName);
3363
3383
3364
- GV->setVisibility (llvmVisibility );
3384
+ GV->setVisibility (Visibility );
3365
3385
CGM.setDSOLocal (GV);
3366
3386
3367
- if (CGM.getTriple ().isWindowsItaniumEnvironment ()) {
3368
- auto RD = Ty->getAsCXXRecordDecl ();
3369
- if (DLLExport || (RD && RD->hasAttr <DLLExportAttr>())) {
3370
- TypeName->setDLLStorageClass (llvm::GlobalValue::DLLExportStorageClass);
3371
- GV->setDLLStorageClass (llvm::GlobalValue::DLLExportStorageClass);
3372
- } else if (RD && RD->hasAttr <DLLImportAttr>() &&
3373
- ShouldUseExternalRTTIDescriptor (CGM, Ty)) {
3374
- TypeName->setDLLStorageClass (llvm::GlobalValue::DLLImportStorageClass);
3375
- GV->setDLLStorageClass (llvm::GlobalValue::DLLImportStorageClass);
3376
-
3377
- // Because the typename and the typeinfo are DLL import, convert them to
3378
- // declarations rather than definitions. The initializers still need to
3379
- // be constructed to calculate the type for the declarations.
3380
- TypeName->setInitializer (nullptr );
3381
- GV->setInitializer (nullptr );
3382
- }
3383
- }
3387
+ TypeName->setDLLStorageClass (DLLStorageClass);
3388
+ GV->setDLLStorageClass (DLLStorageClass);
3384
3389
3385
3390
return llvm::ConstantExpr::getBitCast (GV, CGM.Int8PtrTy );
3386
3391
}
@@ -3655,18 +3660,7 @@ llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
3655
3660
return ItaniumRTTIBuilder (*this ).BuildTypeInfo (Ty);
3656
3661
}
3657
3662
3658
- void ItaniumCXXABI::EmitFundamentalRTTIDescriptor (QualType Type,
3659
- bool DLLExport) {
3660
- QualType PointerType = getContext ().getPointerType (Type);
3661
- QualType PointerTypeConst = getContext ().getPointerType (Type.withConst ());
3662
- ItaniumRTTIBuilder (*this ).BuildTypeInfo (Type, /* Force=*/ true , DLLExport);
3663
- ItaniumRTTIBuilder (*this ).BuildTypeInfo (PointerType, /* Force=*/ true ,
3664
- DLLExport);
3665
- ItaniumRTTIBuilder (*this ).BuildTypeInfo (PointerTypeConst, /* Force=*/ true ,
3666
- DLLExport);
3667
- }
3668
-
3669
- void ItaniumCXXABI::EmitFundamentalRTTIDescriptors (bool DLLExport) {
3663
+ void ItaniumCXXABI::EmitFundamentalRTTIDescriptors (const CXXRecordDecl *RD) {
3670
3664
// Types added here must also be added to TypeInfoIsInStandardLibrary.
3671
3665
QualType FundamentalTypes[] = {
3672
3666
getContext ().VoidTy , getContext ().NullPtrTy ,
@@ -3683,8 +3677,21 @@ void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(bool DLLExport) {
3683
3677
getContext ().Char8Ty , getContext ().Char16Ty ,
3684
3678
getContext ().Char32Ty
3685
3679
};
3686
- for (const QualType &FundamentalType : FundamentalTypes)
3687
- EmitFundamentalRTTIDescriptor (FundamentalType, DLLExport);
3680
+ llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3681
+ RD->hasAttr <DLLExportAttr>()
3682
+ ? llvm::GlobalValue::DLLExportStorageClass
3683
+ : llvm::GlobalValue::DefaultStorageClass;
3684
+ llvm::GlobalValue::VisibilityTypes Visibility =
3685
+ CodeGenModule::GetLLVMVisibility (RD->getVisibility ());
3686
+ for (const QualType &FundamentalType : FundamentalTypes) {
3687
+ QualType PointerType = getContext ().getPointerType (FundamentalType);
3688
+ QualType PointerTypeConst = getContext ().getPointerType (
3689
+ FundamentalType.withConst ());
3690
+ for (QualType Type : {FundamentalType, PointerType, PointerTypeConst})
3691
+ ItaniumRTTIBuilder (*this ).BuildTypeInfo (
3692
+ Type, llvm::GlobalValue::ExternalLinkage,
3693
+ Visibility, DLLStorageClass);
3694
+ }
3688
3695
}
3689
3696
3690
3697
// / What sort of uniqueness rules should we use for the RTTI for the
0 commit comments