From 1d2b31710539d705a3850c9fc3aa1804c2a5efee Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 26 Sep 2011 01:56:30 +0000 Subject: [PATCH] Create a VTableContext class and start moving CodeGenVTables methods to it git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140502 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 8 ++--- lib/CodeGen/CGClass.cpp | 2 +- lib/CodeGen/CGDebugInfo.cpp | 5 +-- lib/CodeGen/CGRTTI.cpp | 2 +- lib/CodeGen/CGVTables.cpp | 35 +++++++++--------- lib/CodeGen/CGVTables.h | 67 +++++++++++++++++++++-------------- lib/CodeGen/CodeGenModule.h | 1 + lib/CodeGen/ItaniumCXXABI.cpp | 2 +- 8 files changed, 70 insertions(+), 52 deletions(-) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index e1463e98ec..3539d90713 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -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(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(DD->getCanonicalDecl()); uint64_t VTableIndex = - CGM.getVTables().getMethodVTableIndex(GlobalDecl(DD, Type)); + CGM.getVTableContext().getMethodVTableIndex(GlobalDecl(DD, Type)); return ::BuildVirtualCall(*this, VTableIndex, This, Ty); } diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index a831ebda84..2ba3262c3c 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -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(), diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index bdb0b57d0e..6baf52a012 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -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(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); diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 1ce69d6093..a1105d2894 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -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); diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index f936a9b89d..b444c26cfb 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -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::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(); const CXXRecordDecl *VBase = cast(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); diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index 1a0ae80952..6e96be7219 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -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 MethodVTableIndicesTy; MethodVTableIndicesTy MethodVTableIndices; + /// NumVirtualFunctionPointers - Contains the number of virtual function + /// pointers in the vtable for a given record decl. + llvm::DenseMap NumVirtualFunctionPointers; + typedef std::pair 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 VTables; - /// NumVirtualFunctionPointers - Contains the number of virtual function - /// pointers in the vtable for a given record decl. - llvm::DenseMap NumVirtualFunctionPointers; - typedef SmallVector ThunkInfoVectorTy; typedef llvm::DenseMap 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); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index c190fa3c56..d310165ca8 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -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(); } diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index d0ec3eb4fa..dcac6a8c7b 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -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 = -- 2.50.1