From: Anders Carlsson Date: Wed, 17 Feb 2010 03:11:55 +0000 (+0000) Subject: Pass through whether a base is virtual or not. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=340963fd040d79ebfd868f976743645254113183;p=clang Pass through whether a base is virtual or not. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96449 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 4fa7449697..e7d7bd56e5 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -831,12 +831,12 @@ private: typedef llvm::SmallPtrSet VisitedVirtualBasesSetTy; /// AddVCallAndVBaseOffsets - Add vcall offsets and vbase offsets for the - /// given class. - void AddVCallAndVBaseOffsets(const CXXRecordDecl *RD, int64_t OffsetToTop, + /// given base subobject. + void AddVCallAndVBaseOffsets(BaseSubobject Base, bool BaseIsVirtual, VisitedVirtualBasesSetTy &VBases); /// AddVBaseOffsets - Add vbase offsets for the given class. - void AddVBaseOffsets(const CXXRecordDecl *RD, int64_t OffsetToTop, + void AddVBaseOffsets(const CXXRecordDecl *Base, int64_t OffsetToTop, VisitedVirtualBasesSetTy &VBases); /// ComputeReturnAdjustment - Compute the return adjustment given a return @@ -862,7 +862,8 @@ private: /// LayoutPrimaryAndAndSecondaryVtables - Layout the primary vtable for the /// given base subobject, as well as all its secondary vtables. - void LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base); + void LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, + bool BaseIsVirtual); /// LayoutSecondaryVtables - Layout the secondary vtables for the given base /// subobject. @@ -940,10 +941,10 @@ VtableBuilder::ComputeThisAdjustment(FinalOverriders::BaseOffset Offset) { } void -VtableBuilder::AddVCallAndVBaseOffsets(const CXXRecordDecl *RD, - int64_t OffsetToTop, +VtableBuilder::AddVCallAndVBaseOffsets(BaseSubobject Base, + bool BaseIsVirtual, VisitedVirtualBasesSetTy &VBases) { - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base.getBase()); // Itanium C++ ABI 2.5.2: // ..in classes sharing a virtual table with a primary base class, the vcall @@ -954,10 +955,15 @@ VtableBuilder::AddVCallAndVBaseOffsets(const CXXRecordDecl *RD, // (Since we're emitting the vcall and vbase offsets in reverse order, we'll // emit them for the primary base first). - if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) - AddVCallAndVBaseOffsets(PrimaryBase, OffsetToTop, VBases); + if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { + bool PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual(); + AddVCallAndVBaseOffsets(BaseSubobject(PrimaryBase, Base.getBaseOffset()), + PrimaryBaseIsVirtual, VBases); + } - AddVBaseOffsets(RD, OffsetToTop, VBases); + // FIXME: Don't use /8 here. + int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8; + AddVBaseOffsets(Base.getBase(), OffsetToTop, VBases); } void VtableBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, @@ -1079,21 +1085,21 @@ VtableBuilder::AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases) { } void VtableBuilder::LayoutVtable() { - LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0)); + LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0), + /*BaseIsVirtual=*/false); VisitedVirtualBasesSetTy VBases; LayoutVtablesForVirtualBases(MostDerivedClass, VBases); } -void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base) { +void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, + bool BaseIsVirtual) { const CXXRecordDecl *RD = Base.getBase(); assert(RD->isDynamicClass() && "class does not have a vtable!"); - int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8; - // Add vcall and vbase offsets for this vtable. VisitedVirtualBasesSetTy VBases; - AddVCallAndVBaseOffsets(RD, OffsetToTop, VBases); + AddVCallAndVBaseOffsets(Base, BaseIsVirtual, VBases); // Reverse them and add them to the vtable components. std::reverse(VCallAndVBaseOffsets.begin(), VCallAndVBaseOffsets.end()); @@ -1103,6 +1109,7 @@ void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base) { // Add the offset to top. // FIXME: This is not going to be right for construction vtables. // FIXME: We should not use / 8 here. + int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8; Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop)); // Next, add the RTTI. @@ -1167,7 +1174,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base) { } // Layout the primary vtable (and any secondary vtables) for this base. - LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset)); + LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), + /*BaseIsVirtual=*/false); } } @@ -1195,7 +1203,8 @@ VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, uint64_t BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); - LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset)); + LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), + /*BaseIsVirtual=*/true); } // We only need to check the base for virtual base vtables if it actually