diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 3539d907136c1692361e3864efc6f1e14ea6acc8..27f5032ad9443ee7082554d5a4f319f9bd0b5c4f 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -337,7 +337,8 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, MD = MD->getCanonicalDecl(); uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(MD); uint64_t AddressPoint = - CGM.getVTables().getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD); + CGM.getVTableContext() + .getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD); VTableIndex += AddressPoint; llvm::Value *VFuncPtr = Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); @@ -372,7 +373,8 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall( uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(GlobalDecl(DD, Type)); uint64_t AddressPoint = - CGM.getVTables().getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD); + CGM.getVTableContext() + .getAddressPoint(BaseSubobject(RD, CharUnits::Zero()), RD); VTableIndex += AddressPoint; llvm::Value *VFuncPtr = Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 2ba3262c3cb15858584619bc4d1287f606e5b39e..cafc95446d7cbaff9e276d1804ae03b8c4aa4045 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1452,7 +1452,8 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, // And load the address point from the VTT. VTableAddressPoint = Builder.CreateLoad(VTT); } else { - uint64_t AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass); + uint64_t AddressPoint = + CGM.getVTableContext().getAddressPoint(Base, VTableClass); VTableAddressPoint = Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); } diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index e3c085a29d8840495d56d6af777e263eab2c8d19..cb3b39fab336085ac93c73372c9e5f95c2028f70 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -67,7 +67,7 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, uint64_t AddressPoint; if (VTTVT.getBase() == RD) { // Just get the address point for the regular vtable. - AddressPoint = getAddressPoint(i->VTableBase, RD); + AddressPoint = VTContext.getAddressPoint(i->VTableBase, RD); assert(AddressPoint != 0 && "Did not find vtable address point!"); } else { AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase); diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index cd3a45ddafe0cb3515b570054d95a07dcbe5d803..00c4e2f725c1d8b5e331446d4ad0f3dc76c0a039 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2507,17 +2507,6 @@ VTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, return I->second; } -uint64_t -CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { - assert(AddressPoints.count(std::make_pair(RD, Base)) && - "Did not find address point!"); - - uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base)); - assert(AddressPoint && "Address point must not be zero!"); - - return AddressPoint; -} - llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk) { const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); @@ -2953,36 +2942,30 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD) if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) return; - const CXXRecordDecl *RD = MD->getParent(); - - // Compute VTable related info for this class. - ComputeVTableRelatedInformation(RD); - - ThunksMapTy::const_iterator I = Thunks.find(MD); - if (I == Thunks.end()) { - // We did not find a thunk for this method. + const VTableContext::ThunkInfoVectorTy *ThunkInfoVector = + VTContext.getThunkInfo(MD); + if (!ThunkInfoVector) return; - } - const ThunkInfoVectorTy &ThunkInfoVector = I->second; - for (unsigned I = 0, E = ThunkInfoVector.size(); I != E; ++I) - EmitThunk(GD, ThunkInfoVector[I], /*UseAvailableExternallyLinkage=*/false); + for (unsigned I = 0, E = ThunkInfoVector->size(); I != E; ++I) + EmitThunk(GD, (*ThunkInfoVector)[I], + /*UseAvailableExternallyLinkage=*/false); } -void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { +void VTableContext::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { uint64_t *&Entry = VTableLayoutMap[RD]; // Check if we've computed this information before. if (Entry) return; - VTableBuilder Builder(VTContext, RD, CharUnits::Zero(), + VTableBuilder Builder(*this, RD, CharUnits::Zero(), /*MostDerivedClassIsVirtual=*/0, RD); // Add the VTable layout. uint64_t NumVTableComponents = Builder.getNumVTableComponents(); // -fapple-kext adds an extra entry at end of vtbl. - bool IsAppleKext = CGM.getContext().getLangOptions().AppleKext; + bool IsAppleKext = Context.getLangOptions().AppleKext; if (IsAppleKext) NumVTableComponents += 1; @@ -3036,17 +3019,16 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) { RD->vbases_begin()->getType()->getAs<RecordType>(); const CXXRecordDecl *VBase = cast<CXXRecordDecl>(VBaseRT->getDecl()); - if (VTContext.VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase))) + if (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. - VTableContext::ClassPairTy ClassPair(RD, I->first); + ClassPairTy ClassPair(RD, I->first); - VTContext.VirtualBaseClassOffsetOffsets.insert( - std::make_pair(ClassPair, I->second)); + VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second)); } } @@ -3054,7 +3036,7 @@ llvm::Constant * CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, const uint64_t *Components, unsigned NumComponents, - const VTableThunksTy &VTableThunks) { + const VTableContext::VTableThunksTy &VTableThunks) { SmallVector<llvm::Constant *, 64> Inits; llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); @@ -3175,11 +3157,9 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { Out.flush(); StringRef Name = OutName.str(); - ComputeVTableRelatedInformation(RD); - llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); llvm::ArrayType *ArrayType = - llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD)); + llvm::ArrayType::get(Int8PtrTy, VTContext.getNumVTableComponents(RD)); VTable = CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, @@ -3200,15 +3180,12 @@ CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, Builder.dumpLayout(llvm::errs()); } - assert(VTableThunksMap.count(RD) && - "No thunk status for this record decl!"); - - const VTableThunksTy& Thunks = VTableThunksMap[RD]; + const VTableContext::VTableThunksTy& Thunks = VTContext.getVTableThunks(RD); // Create and set the initializer. llvm::Constant *Init = - CreateVTableInitializer(RD, getVTableComponentsData(RD), - getNumVTableComponents(RD), Thunks); + CreateVTableInitializer(RD, VTContext.getVTableComponentsData(RD), + VTContext.getNumVTableComponents(RD), Thunks); VTable->setInitializer(Init); // Set the correct linkage. @@ -3258,7 +3235,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, VTable->setUnnamedAddr(true); // Add the thunks. - VTableThunksTy VTableThunks; + VTableContext::VTableThunksTy VTableThunks; VTableThunks.append(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index a29670b45855a30205854a1fb22ceaa171b0c925..6177dfed155ffb54f7e75dec82218f40eafa86dd 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -26,11 +26,16 @@ namespace clang { namespace CodeGen { class CodeGenModule; - class CodeGenVTables; class VTableContext { ASTContext &Context; +public: + typedef SmallVector<std::pair<uint64_t, ThunkInfo>, 1> + VTableThunksTy; + typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; + +private: /// 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; @@ -50,11 +55,88 @@ class VTableContext { VirtualBaseClassOffsetOffsetsMapTy; VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; + // The layout entry. + typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy; + + /// VTableLayoutMap - Stores the vtable layout for all record decls. + /// The layout is stored as an array of 64-bit integers, where the first + /// integer is the number of vtable entries in the layout, and the subsequent + /// integers are the vtable components. + VTableLayoutMapTy VTableLayoutMap; + + typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; + + /// Thunks - Contains all thunks that a given method decl will need. + ThunksMapTy Thunks; + + typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy> + VTableThunksMapTy; + + /// VTableThunksMap - Contains thunks needed by vtables. + VTableThunksMapTy VTableThunksMap; + + typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy; + typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy; + + /// Address points - Address points for all vtables. + AddressPointsMapTy AddressPoints; + void ComputeMethodVTableIndices(const CXXRecordDecl *RD); + /// ComputeVTableRelatedInformation - Compute and store all vtable related + /// information (vtable layout, vbase offset offsets, thunks etc) for the + /// given record decl. + void ComputeVTableRelatedInformation(const CXXRecordDecl *RD); + public: VTableContext(ASTContext &Context) : Context(Context) {} + uint64_t getNumVTableComponents(const CXXRecordDecl *RD) { + ComputeVTableRelatedInformation(RD); + assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); + + return VTableLayoutMap.lookup(RD)[0]; + } + + const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) { + ComputeVTableRelatedInformation(RD); + assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); + + uint64_t *Components = VTableLayoutMap.lookup(RD); + return &Components[1]; + } + + const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) { + ComputeVTableRelatedInformation(MD->getParent()); + + ThunksMapTy::const_iterator I = Thunks.find(MD); + if (I == Thunks.end()) { + // We did not find a thunk for this method. + return 0; + } + + return &I->second; + } + + const VTableThunksTy &getVTableThunks(const CXXRecordDecl *RD) { + ComputeVTableRelatedInformation(RD); + assert(VTableThunksMap.count(RD) && + "No thunk status for this record decl!"); + + return VTableThunksMap[RD]; + } + + uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { + ComputeVTableRelatedInformation(RD); + assert(AddressPoints.count(std::make_pair(RD, Base)) && + "Did not find address point!"); + + uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base)); + assert(AddressPoint && "Address point must not be zero!"); + + return AddressPoint; + } + /// getNumVirtualFunctionPointers - Return the number of virtual function /// pointers in the vtable for a given record decl. uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); @@ -71,8 +153,6 @@ public: /// base. CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); - - friend class CodeGenVTables; }; class CodeGenVTables { @@ -83,52 +163,10 @@ class CodeGenVTables { /// VTables - All the vtables which have been defined. llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables; - typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; - typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; - - /// Thunks - Contains all thunks that a given method decl will need. - ThunksMapTy Thunks; - - // The layout entry. - typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy; - - /// VTableLayoutMap - Stores the vtable layout for all record decls. - /// The layout is stored as an array of 64-bit integers, where the first - /// integer is the number of vtable entries in the layout, and the subsequent - /// integers are the vtable components. - VTableLayoutMapTy VTableLayoutMap; - - typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy; - typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy; - - /// Address points - Address points for all vtables. - AddressPointsMapTy AddressPoints; - /// VTableAddressPointsMapTy - Address points for a single vtable. typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy; - typedef SmallVector<std::pair<uint64_t, ThunkInfo>, 1> - VTableThunksTy; - - typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy> - VTableThunksMapTy; - - /// VTableThunksMap - Contains thunks needed by vtables. - VTableThunksMapTy VTableThunksMap; - - uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const { - assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); - - return VTableLayoutMap.lookup(RD)[0]; - } - - const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const { - assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); - - uint64_t *Components = VTableLayoutMap.lookup(RD); - return &Components[1]; - } - + typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy; typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy; /// SubVTTIndicies - Contains indices into the various sub-VTTs. @@ -151,11 +189,6 @@ class CodeGenVTables { /// doesn't contain any incomplete types. void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk); - /// ComputeVTableRelatedInformation - Compute and store all vtable related - /// information (vtable layout, vbase offset offsets, thunks etc) for the - /// given record decl. - void ComputeVTableRelatedInformation(const CXXRecordDecl *RD); - /// CreateVTableInitializer - Create a vtable initializer for the given record /// decl. /// \param Components - The vtable components; this is really an array of @@ -163,7 +196,7 @@ class CodeGenVTables { llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD, const uint64_t *Components, unsigned NumComponents, - const VTableThunksTy &VTableThunks); + const VTableContext::VTableThunksTy &VTableThunks); public: CodeGenVTables(CodeGenModule &CGM);