tbaeder created this revision. tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The InterpFrame was only created so early so we could use getThis(). However, we need to know the Function when creating the InterpFrame and in the case of virtual functions, we need to determine what function to call at interpretation time. Get the This pointer ourselves and just create the InterpFrame later. This is of course in preparation for virtual function calls. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D142617 Files: clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpStack.h Index: clang/lib/AST/Interp/InterpStack.h =================================================================== --- clang/lib/AST/Interp/InterpStack.h +++ clang/lib/AST/Interp/InterpStack.h @@ -67,6 +67,10 @@ return *reinterpret_cast<T *>(peek(aligned_size<T>())); } + template <typename T> T &peek(size_t Offset) const { + return *reinterpret_cast<T *>(peek(Offset)); + } + /// Returns a pointer to the top object. void *top() const { return Chunk ? peek(0) : nullptr; } Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -1499,10 +1499,11 @@ } inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) { - auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC); - Pointer ThisPtr; if (Func->hasThisPointer()) { - ThisPtr = NewFrame->getThis(); + size_t ThisOffset = + Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0); + const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset); + if (!CheckInvoke(S, PC, ThisPtr)) return false; @@ -1513,6 +1514,7 @@ if (!CheckCallable(S, PC, Func)) return false; + auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC); InterpFrame *FrameBefore = S.Current; S.Current = NewFrame.get();
Index: clang/lib/AST/Interp/InterpStack.h =================================================================== --- clang/lib/AST/Interp/InterpStack.h +++ clang/lib/AST/Interp/InterpStack.h @@ -67,6 +67,10 @@ return *reinterpret_cast<T *>(peek(aligned_size<T>())); } + template <typename T> T &peek(size_t Offset) const { + return *reinterpret_cast<T *>(peek(Offset)); + } + /// Returns a pointer to the top object. void *top() const { return Chunk ? peek(0) : nullptr; } Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -1499,10 +1499,11 @@ } inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) { - auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC); - Pointer ThisPtr; if (Func->hasThisPointer()) { - ThisPtr = NewFrame->getThis(); + size_t ThisOffset = + Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0); + const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset); + if (!CheckInvoke(S, PC, ThisPtr)) return false; @@ -1513,6 +1514,7 @@ if (!CheckCallable(S, PC, Func)) return false; + auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC); InterpFrame *FrameBefore = S.Current; S.Current = NewFrame.get();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits