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