More VTT cleanup.

llvm-svn: 99586
This commit is contained in:
Anders Carlsson 2010-03-26 00:50:17 +00:00
parent a14cb9fd38
commit c1b4747d5a
1 changed files with 43 additions and 22 deletions

View File

@ -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();