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