From c1246c882bfbb3ec6fe982ab3c63998414a72fb9 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 26 Mar 2010 00:35:45 +0000 Subject: [PATCH] Start cleaning up the VTT builder to make it work more like the VTable builder. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99581 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVTT.cpp | 117 ++++++++++++++++++++++----------------- lib/CodeGen/CGVtable.cpp | 2 +- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index e820bef083..1989d6c19b 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -169,56 +169,14 @@ class VTTBuilder { } } - /// BuiltVTT - Add the VTT to Inits. Offset is the offset in bits to the - /// currnet object we're working on. - void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool BaseIsVirtual) { - // Itanium C++ ABI 2.6.2: - // An array of virtual table addresses, called the VTT, is declared for - // 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(); - - llvm::Constant *Vtable; - const CXXRecordDecl *VtableClass; - - // First comes the primary virtual table pointer... - Vtable = getCtorVtable(BaseSubobject(RD, Offset), - /*IsVirtual=*/BaseIsVirtual); - VtableClass = RD; - - llvm::Constant *Init = BuildVtablePtr(Vtable, VtableClass, RD, Offset); - Inits.push_back(Init); - - // then the secondary VTTs.... - SecondaryVTTs(RD, Offset); - - // Make sure to clear the set of seen virtual bases. - SeenVBasesInSecondary.clear(); - - // and last the secondary vtable pointers. - Secondary(RD, Vtable, VtableClass, Offset, false); - } - - /// SecondaryVTTs - Add the secondary VTTs to Inits. The secondary VTTs are - /// built from each direct non-virtual proper base that requires a VTT in - /// declaration order. - void SecondaryVTTs(const CXXRecordDecl *RD, uint64_t Offset) { - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - if (i->isVirtual()) - continue; - const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); - uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base); - - BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/false); - } - } + /// LayoutVTT - Will lay out the VTT for the given subobject, including any + /// secondary VTTs, secondary virtual pointers and virtual VTTs. + void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); + /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base + /// subobject. + void LayoutSecondaryVTTs(BaseSubobject Base); + /// VirtualVTTs - Add the VTT for each proper virtual base in inheritance /// graph preorder. void VirtualVTTs(const CXXRecordDecl *RD) { @@ -229,7 +187,8 @@ class VTTBuilder { if (i->isVirtual() && !SeenVBase.count(Base)) { SeenVBase.insert(Base); uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base); - BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/true); + + LayoutVTT(BaseSubobject(Base, BaseOffset), /*BaseIsVirtual=*/true); } VirtualVTTs(Base); } @@ -251,7 +210,7 @@ public: Inits.push_back(Init); // then the secondary VTTs... - SecondaryVTTs(Class, 0); + LayoutSecondaryVTTs(BaseSubobject(Class, 0)); // Make sure to clear the set of seen virtual bases. SeenVBasesInSecondary.clear(); @@ -267,6 +226,62 @@ public: return SubVTTIndicies; } }; + +void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { + const CXXRecordDecl *RD = Base.getBase(); + + for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), + E = RD->bases_end(); I != E; ++I) { + + // Don't layout virtual bases. + if (I->isVirtual()) + continue; + + const CXXRecordDecl *BaseDecl = + cast(I->getType()->getAs()->getDecl()); + + const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); + uint64_t BaseOffset = Base.getBaseOffset() + + Layout.getBaseClassOffset(BaseDecl); + + // Layout the VTT for this base. + LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false); + } +} + +void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { + const CXXRecordDecl *RD = Base.getBase(); + + // Itanium C++ ABI 2.6.2: + // An array of virtual table addresses, called the VTT, is declared for + // 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(); + + llvm::Constant *Vtable; + const CXXRecordDecl *VtableClass; + + // First comes the primary virtual table pointer... + Vtable = getCtorVtable(Base, /*IsVirtual=*/BaseIsVirtual); + VtableClass = RD; + + llvm::Constant *Init = BuildVtablePtr(Vtable, VtableClass, RD, + Base.getBaseOffset()); + Inits.push_back(Init); + + // then the secondary VTTs.... + LayoutSecondaryVTTs(Base); + + // Make sure to clear the set of seen virtual bases. + SeenVBasesInSecondary.clear(); + + // and last the secondary vtable pointers. + Secondary(RD, Vtable, VtableClass, Base.getBaseOffset(), false); +} + } llvm::GlobalVariable * diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 23cef42a3c..efad6289c0 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -138,7 +138,7 @@ private: /// AddOverriders - Add the final overriders for this base subobject to the /// map of final overriders. - void AddOverriders(BaseSubobject Base,uint64_t OffsetInLayoutClass, + void AddOverriders(BaseSubobject Base, uint64_t OffsetInLayoutClass, SubobjectOffsetsMapTy &Offsets); /// PropagateOverrider - Propagate the NewMD overrider to all the functions -- 2.40.0