diff options
| author | Anders Carlsson <andersca@mac.com> | 2010-02-25 22:23:13 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2010-02-25 22:23:13 +0000 |
| commit | 9e3b3a3bbec814334e5d8c792ee6f5a034838d9b (patch) | |
| tree | 8d2eeeb2cd0726233a646df263deeb4e1837a926 /clang/lib/CodeGen | |
| parent | ed7d0e8be853862c1ece0b59ff84749a0906e8fd (diff) | |
| download | bcm5719-llvm-9e3b3a3bbec814334e5d8c792ee6f5a034838d9b.tar.gz bcm5719-llvm-9e3b3a3bbec814334e5d8c792ee6f5a034838d9b.zip | |
Improve vcall offset handling.
llvm-svn: 97174
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index a6b8eb6d3d4..81f2ac67da3 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -804,8 +804,8 @@ public: /// vtable address point) for the given virtual member function. int64_t getVCallOffsetOffset(const CXXMethodDecl *MD); - /// clear - Clear the offset map. - void clear() { Offsets.clear(); } + // empty - Return whether the offset map is empty or not. + bool empty() const { return Offsets.empty(); } }; bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, @@ -905,7 +905,6 @@ public: const_iterator components_begin() const { return Components.rbegin(); } const_iterator components_end() const { return Components.rend(); } - /// FIXME: Get rid of this getter. const VCallOffsetMap& getVCallOffsets() const { return VCallOffsets; } }; @@ -1092,8 +1091,9 @@ private: /// FinalOverriders - The final overriders of the most derived class. const FinalOverriders Overriders; - /// VCallOffsets - Keeps track of vcall offsets for the current vtable. - VCallOffsetMap VCallOffsets; + /// VCallOffsetsForVBases - Keeps track of vcall offsets for the virtual + /// bases in this vtable. + llvm::DenseMap<const CXXRecordDecl *, VCallOffsetMap> VCallOffsetsForVBases; /// Components - The components of the vtable being built. llvm::SmallVector<VtableComponent, 64> Components; @@ -1267,7 +1267,19 @@ VtableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD, if (!Offset.isEmpty()) { if (Offset.VirtualBase) { - // Get the vcall offset offset. + // Get the vcall offset map for this virtual base. + VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase]; + + if (VCallOffsets.empty()) { + // We don't have vcall offsets for this virtual base, go ahead and + // build them. + VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, 0, + BaseSubobject(Offset.VirtualBase, 0), + /*BaseIsVirtual=*/true); + + VCallOffsets = Builder.getVCallOffsets(); + } + Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD); } @@ -1478,9 +1490,14 @@ void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, Base, BaseIsVirtual); Components.append(Builder.components_begin(), Builder.components_end()); - // FIXME: This is not how we should do vcall offsets. - VCallOffsets = Builder.getVCallOffsets(); - + // Check if we need to add these vcall offsets. + if (BaseIsVirtual && !Builder.getVCallOffsets().empty()) { + VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Base.getBase()]; + + if (VCallOffsets.empty()) + VCallOffsets = Builder.getVCallOffsets(); + } + // Add the offset to top. // FIXME: This is not going to be right for construction vtables. // FIXME: We should not use / 8 here. @@ -1510,9 +1527,6 @@ void VtableBuilder::LayoutPrimaryAndAndSecondaryVtables(BaseSubobject Base, AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint)); } - // Clear the vcall offsets. - VCallOffsets.clear(); - // Layout secondary vtables. LayoutSecondaryVtables(Base); } |

