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