diff options
author | Anders Carlsson <andersca@mac.com> | 2010-03-26 04:10:39 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-03-26 04:10:39 +0000 |
commit | 19f191fad178baf25388d972c71facbd26932693 (patch) | |
tree | c66d67e47da31d67fc9a195d832dbd1bc1775e16 /lib/CodeGen/CGVTT.cpp | |
parent | 2c822f1cecf6e89a129c3e5ad969564b56326140 (diff) |
More cleanup.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99605 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVTT.cpp')
-rw-r--r-- | lib/CodeGen/CGVTT.cpp | 225 |
1 files changed, 47 insertions, 178 deletions
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index bd03583fdc..e179ecbce4 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -22,155 +22,35 @@ namespace { /// VTT builder - Class for building VTT layout information. class VTTBuilder { + + CodeGenModule &CGM; + /// MostDerivedClass - The most derived class for which we're building this /// vtable. const CXXRecordDecl *MostDerivedClass; - /// Inits - The list of values built for the VTT. - std::vector<llvm::Constant *> &Inits; + typedef llvm::SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy; + + /// VTTComponents - The VTT components. + VTTComponentsVectorTy VTTComponents; /// MostDerivedClassLayout - the AST record layout of the most derived class. const ASTRecordLayout &MostDerivedClassLayout; - CodeGenModule &CGM; // Per-module state. - CodeGenVTables::AddrMap_t &AddressPoints; - // vtbl - A pointer to the vtable for Class. - llvm::Constant *ClassVtbl; - llvm::LLVMContext &VMContext; typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; - /// SeenVBasesInSecondary - The seen virtual bases when building the - /// secondary virtual pointers. - llvm::SmallPtrSet<const CXXRecordDecl *, 32> SeenVBasesInSecondary; - + /// SubVTTIndicies - The sub-VTT indices for the bases of the most derived + /// class whose VTT is being built. llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies; + /// GenerateDefinition - Whether the VTT builder should generate LLVM IR for + /// the VTT. bool GenerateDefinition; - - llvm::DenseMap<BaseSubobject, llvm::Constant *> CtorVtables; - llvm::DenseMap<std::pair<const CXXRecordDecl *, BaseSubobject>, uint64_t> - CtorVtableAddressPoints; - llvm::Constant *getCtorVtable(const BaseSubobject &Base, - bool BaseIsVirtual) { - if (!GenerateDefinition) - return 0; - - llvm::Constant *&CtorVtable = CtorVtables[Base]; - return CtorVtable; - } - - - /// BuildVtablePtr - Build up a referene to the given secondary vtable - llvm::Constant *BuildVtablePtr(llvm::Constant *Vtable, - const CXXRecordDecl *VtableClass, - const CXXRecordDecl *RD, - uint64_t Offset) { - if (!GenerateDefinition) - return 0; - - uint64_t AddressPoint; - - if (VtableClass != MostDerivedClass) { - // We have a ctor vtable, look for the address point in the ctor vtable - // address points. - AddressPoint = - CtorVtableAddressPoints[std::make_pair(VtableClass, - BaseSubobject(RD, Offset))]; - } else { - AddressPoint = - (*AddressPoints[VtableClass])[std::make_pair(RD, Offset)]; - } - - // FIXME: We can never have 0 address point. Do this for now so gepping - // retains the same structure. Later we'll just assert. - if (AddressPoint == 0) - AddressPoint = 1; - D1(printf("XXX address point for %s in %s layout %s at offset %d was %d\n", - RD->getNameAsCString(), VtblClass->getNameAsCString(), - Class->getNameAsCString(), (int)Offset, (int)AddressPoint)); - - llvm::Value *Idxs[] = { - llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 0), - llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), AddressPoint) - }; - - llvm::Constant *Init = - llvm::ConstantExpr::getInBoundsGetElementPtr(Vtable, Idxs, 2); - - const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); - return llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); - } - - /// Secondary - Add the secondary vtable pointers to Inits. Offset is the - /// current offset in bits to the object we're working on. - void Secondary(const CXXRecordDecl *RD, llvm::Constant *vtbl, - const CXXRecordDecl *VtblClass, uint64_t Offset, - bool MorallyVirtual) { - if (RD->getNumVBases() == 0 && !MorallyVirtual) - return; - - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); - - // We only want to visit each virtual base once. - if (i->isVirtual() && SeenVBasesInSecondary.count(Base)) - continue; - - // Itanium C++ ABI 2.6.2: - // Secondary virtual pointers are present for all bases with either - // virtual bases or virtual function declarations overridden along a - // virtual path. - // - // If the base class is not dynamic, we don't want to add it, nor any - // of its base classes. - if (!Base->isDynamicClass()) - continue; - - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); - bool NonVirtualPrimaryBase; - NonVirtualPrimaryBase = !PrimaryBaseWasVirtual && Base == PrimaryBase; - bool BaseMorallyVirtual = MorallyVirtual | i->isVirtual(); - uint64_t BaseOffset; - if (!i->isVirtual()) { - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - BaseOffset = Offset + Layout.getBaseClassOffset(Base); - } else - BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(Base); - llvm::Constant *subvtbl = vtbl; - const CXXRecordDecl *subVtblClass = VtblClass; - if ((Base->getNumVBases() || BaseMorallyVirtual) - && !NonVirtualPrimaryBase) { - llvm::Constant *init; - if (BaseMorallyVirtual || VtblClass == MostDerivedClass) - init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset); - else { - init = getCtorVtable(BaseSubobject(Base, BaseOffset), i->isVirtual()); - - subvtbl = init; - subVtblClass = Base; - - init = BuildVtablePtr(init, MostDerivedClass, Base, BaseOffset); - } - - Inits.push_back(init); - } - - if (i->isVirtual()) - SeenVBasesInSecondary.insert(Base); - - Secondary(Base, subvtbl, subVtblClass, BaseOffset, BaseMorallyVirtual); - } - } - /// GetAddrOfVTable - Returns the address of the vtable for the base class in /// the given vtable class. /// @@ -225,47 +105,31 @@ class VTTBuilder { void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); public: - VTTBuilder(std::vector<llvm::Constant *> &inits, - const CXXRecordDecl *MostDerivedClass, - CodeGenModule &cgm, bool GenerateDefinition) - : MostDerivedClass(MostDerivedClass), - Inits(inits), - MostDerivedClassLayout(cgm.getContext().getASTRecordLayout(MostDerivedClass)), - CGM(cgm), - AddressPoints(*cgm.getVTables().OldAddressPoints[MostDerivedClass]), - VMContext(cgm.getModule().getContext()), - GenerateDefinition(GenerateDefinition) { - - LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false); -#if 0 - // First comes the primary virtual table pointer for the complete class... - ClassVtbl = GenerateDefinition ? - CGM.getVTables().GetAddrOfVTable(MostDerivedClass) :0; - - llvm::Constant *Init = BuildVtablePtr(ClassVtbl, MostDerivedClass, - MostDerivedClass, 0); - Inits.push_back(Init); - - // then the secondary VTTs... - LayoutSecondaryVTTs(BaseSubobject(MostDerivedClass, 0)); - - // Make sure to clear the set of seen virtual bases. - SeenVBasesInSecondary.clear(); - - // then the secondary vtable pointers... - Secondary(MostDerivedClass, ClassVtbl, MostDerivedClass, 0, false); - - // and last, the virtual VTTs. - VisitedVirtualBasesSetTy VBases; - LayoutVirtualVTTs(MostDerivedClass, VBases); -#endif - } + VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass, + bool GenerateDefinition); llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getSubVTTIndicies() { return SubVTTIndicies; } + + // getVTTComponents - Returns a reference to the VTT components. + const VTTComponentsVectorTy &getVTTComponents() const { + return VTTComponents; + } }; +VTTBuilder::VTTBuilder(CodeGenModule &CGM, + const CXXRecordDecl *MostDerivedClass, + bool GenerateDefinition) + : CGM(CGM), MostDerivedClass(MostDerivedClass), + MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)), + AddressPoints(*CGM.getVTables().OldAddressPoints[MostDerivedClass]), + GenerateDefinition(GenerateDefinition) { + + // Lay out this VTT. + LayoutVTT(BaseSubobject(MostDerivedClass, 0), /*BaseIsVirtual=*/false); +} + llvm::Constant * VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, AddressPointsMapTy& AddressPoints) { @@ -288,7 +152,7 @@ void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable, const CXXRecordDecl *VTableClass, const AddressPointsMapTy& AddressPoints) { if (!GenerateDefinition) { - Inits.push_back(0); + VTTComponents.push_back(0); return; } @@ -318,7 +182,7 @@ void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable, const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy); - Inits.push_back(Init); + VTTComponents.push_back(Init); } void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { @@ -454,9 +318,13 @@ void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { // each class type that has indirect or direct virtual base classes. if (RD->getNumVBases() == 0) return; - - // Remember the sub-VTT index. - SubVTTIndicies[RD] = Inits.size(); + + bool IsPrimaryVTT = Base.getBase() == MostDerivedClass; + + if (!IsPrimaryVTT) { + // Remember the sub-VTT index. + SubVTTIndicies[RD] = VTTComponents.size(); + } AddressPointsMapTy AddressPoints; llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints); @@ -471,7 +339,7 @@ void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints); // If this is the primary VTT, we want to lay out virtual VTTs as well. - if (Base.getBase() == MostDerivedClass) { + if (IsPrimaryVTT) { VisitedVirtualBasesSetTy VBases; LayoutVirtualVTTs(Base.getBase(), VBases); } @@ -498,13 +366,15 @@ CodeGenVTables::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); - std::vector<llvm::Constant *> inits; - VTTBuilder b(inits, RD, CGM, GenerateDefinition); + VTTBuilder Builder(CGM, RD, GenerateDefinition); + + const llvm::ArrayType *Type = + llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size()); - const llvm::ArrayType *Type = llvm::ArrayType::get(Int8PtrTy, inits.size()); llvm::Constant *Init = 0; if (GenerateDefinition) - Init = llvm::ConstantArray::get(Type, inits); + Init = llvm::ConstantArray::get(Type, Builder.getVTTComponents().data(), + Builder.getVTTComponents().size()); llvm::GlobalVariable *OldGV = GV; GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, @@ -555,8 +425,7 @@ uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, if (I != SubVTTIndicies.end()) return I->second; - std::vector<llvm::Constant *> inits; - VTTBuilder Builder(inits, RD, CGM, /*GenerateDefinition=*/false); + VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/false); for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = Builder.getSubVTTIndicies().begin(), |