forked from OSchip/llvm-project
Make CGVTables use ConstantInitBuilder. NFC.
llvm-svn: 288081
This commit is contained in:
parent
f1788639c5
commit
9c6cb7642e
|
@ -14,6 +14,7 @@
|
|||
#include "CGCXXABI.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "ConstantBuilder.h"
|
||||
#include "clang/AST/CXXInheritance.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/CodeGen/CGFunctionInfo.h"
|
||||
|
@ -524,29 +525,29 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)
|
|||
emitThunk(GD, Thunk, /*ForVTable=*/false);
|
||||
}
|
||||
|
||||
llvm::Constant *CodeGenVTables::CreateVTableComponent(
|
||||
unsigned Idx, const VTableLayout &VTLayout, llvm::Constant *RTTI,
|
||||
unsigned &NextVTableThunkIndex) {
|
||||
VTableComponent Component = VTLayout.vtable_components()[Idx];
|
||||
void CodeGenVTables::addVTableComponent(
|
||||
ConstantArrayBuilder &builder, const VTableLayout &layout,
|
||||
unsigned idx, llvm::Constant *rtti, unsigned &nextVTableThunkIndex) {
|
||||
auto &component = layout.vtable_components()[idx];
|
||||
|
||||
auto OffsetConstant = [&](CharUnits Offset) {
|
||||
return llvm::ConstantExpr::getIntToPtr(
|
||||
llvm::ConstantInt::get(CGM.PtrDiffTy, Offset.getQuantity()),
|
||||
CGM.Int8PtrTy);
|
||||
auto addOffsetConstant = [&](CharUnits offset) {
|
||||
builder.add(llvm::ConstantExpr::getIntToPtr(
|
||||
llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()),
|
||||
CGM.Int8PtrTy));
|
||||
};
|
||||
|
||||
switch (Component.getKind()) {
|
||||
switch (component.getKind()) {
|
||||
case VTableComponent::CK_VCallOffset:
|
||||
return OffsetConstant(Component.getVCallOffset());
|
||||
return addOffsetConstant(component.getVCallOffset());
|
||||
|
||||
case VTableComponent::CK_VBaseOffset:
|
||||
return OffsetConstant(Component.getVBaseOffset());
|
||||
return addOffsetConstant(component.getVBaseOffset());
|
||||
|
||||
case VTableComponent::CK_OffsetToTop:
|
||||
return OffsetConstant(Component.getOffsetToTop());
|
||||
return addOffsetConstant(component.getOffsetToTop());
|
||||
|
||||
case VTableComponent::CK_RTTI:
|
||||
return RTTI;
|
||||
return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.Int8PtrTy));
|
||||
|
||||
case VTableComponent::CK_FunctionPointer:
|
||||
case VTableComponent::CK_CompleteDtorPointer:
|
||||
|
@ -554,17 +555,17 @@ llvm::Constant *CodeGenVTables::CreateVTableComponent(
|
|||
GlobalDecl GD;
|
||||
|
||||
// Get the right global decl.
|
||||
switch (Component.getKind()) {
|
||||
switch (component.getKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unexpected vtable component kind");
|
||||
case VTableComponent::CK_FunctionPointer:
|
||||
GD = Component.getFunctionDecl();
|
||||
GD = component.getFunctionDecl();
|
||||
break;
|
||||
case VTableComponent::CK_CompleteDtorPointer:
|
||||
GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
|
||||
GD = GlobalDecl(component.getDestructorDecl(), Dtor_Complete);
|
||||
break;
|
||||
case VTableComponent::CK_DeletingDtorPointer:
|
||||
GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
|
||||
GD = GlobalDecl(component.getDestructorDecl(), Dtor_Deleting);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -580,68 +581,69 @@ llvm::Constant *CodeGenVTables::CreateVTableComponent(
|
|||
? MD->hasAttr<CUDADeviceAttr>()
|
||||
: (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
|
||||
if (!CanEmitMethod)
|
||||
return llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy);
|
||||
return builder.addNullPointer(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;
|
||||
auto getSpecialVirtualFn = [&](StringRef name) {
|
||||
llvm::FunctionType *fnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
|
||||
llvm::Constant *fn = CGM.CreateRuntimeFunction(fnTy, name);
|
||||
if (auto f = dyn_cast<llvm::Function>(fn))
|
||||
f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy);
|
||||
};
|
||||
|
||||
if (cast<CXXMethodDecl>(GD.getDecl())->isPure())
|
||||
// We have a pure virtual member function.
|
||||
return SpecialVirtualFn(PureVirtualFn,
|
||||
CGM.getCXXABI().GetPureVirtualCallName());
|
||||
llvm::Constant *fnPtr;
|
||||
|
||||
if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted())
|
||||
return SpecialVirtualFn(DeletedVirtualFn,
|
||||
CGM.getCXXABI().GetDeletedVirtualCallName());
|
||||
// Pure virtual member functions.
|
||||
if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
|
||||
if (!PureVirtualFn)
|
||||
PureVirtualFn =
|
||||
getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
|
||||
fnPtr = PureVirtualFn;
|
||||
|
||||
// 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;
|
||||
// Deleted virtual member functions.
|
||||
} else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
|
||||
if (!DeletedVirtualFn)
|
||||
DeletedVirtualFn =
|
||||
getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());
|
||||
fnPtr = DeletedVirtualFn;
|
||||
|
||||
maybeEmitThunkForVTable(GD, Thunk);
|
||||
NextVTableThunkIndex++;
|
||||
return CGM.GetAddrOfThunk(GD, Thunk);
|
||||
// Thunks.
|
||||
} else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
|
||||
layout.vtable_thunks()[nextVTableThunkIndex].first == idx) {
|
||||
auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
|
||||
|
||||
maybeEmitThunkForVTable(GD, thunkInfo);
|
||||
nextVTableThunkIndex++;
|
||||
fnPtr = CGM.GetAddrOfThunk(GD, thunkInfo);
|
||||
|
||||
// Otherwise we can use the method definition directly.
|
||||
} else {
|
||||
llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
|
||||
fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
|
||||
}
|
||||
|
||||
llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
|
||||
return CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
|
||||
fnPtr = llvm::ConstantExpr::getBitCast(fnPtr, CGM.Int8PtrTy);
|
||||
builder.add(fnPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
case VTableComponent::CK_UnusedFunctionPointer:
|
||||
return llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy);
|
||||
return builder.addNullPointer(CGM.Int8PtrTy);
|
||||
}
|
||||
|
||||
llvm_unreachable("Unexpected vtable component kind");
|
||||
}
|
||||
|
||||
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));
|
||||
void CodeGenVTables::createVTableInitializer(ConstantArrayBuilder &builder,
|
||||
const VTableLayout &layout,
|
||||
llvm::Constant *rtti) {
|
||||
unsigned nextVTableThunkIndex = 0;
|
||||
for (unsigned i = 0, e = layout.vtable_components().size(); i != e; ++i) {
|
||||
addVTableComponent(builder, layout, i, rtti, nextVTableThunkIndex);
|
||||
}
|
||||
|
||||
llvm::ArrayType *ArrayType =
|
||||
llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout.vtable_components().size());
|
||||
return llvm::ConstantArray::get(ArrayType, Inits);
|
||||
}
|
||||
|
||||
llvm::GlobalVariable *
|
||||
|
@ -691,8 +693,10 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
|
|||
CGM.getContext().getTagDeclType(Base.getBase()));
|
||||
|
||||
// Create and set the initializer.
|
||||
llvm::Constant *Init = CreateVTableInitializer(*VTLayout, RTTI);
|
||||
VTable->setInitializer(Init);
|
||||
ConstantInitBuilder builder(CGM);
|
||||
auto components = builder.beginArray(CGM.Int8PtrTy);
|
||||
createVTableInitializer(components, *VTLayout, RTTI);
|
||||
components.finishAndSetAsInitializer(VTable);
|
||||
|
||||
CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get());
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace clang {
|
|||
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
class ConstantArrayBuilder;
|
||||
|
||||
class CodeGenVTables {
|
||||
CodeGenModule &CGM;
|
||||
|
@ -62,16 +63,17 @@ class CodeGenVTables {
|
|||
/// the ABI.
|
||||
void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk);
|
||||
|
||||
llvm::Constant *CreateVTableComponent(unsigned Idx,
|
||||
const VTableLayout &VTLayout,
|
||||
llvm::Constant *RTTI,
|
||||
unsigned &NextVTableThunkIndex);
|
||||
void addVTableComponent(ConstantArrayBuilder &builder,
|
||||
const VTableLayout &layout, unsigned idx,
|
||||
llvm::Constant *rtti,
|
||||
unsigned &nextVTableThunkIndex);
|
||||
|
||||
public:
|
||||
/// CreateVTableInitializer - Create a vtable initializer with the given
|
||||
/// layout.
|
||||
llvm::Constant *CreateVTableInitializer(const VTableLayout &VTLayout,
|
||||
llvm::Constant *RTTI);
|
||||
/// Add vtable components for the given vtable layout to the given
|
||||
/// global initializer.
|
||||
void createVTableInitializer(ConstantArrayBuilder &builder,
|
||||
const VTableLayout &layout,
|
||||
llvm::Constant *rtti);
|
||||
|
||||
CodeGenVTables(CodeGenModule &CGM);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "CGVTables.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "ConstantBuilder.h"
|
||||
#include "TargetInfo.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/Type.h"
|
||||
|
@ -1479,8 +1480,10 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
|
|||
CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
|
||||
|
||||
// Create and set the initializer.
|
||||
llvm::Constant *Init = CGVT.CreateVTableInitializer(VTLayout, RTTI);
|
||||
VTable->setInitializer(Init);
|
||||
ConstantInitBuilder Builder(CGM);
|
||||
auto Components = Builder.beginArray(CGM.Int8PtrTy);
|
||||
CGVT.createVTableInitializer(Components, VTLayout, RTTI);
|
||||
Components.finishAndSetAsInitializer(VTable);
|
||||
|
||||
// Set the correct linkage.
|
||||
VTable->setLinkage(Linkage);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "CGVTables.h"
|
||||
#include "CodeGenModule.h"
|
||||
#include "CodeGenTypes.h"
|
||||
#include "ConstantBuilder.h"
|
||||
#include "TargetInfo.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
|
@ -1584,9 +1585,10 @@ void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
|
|||
[](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
|
||||
RTTI = getMSCompleteObjectLocator(RD, *Info);
|
||||
|
||||
llvm::Constant *Init = CGVT.CreateVTableInitializer(VTLayout, RTTI);
|
||||
|
||||
VTable->setInitializer(Init);
|
||||
ConstantInitBuilder Builder(CGM);
|
||||
auto Components = Builder.beginArray(CGM.Int8PtrTy);
|
||||
CGVT.createVTableInitializer(Components, VTLayout, RTTI);
|
||||
Components.finishAndSetAsInitializer(VTable);
|
||||
|
||||
emitVTableTypeMetadata(*Info, RD, VTable);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue