From: Mike Stump Date: Wed, 11 Nov 2009 03:08:24 +0000 (+0000) Subject: More VTT work. We now track offsets and use the ctor vtable builder X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aee8de30e194e494d2be1651ed54eda38e6a16bd;p=clang More VTT work. We now track offsets and use the ctor vtable builder interface. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86793 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index d98d40c0ec..4d3c3a595d 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -724,9 +724,13 @@ class VTTBuilder { const CXXRecordDecl *Class; CodeGenModule &CGM; // Per-module state. llvm::SmallSet SeenVBase; + /// BLayout - Layout for the most derived class that this vtable is being + /// built for. + const ASTRecordLayout &BLayout; /// Secondary - Add the secondary vtable pointers to Inits. - void Secondary(const CXXRecordDecl *RD, bool MorallyVirtual=false) { + void Secondary(const CXXRecordDecl *RD, uint64_t Offset=0, + bool MorallyVirtual=false) { if (RD->getNumVBases() == 0 && ! MorallyVirtual) return; @@ -740,31 +744,37 @@ class VTTBuilder { 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 = BLayout.getVBaseClassOffset(Base); if ((Base->getNumVBases() || BaseMorallyVirtual) && !NonVirtualPrimaryBase) { // FIXME: Slightly too many of these for __ZTT8test8_B2 - // FIXME: ctor vtbl or normal vtable. - llvm::Constant *vtbl = CGM.getVtableInfo().getVtable(Base); + llvm::Constant *vtbl; + vtbl = CGM.getVtableInfo().getVtable(Base, Class, BaseOffset/8); Inits.push_back(vtbl); } - Secondary(Base, BaseMorallyVirtual); + Secondary(Base, BaseOffset, BaseMorallyVirtual); } } /// BuiltVTT - Add the VTT to Inits. - void BuildVTT(const CXXRecordDecl *RD, bool MorallyVirtual=false) { + void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, + bool MorallyVirtual=false) { if (RD->getNumVBases() == 0 && !MorallyVirtual) return; // First comes the primary virtual table pointer... - // FIXME: ctor vtable instead - Inits.push_back(CGM.getVtableInfo().getVtable(RD)); + Inits.push_back(CGM.getVtableInfo().getVtable(RD, Class, Offset)); // then the secondary VTTs.... SecondaryVTTs(RD, MorallyVirtual); // and last the secondary vtable pointers. - Secondary(RD, MorallyVirtual); + Secondary(RD, MorallyVirtual, Offset); } /// SecondaryVTTs - Add the secondary VTTs to Inits. The secondary VTTs are @@ -797,7 +807,9 @@ class VTTBuilder { } public: VTTBuilder(std::vector &inits, const CXXRecordDecl *c, - CodeGenModule &cgm) : Inits(inits), Class(c), CGM(cgm) { + CodeGenModule &cgm) + : Inits(inits), Class(c), CGM(cgm), + BLayout(cgm.getContext().getASTRecordLayout(c)) { // First comes the primary virtual table pointer for the complete class... Inits.push_back(CGM.getVtableInfo().getVtable(Class)); @@ -840,7 +852,10 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) { return vtt; } -llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { +llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD, + const CXXRecordDecl *Class, + uint64_t Offset) { + // FIXME: Add ctor vtable support llvm::Constant *&vtbl = Vtables[RD]; if (vtbl) return vtbl; diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index cdba953718..9620e42aab 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -57,7 +57,8 @@ public: int64_t getVirtualBaseOffsetIndex(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); - llvm::Constant *getVtable(const CXXRecordDecl *RD); + llvm::Constant *getVtable(const CXXRecordDecl *RD, + const CXXRecordDecl *Class=0, uint64_t Offset=0); }; }