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 "DynamicAllocator.h"
18#include "Function.h"
19#include "InterpFrame.h"
20#include "InterpStack.h"
21#include "State.h"
22#include "clang/AST/APValue.h"
23#include "clang/AST/ASTDiagnostic.h"
24#include "clang/AST/Expr.h"
25#include "clang/AST/OptionalDiagnostic.h"
26
27namespace clang {
28namespace interp {
29class Context;
30class Function;
31class InterpStack;
32class InterpFrame;
33class SourceMapper;
34
35/// Interpreter context.
36class InterpState final : public State, public SourceMapper {
37public:
38 InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx,
39 SourceMapper *M = nullptr);
40
41 ~InterpState();
42
43 void cleanup();
44
45 InterpState(const InterpState &) = delete;
46 InterpState &operator=(const InterpState &) = delete;
47
48 // Stack frame accessors.
49 Frame *getSplitFrame() { return Parent.getCurrentFrame(); }
50 Frame *getCurrentFrame() override;
51 unsigned getCallStackDepth() override {
52 return Current ? (Current->getDepth() + 1) : 1;
53 }
54 const Frame *getBottomFrame() const override {
55 return Parent.getBottomFrame();
56 }
57
58 // Access objects from the walker context.
59 Expr::EvalStatus &getEvalStatus() const override {
60 return Parent.getEvalStatus();
61 }
62 ASTContext &getCtx() const override { return Parent.getCtx(); }
63
64 // Forward status checks and updates to the walker.
65 bool checkingForUndefinedBehavior() const override {
66 return Parent.checkingForUndefinedBehavior();
67 }
68 bool keepEvaluatingAfterFailure() const override {
69 return Parent.keepEvaluatingAfterFailure();
70 }
71 bool checkingPotentialConstantExpression() const override {
72 return Parent.checkingPotentialConstantExpression();
73 }
74 bool noteUndefinedBehavior() override {
75 return Parent.noteUndefinedBehavior();
76 }
77 bool inConstantContext() const { return Parent.InConstantContext; }
78 bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); }
79 void setActiveDiagnostic(bool Flag) override {
80 Parent.setActiveDiagnostic(Flag);
81 }
82 void setFoldFailureDiagnostic(bool Flag) override {
83 Parent.setFoldFailureDiagnostic(Flag);
84 }
85 bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); }
86
87 /// Reports overflow and return true if evaluation should continue.
88 bool reportOverflow(const Expr *E, const llvm::APSInt &Value);
89
90 /// Deallocates a pointer.
91 void deallocate(Block *B);
92
93 /// Delegates source mapping to the mapper.
94 SourceInfo getSource(const Function *F, CodePtr PC) const override {
95 if (M)
96 return M->getSource(F, PC);
97
98 assert(F && "Function cannot be null");
99 return F->getSource(PC);
100 }
101
102 Context &getContext() const { return Ctx; }
103
104 void setEvalLocation(SourceLocation SL) { this->EvalLocation = SL; }
105
106 DynamicAllocator &getAllocator() { return Alloc; }
107
108 /// Diagnose any dynamic allocations that haven't been freed yet.
109 /// Will return \c false if there were any allocations to diagnose,
110 /// \c true otherwise.
111 bool maybeDiagnoseDanglingAllocations();
112
113private:
114 friend class EvaluationResult;
115 /// AST Walker state.
116 State &Parent;
117 /// Dead block chain.
118 DeadBlock *DeadBlocks = nullptr;
119 /// Reference to the offset-source mapping.
120 SourceMapper *M;
121 /// Allocator used for dynamic allocations performed via the program.
122 DynamicAllocator Alloc;
123
124public:
125 /// Reference to the module containing all bytecode.
126 Program &P;
127 /// Temporary stack.
128 InterpStack &Stk;
129 /// Interpreter Context.
130 Context &Ctx;
131 /// The current frame.
132 InterpFrame *Current = nullptr;
133 /// Source location of the evaluating expression
134 SourceLocation EvalLocation;
135 /// Declaration we're initializing/evaluting, if any.
136 const VarDecl *EvaluatingDecl = nullptr;
137
138 llvm::SmallVector<
139 std::pair<const Expr *, const LifetimeExtendedTemporaryDecl *>>
140 SeenGlobalTemporaries;
141};
142
143} // namespace interp
144} // namespace clang
145
146#endif
147