From 9f17d410044af23fe426c504bc969156f0fc248d Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 26 Mar 2010 00:50:17 +0000 Subject: [PATCH] More VTT cleanup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99586 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVTT.cpp | 65 ++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 1989d6c19b..09cb5a88b7 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -34,6 +34,8 @@ class VTTBuilder { llvm::Constant *ClassVtbl; llvm::LLVMContext &VMContext; + typedef llvm::SmallPtrSet VisitedVirtualBasesSetTy; + /// SeenVBasesInSecondary - The seen virtual bases when building the /// secondary virtual pointers. llvm::SmallPtrSet SeenVBasesInSecondary; @@ -169,31 +171,19 @@ class VTTBuilder { } } - /// 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) { - 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() && !SeenVBase.count(Base)) { - SeenVBase.insert(Base); - uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base); - - LayoutVTT(BaseSubobject(Base, BaseOffset), /*BaseIsVirtual=*/true); - } - VirtualVTTs(Base); - } - } - + /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the + /// given record decl. + void LayoutVirtualVTTs(const CXXRecordDecl *RD, + VisitedVirtualBasesSetTy &VBases); + + /// 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); + public: VTTBuilder(std::vector &inits, const CXXRecordDecl *c, CodeGenModule &cgm, bool GenerateDefinition) @@ -219,7 +209,8 @@ public: Secondary(Class, ClassVtbl, Class, 0, false); // and last, the virtual VTTs. - VirtualVTTs(Class); + VisitedVirtualBasesSetTy VBases; + LayoutVirtualVTTs(Class, VBases); } llvm::DenseMap &getSubVTTIndicies() { @@ -249,6 +240,36 @@ void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) { } } +/// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the +/// given record decl. +void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD, + VisitedVirtualBasesSetTy &VBases) { + for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), + E = RD->bases_end(); I != E; ++I) { + const CXXRecordDecl *BaseDecl = + cast(I->getType()->getAs()->getDecl()); + + // Check if this is a virtual base. + if (I->isVirtual()) { + // Check if we've seen this base before. + if (!VBases.insert(BaseDecl)) + continue; + + const ASTRecordLayout &MostDerivedClassLayout = + CGM.getContext().getASTRecordLayout(Class); + uint64_t BaseOffset = + MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); + + LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true); + } + + // We only need to layout virtual VTTs for this base if it actually has + // virtual bases. + if (BaseDecl->getNumVBases()) + LayoutVirtualVTTs(BaseDecl, VBases); + } +} + void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) { const CXXRecordDecl *RD = Base.getBase(); -- 2.40.0