1 //===--- State.h - State chain for the VM and AST Walker --------*- 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 // Defines the base class of the interpreter and evaluator state. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_AST_INTERP_STATE_H 14 #define LLVM_CLANG_AST_INTERP_STATE_H 15 16 #include "clang/AST/ASTDiagnostic.h" 17 #include "clang/AST/Expr.h" 18 #include "clang/AST/OptionalDiagnostic.h" 19 20 namespace clang { 21 22 /// Kinds of access we can perform on an object, for diagnostics. Note that 23 /// we consider a member function call to be a kind of access, even though 24 /// it is not formally an access of the object, because it has (largely) the 25 /// same set of semantic restrictions. 26 enum AccessKinds { 27 AK_Read, 28 AK_ReadObjectRepresentation, 29 AK_Assign, 30 AK_Increment, 31 AK_Decrement, 32 AK_MemberCall, 33 AK_DynamicCast, 34 AK_TypeId, 35 AK_Construct, 36 AK_Destroy, 37 }; 38 39 // The order of this enum is important for diagnostics. 40 enum CheckSubobjectKind { 41 CSK_Base, 42 CSK_Derived, 43 CSK_Field, 44 CSK_ArrayToPointer, 45 CSK_ArrayIndex, 46 CSK_Real, 47 CSK_Imag 48 }; 49 50 namespace interp { 51 class Frame; 52 class SourceInfo; 53 54 /// Interface for the VM to interact with the AST walker's context. 55 class State { 56 public: 57 virtual ~State(); 58 59 virtual bool checkingForUndefinedBehavior() const = 0; 60 virtual bool checkingPotentialConstantExpression() const = 0; 61 virtual bool noteUndefinedBehavior() = 0; 62 virtual bool keepEvaluatingAfterFailure() const = 0; 63 virtual Frame *getCurrentFrame() = 0; 64 virtual const Frame *getBottomFrame() const = 0; 65 virtual bool hasActiveDiagnostic() = 0; 66 virtual void setActiveDiagnostic(bool Flag) = 0; 67 virtual void setFoldFailureDiagnostic(bool Flag) = 0; 68 virtual Expr::EvalStatus &getEvalStatus() const = 0; 69 virtual ASTContext &getCtx() const = 0; 70 virtual bool hasPriorDiagnostic() = 0; 71 virtual unsigned getCallStackDepth() = 0; 72 73 public: 74 // Diagnose that the evaluation could not be folded (FF => FoldFailure) 75 OptionalDiagnostic 76 FFDiag(SourceLocation Loc, 77 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, 78 unsigned ExtraNotes = 0); 79 80 OptionalDiagnostic 81 FFDiag(const Expr *E, 82 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, 83 unsigned ExtraNotes = 0); 84 85 OptionalDiagnostic 86 FFDiag(const SourceInfo &SI, 87 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, 88 unsigned ExtraNotes = 0); 89 90 /// Diagnose that the evaluation does not produce a C++11 core constant 91 /// expression. 92 /// 93 /// FIXME: Stop evaluating if we're in EM_ConstantExpression or 94 /// EM_PotentialConstantExpression mode and we produce one of these. 95 OptionalDiagnostic 96 CCEDiag(SourceLocation Loc, 97 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, 98 unsigned ExtraNotes = 0); 99 100 OptionalDiagnostic 101 CCEDiag(const Expr *E, 102 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, 103 unsigned ExtraNotes = 0); 104 105 OptionalDiagnostic 106 CCEDiag(const SourceInfo &SI, 107 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, 108 unsigned ExtraNotes = 0); 109 110 /// Add a note to a prior diagnostic. 111 OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId); 112 113 /// Add a stack of notes to a prior diagnostic. 114 void addNotes(ArrayRef<PartialDiagnosticAt> Diags); 115 116 /// Directly reports a diagnostic message. 117 DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId); 118 119 const LangOptions &getLangOpts() const; 120 121 private: 122 void addCallStack(unsigned Limit); 123 124 PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId); 125 126 OptionalDiagnostic diag(SourceLocation Loc, diag::kind DiagId, 127 unsigned ExtraNotes, bool IsCCEDiag); 128 }; 129 130 } // namespace interp 131 } // namespace clang 132 133 #endif 134