1*7330f729Sjoerg //===--- InterpState.h - Interpreter state for the constexpr VM -*- C++ -*-===// 2*7330f729Sjoerg // 3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*7330f729Sjoerg // 7*7330f729Sjoerg //===----------------------------------------------------------------------===// 8*7330f729Sjoerg // 9*7330f729Sjoerg // Definition of the interpreter state and entry point. 10*7330f729Sjoerg // 11*7330f729Sjoerg //===----------------------------------------------------------------------===// 12*7330f729Sjoerg 13*7330f729Sjoerg #ifndef LLVM_CLANG_AST_INTERP_INTERPSTATE_H 14*7330f729Sjoerg #define LLVM_CLANG_AST_INTERP_INTERPSTATE_H 15*7330f729Sjoerg 16*7330f729Sjoerg #include "Context.h" 17*7330f729Sjoerg #include "Function.h" 18*7330f729Sjoerg #include "InterpStack.h" 19*7330f729Sjoerg #include "State.h" 20*7330f729Sjoerg #include "clang/AST/APValue.h" 21*7330f729Sjoerg #include "clang/AST/ASTDiagnostic.h" 22*7330f729Sjoerg #include "clang/AST/Expr.h" 23*7330f729Sjoerg #include "clang/AST/OptionalDiagnostic.h" 24*7330f729Sjoerg 25*7330f729Sjoerg namespace clang { 26*7330f729Sjoerg namespace interp { 27*7330f729Sjoerg class Context; 28*7330f729Sjoerg class Function; 29*7330f729Sjoerg class InterpStack; 30*7330f729Sjoerg class InterpFrame; 31*7330f729Sjoerg class SourceMapper; 32*7330f729Sjoerg 33*7330f729Sjoerg /// Interpreter context. 34*7330f729Sjoerg class InterpState final : public State, public SourceMapper { 35*7330f729Sjoerg public: 36*7330f729Sjoerg InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, 37*7330f729Sjoerg SourceMapper *M = nullptr); 38*7330f729Sjoerg 39*7330f729Sjoerg ~InterpState(); 40*7330f729Sjoerg 41*7330f729Sjoerg // Stack frame accessors. getSplitFrame()42*7330f729Sjoerg Frame *getSplitFrame() { return Parent.getCurrentFrame(); } 43*7330f729Sjoerg Frame *getCurrentFrame() override; getCallStackDepth()44*7330f729Sjoerg unsigned getCallStackDepth() override { return CallStackDepth; } getBottomFrame()45*7330f729Sjoerg const Frame *getBottomFrame() const override { 46*7330f729Sjoerg return Parent.getBottomFrame(); 47*7330f729Sjoerg } 48*7330f729Sjoerg 49*7330f729Sjoerg // Acces objects from the walker context. getEvalStatus()50*7330f729Sjoerg Expr::EvalStatus &getEvalStatus() const override { 51*7330f729Sjoerg return Parent.getEvalStatus(); 52*7330f729Sjoerg } getCtx()53*7330f729Sjoerg ASTContext &getCtx() const override { return Parent.getCtx(); } 54*7330f729Sjoerg 55*7330f729Sjoerg // Forward status checks and updates to the walker. checkingForUndefinedBehavior()56*7330f729Sjoerg bool checkingForUndefinedBehavior() const override { 57*7330f729Sjoerg return Parent.checkingForUndefinedBehavior(); 58*7330f729Sjoerg } keepEvaluatingAfterFailure()59*7330f729Sjoerg bool keepEvaluatingAfterFailure() const override { 60*7330f729Sjoerg return Parent.keepEvaluatingAfterFailure(); 61*7330f729Sjoerg } checkingPotentialConstantExpression()62*7330f729Sjoerg bool checkingPotentialConstantExpression() const override { 63*7330f729Sjoerg return Parent.checkingPotentialConstantExpression(); 64*7330f729Sjoerg } noteUndefinedBehavior()65*7330f729Sjoerg bool noteUndefinedBehavior() override { 66*7330f729Sjoerg return Parent.noteUndefinedBehavior(); 67*7330f729Sjoerg } hasActiveDiagnostic()68*7330f729Sjoerg bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); } setActiveDiagnostic(bool Flag)69*7330f729Sjoerg void setActiveDiagnostic(bool Flag) override { 70*7330f729Sjoerg Parent.setActiveDiagnostic(Flag); 71*7330f729Sjoerg } setFoldFailureDiagnostic(bool Flag)72*7330f729Sjoerg void setFoldFailureDiagnostic(bool Flag) override { 73*7330f729Sjoerg Parent.setFoldFailureDiagnostic(Flag); 74*7330f729Sjoerg } hasPriorDiagnostic()75*7330f729Sjoerg bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); } 76*7330f729Sjoerg 77*7330f729Sjoerg /// Reports overflow and return true if evaluation should continue. 78*7330f729Sjoerg bool reportOverflow(const Expr *E, const llvm::APSInt &Value); 79*7330f729Sjoerg 80*7330f729Sjoerg /// Deallocates a pointer. 81*7330f729Sjoerg void deallocate(Block *B); 82*7330f729Sjoerg 83*7330f729Sjoerg /// Delegates source mapping to the mapper. getSource(Function * F,CodePtr PC)84*7330f729Sjoerg SourceInfo getSource(Function *F, CodePtr PC) const override { 85*7330f729Sjoerg return M ? M->getSource(F, PC) : F->getSource(PC); 86*7330f729Sjoerg } 87*7330f729Sjoerg 88*7330f729Sjoerg private: 89*7330f729Sjoerg /// AST Walker state. 90*7330f729Sjoerg State &Parent; 91*7330f729Sjoerg /// Dead block chain. 92*7330f729Sjoerg DeadBlock *DeadBlocks = nullptr; 93*7330f729Sjoerg /// Reference to the offset-source mapping. 94*7330f729Sjoerg SourceMapper *M; 95*7330f729Sjoerg 96*7330f729Sjoerg public: 97*7330f729Sjoerg /// Reference to the module containing all bytecode. 98*7330f729Sjoerg Program &P; 99*7330f729Sjoerg /// Temporary stack. 100*7330f729Sjoerg InterpStack &Stk; 101*7330f729Sjoerg /// Interpreter Context. 102*7330f729Sjoerg Context &Ctx; 103*7330f729Sjoerg /// The current frame. 104*7330f729Sjoerg InterpFrame *Current = nullptr; 105*7330f729Sjoerg /// Call stack depth. 106*7330f729Sjoerg unsigned CallStackDepth; 107*7330f729Sjoerg }; 108*7330f729Sjoerg 109*7330f729Sjoerg } // namespace interp 110*7330f729Sjoerg } // namespace clang 111*7330f729Sjoerg 112*7330f729Sjoerg #endif 113