diff options
| author | Anders Carlsson <andersca@mac.com> | 2010-03-10 03:02:01 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2010-03-10 03:02:01 +0000 |
| commit | 02b99d6b7c49d8880d29114e4e1554bb4b55923e (patch) | |
| tree | b23f5c429c14a393c08947ad1d70ce6424b29721 /clang/lib/CodeGen/CGVtable.cpp | |
| parent | eec9bf1198207df2d9c6d564592e45d2e86fe081 (diff) | |
| download | bcm5719-llvm-02b99d6b7c49d8880d29114e4e1554bb4b55923e.tar.gz bcm5719-llvm-02b99d6b7c49d8880d29114e4e1554bb4b55923e.zip | |
When building construction vtables, we need to check if a primary virtual base is actually a primary virtual base in the layout class.
llvm-svn: 98131
Diffstat (limited to 'clang/lib/CodeGen/CGVtable.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index fbd0ed8fbef..8b239f2614f 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1238,6 +1238,7 @@ private: /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this /// class hierarchy. void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + uint64_t OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases); /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the @@ -1699,7 +1700,8 @@ void VtableBuilder::LayoutVtable() { VisitedVirtualBasesSetTy VBases; // Determine the primary virtual bases. - DeterminePrimaryVirtualBases(MostDerivedClass, VBases); + DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, + VBases); VBases.clear(); LayoutVtablesForVirtualBases(MostDerivedClass, VBases); @@ -1808,7 +1810,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base, } void -VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, +VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + uint64_t OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -1822,8 +1825,15 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, if (isBuildingConstructorVtable()) { // Check if the base is actually a primary base in the class we use for // layout. - // FIXME: Is this check enough? - if (MostDerivedClassOffset != 0) + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + + uint64_t PrimaryBaseOffsetInLayoutClass = + LayoutClassLayout.getVBaseClassOffset(PrimaryBase); + + // We know that the base is not a primary base in the layout class if + // the base offsets are different. + if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) IsPrimaryVirtualBase = false; } @@ -1838,10 +1848,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); - if (I->isVirtual() && !VBases.insert(BaseDecl)) - continue; + uint64_t BaseOffsetInLayoutClass; + + if (I->isVirtual()) { + if (!VBases.insert(BaseDecl)) + continue; + + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + + BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); + } else { + BaseOffsetInLayoutClass = + OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); + } - DeterminePrimaryVirtualBases(BaseDecl, VBases); + DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); } } |

