xref: /freebsd/contrib/llvm-project/clang/lib/AST/Interp/InterpState.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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"
1806c3fb27SDimitry 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 
42*5f757f3fSDimitry Andric   InterpState(const InterpState &) = delete;
43*5f757f3fSDimitry Andric   InterpState &operator=(const InterpState &) = delete;
44*5f757f3fSDimitry Andric 
45a7dea167SDimitry Andric   // Stack frame accessors.
46a7dea167SDimitry Andric   Frame *getSplitFrame() { return Parent.getCurrentFrame(); }
47a7dea167SDimitry Andric   Frame *getCurrentFrame() override;
4806c3fb27SDimitry Andric   unsigned getCallStackDepth() override {
4906c3fb27SDimitry Andric     return Current ? (Current->getDepth() + 1) : 1;
5006c3fb27SDimitry Andric   }
51a7dea167SDimitry Andric   const Frame *getBottomFrame() const override {
52a7dea167SDimitry Andric     return Parent.getBottomFrame();
53a7dea167SDimitry Andric   }
54a7dea167SDimitry Andric 
55349cc55cSDimitry Andric   // Access objects from the walker context.
56a7dea167SDimitry Andric   Expr::EvalStatus &getEvalStatus() const override {
57a7dea167SDimitry Andric     return Parent.getEvalStatus();
58a7dea167SDimitry Andric   }
59a7dea167SDimitry Andric   ASTContext &getCtx() const override { return Parent.getCtx(); }
60a7dea167SDimitry Andric 
61a7dea167SDimitry Andric   // Forward status checks and updates to the walker.
62a7dea167SDimitry Andric   bool checkingForUndefinedBehavior() const override {
63a7dea167SDimitry Andric     return Parent.checkingForUndefinedBehavior();
64a7dea167SDimitry Andric   }
65a7dea167SDimitry Andric   bool keepEvaluatingAfterFailure() const override {
66a7dea167SDimitry Andric     return Parent.keepEvaluatingAfterFailure();
67a7dea167SDimitry Andric   }
68a7dea167SDimitry Andric   bool checkingPotentialConstantExpression() const override {
69a7dea167SDimitry Andric     return Parent.checkingPotentialConstantExpression();
70a7dea167SDimitry Andric   }
71a7dea167SDimitry Andric   bool noteUndefinedBehavior() override {
72a7dea167SDimitry Andric     return Parent.noteUndefinedBehavior();
73a7dea167SDimitry Andric   }
74bdd1243dSDimitry Andric   bool inConstantContext() const { return Parent.InConstantContext; }
75a7dea167SDimitry Andric   bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); }
76a7dea167SDimitry Andric   void setActiveDiagnostic(bool Flag) override {
77a7dea167SDimitry Andric     Parent.setActiveDiagnostic(Flag);
78a7dea167SDimitry Andric   }
79a7dea167SDimitry Andric   void setFoldFailureDiagnostic(bool Flag) override {
80a7dea167SDimitry Andric     Parent.setFoldFailureDiagnostic(Flag);
81a7dea167SDimitry Andric   }
82a7dea167SDimitry Andric   bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); }
83a7dea167SDimitry Andric 
84a7dea167SDimitry Andric   /// Reports overflow and return true if evaluation should continue.
85a7dea167SDimitry Andric   bool reportOverflow(const Expr *E, const llvm::APSInt &Value);
86a7dea167SDimitry Andric 
87a7dea167SDimitry Andric   /// Deallocates a pointer.
88a7dea167SDimitry Andric   void deallocate(Block *B);
89a7dea167SDimitry Andric 
90a7dea167SDimitry Andric   /// Delegates source mapping to the mapper.
91bdd1243dSDimitry Andric   SourceInfo getSource(const Function *F, CodePtr PC) const override {
92a7dea167SDimitry Andric     return M ? M->getSource(F, PC) : F->getSource(PC);
93a7dea167SDimitry Andric   }
94a7dea167SDimitry Andric 
9506c3fb27SDimitry Andric   Context &getContext() const { return Ctx; }
9606c3fb27SDimitry Andric 
97a7dea167SDimitry Andric private:
98a7dea167SDimitry Andric   /// AST Walker state.
99a7dea167SDimitry Andric   State &Parent;
100a7dea167SDimitry Andric   /// Dead block chain.
101a7dea167SDimitry Andric   DeadBlock *DeadBlocks = nullptr;
102a7dea167SDimitry Andric   /// Reference to the offset-source mapping.
103a7dea167SDimitry Andric   SourceMapper *M;
104a7dea167SDimitry Andric 
105a7dea167SDimitry Andric public:
106a7dea167SDimitry Andric   /// Reference to the module containing all bytecode.
107a7dea167SDimitry Andric   Program &P;
108a7dea167SDimitry Andric   /// Temporary stack.
109a7dea167SDimitry Andric   InterpStack &Stk;
110a7dea167SDimitry Andric   /// Interpreter Context.
111a7dea167SDimitry Andric   Context &Ctx;
112a7dea167SDimitry Andric   /// The current frame.
113a7dea167SDimitry Andric   InterpFrame *Current = nullptr;
114a7dea167SDimitry Andric };
115a7dea167SDimitry Andric 
116a7dea167SDimitry Andric } // namespace interp
117a7dea167SDimitry Andric } // namespace clang
118a7dea167SDimitry Andric 
119a7dea167SDimitry Andric #endif
120