When building construction vtables, we need to check if a primary virtual base is actually a primary virtual base in the layout class.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98131 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2010-03-10 03:02:01 +00:00
Родитель 3c1c4aaa46
Коммит d7fdae5ea0
1 изменённых файлов: 29 добавлений и 7 удалений

Просмотреть файл

@ -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);
DeterminePrimaryVirtualBases(BaseDecl, VBases);
BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl);
} else {
BaseOffsetInLayoutClass =
OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl);
}
DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases);
}
}