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

Code before:
  State(ASTContext &ASTCtx, Expr::EvalStatus &EvalStatus)
      : Ctx(ASTCtx), EvalStatus(EvalStatus) {}
  virtual ~State();

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

  Expr::EvalStatus &getEvalStatus() const { return EvalStatus; }

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

  // If we have a prior diagnostic, it will be noting that the expression
  // isn't a constant expression. This diagnostic is more important,
  // unless we require this evaluation to produce a constant expression.
  //
  // FIXME: We might want to show both diagnostics to the user in
  // EvaluationMode::ConstantFold mode.

  bool hasPriorDiagnostic() {
    if (!getEvalStatus().Diag->empty()) {
      switch (EvalMode) {
      case EvaluationMode::ConstantFold:
      case EvaluationMode::IgnoreSideEffects:
        if (!HasFoldFailureDiagnostic)
          break;
        // We've already failed to fold something. Keep that diagnostic.
        [[fallthrough]];
      case EvaluationMode::ConstantExpression:
      case EvaluationMode::ConstantExpressionUnevaluated:
        setActiveDiagnostic(false);
        return true;
      }
    }
    return false;
  }

  /// 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 {
    switch (EvalMode) {
    case EvaluationMode::IgnoreSideEffects:

Review comment (suggestion):
I feel like this and `keepEvaluatingAfterSideEffect()` should be in the cpp file instead since they're a bit longer, but the rest lgtm

Code after:
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;

  /// Note that we hit something that was technically undefined behavior, but
  /// that we can evaluate past it (such as signed overflow or floating-point
  /// division by zero.)
  bool noteUndefinedBehavior() const {
    EvalStatus.HasUndefinedBehavior = true;
    return keepEvaluatingAfterUndefinedBehavior();
  }

  /// 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;
  }

  /// Diagnose that the evaluation could not be folded (FF => FoldFailure)
  OptionalDiagnostic
  FFDiag(SourceLocation Loc,
         diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,