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 26namespace clang { 27namespace interp { 28class Context; 29class Function; 30class InterpStack; 31class InterpFrame; 32class SourceMapper; 33 34/// Interpreter context. 35class InterpState final : public State, public SourceMapper { 36public: 37 InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, 38 SourceMapper *M = nullptr); 39 40 ~InterpState(); 41 42 InterpState(const InterpState &) = delete; 43 InterpState &operator=(const InterpState &) = delete; 44 45 // Stack frame accessors. 46 Frame *getSplitFrame() { return Parent.getCurrentFrame(); } 47 Frame *getCurrentFrame() override; 48 unsigned getCallStackDepth() override { 49 return Current ? (Current->getDepth() + 1) : 1; 50 } 51 const Frame *getBottomFrame() const override { 52 return Parent.getBottomFrame(); 53 } 54 55 // Access objects from the walker context. 56 Expr::EvalStatus &getEvalStatus() const override { 57 return Parent.getEvalStatus(); 58 } 59 ASTContext &getCtx() const override { return Parent.getCtx(); } 60 61 // Forward status checks and updates to the walker. 62 bool checkingForUndefinedBehavior() const override { 63 return Parent.checkingForUndefinedBehavior(); 64 } 65 bool keepEvaluatingAfterFailure() const override { 66 return Parent.keepEvaluatingAfterFailure(); 67 } 68 bool checkingPotentialConstantExpression() const override { 69 return Parent.checkingPotentialConstantExpression(); 70 } 71 bool noteUndefinedBehavior() override { 72 return Parent.noteUndefinedBehavior(); 73 } 74 bool inConstantContext() const { return Parent.InConstantContext; } 75 bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); } 76 void setActiveDiagnostic(bool Flag) override { 77 Parent.setActiveDiagnostic(Flag); 78 } 79 void setFoldFailureDiagnostic(bool Flag) override { 80 Parent.setFoldFailureDiagnostic(Flag); 81 } 82 bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); } 83 84 /// Reports overflow and return true if evaluation should continue. 85 bool reportOverflow(const Expr *E, const llvm::APSInt &Value); 86 87 /// Deallocates a pointer. 88 void deallocate(Block *B); 89 90 /// Delegates source mapping to the mapper. 91 SourceInfo getSource(const Function *F, CodePtr PC) const override { 92 return M ? M->getSource(F, PC) : F->getSource(PC); 93 } 94 95 Context &getContext() const { return Ctx; } 96 97private: 98 /// AST Walker state. 99 State &Parent; 100 /// Dead block chain. 101 DeadBlock *DeadBlocks = nullptr; 102 /// Reference to the offset-source mapping. 103 SourceMapper *M; 104 105public: 106 /// Reference to the module containing all bytecode. 107 Program &P; 108 /// Temporary stack. 109 InterpStack &Stk; 110 /// Interpreter Context. 111 Context &Ctx; 112 /// The current frame. 113 InterpFrame *Current = nullptr; 114}; 115 116} // namespace interp 117} // namespace clang 118 119#endif 120