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