diff options
author | Mike Stump <mrs@apple.com> | 2009-10-14 18:14:51 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-10-14 18:14:51 +0000 |
commit | 0ca4279d84635e1e54951761bd6fe89a45a23ff1 (patch) | |
tree | a4297491842271d50b08a6cda80bc72745a58e5c | |
parent | 542b548e041a6fab0fe06601ccc6b91a81bc217a (diff) |
Shift the vcall slots for non-virtual bases of a virtual base, up into
the virtual base so they can be reused properly. Don't reuse vcall
slots across a virtual boundary. WIP. I have a testcase, but there
are still things that need to be fixed before the testcase can go in.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84120 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 41f7eefbe8..b84f34cf44 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -332,6 +332,22 @@ public: } } +// #define D(X) do { X; } while (0) +#define D(X) + + void insertVCalls(int InsertionPoint) { + llvm::Constant *e = 0; + D(VCalls.insert(VCalls.begin(), 673)); + D(VCalls.push_back(672)); + methods.insert(methods.begin() + InsertionPoint, VCalls.size()/*+2*/, e); + // The vcalls come first... + for (std::vector<Index_t>::reverse_iterator i = VCalls.rbegin(), + e = VCalls.rend(); + i != e; ++i) + methods[InsertionPoint++] = wrap((0?600:0) + *i); + VCalls.clear(); + } + Index_t end(const CXXRecordDecl *RD, std::vector<llvm::Constant *> &offsets, const ASTRecordLayout &Layout, const CXXRecordDecl *PrimaryBase, @@ -341,24 +357,27 @@ public: extra = 0; // FIXME: Cleanup. if (!ForVirtualBase) { + D(methods.push_back(wrap(666))); // then virtual base offsets... for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(), e = offsets.rend(); i != e; ++i) methods.push_back(*i); + D(methods.push_back(wrap(667))); } - // The vcalls come first... - for (std::vector<Index_t>::reverse_iterator i=VCalls.rbegin(), - e=VCalls.rend(); - i != e; ++i) - methods.push_back(wrap((0?600:0) + *i)); - VCalls.clear(); + bool DeferVCalls = MorallyVirtual || ForVirtualBase; + int VCallInsertionPoint = methods.size(); + if (!DeferVCalls) { + insertVCalls(VCallInsertionPoint); + } if (ForVirtualBase) { + D(methods.push_back(wrap(668))); // then virtual base offsets... for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(), e = offsets.rend(); i != e; ++i) methods.push_back(*i); + D(methods.push_back(wrap(669))); } methods.push_back(wrap(-(Offset/8))); @@ -372,6 +391,14 @@ public: // and then the non-virtual bases. NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual, MorallyVirtual, Offset); + + if (ForVirtualBase) { + D(methods.push_back(wrap(670))); + insertVCalls(VCallInsertionPoint); + AddressPoint += VCalls.size(); + D(methods.push_back(wrap(671))); + } + return AddressPoint; } @@ -450,6 +477,7 @@ public: // Mark it so we don't output it twice. IndirectPrimary.insert(Base); StartNewTable(); + VCall.clear(); int64_t BaseOffset = BLayout.getVBaseClassOffset(Base); GenerateVtableForBase(Base, true, BaseOffset, true, Path); } |