xref: /freebsd/contrib/llvm-project/clang/lib/AST/Interp/InterpState.h (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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 
27 namespace clang {
28 namespace interp {
29 class Context;
30 class Function;
31 class InterpStack;
32 class InterpFrame;
33 class SourceMapper;
34 
35 /// Interpreter context.
36 class InterpState final : public State, public SourceMapper {
37 public:
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 
113 private:
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 
124 public:
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