Create a VTableContext class and start moving CodeGenVTables methods to it
llvm-svn: 140502
This commit is contained in:
parent
2d2595235d
commit
a834166e48
|
@ -305,7 +305,7 @@ llvm::Value *
|
|||
CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
|
||||
llvm::Type *Ty) {
|
||||
MD = MD->getCanonicalDecl();
|
||||
uint64_t VTableIndex = CGM.getVTables().getMethodVTableIndex(MD);
|
||||
uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(MD);
|
||||
|
||||
return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
|
|||
VTable = Builder.CreateBitCast(VTable, Ty);
|
||||
assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");
|
||||
MD = MD->getCanonicalDecl();
|
||||
uint64_t VTableIndex = CGM.getVTables().getMethodVTableIndex(MD);
|
||||
uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(MD);
|
||||
uint64_t AddressPoint =
|
||||
CGM.getVTables().getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD);
|
||||
VTableIndex += AddressPoint;
|
||||
|
@ -370,7 +370,7 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall(
|
|||
VTable = Builder.CreateBitCast(VTable, Ty);
|
||||
DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
|
||||
uint64_t VTableIndex =
|
||||
CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type));
|
||||
CGM.getVTableContext().getMethodVTableIndex(GlobalDecl(DD, Type));
|
||||
uint64_t AddressPoint =
|
||||
CGM.getVTables().getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD);
|
||||
VTableIndex += AddressPoint;
|
||||
|
@ -386,7 +386,7 @@ CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,
|
|||
llvm::Value *This, llvm::Type *Ty) {
|
||||
DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl());
|
||||
uint64_t VTableIndex =
|
||||
CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type));
|
||||
CGM.getVTableContext().getMethodVTableIndex(GlobalDecl(DD, Type));
|
||||
|
||||
return ::BuildVirtualCall(*this, VTableIndex, This, Ty);
|
||||
}
|
||||
|
|
|
@ -1410,7 +1410,7 @@ CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
|
|||
const CXXRecordDecl *BaseClassDecl) {
|
||||
llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy);
|
||||
CharUnits VBaseOffsetOffset =
|
||||
CGM.getVTables().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl);
|
||||
CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl);
|
||||
|
||||
llvm::Value *VBaseOffsetPtr =
|
||||
Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(),
|
||||
|
|
|
@ -762,7 +762,7 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
|
|||
// It doesn't make sense to give a virtual destructor a vtable index,
|
||||
// since a single destructor has two entries in the vtable.
|
||||
if (!isa<CXXDestructorDecl>(Method))
|
||||
VIndex = CGM.getVTables().getMethodVTableIndex(Method);
|
||||
VIndex = CGM.getVTableContext().getMethodVTableIndex(Method);
|
||||
ContainingType = RecordTy;
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,8 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,
|
|||
// virtual base offset offset is -ve. The code generator emits dwarf
|
||||
// expression where it expects +ve number.
|
||||
BaseOffset =
|
||||
0 - CGM.getVTables().getVirtualBaseOffsetOffset(RD, Base).getQuantity();
|
||||
0 - CGM.getVTableContext()
|
||||
.getVirtualBaseOffsetOffset(RD, Base).getQuantity();
|
||||
BFlags = llvm::DIDescriptor::FlagVirtual;
|
||||
} else
|
||||
BaseOffset = RL.getBaseClassOffsetInBits(Base);
|
||||
|
|
|
@ -879,7 +879,7 @@ void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
|
|||
CharUnits Offset;
|
||||
if (Base->isVirtual())
|
||||
Offset =
|
||||
CGM.getVTables().getVirtualBaseOffsetOffset(RD, BaseDecl);
|
||||
CGM.getVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
|
||||
else {
|
||||
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
|
||||
Offset = Layout.getBaseClassOffset(BaseDecl);
|
||||
|
|
|
@ -963,7 +963,7 @@ public:
|
|||
|
||||
private:
|
||||
/// VTables - Global vtable information.
|
||||
CodeGenVTables &VTables;
|
||||
VTableContext &VTables;
|
||||
|
||||
/// MostDerivedClass - The most derived class for which we're building this
|
||||
/// vtable.
|
||||
|
@ -1156,7 +1156,7 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
VTableBuilder(CodeGenVTables &VTables, const CXXRecordDecl *MostDerivedClass,
|
||||
VTableBuilder(VTableContext &VTables, const CXXRecordDecl *MostDerivedClass,
|
||||
CharUnits MostDerivedClassOffset,
|
||||
bool MostDerivedClassIsVirtual, const
|
||||
CXXRecordDecl *LayoutClass)
|
||||
|
@ -2316,7 +2316,7 @@ CollectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context,
|
|||
llvm_unreachable("Found a duplicate primary base!");
|
||||
}
|
||||
|
||||
void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
|
||||
void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
|
||||
|
||||
// Itanium C++ ABI 2.5.2:
|
||||
// The order of the virtual function pointers in a virtual table is the
|
||||
|
@ -2329,7 +2329,7 @@ void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
|
|||
|
||||
int64_t CurrentIndex = 0;
|
||||
|
||||
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
|
||||
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
|
||||
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
|
||||
|
||||
if (PrimaryBase) {
|
||||
|
@ -2344,7 +2344,7 @@ void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
|
|||
// Collect all the primary bases, so we can check whether methods override
|
||||
// a method from the base.
|
||||
VTableBuilder::PrimaryBasesSetVectorTy PrimaryBases;
|
||||
CollectPrimaryBases(RD, CGM.getContext(), PrimaryBases);
|
||||
CollectPrimaryBases(RD, Context, PrimaryBases);
|
||||
|
||||
const CXXDestructorDecl *ImplicitVirtualDtor = 0;
|
||||
|
||||
|
@ -2361,7 +2361,7 @@ void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
|
|||
FindNearestOverriddenMethod(MD, PrimaryBases)) {
|
||||
// Check if converting from the return type of the method to the
|
||||
// return type of the overridden method requires conversion.
|
||||
if (ComputeReturnAdjustmentBaseOffset(CGM.getContext(), MD,
|
||||
if (ComputeReturnAdjustmentBaseOffset(Context, MD,
|
||||
OverriddenMD).isEmpty()) {
|
||||
// This index is shared between the index in the vtable of the primary
|
||||
// base class.
|
||||
|
@ -2419,6 +2419,9 @@ void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
|
|||
NumVirtualFunctionPointers[RD] = CurrentIndex;
|
||||
}
|
||||
|
||||
CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
|
||||
: CGM(CGM), VTContext(CGM.getContext()) { }
|
||||
|
||||
bool CodeGenVTables::ShouldEmitVTableInThisTU(const CXXRecordDecl *RD) {
|
||||
assert(RD->isDynamicClass() && "Non dynamic classes have no VTable.");
|
||||
|
||||
|
@ -2446,7 +2449,7 @@ bool CodeGenVTables::ShouldEmitVTableInThisTU(const CXXRecordDecl *RD) {
|
|||
return KeyFunction->hasBody();
|
||||
}
|
||||
|
||||
uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) {
|
||||
uint64_t VTableContext::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) {
|
||||
llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
|
||||
NumVirtualFunctionPointers.find(RD);
|
||||
if (I != NumVirtualFunctionPointers.end())
|
||||
|
@ -2459,7 +2462,7 @@ uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD)
|
|||
return I->second;
|
||||
}
|
||||
|
||||
uint64_t CodeGenVTables::getMethodVTableIndex(GlobalDecl GD) {
|
||||
uint64_t VTableContext::getMethodVTableIndex(GlobalDecl GD) {
|
||||
MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD);
|
||||
if (I != MethodVTableIndices.end())
|
||||
return I->second;
|
||||
|
@ -2474,8 +2477,8 @@ uint64_t CodeGenVTables::getMethodVTableIndex(GlobalDecl GD) {
|
|||
}
|
||||
|
||||
CharUnits
|
||||
CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *VBase) {
|
||||
VTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *VBase) {
|
||||
ClassPairTy ClassPair(RD, VBase);
|
||||
|
||||
VirtualBaseClassOffsetOffsetsMapTy::iterator I =
|
||||
|
@ -2982,7 +2985,7 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
|
|||
if (Entry.getPointer())
|
||||
return;
|
||||
|
||||
VTableBuilder Builder(*this, RD, CharUnits::Zero(),
|
||||
VTableBuilder Builder(VTContext, RD, CharUnits::Zero(),
|
||||
/*MostDerivedClassIsVirtual=*/0, RD);
|
||||
|
||||
// Add the VTable layout.
|
||||
|
@ -3042,16 +3045,16 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
|
|||
RD->vbases_begin()->getType()->getAs<RecordType>();
|
||||
const CXXRecordDecl *VBase = cast<CXXRecordDecl>(VBaseRT->getDecl());
|
||||
|
||||
if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase)))
|
||||
if (VTContext.VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase)))
|
||||
return;
|
||||
|
||||
for (VTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator I =
|
||||
Builder.getVBaseOffsetOffsets().begin(),
|
||||
E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) {
|
||||
// Insert all types.
|
||||
ClassPairTy ClassPair(RD, I->first);
|
||||
VTableContext::ClassPairTy ClassPair(RD, I->first);
|
||||
|
||||
VirtualBaseClassOffsetOffsets.insert(
|
||||
VTContext.VirtualBaseClassOffsetOffsets.insert(
|
||||
std::make_pair(ClassPair, I->second));
|
||||
}
|
||||
}
|
||||
|
@ -3192,7 +3195,7 @@ CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,
|
|||
const CXXRecordDecl *RD) {
|
||||
// Dump the vtable layout if necessary.
|
||||
if (CGM.getLangOptions().DumpVTableLayouts) {
|
||||
VTableBuilder Builder(*this, RD, CharUnits::Zero(),
|
||||
VTableBuilder Builder(VTContext, RD, CharUnits::Zero(),
|
||||
/*MostDerivedClassIsVirtual=*/0, RD);
|
||||
|
||||
Builder.dumpLayout(llvm::errs());
|
||||
|
@ -3222,7 +3225,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
|
|||
bool BaseIsVirtual,
|
||||
llvm::GlobalVariable::LinkageTypes Linkage,
|
||||
VTableAddressPointsMapTy& AddressPoints) {
|
||||
VTableBuilder Builder(*this, Base.getBase(),
|
||||
VTableBuilder Builder(VTContext, Base.getBase(),
|
||||
Base.getBaseOffset(),
|
||||
/*MostDerivedClassIsVirtual=*/BaseIsVirtual, RD);
|
||||
|
||||
|
|
|
@ -26,15 +26,20 @@ namespace clang {
|
|||
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
class CodeGenVTables;
|
||||
|
||||
class CodeGenVTables {
|
||||
CodeGenModule &CGM;
|
||||
class VTableContext {
|
||||
ASTContext &Context;
|
||||
|
||||
/// MethodVTableIndices - Contains the index (relative to the vtable address
|
||||
/// point) where the function pointer for a virtual function is stored.
|
||||
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
|
||||
MethodVTableIndicesTy MethodVTableIndices;
|
||||
|
||||
/// NumVirtualFunctionPointers - Contains the number of virtual function
|
||||
/// pointers in the vtable for a given record decl.
|
||||
llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
|
||||
|
||||
typedef std::pair<const CXXRecordDecl *,
|
||||
const CXXRecordDecl *> ClassPairTy;
|
||||
|
||||
|
@ -45,13 +50,39 @@ class CodeGenVTables {
|
|||
VirtualBaseClassOffsetOffsetsMapTy;
|
||||
VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
|
||||
|
||||
void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
|
||||
|
||||
public:
|
||||
VTableContext(ASTContext &Context) : Context(Context) {}
|
||||
|
||||
/// getNumVirtualFunctionPointers - Return the number of virtual function
|
||||
/// pointers in the vtable for a given record decl.
|
||||
uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
|
||||
|
||||
/// getMethodVTableIndex - Return the index (relative to the vtable address
|
||||
/// point) where the function pointer for the given virtual function is
|
||||
/// stored.
|
||||
uint64_t getMethodVTableIndex(GlobalDecl GD);
|
||||
|
||||
/// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the
|
||||
/// vtable address point) where the offset of the virtual base that contains
|
||||
/// the given base is stored, otherwise, if no virtual base contains the given
|
||||
/// class, return 0. Base must be a virtual base class or an unambigious
|
||||
/// base.
|
||||
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *VBase);
|
||||
|
||||
friend class CodeGenVTables;
|
||||
};
|
||||
|
||||
class CodeGenVTables {
|
||||
CodeGenModule &CGM;
|
||||
|
||||
VTableContext VTContext;
|
||||
|
||||
/// VTables - All the vtables which have been defined.
|
||||
llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
|
||||
|
||||
/// NumVirtualFunctionPointers - Contains the number of virtual function
|
||||
/// pointers in the vtable for a given record decl.
|
||||
llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
|
||||
|
||||
typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
|
||||
typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
|
||||
|
||||
|
@ -113,12 +144,6 @@ class CodeGenVTables {
|
|||
/// indices.
|
||||
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
|
||||
|
||||
/// getNumVirtualFunctionPointers - Return the number of virtual function
|
||||
/// pointers in the vtable for a given record decl.
|
||||
uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
|
||||
|
||||
void ComputeMethodVTableIndices(const CXXRecordDecl *RD);
|
||||
|
||||
/// EmitThunk - Emit a single thunk.
|
||||
void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
|
||||
bool UseAvailableExternallyLinkage);
|
||||
|
@ -145,8 +170,9 @@ class CodeGenVTables {
|
|||
const VTableThunksTy &VTableThunks);
|
||||
|
||||
public:
|
||||
CodeGenVTables(CodeGenModule &CGM)
|
||||
: CGM(CGM) { }
|
||||
CodeGenVTables(CodeGenModule &CGM);
|
||||
|
||||
VTableContext &getVTableContext() { return VTContext; }
|
||||
|
||||
/// \brief True if the VTable of this record must be emitted in the
|
||||
/// translation unit.
|
||||
|
@ -166,19 +192,6 @@ public:
|
|||
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
|
||||
BaseSubobject Base);
|
||||
|
||||
/// getMethodVTableIndex - Return the index (relative to the vtable address
|
||||
/// point) where the function pointer for the given virtual function is
|
||||
/// stored.
|
||||
uint64_t getMethodVTableIndex(GlobalDecl GD);
|
||||
|
||||
/// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the
|
||||
/// vtable address point) where the offset of the virtual base that contains
|
||||
/// the given base is stored, otherwise, if no virtual base contains the given
|
||||
/// class, return 0. Base must be a virtual base class or an unambigious
|
||||
/// base.
|
||||
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *VBase);
|
||||
|
||||
/// getAddressPoint - Get the address point of the given subobject in the
|
||||
/// class decl.
|
||||
uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);
|
||||
|
|
|
@ -396,6 +396,7 @@ public:
|
|||
llvm::Module &getModule() const { return TheModule; }
|
||||
CodeGenTypes &getTypes() { return Types; }
|
||||
CodeGenVTables &getVTables() { return VTables; }
|
||||
VTableContext &getVTableContext() { return VTables.getVTableContext(); }
|
||||
DiagnosticsEngine &getDiags() const { return Diags; }
|
||||
const llvm::TargetData &getTargetData() const { return TheTargetData; }
|
||||
const TargetInfo &getTarget() const { return Context.getTargetInfo(); }
|
||||
|
|
|
@ -509,7 +509,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
|
|||
// Get the function pointer (or index if this is a virtual function).
|
||||
llvm::Constant *MemPtr[2];
|
||||
if (MD->isVirtual()) {
|
||||
uint64_t Index = CGM.getVTables().getMethodVTableIndex(MD);
|
||||
uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD);
|
||||
|
||||
const ASTContext &Context = getContext();
|
||||
CharUnits PointerWidth =
|
||||
|
|
Loading…
Reference in New Issue