xref: /freebsd/contrib/llvm-project/clang/lib/AST/Interp/InterpState.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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"
18a7dea167SDimitry Andric #include "InterpStack.h"
19a7dea167SDimitry Andric #include "State.h"
20a7dea167SDimitry Andric #include "clang/AST/APValue.h"
21a7dea167SDimitry Andric #include "clang/AST/ASTDiagnostic.h"
22a7dea167SDimitry Andric #include "clang/AST/Expr.h"
23a7dea167SDimitry Andric #include "clang/AST/OptionalDiagnostic.h"
24a7dea167SDimitry Andric 
25a7dea167SDimitry Andric namespace clang {
26a7dea167SDimitry Andric namespace interp {
27a7dea167SDimitry Andric class Context;
28a7dea167SDimitry Andric class Function;
29a7dea167SDimitry Andric class InterpStack;
30a7dea167SDimitry Andric class InterpFrame;
31a7dea167SDimitry Andric class SourceMapper;
32a7dea167SDimitry Andric 
33a7dea167SDimitry Andric /// Interpreter context.
34a7dea167SDimitry Andric class InterpState final : public State, public SourceMapper {
35a7dea167SDimitry Andric public:
36a7dea167SDimitry Andric   InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx,
37a7dea167SDimitry Andric               SourceMapper *M = nullptr);
38a7dea167SDimitry Andric 
39a7dea167SDimitry Andric   ~InterpState();
40a7dea167SDimitry Andric 
41a7dea167SDimitry Andric   // Stack frame accessors.
42a7dea167SDimitry Andric   Frame *getSplitFrame() { return Parent.getCurrentFrame(); }
43a7dea167SDimitry Andric   Frame *getCurrentFrame() override;
44a7dea167SDimitry Andric   unsigned getCallStackDepth() override { return CallStackDepth; }
45a7dea167SDimitry Andric   const Frame *getBottomFrame() const override {
46a7dea167SDimitry Andric     return Parent.getBottomFrame();
47a7dea167SDimitry Andric   }
48a7dea167SDimitry Andric 
49349cc55cSDimitry Andric   // Access objects from the walker context.
50a7dea167SDimitry Andric   Expr::EvalStatus &getEvalStatus() const override {
51a7dea167SDimitry Andric     return Parent.getEvalStatus();
52a7dea167SDimitry Andric   }
53a7dea167SDimitry Andric   ASTContext &getCtx() const override { return Parent.getCtx(); }
54a7dea167SDimitry Andric 
55a7dea167SDimitry Andric   // Forward status checks and updates to the walker.
56a7dea167SDimitry Andric   bool checkingForUndefinedBehavior() const override {
57a7dea167SDimitry Andric     return Parent.checkingForUndefinedBehavior();
58a7dea167SDimitry Andric   }
59a7dea167SDimitry Andric   bool keepEvaluatingAfterFailure() const override {
60a7dea167SDimitry Andric     return Parent.keepEvaluatingAfterFailure();
61a7dea167SDimitry Andric   }
62a7dea167SDimitry Andric   bool checkingPotentialConstantExpression() const override {
63a7dea167SDimitry Andric     return Parent.checkingPotentialConstantExpression();
64a7dea167SDimitry Andric   }
65a7dea167SDimitry Andric   bool noteUndefinedBehavior() override {
66a7dea167SDimitry Andric     return Parent.noteUndefinedBehavior();
67a7dea167SDimitry Andric   }
68*bdd1243dSDimitry Andric   bool inConstantContext() const { return Parent.InConstantContext; }
69a7dea167SDimitry Andric   bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); }
70a7dea167SDimitry Andric   void setActiveDiagnostic(bool Flag) override {
71a7dea167SDimitry Andric     Parent.setActiveDiagnostic(Flag);
72a7dea167SDimitry Andric   }
73a7dea167SDimitry Andric   void setFoldFailureDiagnostic(bool Flag) override {
74a7dea167SDimitry Andric     Parent.setFoldFailureDiagnostic(Flag);
75a7dea167SDimitry Andric   }
76a7dea167SDimitry Andric   bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); }
77a7dea167SDimitry Andric 
78a7dea167SDimitry Andric   /// Reports overflow and return true if evaluation should continue.
79a7dea167SDimitry Andric   bool reportOverflow(const Expr *E, const llvm::APSInt &Value);
80a7dea167SDimitry Andric 
81a7dea167SDimitry Andric   /// Deallocates a pointer.
82a7dea167SDimitry Andric   void deallocate(Block *B);
83a7dea167SDimitry Andric 
84a7dea167SDimitry Andric   /// Delegates source mapping to the mapper.
85*bdd1243dSDimitry Andric   SourceInfo getSource(const Function *F, CodePtr PC) const override {
86a7dea167SDimitry Andric     return M ? M->getSource(F, PC) : F->getSource(PC);
87a7dea167SDimitry Andric   }
88a7dea167SDimitry Andric 
89a7dea167SDimitry Andric private:
90a7dea167SDimitry Andric   /// AST Walker state.
91a7dea167SDimitry Andric   State &Parent;
92a7dea167SDimitry Andric   /// Dead block chain.
93a7dea167SDimitry Andric   DeadBlock *DeadBlocks = nullptr;
94a7dea167SDimitry Andric   /// Reference to the offset-source mapping.
95a7dea167SDimitry Andric   SourceMapper *M;
96a7dea167SDimitry Andric 
97a7dea167SDimitry Andric public:
98a7dea167SDimitry Andric   /// Reference to the module containing all bytecode.
99a7dea167SDimitry Andric   Program &P;
100a7dea167SDimitry Andric   /// Temporary stack.
101a7dea167SDimitry Andric   InterpStack &Stk;
102a7dea167SDimitry Andric   /// Interpreter Context.
103a7dea167SDimitry Andric   Context &Ctx;
104a7dea167SDimitry Andric   /// The current frame.
105a7dea167SDimitry Andric   InterpFrame *Current = nullptr;
106a7dea167SDimitry Andric   /// Call stack depth.
107a7dea167SDimitry Andric   unsigned CallStackDepth;
108a7dea167SDimitry Andric };
109a7dea167SDimitry Andric 
110a7dea167SDimitry Andric } // namespace interp
111a7dea167SDimitry Andric } // namespace clang
112a7dea167SDimitry Andric 
113a7dea167SDimitry Andric #endif
114