aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-16 16:49:35 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-16 16:49:35 +0000
commit69dc04e94872616cebbdd8215d1f5036a8add3f7 (patch)
tree82b0afc55d3716b05c09fd858c0779e5567226c9 /lib/CodeGen/CGVtable.cpp
parent89ad4219e4ed8f025ef2049e7b1ca6af4624d989 (diff)
Handle layout of vtables for virtual bases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96355 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index b9d6332b68..b60d470b39 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -831,6 +831,11 @@ private:
/// subobject.
void LayoutSecondaryVtables(BaseSubobject Base);
+ /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the
+ /// given base (excluding any primary bases).
+ void LayoutVtablesForVirtualBases(const CXXRecordDecl *RD,
+ VisitedVirtualBasesSetTy &VBases);
+
public:
VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass)
: VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass),
@@ -1039,7 +1044,8 @@ VtableBuilder::AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases) {
void VtableBuilder::LayoutVtable() {
LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0));
- // FIXME: Emit vtables for virtual bases here.
+ VisitedVirtualBasesSetTy VBases;
+ LayoutVtablesForVirtualBases(MostDerivedClass, VBases);
}
void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base) {
@@ -1128,6 +1134,40 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base) {
}
}
+void
+VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD,
+ VisitedVirtualBasesSetTy &VBases) {
+ // Itanium C++ ABI 2.5.2:
+ // Then come the virtual base virtual tables, also in inheritance graph
+ // order, and again excluding primary bases (which share virtual tables with
+ // the classes for which they are primary).
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+ const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ // Check if this base needs a vtable. (If it's virtual, and we haven't
+ // visited it before).
+ if (I->isVirtual() && BaseDecl->isDynamicClass() &&
+ BaseDecl != PrimaryBase && VBases.insert(BaseDecl)) {
+ const ASTRecordLayout &MostDerivedClassLayout =
+ Context.getASTRecordLayout(MostDerivedClass);
+ uint64_t BaseOffset =
+ MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+
+ LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset));
+ }
+
+ // We only need to check the base for virtual base vtables if it actually
+ // has virtual bases.
+ if (BaseDecl->getNumVBases())
+ LayoutVtablesForVirtualBases(BaseDecl, VBases);
+ }
+}
+
/// dumpLayout - Dump the vtable layout.
void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {