Repository: llvm/llvm-project
File: clang/lib/AST/ByteCode/State.h (C/C++)

Code before:
  /// Evaluate as a constant expression. Stop if we find that the expression
  /// is not a constant expression. Some expressions can be retried in the
  /// optimizer if we don't constant fold them here, but in an unevaluated
  /// context we try to fold them immediately since the optimizer never
  /// gets a chance to look at it.
  ConstantExpressionUnevaluated,

  /// Fold the expression to a constant. Stop if we hit a side-effect that
  /// we can't model.
  ConstantFold,

  /// Evaluate in any way we know how. Don't worry about side-effects that
  /// can't be modeled.
  IgnoreSideEffects,
};

namespace interp {
class Frame;
class SourceInfo;

/// Interface for the VM to interact with the AST walker's context.
class State {
public:
  virtual ~State();

  virtual bool noteUndefinedBehavior() = 0;
  virtual bool keepEvaluatingAfterFailure() const = 0;
  virtual bool keepEvaluatingAfterSideEffect() const = 0;
  virtual Frame *getCurrentFrame() = 0;
  virtual const Frame *getBottomFrame() const = 0;
  virtual bool hasActiveDiagnostic() = 0;
  virtual void setActiveDiagnostic(bool Flag) = 0;
  virtual void setFoldFailureDiagnostic(bool Flag) = 0;
  virtual Expr::EvalStatus &getEvalStatus() const = 0;
  virtual ASTContext &getASTContext() const = 0;
  virtual bool hasPriorDiagnostic() = 0;
  virtual unsigned getCallStackDepth() = 0;
  virtual bool noteSideEffect() = 0;

  /// Are we checking whether the expression is a potential constant
  /// expression?
  bool checkingPotentialConstantExpression() const {
    return CheckingPotentialConstantExpression;
  }
  /// Are we checking an expression for overflow?
  bool checkingForUndefinedBehavior() const {
    return CheckingForUndefinedBehavior;
  }

public:
  State() = default;

Review comment (suggestion):
This was flagged by static analysis. it does not look like `EvalMode` is ever set anywhere but we definitely use it.

Code after:

  /// Evaluate as a constant expression. Stop if we find that the expression
  /// is not a constant expression. Some expressions can be retried in the
  /// optimizer if we don't constant fold them here, but in an unevaluated
  /// context we try to fold them immediately since the optimizer never
  /// gets a chance to look at it.
  ConstantExpressionUnevaluated,

  /// Fold the expression to a constant. Stop if we hit a side-effect that
  /// we can't model.
  ConstantFold,

  /// Evaluate in any way we know how. Don't worry about side-effects that
  /// can't be modeled.
  IgnoreSideEffects,
};

namespace interp {
class Frame;
class SourceInfo;

/// Interface for the VM to interact with the AST walker's context.
class State {
public:
  State(ASTContext &ASTCtx, Expr::EvalStatus &EvalStatus)
      : Ctx(ASTCtx), EvalStatus(EvalStatus) {}
  virtual ~State();

  virtual const Frame *getCurrentFrame() = 0;
  virtual const Frame *getBottomFrame() const = 0;
  virtual unsigned getCallStackDepth() = 0;
  virtual bool stepsLeft() const = 0;

  Expr::EvalStatus &getEvalStatus() const { return EvalStatus; }
  ASTContext &getASTContext() const { return Ctx; }
  const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }

  /// Note that we have had a side-effect, and determine whether we should
  /// keep evaluating.
  bool noteSideEffect() const {
    EvalStatus.HasSideEffects = true;
    return keepEvaluatingAfterSideEffect();
  }

  /// Should we continue evaluation as much as possible after encountering a
  /// construct which can't be reduced to a value?
  bool keepEvaluatingAfterFailure() const;
  /// Should we continue evaluation after encountering a side-effect that we
  /// couldn't model?
  bool keepEvaluatingAfterSideEffect() const;