summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-03-10 03:02:01 +0000
committerAnders Carlsson <andersca@mac.com>2010-03-10 03:02:01 +0000
commit02b99d6b7c49d8880d29114e4e1554bb4b55923e (patch)
treeb23f5c429c14a393c08947ad1d70ce6424b29721 /clang/lib/CodeGen/CGVtable.cpp
parenteec9bf1198207df2d9c6d564592e45d2e86fe081 (diff)
downloadbcm5719-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.cpp36
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);
}
}
OpenPOWER on IntegriCloud