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 
26 namespace clang {
27 namespace interp {
28 class Context;
29 class Function;
30 class InterpStack;
31 class InterpFrame;
32 class SourceMapper;
33 
34 /// Interpreter context.
35 class InterpState final : public State, public SourceMapper {
36 public:
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.
getSplitFrame()46   Frame *getSplitFrame() { return Parent.getCurrentFrame(); }
47   Frame *getCurrentFrame() override;
getCallStackDepth()48   unsigned getCallStackDepth() override {
49     return Current ? (Current->getDepth() + 1) : 1;
50   }
getBottomFrame()51   const Frame *getBottomFrame() const override {
52     return Parent.getBottomFrame();
53   }
54 
55   // Access objects from the walker context.
getEvalStatus()56   Expr::EvalStatus &getEvalStatus() const override {
57     return Parent.getEvalStatus();
58   }
getCtx()59   ASTContext &getCtx() const override { return Parent.getCtx(); }
60 
61   // Forward status checks and updates to the walker.
checkingForUndefinedBehavior()62   bool checkingForUndefinedBehavior() const override {
63     return Parent.checkingForUndefinedBehavior();
64   }
keepEvaluatingAfterFailure()65   bool keepEvaluatingAfterFailure() const override {
66     return Parent.keepEvaluatingAfterFailure();
67   }
checkingPotentialConstantExpression()68   bool checkingPotentialConstantExpression() const override {
69     return Parent.checkingPotentialConstantExpression();
70   }
noteUndefinedBehavior()71   bool noteUndefinedBehavior() override {
72     return Parent.noteUndefinedBehavior();
73   }
inConstantContext()74   bool inConstantContext() const { return Parent.InConstantContext; }
hasActiveDiagnostic()75   bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); }
setActiveDiagnostic(bool Flag)76   void setActiveDiagnostic(bool Flag) override {
77     Parent.setActiveDiagnostic(Flag);
78   }
setFoldFailureDiagnostic(bool Flag)79   void setFoldFailureDiagnostic(bool Flag) override {
80     Parent.setFoldFailureDiagnostic(Flag);
81   }
hasPriorDiagnostic()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.
getSource(const Function * F,CodePtr PC)91   SourceInfo getSource(const Function *F, CodePtr PC) const override {
92     return M ? M->getSource(F, PC) : F->getSource(PC);
93   }
94 
getContext()95   Context &getContext() const { return Ctx; }
96 
97 private:
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 
105 public:
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