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