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