aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-01-18 17:13:59 +0000
committerAnders Carlsson <andersca@mac.com>2010-01-18 17:13:59 +0000
commit35aa62aacf2b644f2ff2f0bdfd89136323698a39 (patch)
tree2beed1fba4e113f0ebbbc16ef34c0180b9375905 /lib/CodeGen/CGVtable.cpp
parent3ed04d37573c566205d965d2e91d54ccae898d0a (diff)
More VTT builder fixes. With these fixes we now correctly handle the very complex VTT example from the Itanium ABI spec.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93725 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 2f5681e181..b2fb8662fe 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -1221,6 +1221,10 @@ class VTTBuilder {
llvm::Constant *ClassVtbl;
llvm::LLVMContext &VMContext;
+ /// SeenVBasesInSecondary - The seen virtual bases when building the
+ /// secondary virtual pointers.
+ llvm::SmallPtrSet<const CXXRecordDecl *, 32> SeenVBasesInSecondary;
+
llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
bool GenerateDefinition;
@@ -1314,6 +1318,10 @@ class VTTBuilder {
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+ // We only want to visit each virtual base once.
+ if (i->isVirtual() && SeenVBasesInSecondary.count(Base))
+ continue;
// Itanium C++ ABI 2.6.2:
// Secondary virtual pointers are present for all bases with either
@@ -1352,8 +1360,13 @@ class VTTBuilder {
init = BuildVtablePtr(init, Class, Base, BaseOffset);
}
+
Inits.push_back(init);
}
+
+ if (i->isVirtual())
+ SeenVBasesInSecondary.insert(Base);
+
Secondary(Base, subvtbl, subVtblClass, BaseOffset, BaseMorallyVirtual);
}
}
@@ -1388,6 +1401,9 @@ class VTTBuilder {
// then the secondary VTTs....
SecondaryVTTs(RD, Offset, MorallyVirtual);
+ // Make sure to clear the set of seen virtual bases.
+ SeenVBasesInSecondary.clear();
+
// and last the secondary vtable pointers.
Secondary(RD, Vtable, VtableClass, Offset, MorallyVirtual);
}
@@ -1420,7 +1436,7 @@ class VTTBuilder {
if (i->isVirtual() && !SeenVBase.count(Base)) {
SeenVBase.insert(Base);
uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
- BuildVTT(Base, BaseOffset, true);
+ BuildVTT(Base, BaseOffset, false);
}
VirtualVTTs(Base);
}
@@ -1444,6 +1460,9 @@ public:
// then the secondary VTTs...
SecondaryVTTs(Class);
+ // Make sure to clear the set of seen virtual bases.
+ SeenVBasesInSecondary.clear();
+
// then the secondary vtable pointers...
Secondary(Class, ClassVtbl, Class);