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