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 | 07894e8a0ed96b04afaeb1749e18784d3dd2ffd0 (patch) | |
| tree | 38f558ace43ee35b438ac3762effb89fe499ea5b /clang/lib | |
| parent | 6dea75c65897286ada74dcaea61a1b9fdc98ae6b (diff) | |
| download | bcm5719-llvm-07894e8a0ed96b04afaeb1749e18784d3dd2ffd0.tar.gz bcm5719-llvm-07894e8a0ed96b04afaeb1749e18784d3dd2ffd0.zip | |
More VTT builder fixes. With these fixes we now correctly handle the very complex VTT example from the Itanium ABI spec.
llvm-svn: 93725
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 2f5681e181a..b2fb8662fe6 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/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); |

