Create a VTableContext class and start moving CodeGenVTables methods to it

llvm-svn: 140502
This commit is contained in:
Peter Collingbourne 2011-09-26 01:56:30 +00:00
parent 2d2595235d
commit a834166e48
8 changed files with 70 additions and 52 deletions

View File

@ -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);
}

View File

@ -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(),

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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(); }

View File

@ -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 =