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