diff options
| author | Anders Carlsson <andersca@mac.com> | 2010-02-27 04:05:52 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2010-02-27 04:05:52 +0000 |
| commit | b08aaa3e108ac1bb0f81a89f31bc4ac2a52738ef (patch) | |
| tree | 868bf30b6c289bd15eaafd657605cc8430e0a7f9 /clang/lib/CodeGen | |
| parent | e334bb1a6640e5b7b0c0a8ff0c43e2b7605e5603 (diff) | |
| download | bcm5719-llvm-b08aaa3e108ac1bb0f81a89f31bc4ac2a52738ef.tar.gz bcm5719-llvm-b08aaa3e108ac1bb0f81a89f31bc4ac2a52738ef.zip | |
Fix a bug where we were generating an unnecessary vtable for a virtual base that's already a primary virtual base.
llvm-svn: 97303
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 3dc29ad9caf..3c8ddfaed57 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1220,7 +1220,12 @@ private: /// LayoutSecondaryVtables - Layout the secondary vtables for the given base /// subobject. void LayoutSecondaryVtables(BaseSubobject Base); - + + /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this + /// class hierarchy. + void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + VisitedVirtualBasesSetTy &VBases); + /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the /// given base (excluding any primary bases). void LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, @@ -1418,9 +1423,6 @@ VtableBuilder::AddMethods(BaseSubobject Base, Context.getASTRecordLayout(MostDerivedClass); BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase); - - // Keep track of this primary virtual base. - PrimaryVirtualBases.insert(PrimaryBase); } else { assert(Layout.getBaseClassOffset(PrimaryBase) == 0 && "Primary base should have a zero offset!"); @@ -1498,6 +1500,11 @@ void VtableBuilder::LayoutVtable() { /*BaseIsVirtual=*/false); VisitedVirtualBasesSetTy VBases; + + // Determine the primary virtual bases. + DeterminePrimaryVirtualBases(MostDerivedClass, VBases); + VBases.clear(); + LayoutVtablesForVirtualBases(MostDerivedClass, VBases); } @@ -1592,15 +1599,37 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base) { } void +VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + VisitedVirtualBasesSetTy &VBases) { + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + + // Check if this base has a primary base. + if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { + // Check if it's virtual + if (Layout.getPrimaryBaseWasVirtual()) + PrimaryVirtualBases.insert(PrimaryBase); + } + + // Traverse bases, looking for more primary virtual bases. + for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), + E = RD->bases_end(); I != E; ++I) { + const CXXRecordDecl *BaseDecl = + cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); + + if (I->isVirtual() && !VBases.insert(BaseDecl)) + continue; + + DeterminePrimaryVirtualBases(BaseDecl, VBases); + } +} + +void VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, VisitedVirtualBasesSetTy &VBases) { // Itanium C++ ABI 2.5.2: // Then come the virtual base virtual tables, also in inheritance graph // order, and again excluding primary bases (which share virtual tables with // the classes for which they are primary). - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { const CXXRecordDecl *BaseDecl = @@ -1609,8 +1638,7 @@ VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, // Check if this base needs a vtable. (If it's virtual, not a primary base // of some other class, and we haven't visited it before). if (I->isVirtual() && BaseDecl->isDynamicClass() && - BaseDecl != PrimaryBase && !PrimaryVirtualBases.count(BaseDecl) && - VBases.insert(BaseDecl)) { + !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) { const ASTRecordLayout &MostDerivedClassLayout = Context.getASTRecordLayout(MostDerivedClass); uint64_t BaseOffset = |

