forked from OSchip/llvm-project
Make emitting a VTT a two-step process, much like emitting a VTable. You first get the address of the VTT, and then pass it to EmitVTTDefinition.
llvm-svn: 124539
This commit is contained in:
parent
93be9a90cc
commit
883fc72c3c
|
@ -318,7 +318,7 @@ static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD,
|
||||||
VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
|
VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
|
||||||
} else {
|
} else {
|
||||||
// We're the complete constructor, so get the VTT by name.
|
// We're the complete constructor, so get the VTT by name.
|
||||||
VTT = CGF.CGM.getVTables().getVTT(RD);
|
VTT = CGF.CGM.getVTables().GetAddrOfVTT(RD);
|
||||||
VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
|
VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -366,58 +366,47 @@ void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::GlobalVariable *
|
void
|
||||||
CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
|
CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
|
||||||
bool GenerateDefinition,
|
llvm::GlobalVariable::LinkageTypes Linkage,
|
||||||
const CXXRecordDecl *RD) {
|
const CXXRecordDecl *RD) {
|
||||||
// Only classes that have virtual bases need a VTT.
|
VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true);
|
||||||
if (RD->getNumVBases() == 0)
|
|
||||||
return 0;
|
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
|
||||||
|
const llvm::ArrayType *ArrayType =
|
||||||
|
llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
|
||||||
|
|
||||||
|
llvm::Constant *Init =
|
||||||
|
llvm::ConstantArray::get(ArrayType, Builder.getVTTComponents().data(),
|
||||||
|
Builder.getVTTComponents().size());
|
||||||
|
|
||||||
|
VTT->setInitializer(Init);
|
||||||
|
|
||||||
|
// Set the correct linkage.
|
||||||
|
VTT->setLinkage(Linkage);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
|
||||||
|
assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT");
|
||||||
|
|
||||||
llvm::SmallString<256> OutName;
|
llvm::SmallString<256> OutName;
|
||||||
CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, OutName);
|
CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, OutName);
|
||||||
llvm::StringRef Name = OutName.str();
|
llvm::StringRef Name = OutName.str();
|
||||||
|
|
||||||
D1(printf("vtt %s\n", RD->getNameAsCString()));
|
VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false);
|
||||||
|
|
||||||
llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
|
|
||||||
if (GV == 0 || GV->isDeclaration()) {
|
|
||||||
const llvm::Type *Int8PtrTy =
|
const llvm::Type *Int8PtrTy =
|
||||||
llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
|
llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
|
||||||
|
const llvm::ArrayType *ArrayType =
|
||||||
VTTBuilder Builder(CGM, RD, GenerateDefinition);
|
|
||||||
|
|
||||||
const llvm::ArrayType *Type =
|
|
||||||
llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
|
llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
|
||||||
|
|
||||||
llvm::Constant *Init = 0;
|
llvm::GlobalVariable *GV =
|
||||||
if (GenerateDefinition)
|
CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType,
|
||||||
Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(),
|
llvm::GlobalValue::ExternalLinkage);
|
||||||
Builder.getVTTComponents().size());
|
|
||||||
|
|
||||||
llvm::GlobalVariable *OldGV = GV;
|
|
||||||
GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
|
|
||||||
Linkage, Init, Name);
|
|
||||||
CGM.setGlobalVisibility(GV, RD, /*ForDefinition*/ GenerateDefinition);
|
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(true);
|
||||||
|
|
||||||
if (OldGV) {
|
|
||||||
GV->takeName(OldGV);
|
|
||||||
llvm::Constant *NewPtr =
|
|
||||||
llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
|
|
||||||
OldGV->replaceAllUsesWith(NewPtr);
|
|
||||||
OldGV->eraseFromParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::GlobalVariable *CodeGenVTables::getVTT(const CXXRecordDecl *RD) {
|
|
||||||
return GenerateVTT(llvm::GlobalValue::ExternalLinkage,
|
|
||||||
/*GenerateDefinition=*/false, RD);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
|
bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
|
||||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
||||||
|
|
||||||
|
|
|
@ -3040,7 +3040,10 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
|
||||||
VTable = GetAddrOfVTable(RD);
|
VTable = GetAddrOfVTable(RD);
|
||||||
EmitVTableDefinition(VTable, Linkage, RD);
|
EmitVTableDefinition(VTable, Linkage, RD);
|
||||||
|
|
||||||
GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
|
if (RD->getNumVBases()) {
|
||||||
|
llvm::GlobalVariable *VTT = GetAddrOfVTT(RD);
|
||||||
|
EmitVTTDefinition(VTT, Linkage, RD);
|
||||||
|
}
|
||||||
|
|
||||||
// If this is the magic class __cxxabiv1::__fundamental_type_info,
|
// If this is the magic class __cxxabiv1::__fundamental_type_info,
|
||||||
// we will emit the typeinfo for the fundamental types. This is the
|
// we will emit the typeinfo for the fundamental types. This is the
|
||||||
|
|
|
@ -182,10 +182,6 @@ class CodeGenVTables {
|
||||||
|
|
||||||
void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
|
void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
|
||||||
|
|
||||||
llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
|
|
||||||
bool GenerateDefinition,
|
|
||||||
const CXXRecordDecl *RD);
|
|
||||||
|
|
||||||
/// EmitThunk - Emit a single thunk.
|
/// EmitThunk - Emit a single thunk.
|
||||||
void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
|
void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
|
||||||
|
|
||||||
|
@ -258,7 +254,14 @@ public:
|
||||||
bool BaseIsVirtual,
|
bool BaseIsVirtual,
|
||||||
VTableAddressPointsMapTy& AddressPoints);
|
VTableAddressPointsMapTy& AddressPoints);
|
||||||
|
|
||||||
llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
|
|
||||||
|
/// GetAddrOfVTable - Get the address of the VTT for the given record decl.
|
||||||
|
llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
|
||||||
|
|
||||||
|
/// EmitVTTDefinition - Emit the definition of the given vtable.
|
||||||
|
void EmitVTTDefinition(llvm::GlobalVariable *VTT,
|
||||||
|
llvm::GlobalVariable::LinkageTypes Linkage,
|
||||||
|
const CXXRecordDecl *RD);
|
||||||
|
|
||||||
/// EmitThunks - Emit the associated thunks for the given global decl.
|
/// EmitThunks - Emit the associated thunks for the given global decl.
|
||||||
void EmitThunks(GlobalDecl GD);
|
void EmitThunks(GlobalDecl GD);
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
// Check mangling of Vtables, VTTs, and construction vtables that
|
// Check mangling of Vtables, VTTs, and construction vtables that
|
||||||
// involve standard substitutions.
|
// involve standard substitutions.
|
||||||
|
|
||||||
|
// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
|
||||||
// CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant
|
// CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant
|
||||||
// CHECK: @_ZTCSd0_Si = internal constant
|
// CHECK: @_ZTCSd0_Si = internal constant
|
||||||
// CHECK: @_ZTCSd16_So = internal constant
|
// CHECK: @_ZTCSd16_So = internal constant
|
||||||
// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
|
|
||||||
// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
|
|
||||||
// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
|
// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
|
||||||
// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
|
// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
|
||||||
// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
|
// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
|
||||||
|
// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
|
||||||
namespace std {
|
namespace std {
|
||||||
struct A { A(); };
|
struct A { A(); };
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue