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
This commit is contained in:
Anders Carlsson 2010-03-10 03:02:01 +00:00
parent eec9bf1198
commit 02b99d6b7c
1 changed files with 29 additions and 7 deletions

View File

@ -1238,6 +1238,7 @@ private:
/// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
/// class hierarchy. /// class hierarchy.
void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
uint64_t OffsetInLayoutClass,
VisitedVirtualBasesSetTy &VBases); VisitedVirtualBasesSetTy &VBases);
/// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the
@ -1699,7 +1700,8 @@ void VtableBuilder::LayoutVtable() {
VisitedVirtualBasesSetTy VBases; VisitedVirtualBasesSetTy VBases;
// Determine the primary virtual bases. // Determine the primary virtual bases.
DeterminePrimaryVirtualBases(MostDerivedClass, VBases); DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset,
VBases);
VBases.clear(); VBases.clear();
LayoutVtablesForVirtualBases(MostDerivedClass, VBases); LayoutVtablesForVirtualBases(MostDerivedClass, VBases);
@ -1808,7 +1810,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
} }
void void
VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
uint64_t OffsetInLayoutClass,
VisitedVirtualBasesSetTy &VBases) { VisitedVirtualBasesSetTy &VBases) {
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
@ -1822,8 +1825,15 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
if (isBuildingConstructorVtable()) { if (isBuildingConstructorVtable()) {
// Check if the base is actually a primary base in the class we use for // Check if the base is actually a primary base in the class we use for
// layout. // layout.
// FIXME: Is this check enough? const ASTRecordLayout &LayoutClassLayout =
if (MostDerivedClassOffset != 0) 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; IsPrimaryVirtualBase = false;
} }
@ -1838,10 +1848,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
const CXXRecordDecl *BaseDecl = const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
if (I->isVirtual() && !VBases.insert(BaseDecl)) uint64_t BaseOffsetInLayoutClass;
continue;
if (I->isVirtual()) {
if (!VBases.insert(BaseDecl))
continue;
const ASTRecordLayout &LayoutClassLayout =
Context.getASTRecordLayout(LayoutClass);
DeterminePrimaryVirtualBases(BaseDecl, VBases); BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl);
} else {
BaseOffsetInLayoutClass =
OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl);
}
DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases);
} }
} }