From 62c6c72babaa0fadd83d16ad862406820497d2d0 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 28 Feb 2010 00:36:23 +0000 Subject: [PATCH] Pass information about whether a base is virtual or not down to getCtorVtable, we need this information in the vtable builder. llvm-svn: 97356 --- clang/lib/CodeGen/CGVTT.cpp | 21 ++++++++++++--------- clang/lib/CodeGen/CGVtable.cpp | 30 ++++++++++++++++++++++-------- clang/lib/CodeGen/CGVtable.h | 5 +++-- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/clang/lib/CodeGen/CGVTT.cpp b/clang/lib/CodeGen/CGVTT.cpp index 9714bd9d9678..96c104b22d15 100644 --- a/clang/lib/CodeGen/CGVTT.cpp +++ b/clang/lib/CodeGen/CGVTT.cpp @@ -46,7 +46,8 @@ class VTTBuilder { llvm::DenseMap, uint64_t> CtorVtableAddressPoints; - llvm::Constant *getCtorVtable(const BaseSubobject &Base) { + llvm::Constant *getCtorVtable(const BaseSubobject &Base, + bool BaseIsVirtual) { if (!GenerateDefinition) return 0; @@ -54,7 +55,7 @@ class VTTBuilder { if (!CtorVtable) { // Build the vtable. CGVtableInfo::CtorVtableInfo Info - = CGM.getVtableInfo().getCtorVtable(Class, Base); + = CGM.getVtableInfo().getCtorVtable(Class, Base, BaseIsVirtual); CtorVtable = Info.Vtable; @@ -166,7 +167,7 @@ class VTTBuilder { if (BaseMorallyVirtual || VtblClass == Class) init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset); else { - init = getCtorVtable(BaseSubobject(Base, BaseOffset)); + init = getCtorVtable(BaseSubobject(Base, BaseOffset), i->isVirtual()); subvtbl = init; subVtblClass = Base; @@ -186,7 +187,8 @@ class VTTBuilder { /// BuiltVTT - Add the VTT to Inits. Offset is the offset in bits to the /// currnet object we're working on. - void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool MorallyVirtual) { + void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool BaseIsVirtual, + bool MorallyVirtual) { // Itanium C++ ABI 2.6.2: // An array of virtual table addresses, called the VTT, is declared for // each class type that has indirect or direct virtual base classes. @@ -204,7 +206,8 @@ class VTTBuilder { Vtable = ClassVtbl; VtableClass = Class; } else { - Vtable = getCtorVtable(BaseSubobject(RD, Offset)); + Vtable = getCtorVtable(BaseSubobject(RD, Offset), + /*IsVirtual=*/BaseIsVirtual); VtableClass = RD; } @@ -235,7 +238,7 @@ class VTTBuilder { const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base); - BuildVTT(Base, BaseOffset, MorallyVirtual); + BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/false, MorallyVirtual); } } @@ -249,7 +252,7 @@ class VTTBuilder { if (i->isVirtual() && !SeenVBase.count(Base)) { SeenVBase.insert(Base); uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base); - BuildVTT(Base, BaseOffset, false); + BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/true, false); } VirtualVTTs(Base); } @@ -335,13 +338,13 @@ CGVtableInfo::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, CGVtableInfo::CtorVtableInfo CGVtableInfo::getCtorVtable(const CXXRecordDecl *RD, - const BaseSubobject &Base) { + const BaseSubobject &Base, bool BaseIsVirtual) { CtorVtableInfo Info; Info.Vtable = GenerateVtable(llvm::GlobalValue::InternalLinkage, /*GenerateDefinition=*/true, RD, Base.getBase(), Base.getBaseOffset(), - Info.AddressPoints); + BaseIsVirtual, Info.AddressPoints); return Info; } diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index ad035cd1fcf7..6fc81d497409 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1076,6 +1076,10 @@ private: /// holds the offset from the layout class to the most derived class. const uint64_t MostDerivedClassOffset; + /// MostDerivedClassIsVirtual - Whether the most derived class is a virtual + /// base. (This only makes sense when building a construction vtable). + bool MostDerivedClassIsVirtual; + /// LayoutClass - The class we're using for layout information. Will be /// different than the most derived class if we're building a construction /// vtable. @@ -1214,7 +1218,7 @@ private: void AddMethods(BaseSubobject Base, BaseSubobject FirstBaseInPrimaryBaseChain, PrimaryBasesSetVectorTy &PrimaryBases); - // LayoutVtable - Layout the vtable for the most derived class, including its + // LayoutVtable - Layout the vtable for the given base class, including its // secondary vtables and any vtables for virtual bases. void LayoutVtable(); @@ -1245,11 +1249,13 @@ private: public: VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass, - uint64_t MostDerivedClassOffset, + uint64_t MostDerivedClassOffset, bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass) : VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass), - MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), - Context(MostDerivedClass->getASTContext()), Overriders(MostDerivedClass) { + MostDerivedClassOffset(MostDerivedClassOffset), + MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), + LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), + Overriders(MostDerivedClass) { LayoutVtable(); } @@ -1678,7 +1684,7 @@ VtableBuilder::AddMethods(BaseSubobject Base, void VtableBuilder::LayoutVtable() { LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0), - /*BaseIsVirtual=*/false); + MostDerivedClassIsVirtual); VisitedVirtualBasesSetTy VBases; @@ -3318,16 +3324,23 @@ CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, const CXXRecordDecl *LayoutClass, const CXXRecordDecl *RD, uint64_t Offset, + bool IsVirtual, AddressPointsMapTy& AddressPoints) { if (GenerateDefinition) { if (LayoutClass == RD) { - VtableBuilder Builder(*this, RD, Offset, LayoutClass); + assert(!IsVirtual && + "Can't only have a virtual base in construction vtables!"); + VtableBuilder Builder(*this, RD, Offset, + /*MostDerivedClassIsVirtual=*/false, + LayoutClass); if (CGM.getLangOptions().DumpVtableLayouts) Builder.dumpLayout(llvm::errs()); } else if (CGM.getLangOptions().DumpVtableLayouts) { // We only build construction vtables when dumping vtable layouts for now. - VtableBuilder Builder(*this, RD, Offset, LayoutClass); + VtableBuilder Builder(*this, RD, Offset, + /*MostDerivedClassIsVirtual=*/IsVirtual, + LayoutClass); Builder.dumpLayout(llvm::errs()); } } @@ -3390,6 +3403,7 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, AddressPointsMapTy AddressPoints; Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, + /*IsVirtual=*/false, AddressPoints); GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); } @@ -3401,7 +3415,7 @@ llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { AddressPointsMapTy AddressPoints; Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, /*GenerateDefinition=*/false, RD, RD, 0, - AddressPoints); + /*IsVirtual=*/false, AddressPoints); } return Vtable; diff --git a/clang/lib/CodeGen/CGVtable.h b/clang/lib/CodeGen/CGVtable.h index 471d6384d6b2..6ccb011985fd 100644 --- a/clang/lib/CodeGen/CGVtable.h +++ b/clang/lib/CodeGen/CGVtable.h @@ -185,7 +185,7 @@ private: llvm::GlobalVariable * GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, const CXXRecordDecl *LayoutClass, - const CXXRecordDecl *RD, uint64_t Offset, + const CXXRecordDecl *RD, uint64_t Offset, bool IsVirtual, AddressPointsMapTy& AddressPoints); llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, @@ -239,7 +239,8 @@ public: }; CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD, - const BaseSubobject &Base); + const BaseSubobject &Base, + bool BaseIsVirtual); llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);