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   // Access 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 inConstantContext() const { return Parent.InConstantContext; }
69   bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); }
70   void setActiveDiagnostic(bool Flag) override {
71     Parent.setActiveDiagnostic(Flag);
72   }
73   void setFoldFailureDiagnostic(bool Flag) override {
74     Parent.setFoldFailureDiagnostic(Flag);
75   }
76   bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); }
77 
78   /// Reports overflow and return true if evaluation should continue.
79   bool reportOverflow(const Expr *E, const llvm::APSInt &Value);
80 
81   /// Deallocates a pointer.
82   void deallocate(Block *B);
83 
84   /// Delegates source mapping to the mapper.
85   SourceInfo getSource(const Function *F, CodePtr PC) const override {
86     return M ? M->getSource(F, PC) : F->getSource(PC);
87   }
88 
89 private:
90   /// AST Walker state.
91   State &Parent;
92   /// Dead block chain.
93   DeadBlock *DeadBlocks = nullptr;
94   /// Reference to the offset-source mapping.
95   SourceMapper *M;
96 
97 public:
98   /// Reference to the module containing all bytecode.
99   Program &P;
100   /// Temporary stack.
101   InterpStack &Stk;
102   /// Interpreter Context.
103   Context &Ctx;
104   /// The current frame.
105   InterpFrame *Current = nullptr;
106   /// Call stack depth.
107   unsigned CallStackDepth;
108 };
109 
110 } // namespace interp
111 } // namespace clang
112 
113 #endif
114