diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-18 17:13:59 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-18 17:13:59 +0000 |
commit | 35aa62aacf2b644f2ff2f0bdfd89136323698a39 (patch) | |
tree | 2beed1fba4e113f0ebbbc16ef34c0180b9375905 /lib/CodeGen/CGVtable.cpp | |
parent | 3ed04d37573c566205d965d2e91d54ccae898d0a (diff) |
More VTT builder fixes. With these fixes we now correctly handle the very complex VTT example from the Itanium ABI spec.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93725 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 2f5681e181..b2fb8662fe 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1221,6 +1221,10 @@ class VTTBuilder { llvm::Constant *ClassVtbl; llvm::LLVMContext &VMContext; + /// SeenVBasesInSecondary - The seen virtual bases when building the + /// secondary virtual pointers. + llvm::SmallPtrSet<const CXXRecordDecl *, 32> SeenVBasesInSecondary; + llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies; bool GenerateDefinition; @@ -1314,6 +1318,10 @@ class VTTBuilder { 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 @@ -1352,8 +1360,13 @@ class VTTBuilder { init = BuildVtablePtr(init, Class, Base, BaseOffset); } + Inits.push_back(init); } + + if (i->isVirtual()) + SeenVBasesInSecondary.insert(Base); + Secondary(Base, subvtbl, subVtblClass, BaseOffset, BaseMorallyVirtual); } } @@ -1388,6 +1401,9 @@ class VTTBuilder { // then the secondary VTTs.... SecondaryVTTs(RD, Offset, MorallyVirtual); + // Make sure to clear the set of seen virtual bases. + SeenVBasesInSecondary.clear(); + // and last the secondary vtable pointers. Secondary(RD, Vtable, VtableClass, Offset, MorallyVirtual); } @@ -1420,7 +1436,7 @@ class VTTBuilder { if (i->isVirtual() && !SeenVBase.count(Base)) { SeenVBase.insert(Base); uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base); - BuildVTT(Base, BaseOffset, true); + BuildVTT(Base, BaseOffset, false); } VirtualVTTs(Base); } @@ -1444,6 +1460,9 @@ public: // then the secondary VTTs... SecondaryVTTs(Class); + // Make sure to clear the set of seen virtual bases. + SeenVBasesInSecondary.clear(); + // then the secondary vtable pointers... Secondary(Class, ClassVtbl, Class); |