diff options
author | Anders Carlsson <andersca@mac.com> | 2010-03-25 21:45:14 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-03-25 21:45:14 +0000 |
commit | 014a358058fab46a84718b1424e40ad5a8068827 (patch) | |
tree | 2792ca3f82e55846e422b43c0bb337128f26e5f1 /lib/CodeGen/CGVtable.cpp | |
parent | e06c1a13172bd6ef38fe927d72198ab3f97c0b4a (diff) |
Don't add address points for virtual primary bases that aren't primary bases in the complete class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 768e6a7566..23cef42a3c 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1900,20 +1900,32 @@ VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, // Compute 'this' pointer adjustments. ComputeThisAdjustments(); - // Record the address point. - AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(), - OffsetInLayoutClass), - AddressPoint)); - - // Record the address points for all primary bases. - for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(), - E = PrimaryBases.end(); I != E; ++I) { - const CXXRecordDecl *BaseDecl = *I; + // Add all address points. + const CXXRecordDecl *RD = Base.getBase(); + while (true) { + AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass), + AddressPoint)); + + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); - // We know that all the primary bases have the same offset as the base - // subobject. - BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass); - AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint)); + if (!PrimaryBase) + break; + + if (Layout.getPrimaryBaseWasVirtual()) { + // Check if this virtual primary base is a primary base in the layout + // class. If it's not, we don't want to add it. + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + + if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) != + OffsetInLayoutClass) { + // We don't want to add this class (or any of its primary bases). + break; + } + } + + RD = PrimaryBase; } bool BaseIsMorallyVirtual = BaseIsVirtual; |