summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGVTT.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-03-26 00:50:17 +0000
committerAnders Carlsson <andersca@mac.com>2010-03-26 00:50:17 +0000
commit9f17d410044af23fe426c504bc969156f0fc248d (patch)
treec6db77a68cbbc009d28415e3ddf7ef07adcec6ab /lib/CodeGen/CGVTT.cpp
parent0d4fd8ef35ecd73ce6388cb5a6fdcfb15171f5aa (diff)
More VTT cleanup.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVTT.cpp')
-rw-r--r--lib/CodeGen/CGVTT.cpp65
1 files changed, 43 insertions, 22 deletions
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index 1989d6c19b..09cb5a88b7 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -34,6 +34,8 @@ class VTTBuilder {
llvm::Constant *ClassVtbl;
llvm::LLVMContext &VMContext;
+ typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+
/// SeenVBasesInSecondary - The seen virtual bases when building the
/// secondary virtual pointers.
llvm::SmallPtrSet<const CXXRecordDecl *, 32> SeenVBasesInSecondary;
@@ -169,31 +171,19 @@ class VTTBuilder {
}
}
- /// LayoutVTT - Will lay out the VTT for the given subobject, including any
- /// secondary VTTs, secondary virtual pointers and virtual VTTs.
- void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
-
/// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base
/// subobject.
void LayoutSecondaryVTTs(BaseSubobject Base);
- /// VirtualVTTs - Add the VTT for each proper virtual base in inheritance
- /// graph preorder.
- void VirtualVTTs(const CXXRecordDecl *RD) {
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end(); i != e; ++i) {
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- if (i->isVirtual() && !SeenVBase.count(Base)) {
- SeenVBase.insert(Base);
- uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
-
- LayoutVTT(BaseSubobject(Base, BaseOffset), /*BaseIsVirtual=*/true);
- }
- VirtualVTTs(Base);
- }
- }
-
+ /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
+ /// given record decl.
+ void LayoutVirtualVTTs(const CXXRecordDecl *RD,
+ VisitedVirtualBasesSetTy &VBases);
+
+ /// LayoutVTT - Will lay out the VTT for the given subobject, including any
+ /// secondary VTTs, secondary virtual pointers and virtual VTTs.
+ void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
+
public:
VTTBuilder(std::vector<llvm::Constant *> &inits, const CXXRecordDecl *c,
CodeGenModule &cgm, bool GenerateDefinition)
@@ -219,7 +209,8 @@ public:
Secondary(Class, ClassVtbl, Class, 0, false);
// and last, the virtual VTTs.
- VirtualVTTs(Class);
+ VisitedVirtualBasesSetTy VBases;
+ LayoutVirtualVTTs(Class, VBases);
}
llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getSubVTTIndicies() {
@@ -249,6 +240,36 @@ void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
}
}
+/// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
+/// given record decl.
+void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
+ VisitedVirtualBasesSetTy &VBases) {
+ 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 is a virtual base.
+ if (I->isVirtual()) {
+ // Check if we've seen this base before.
+ if (!VBases.insert(BaseDecl))
+ continue;
+
+ const ASTRecordLayout &MostDerivedClassLayout =
+ CGM.getContext().getASTRecordLayout(Class);
+ uint64_t BaseOffset =
+ MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+
+ LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
+ }
+
+ // We only need to layout virtual VTTs for this base if it actually has
+ // virtual bases.
+ if (BaseDecl->getNumVBases())
+ LayoutVirtualVTTs(BaseDecl, VBases);
+ }
+}
+
void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
const CXXRecordDecl *RD = Base.getBase();