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