brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 0695c61 Raw
186 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// Defines the base class of the interpreter and evaluator state.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_AST_INTERP_STATE_H14#define LLVM_CLANG_AST_INTERP_STATE_H15 16#include "clang/AST/ASTDiagnostic.h"17#include "clang/AST/Expr.h"18 19namespace clang {20class OptionalDiagnostic;21 22/// Kinds of access we can perform on an object, for diagnostics. Note that23/// we consider a member function call to be a kind of access, even though24/// it is not formally an access of the object, because it has (largely) the25/// same set of semantic restrictions.26enum 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  AK_IsWithinLifetime,38  AK_Dereference39};40 41/// The order of this enum is important for diagnostics.42enum CheckSubobjectKind {43  CSK_Base,44  CSK_Derived,45  CSK_Field,46  CSK_ArrayToPointer,47  CSK_ArrayIndex,48  CSK_Real,49  CSK_Imag,50  CSK_VectorElement51};52 53enum class EvaluationMode {54  /// Evaluate as a constant expression. Stop if we find that the expression55  /// is not a constant expression.56  ConstantExpression,57 58  /// Evaluate as a constant expression. Stop if we find that the expression59  /// is not a constant expression. Some expressions can be retried in the60  /// optimizer if we don't constant fold them here, but in an unevaluated61  /// context we try to fold them immediately since the optimizer never62  /// gets a chance to look at it.63  ConstantExpressionUnevaluated,64 65  /// Fold the expression to a constant. Stop if we hit a side-effect that66  /// we can't model.67  ConstantFold,68 69  /// Evaluate in any way we know how. Don't worry about side-effects that70  /// can't be modeled.71  IgnoreSideEffects,72};73 74namespace interp {75class Frame;76class SourceInfo;77 78/// Interface for the VM to interact with the AST walker's context.79class State {80public:81  virtual ~State();82 83  virtual bool noteUndefinedBehavior() = 0;84  virtual bool keepEvaluatingAfterFailure() const = 0;85  virtual bool keepEvaluatingAfterSideEffect() const = 0;86  virtual Frame *getCurrentFrame() = 0;87  virtual const Frame *getBottomFrame() const = 0;88  virtual bool hasActiveDiagnostic() = 0;89  virtual void setActiveDiagnostic(bool Flag) = 0;90  virtual void setFoldFailureDiagnostic(bool Flag) = 0;91  virtual Expr::EvalStatus &getEvalStatus() const = 0;92  virtual ASTContext &getASTContext() const = 0;93  virtual bool hasPriorDiagnostic() = 0;94  virtual unsigned getCallStackDepth() = 0;95  virtual bool noteSideEffect() = 0;96 97  /// Are we checking whether the expression is a potential constant98  /// expression?99  bool checkingPotentialConstantExpression() const {100    return CheckingPotentialConstantExpression;101  }102  /// Are we checking an expression for overflow?103  bool checkingForUndefinedBehavior() const {104    return CheckingForUndefinedBehavior;105  }106 107public:108  State() = default;109  /// Diagnose that the evaluation could not be folded (FF => FoldFailure)110  OptionalDiagnostic111  FFDiag(SourceLocation Loc,112         diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,113         unsigned ExtraNotes = 0);114 115  OptionalDiagnostic116  FFDiag(const Expr *E,117         diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,118         unsigned ExtraNotes = 0);119 120  OptionalDiagnostic121  FFDiag(const SourceInfo &SI,122         diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,123         unsigned ExtraNotes = 0);124 125  /// Diagnose that the evaluation does not produce a C++11 core constant126  /// expression.127  ///128  /// FIXME: Stop evaluating if we're in EM_ConstantExpression or129  /// EM_PotentialConstantExpression mode and we produce one of these.130  OptionalDiagnostic131  CCEDiag(SourceLocation Loc,132          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,133          unsigned ExtraNotes = 0);134 135  OptionalDiagnostic136  CCEDiag(const Expr *E,137          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,138          unsigned ExtraNotes = 0);139 140  OptionalDiagnostic141  CCEDiag(const SourceInfo &SI,142          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,143          unsigned ExtraNotes = 0);144 145  /// Add a note to a prior diagnostic.146  OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId);147 148  /// Add a stack of notes to a prior diagnostic.149  void addNotes(ArrayRef<PartialDiagnosticAt> Diags);150 151  /// Directly reports a diagnostic message.152  DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId);153 154  /// Whether or not we're in a context where the front end requires a155  /// constant value.156  bool InConstantContext = false;157 158  /// Whether we're checking that an expression is a potential constant159  /// expression. If so, do not fail on constructs that could become constant160  /// later on (such as a use of an undefined global).161  bool CheckingPotentialConstantExpression = false;162 163  /// Whether we're checking for an expression that has undefined behavior.164  /// If so, we will produce warnings if we encounter an operation that is165  /// always undefined.166  ///167  /// Note that we still need to evaluate the expression normally when this168  /// is set; this is used when evaluating ICEs in C.169  bool CheckingForUndefinedBehavior = false;170 171  EvaluationMode EvalMode;172 173private:174  void addCallStack(unsigned Limit);175 176  PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId);177 178  OptionalDiagnostic diag(SourceLocation Loc, diag::kind DiagId,179                          unsigned ExtraNotes, bool IsCCEDiag);180};181 182} // namespace interp183} // namespace clang184 185#endif186