diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-18 04:25:18 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-18 04:25:18 +0000 |
commit | 20314fffcf5d97bab58686cdcb914637b453a166 (patch) | |
tree | 2a208d9e838558ec4688aad856fc6cc09728fcf3 /lib/CodeGen/CGVtable.cpp | |
parent | 425c7ed03b5c7d4263f592416338642b6d99f3ba (diff) |
Fix a bunch of VTT layout bugs, add simple tests for VTT layout.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93709 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index d72c32ac44..67b2b3dcb6 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1314,6 +1314,17 @@ class VTTBuilder { e = RD->bases_end(); i != e; ++i) { const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + + // 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(); @@ -1330,10 +1341,9 @@ class VTTBuilder { const CXXRecordDecl *subVtblClass = VtblClass; if ((Base->getNumVBases() || BaseMorallyVirtual) && !NonVirtualPrimaryBase) { - // FIXME: Slightly too many of these for __ZTT8test8_B2 llvm::Constant *init; - if (BaseMorallyVirtual) - init = BuildVtablePtr(vtbl, VtblClass, RD, Offset); + if (BaseMorallyVirtual || VtblClass == Class) + init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset); else { init = getCtorVtable(BaseSubobject(Base, BaseOffset)); @@ -1351,7 +1361,10 @@ 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 MorallyVirtual) { - if (RD->getNumVBases() == 0 && !MorallyVirtual) + // 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; llvm::Constant *Vtable; |