forked from OSchip/llvm-project
CodeGen: Clean up implementation of vtable initializer builder. NFC.
- Simplify signature of CreateVTableInitializer function. - Move vtable component builder to a separate function. - Remove unnecessary accessors from VTableLayout class. This is in preparation for a future change that will alter the type of the vtable initializer. Differential Revision: https://reviews.llvm.org/D22642 llvm-svn: 280897
This commit is contained in:
parent
0053c0b679
commit
e53683f97b
|
@ -218,12 +218,6 @@ private:
|
||||||
class VTableLayout {
|
class VTableLayout {
|
||||||
public:
|
public:
|
||||||
typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
|
typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
|
||||||
|
|
||||||
typedef const VTableComponent *vtable_component_iterator;
|
|
||||||
typedef const VTableThunkTy *vtable_thunk_iterator;
|
|
||||||
typedef llvm::iterator_range<vtable_component_iterator>
|
|
||||||
vtable_component_range;
|
|
||||||
|
|
||||||
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
|
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -248,31 +242,12 @@ public:
|
||||||
bool IsMicrosoftABI);
|
bool IsMicrosoftABI);
|
||||||
~VTableLayout();
|
~VTableLayout();
|
||||||
|
|
||||||
uint64_t getNumVTableComponents() const {
|
ArrayRef<VTableComponent> vtable_components() const {
|
||||||
return NumVTableComponents;
|
return {VTableComponents.get(), NumVTableComponents};
|
||||||
}
|
}
|
||||||
|
|
||||||
vtable_component_range vtable_components() const {
|
ArrayRef<VTableThunkTy> vtable_thunks() const {
|
||||||
return vtable_component_range(vtable_component_begin(),
|
return {VTableThunks.get(), NumVTableThunks};
|
||||||
vtable_component_end());
|
|
||||||
}
|
|
||||||
|
|
||||||
vtable_component_iterator vtable_component_begin() const {
|
|
||||||
return VTableComponents.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
vtable_component_iterator vtable_component_end() const {
|
|
||||||
return VTableComponents.get() + NumVTableComponents;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t getNumVTableThunks() const { return NumVTableThunks; }
|
|
||||||
|
|
||||||
vtable_thunk_iterator vtable_thunk_begin() const {
|
|
||||||
return VTableThunks.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
vtable_thunk_iterator vtable_thunk_end() const {
|
|
||||||
return VTableThunks.get() + NumVTableThunks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getAddressPoint(BaseSubobject Base) const {
|
uint64_t getAddressPoint(BaseSubobject Base) const {
|
||||||
|
|
|
@ -1576,7 +1576,7 @@ void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,
|
||||||
const VTableLayout &VFTLayout =
|
const VTableLayout &VFTLayout =
|
||||||
CGM.getMicrosoftVTableContext().getVFTableLayout(RD, CharUnits::Zero());
|
CGM.getMicrosoftVTableContext().getVFTableLayout(RD, CharUnits::Zero());
|
||||||
unsigned VSlotCount =
|
unsigned VSlotCount =
|
||||||
VFTLayout.getNumVTableComponents() - CGM.getLangOpts().RTTIData;
|
VFTLayout.vtable_components().size() - CGM.getLangOpts().RTTIData;
|
||||||
unsigned VTableWidth = PtrWidth * VSlotCount;
|
unsigned VTableWidth = PtrWidth * VSlotCount;
|
||||||
|
|
||||||
// Create a very wide void* type and insert it directly in the element list.
|
// Create a very wide void* type and insert it directly in the element list.
|
||||||
|
|
|
@ -517,139 +517,121 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)
|
||||||
emitThunk(GD, Thunk, /*ForVTable=*/false);
|
emitThunk(GD, Thunk, /*ForVTable=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Constant *CodeGenVTables::CreateVTableInitializer(
|
llvm::Constant *CodeGenVTables::CreateVTableComponent(
|
||||||
const CXXRecordDecl *RD, const VTableComponent *Components,
|
unsigned Idx, const VTableLayout &VTLayout, llvm::Constant *RTTI,
|
||||||
unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
|
unsigned &NextVTableThunkIndex) {
|
||||||
unsigned NumVTableThunks, llvm::Constant *RTTI) {
|
VTableComponent Component = VTLayout.vtable_components()[Idx];
|
||||||
SmallVector<llvm::Constant *, 64> Inits;
|
|
||||||
|
|
||||||
llvm::Type *Int8PtrTy = CGM.Int8PtrTy;
|
auto OffsetConstant = [&](CharUnits Offset) {
|
||||||
|
return llvm::ConstantExpr::getIntToPtr(
|
||||||
|
llvm::ConstantInt::get(CGM.PtrDiffTy, Offset.getQuantity()),
|
||||||
|
CGM.Int8PtrTy);
|
||||||
|
};
|
||||||
|
|
||||||
llvm::Type *PtrDiffTy =
|
switch (Component.getKind()) {
|
||||||
CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
|
case VTableComponent::CK_VCallOffset:
|
||||||
|
return OffsetConstant(Component.getVCallOffset());
|
||||||
|
|
||||||
unsigned NextVTableThunkIndex = 0;
|
case VTableComponent::CK_VBaseOffset:
|
||||||
|
return OffsetConstant(Component.getVBaseOffset());
|
||||||
|
|
||||||
llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr;
|
case VTableComponent::CK_OffsetToTop:
|
||||||
|
return OffsetConstant(Component.getOffsetToTop());
|
||||||
|
|
||||||
for (unsigned I = 0; I != NumComponents; ++I) {
|
case VTableComponent::CK_RTTI:
|
||||||
VTableComponent Component = Components[I];
|
return RTTI;
|
||||||
|
|
||||||
llvm::Constant *Init = nullptr;
|
case VTableComponent::CK_FunctionPointer:
|
||||||
|
case VTableComponent::CK_CompleteDtorPointer:
|
||||||
|
case VTableComponent::CK_DeletingDtorPointer: {
|
||||||
|
GlobalDecl GD;
|
||||||
|
|
||||||
|
// Get the right global decl.
|
||||||
switch (Component.getKind()) {
|
switch (Component.getKind()) {
|
||||||
case VTableComponent::CK_VCallOffset:
|
default:
|
||||||
Init = llvm::ConstantInt::get(PtrDiffTy,
|
llvm_unreachable("Unexpected vtable component kind");
|
||||||
Component.getVCallOffset().getQuantity());
|
|
||||||
Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
|
|
||||||
break;
|
|
||||||
case VTableComponent::CK_VBaseOffset:
|
|
||||||
Init = llvm::ConstantInt::get(PtrDiffTy,
|
|
||||||
Component.getVBaseOffset().getQuantity());
|
|
||||||
Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
|
|
||||||
break;
|
|
||||||
case VTableComponent::CK_OffsetToTop:
|
|
||||||
Init = llvm::ConstantInt::get(PtrDiffTy,
|
|
||||||
Component.getOffsetToTop().getQuantity());
|
|
||||||
Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
|
|
||||||
break;
|
|
||||||
case VTableComponent::CK_RTTI:
|
|
||||||
Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy);
|
|
||||||
break;
|
|
||||||
case VTableComponent::CK_FunctionPointer:
|
case VTableComponent::CK_FunctionPointer:
|
||||||
|
GD = Component.getFunctionDecl();
|
||||||
|
break;
|
||||||
case VTableComponent::CK_CompleteDtorPointer:
|
case VTableComponent::CK_CompleteDtorPointer:
|
||||||
case VTableComponent::CK_DeletingDtorPointer: {
|
GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
|
||||||
GlobalDecl GD;
|
break;
|
||||||
|
case VTableComponent::CK_DeletingDtorPointer:
|
||||||
// Get the right global decl.
|
GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
|
||||||
switch (Component.getKind()) {
|
|
||||||
default:
|
|
||||||
llvm_unreachable("Unexpected vtable component kind");
|
|
||||||
case VTableComponent::CK_FunctionPointer:
|
|
||||||
GD = Component.getFunctionDecl();
|
|
||||||
break;
|
|
||||||
case VTableComponent::CK_CompleteDtorPointer:
|
|
||||||
GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
|
|
||||||
break;
|
|
||||||
case VTableComponent::CK_DeletingDtorPointer:
|
|
||||||
GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CGM.getLangOpts().CUDA) {
|
|
||||||
// Emit NULL for methods we can't codegen on this
|
|
||||||
// side. Otherwise we'd end up with vtable with unresolved
|
|
||||||
// references.
|
|
||||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
|
||||||
// OK on device side: functions w/ __device__ attribute
|
|
||||||
// OK on host side: anything except __device__-only functions.
|
|
||||||
bool CanEmitMethod = CGM.getLangOpts().CUDAIsDevice
|
|
||||||
? MD->hasAttr<CUDADeviceAttr>()
|
|
||||||
: (MD->hasAttr<CUDAHostAttr>() ||
|
|
||||||
!MD->hasAttr<CUDADeviceAttr>());
|
|
||||||
if (!CanEmitMethod) {
|
|
||||||
Init = llvm::ConstantExpr::getNullValue(Int8PtrTy);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Method is acceptable, continue processing as usual.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
|
|
||||||
// We have a pure virtual member function.
|
|
||||||
if (!PureVirtualFn) {
|
|
||||||
llvm::FunctionType *Ty =
|
|
||||||
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
|
|
||||||
StringRef PureCallName = CGM.getCXXABI().GetPureVirtualCallName();
|
|
||||||
PureVirtualFn = CGM.CreateRuntimeFunction(Ty, PureCallName);
|
|
||||||
if (auto *F = dyn_cast<llvm::Function>(PureVirtualFn))
|
|
||||||
F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
|
||||||
PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn,
|
|
||||||
CGM.Int8PtrTy);
|
|
||||||
}
|
|
||||||
Init = PureVirtualFn;
|
|
||||||
} else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
|
|
||||||
if (!DeletedVirtualFn) {
|
|
||||||
llvm::FunctionType *Ty =
|
|
||||||
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
|
|
||||||
StringRef DeletedCallName =
|
|
||||||
CGM.getCXXABI().GetDeletedVirtualCallName();
|
|
||||||
DeletedVirtualFn = CGM.CreateRuntimeFunction(Ty, DeletedCallName);
|
|
||||||
if (auto *F = dyn_cast<llvm::Function>(DeletedVirtualFn))
|
|
||||||
F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
|
||||||
DeletedVirtualFn = llvm::ConstantExpr::getBitCast(DeletedVirtualFn,
|
|
||||||
CGM.Int8PtrTy);
|
|
||||||
}
|
|
||||||
Init = DeletedVirtualFn;
|
|
||||||
} else {
|
|
||||||
// Check if we should use a thunk.
|
|
||||||
if (NextVTableThunkIndex < NumVTableThunks &&
|
|
||||||
VTableThunks[NextVTableThunkIndex].first == I) {
|
|
||||||
const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
|
|
||||||
|
|
||||||
maybeEmitThunkForVTable(GD, Thunk);
|
|
||||||
Init = CGM.GetAddrOfThunk(GD, Thunk);
|
|
||||||
|
|
||||||
NextVTableThunkIndex++;
|
|
||||||
} else {
|
|
||||||
llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
|
|
||||||
|
|
||||||
Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VTableComponent::CK_UnusedFunctionPointer:
|
if (CGM.getLangOpts().CUDA) {
|
||||||
Init = llvm::ConstantExpr::getNullValue(Int8PtrTy);
|
// Emit NULL for methods we can't codegen on this
|
||||||
break;
|
// side. Otherwise we'd end up with vtable with unresolved
|
||||||
|
// references.
|
||||||
|
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
||||||
|
// OK on device side: functions w/ __device__ attribute
|
||||||
|
// OK on host side: anything except __device__-only functions.
|
||||||
|
bool CanEmitMethod =
|
||||||
|
CGM.getLangOpts().CUDAIsDevice
|
||||||
|
? MD->hasAttr<CUDADeviceAttr>()
|
||||||
|
: (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
|
||||||
|
if (!CanEmitMethod)
|
||||||
|
return llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy);
|
||||||
|
// Method is acceptable, continue processing as usual.
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SpecialVirtualFn = [&](llvm::Constant *&Cache, StringRef Name) {
|
||||||
|
if (!Cache) {
|
||||||
|
llvm::FunctionType *Ty =
|
||||||
|
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
|
||||||
|
Cache = CGM.CreateRuntimeFunction(Ty, Name);
|
||||||
|
if (auto *F = dyn_cast<llvm::Function>(Cache))
|
||||||
|
F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||||
|
Cache = llvm::ConstantExpr::getBitCast(Cache, CGM.Int8PtrTy);
|
||||||
|
}
|
||||||
|
return Cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
Inits.push_back(Init);
|
if (cast<CXXMethodDecl>(GD.getDecl())->isPure())
|
||||||
|
// We have a pure virtual member function.
|
||||||
|
return SpecialVirtualFn(PureVirtualFn,
|
||||||
|
CGM.getCXXABI().GetPureVirtualCallName());
|
||||||
|
|
||||||
|
if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted())
|
||||||
|
return SpecialVirtualFn(DeletedVirtualFn,
|
||||||
|
CGM.getCXXABI().GetDeletedVirtualCallName());
|
||||||
|
|
||||||
|
// Check if we should use a thunk.
|
||||||
|
if (NextVTableThunkIndex < VTLayout.vtable_thunks().size() &&
|
||||||
|
VTLayout.vtable_thunks()[NextVTableThunkIndex].first == Idx) {
|
||||||
|
const ThunkInfo &Thunk =
|
||||||
|
VTLayout.vtable_thunks()[NextVTableThunkIndex].second;
|
||||||
|
|
||||||
|
maybeEmitThunkForVTable(GD, Thunk);
|
||||||
|
NextVTableThunkIndex++;
|
||||||
|
return CGM.GetAddrOfThunk(GD, Thunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
|
||||||
|
return CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents);
|
case VTableComponent::CK_UnusedFunctionPointer:
|
||||||
|
return llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Constant *
|
||||||
|
CodeGenVTables::CreateVTableInitializer(const VTableLayout &VTLayout,
|
||||||
|
llvm::Constant *RTTI) {
|
||||||
|
SmallVector<llvm::Constant *, 64> Inits;
|
||||||
|
unsigned NextVTableThunkIndex = 0;
|
||||||
|
|
||||||
|
for (unsigned I = 0, E = VTLayout.vtable_components().size(); I != E; ++I) {
|
||||||
|
llvm::Constant *Init =
|
||||||
|
CreateVTableComponent(I, VTLayout, RTTI, NextVTableThunkIndex);
|
||||||
|
Inits.push_back(llvm::ConstantExpr::getBitCast(Init, CGM.Int8PtrTy));
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::ArrayType *ArrayType =
|
||||||
|
llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout.vtable_components().size());
|
||||||
return llvm::ConstantArray::get(ArrayType, Inits);
|
return llvm::ConstantArray::get(ArrayType, Inits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +660,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
|
||||||
StringRef Name = OutName.str();
|
StringRef Name = OutName.str();
|
||||||
|
|
||||||
llvm::ArrayType *ArrayType =
|
llvm::ArrayType *ArrayType =
|
||||||
llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->getNumVTableComponents());
|
llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->vtable_components().size());
|
||||||
|
|
||||||
// Construction vtable symbols are not part of the Itanium ABI, so we cannot
|
// Construction vtable symbols are not part of the Itanium ABI, so we cannot
|
||||||
// guarantee that they actually will be available externally. Instead, when
|
// guarantee that they actually will be available externally. Instead, when
|
||||||
|
@ -700,10 +682,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
|
||||||
CGM.getContext().getTagDeclType(Base.getBase()));
|
CGM.getContext().getTagDeclType(Base.getBase()));
|
||||||
|
|
||||||
// Create and set the initializer.
|
// Create and set the initializer.
|
||||||
llvm::Constant *Init = CreateVTableInitializer(
|
llvm::Constant *Init = CreateVTableInitializer(*VTLayout, RTTI);
|
||||||
Base.getBase(), VTLayout->vtable_component_begin(),
|
|
||||||
VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(),
|
|
||||||
VTLayout->getNumVTableThunks(), RTTI);
|
|
||||||
VTable->setInitializer(Init);
|
VTable->setInitializer(Init);
|
||||||
|
|
||||||
CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get());
|
CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get());
|
||||||
|
|
|
@ -49,6 +49,12 @@ class CodeGenVTables {
|
||||||
/// indices.
|
/// indices.
|
||||||
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
|
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
|
||||||
|
|
||||||
|
/// Cache for the pure virtual member call function.
|
||||||
|
llvm::Constant *PureVirtualFn = nullptr;
|
||||||
|
|
||||||
|
/// Cache for the deleted virtual member call function.
|
||||||
|
llvm::Constant *DeletedVirtualFn = nullptr;
|
||||||
|
|
||||||
/// emitThunk - Emit a single thunk.
|
/// emitThunk - Emit a single thunk.
|
||||||
void emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, bool ForVTable);
|
void emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, bool ForVTable);
|
||||||
|
|
||||||
|
@ -56,15 +62,16 @@ class CodeGenVTables {
|
||||||
/// the ABI.
|
/// the ABI.
|
||||||
void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk);
|
void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk);
|
||||||
|
|
||||||
|
llvm::Constant *CreateVTableComponent(unsigned Idx,
|
||||||
|
const VTableLayout &VTLayout,
|
||||||
|
llvm::Constant *RTTI,
|
||||||
|
unsigned &NextVTableThunkIndex);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// CreateVTableInitializer - Create a vtable initializer for the given record
|
/// CreateVTableInitializer - Create a vtable initializer with the given
|
||||||
/// decl.
|
/// layout.
|
||||||
/// \param Components - The vtable components; this is really an array of
|
llvm::Constant *CreateVTableInitializer(const VTableLayout &VTLayout,
|
||||||
/// VTableComponents.
|
llvm::Constant *RTTI);
|
||||||
llvm::Constant *CreateVTableInitializer(
|
|
||||||
const CXXRecordDecl *RD, const VTableComponent *Components,
|
|
||||||
unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
|
|
||||||
unsigned NumVTableThunks, llvm::Constant *RTTI);
|
|
||||||
|
|
||||||
CodeGenVTables(CodeGenModule &CGM);
|
CodeGenVTables(CodeGenModule &CGM);
|
||||||
|
|
||||||
|
|
|
@ -1462,9 +1462,7 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
|
||||||
CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
|
CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
|
||||||
|
|
||||||
// Create and set the initializer.
|
// Create and set the initializer.
|
||||||
llvm::Constant *Init = CGVT.CreateVTableInitializer(
|
llvm::Constant *Init = CGVT.CreateVTableInitializer(VTLayout, RTTI);
|
||||||
RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(),
|
|
||||||
VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(), RTTI);
|
|
||||||
VTable->setInitializer(Init);
|
VTable->setInitializer(Init);
|
||||||
|
|
||||||
// Set the correct linkage.
|
// Set the correct linkage.
|
||||||
|
@ -1575,7 +1573,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
|
||||||
|
|
||||||
ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
|
ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
|
||||||
llvm::ArrayType *ArrayType = llvm::ArrayType::get(
|
llvm::ArrayType *ArrayType = llvm::ArrayType::get(
|
||||||
CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents());
|
CGM.Int8PtrTy, VTContext.getVTableLayout(RD).vtable_components().size());
|
||||||
|
|
||||||
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
|
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
|
||||||
Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
|
Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
|
||||||
|
|
|
@ -1575,10 +1575,7 @@ void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
|
||||||
[](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
|
[](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
|
||||||
RTTI = getMSCompleteObjectLocator(RD, Info);
|
RTTI = getMSCompleteObjectLocator(RD, Info);
|
||||||
|
|
||||||
llvm::Constant *Init = CGVT.CreateVTableInitializer(
|
llvm::Constant *Init = CGVT.CreateVTableInitializer(VTLayout, RTTI);
|
||||||
RD, VTLayout.vtable_component_begin(),
|
|
||||||
VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(),
|
|
||||||
VTLayout.getNumVTableThunks(), RTTI);
|
|
||||||
|
|
||||||
VTable->setInitializer(Init);
|
VTable->setInitializer(Init);
|
||||||
|
|
||||||
|
@ -1701,7 +1698,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
|
||||||
|
|
||||||
uint64_t NumVTableSlots =
|
uint64_t NumVTableSlots =
|
||||||
VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC)
|
VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC)
|
||||||
.getNumVTableComponents();
|
.vtable_components()
|
||||||
|
.size();
|
||||||
llvm::GlobalValue::LinkageTypes VTableLinkage =
|
llvm::GlobalValue::LinkageTypes VTableLinkage =
|
||||||
VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
|
VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue