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