diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-28 01:43:58 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-28 01:43:58 +0000 |
commit | 530c40c516427112f76a88958bf7c17769b5ca12 (patch) | |
tree | 4fef41fcb9f9144dfa2e7d2f861e51a545e4ddd9 /lib/CodeGen/CGVtable.cpp | |
parent | d68fc055e17e8b01ac824d8ab749bc169fc4b93d (diff) |
More improvements to construction vtables; we know handle vbase offsets correctly (I hope).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97361 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 6fc81d4974..4f3cdde2d8 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -824,14 +824,10 @@ int64_t VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) { /// VCallAndVBaseOffsetBuilder - Class for building vcall and vbase offsets. class VCallAndVBaseOffsetBuilder { - /// MostDerivedClass - The most derived class for which we're building this - /// vtable. + /// MostDerivedClass - The most derived class for which we're building vcall + /// and vbase offsets. const CXXRecordDecl *MostDerivedClass; - /// MostDerivedClassOffset - If we're building a construction vtable, this - /// holds the offset from the layout class to the most derived class. - const uint64_t MostDerivedClassOffset; - /// LayoutClass - The class we're using for layout information. Will be /// different than the most derived class if we're building a construction /// vtable. @@ -867,16 +863,15 @@ class VCallAndVBaseOffsetBuilder { public: VCallAndVBaseOffsetBuilder(const CXXRecordDecl *MostDerivedClass, - uint64_t MostDerivedClassOffset, const CXXRecordDecl *LayoutClass, const FinalOverriders *Overriders, - BaseSubobject Base, bool BaseIsVirtual) - : MostDerivedClass(MostDerivedClass), - MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass), + BaseSubobject Base, bool BaseIsVirtual, + uint64_t OffsetInLayoutClass) + : MostDerivedClass(MostDerivedClass), LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), Overriders(Overriders) { // Add vcall and vbase offsets. - AddVCallAndVBaseOffsets(Base, BaseIsVirtual, Base.getBaseOffset()); + AddVCallAndVBaseOffsets(Base, BaseIsVirtual, OffsetInLayoutClass); } /// Methods for iterating over the components. @@ -1045,9 +1040,6 @@ void VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset = OffsetToTop + LayoutClassLayout.getVBaseClassOffset(BaseDecl) / 8; - // The offset should be relative to the most derived class offset. - Offset -= MostDerivedClassOffset / 8; - Components.push_back(VtableComponent::MakeVBaseOffset(Offset)); } @@ -1222,14 +1214,15 @@ private: // secondary vtables and any vtables for virtual bases. void LayoutVtable(); - /// LayoutPrimaryAndAndSecondaryVtables - Layout the primary vtable for the + /// LayoutPrimaryAndSecondaryVtables - Layout the primary vtable for the /// given base subobject, as well as all its secondary vtables. - void LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, - bool BaseIsVirtual); + void LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, + bool BaseIsVirtual, + uint64_t OffsetInLayoutClass); /// LayoutSecondaryVtables - Layout the secondary vtables for the given base /// subobject. - void LayoutSecondaryVtables(BaseSubobject Base); + void LayoutSecondaryVtables(BaseSubobject Base, uint64_t OffsetInLayoutClass); /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this /// class hierarchy. @@ -1434,10 +1427,11 @@ VtableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, if (VCallOffsets.empty()) { // We don't have vcall offsets for this virtual base, go ahead and // build them. - VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, 0, - MostDerivedClass, 0, - BaseSubobject(Offset.VirtualBase, 0), - /*BaseIsVirtual=*/true); + VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass, + /*FinalOverriders=*/0, + BaseSubobject(Offset.VirtualBase, 0), + /*BaseIsVirtual=*/true, + /*OffsetInLayoutClass=*/0); VCallOffsets = Builder.getVCallOffsets(); } @@ -1683,8 +1677,9 @@ VtableBuilder::AddMethods(BaseSubobject Base, } void VtableBuilder::LayoutVtable() { - LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0), - MostDerivedClassIsVirtual); + LayoutPrimaryAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0), + MostDerivedClassIsVirtual, + MostDerivedClassOffset); VisitedVirtualBasesSetTy VBases; @@ -1695,14 +1690,15 @@ void VtableBuilder::LayoutVtable() { LayoutVtablesForVirtualBases(MostDerivedClass, VBases); } -void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, - bool BaseIsVirtual) { +void +VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base, + bool BaseIsVirtual, + uint64_t OffsetInLayoutClass) { assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!"); // Add vcall and vbase offsets for this vtable. - VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClassOffset, - LayoutClass, &Overriders, - Base, BaseIsVirtual); + VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders, + Base, BaseIsVirtual, OffsetInLayoutClass); Components.append(Builder.components_begin(), Builder.components_end()); // Check if we need to add these vcall offsets. @@ -1714,9 +1710,9 @@ 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; + int64_t OffsetToTop = -(int64_t)(OffsetInLayoutClass - + MostDerivedClassOffset) / 8; Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop)); // Next, add the RTTI. @@ -1732,7 +1728,9 @@ void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, ComputeThisAdjustments(); // Record the address point. - AddressPoints.insert(std::make_pair(Base, AddressPoint)); + AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(), + OffsetInLayoutClass), + AddressPoint)); // Record the address points for all primary bases. for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(), @@ -1741,15 +1739,16 @@ void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, // We know that all the primary bases have the same offset as the base // subobject. - BaseSubobject PrimaryBase(BaseDecl, Base.getBaseOffset()); + BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass); AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint)); } // Layout secondary vtables. - LayoutSecondaryVtables(Base); + LayoutSecondaryVtables(Base, OffsetInLayoutClass); } -void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base) { +void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base, + uint64_t OffsetInLayoutClass) { // Itanium C++ ABI 2.5.2: // Following the primary virtual table of a derived class are secondary // virtual tables for each of its proper base classes, except any primary @@ -1773,19 +1772,23 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base) { continue; // Get the base offset of this base. - uint64_t BaseOffset = Base.getBaseOffset() + - Layout.getBaseClassOffset(BaseDecl); + uint64_t RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl); + uint64_t BaseOffset = Base.getBaseOffset() + RelativeBaseOffset; + + uint64_t BaseOffsetInLayoutClass = OffsetInLayoutClass + RelativeBaseOffset; // Don't emit a secondary vtable for a primary base. We might however want // to emit secondary vtables for other bases of this base. if (BaseDecl == PrimaryBase) { - LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset)); + LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), + BaseOffsetInLayoutClass); continue; } // Layout the primary vtable (and any secondary vtables) for this base. - LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), - /*BaseIsVirtual=*/false); + LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), + /*BaseIsVirtual=*/false, + BaseOffsetInLayoutClass); } } @@ -1835,8 +1838,14 @@ VtableBuilder::LayoutVtablesForVirtualBases(const CXXRecordDecl *RD, uint64_t BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl); - LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), - /*BaseIsVirtual=*/true); + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + uint64_t BaseOffsetInLayoutClass = + LayoutClassLayout.getVBaseClassOffset(BaseDecl); + + LayoutPrimaryAndSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset), + /*BaseIsVirtual=*/true, + BaseOffsetInLayoutClass); } // We only need to check the base for virtual base vtables if it actually |