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