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