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