Skip to content

Commit 30f9fb7

Browse files
authored
[clang][ExprConst][NFC] Move EvalMode enum to State (#157988)
Make it an enum class and move the enum to State.h as well as the `EvalMode` member to `State`. This is in preparation of using the evaluation mode from `InterpState` as well.
1 parent b4c98fc commit 30f9fb7

File tree

2 files changed

+75
-70
lines changed

2 files changed

+75
-70
lines changed

clang/lib/AST/ByteCode/State.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,27 @@ enum CheckSubobjectKind {
5050
CSK_VectorElement
5151
};
5252

53+
enum class EvaluationMode {
54+
/// Evaluate as a constant expression. Stop if we find that the expression
55+
/// is not a constant expression.
56+
ConstantExpression,
57+
58+
/// Evaluate as a constant expression. Stop if we find that the expression
59+
/// is not a constant expression. Some expressions can be retried in the
60+
/// optimizer if we don't constant fold them here, but in an unevaluated
61+
/// context we try to fold them immediately since the optimizer never
62+
/// gets a chance to look at it.
63+
ConstantExpressionUnevaluated,
64+
65+
/// Fold the expression to a constant. Stop if we hit a side-effect that
66+
/// we can't model.
67+
ConstantFold,
68+
69+
/// Evaluate in any way we know how. Don't worry about side-effects that
70+
/// can't be modeled.
71+
IgnoreSideEffects,
72+
};
73+
5374
namespace interp {
5475
class Frame;
5576
class SourceInfo;
@@ -149,6 +170,8 @@ class State {
149170
/// is set; this is used when evaluating ICEs in C.
150171
bool CheckingForUndefinedBehavior = false;
151172

173+
EvaluationMode EvalMode;
174+
152175
private:
153176
void addCallStack(unsigned Limit);
154177

clang/lib/AST/ExprConstant.cpp

Lines changed: 52 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -926,27 +926,6 @@ namespace {
926926
/// fold (not just why it's not strictly a constant expression)?
927927
bool HasFoldFailureDiagnostic;
928928

929-
enum EvaluationMode {
930-
/// Evaluate as a constant expression. Stop if we find that the expression
931-
/// is not a constant expression.
932-
EM_ConstantExpression,
933-
934-
/// Evaluate as a constant expression. Stop if we find that the expression
935-
/// is not a constant expression. Some expressions can be retried in the
936-
/// optimizer if we don't constant fold them here, but in an unevaluated
937-
/// context we try to fold them immediately since the optimizer never
938-
/// gets a chance to look at it.
939-
EM_ConstantExpressionUnevaluated,
940-
941-
/// Fold the expression to a constant. Stop if we hit a side-effect that
942-
/// we can't model.
943-
EM_ConstantFold,
944-
945-
/// Evaluate in any way we know how. Don't worry about side-effects that
946-
/// can't be modeled.
947-
EM_IgnoreSideEffects,
948-
} EvalMode;
949-
950929
EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
951930
: Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
952931
CallStackDepth(0), NextCallIndex(1),
@@ -957,7 +936,9 @@ namespace {
957936
/*CallExpr=*/nullptr, CallRef()),
958937
EvaluatingDecl((const ValueDecl *)nullptr),
959938
EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
960-
HasFoldFailureDiagnostic(false), EvalMode(Mode) {}
939+
HasFoldFailureDiagnostic(false) {
940+
EvalMode = Mode;
941+
}
961942

962943
~EvalInfo() {
963944
discardCleanups();
@@ -1132,18 +1113,18 @@ namespace {
11321113
// unless we require this evaluation to produce a constant expression.
11331114
//
11341115
// FIXME: We might want to show both diagnostics to the user in
1135-
// EM_ConstantFold mode.
1116+
// EvaluationMode::ConstantFold mode.
11361117
bool hasPriorDiagnostic() override {
11371118
if (!EvalStatus.Diag->empty()) {
11381119
switch (EvalMode) {
1139-
case EM_ConstantFold:
1140-
case EM_IgnoreSideEffects:
1120+
case EvaluationMode::ConstantFold:
1121+
case EvaluationMode::IgnoreSideEffects:
11411122
if (!HasFoldFailureDiagnostic)
11421123
break;
11431124
// We've already failed to fold something. Keep that diagnostic.
11441125
[[fallthrough]];
1145-
case EM_ConstantExpression:
1146-
case EM_ConstantExpressionUnevaluated:
1126+
case EvaluationMode::ConstantExpression:
1127+
case EvaluationMode::ConstantExpressionUnevaluated:
11471128
setActiveDiagnostic(false);
11481129
return true;
11491130
}
@@ -1158,12 +1139,12 @@ namespace {
11581139
/// couldn't model?
11591140
bool keepEvaluatingAfterSideEffect() const override {
11601141
switch (EvalMode) {
1161-
case EM_IgnoreSideEffects:
1142+
case EvaluationMode::IgnoreSideEffects:
11621143
return true;
11631144

1164-
case EM_ConstantExpression:
1165-
case EM_ConstantExpressionUnevaluated:
1166-
case EM_ConstantFold:
1145+
case EvaluationMode::ConstantExpression:
1146+
case EvaluationMode::ConstantExpressionUnevaluated:
1147+
case EvaluationMode::ConstantFold:
11671148
// By default, assume any side effect might be valid in some other
11681149
// evaluation of this expression from a different context.
11691150
return checkingPotentialConstantExpression() ||
@@ -1182,12 +1163,12 @@ namespace {
11821163
/// Should we continue evaluation after encountering undefined behavior?
11831164
bool keepEvaluatingAfterUndefinedBehavior() {
11841165
switch (EvalMode) {
1185-
case EM_IgnoreSideEffects:
1186-
case EM_ConstantFold:
1166+
case EvaluationMode::IgnoreSideEffects:
1167+
case EvaluationMode::ConstantFold:
11871168
return true;
11881169

1189-
case EM_ConstantExpression:
1190-
case EM_ConstantExpressionUnevaluated:
1170+
case EvaluationMode::ConstantExpression:
1171+
case EvaluationMode::ConstantExpressionUnevaluated:
11911172
return checkingForUndefinedBehavior();
11921173
}
11931174
llvm_unreachable("Missed EvalMode case");
@@ -1208,10 +1189,10 @@ namespace {
12081189
return false;
12091190

12101191
switch (EvalMode) {
1211-
case EM_ConstantExpression:
1212-
case EM_ConstantExpressionUnevaluated:
1213-
case EM_ConstantFold:
1214-
case EM_IgnoreSideEffects:
1192+
case EvaluationMode::ConstantExpression:
1193+
case EvaluationMode::ConstantExpressionUnevaluated:
1194+
case EvaluationMode::ConstantFold:
1195+
case EvaluationMode::IgnoreSideEffects:
12151196
return checkingPotentialConstantExpression() ||
12161197
checkingForUndefinedBehavior();
12171198
}
@@ -1261,7 +1242,7 @@ namespace {
12611242
EvalInfo &Info;
12621243
bool Enabled;
12631244
bool HadNoPriorDiags;
1264-
EvalInfo::EvaluationMode OldMode;
1245+
EvaluationMode OldMode;
12651246

12661247
explicit FoldConstant(EvalInfo &Info, bool Enabled)
12671248
: Info(Info),
@@ -1271,7 +1252,7 @@ namespace {
12711252
!Info.EvalStatus.HasSideEffects),
12721253
OldMode(Info.EvalMode) {
12731254
if (Enabled)
1274-
Info.EvalMode = EvalInfo::EM_ConstantFold;
1255+
Info.EvalMode = EvaluationMode::ConstantFold;
12751256
}
12761257
void keepDiagnostics() { Enabled = false; }
12771258
~FoldConstant() {
@@ -1286,10 +1267,10 @@ namespace {
12861267
/// side-effects.
12871268
struct IgnoreSideEffectsRAII {
12881269
EvalInfo &Info;
1289-
EvalInfo::EvaluationMode OldMode;
1270+
EvaluationMode OldMode;
12901271
explicit IgnoreSideEffectsRAII(EvalInfo &Info)
12911272
: Info(Info), OldMode(Info.EvalMode) {
1292-
Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1273+
Info.EvalMode = EvaluationMode::IgnoreSideEffects;
12931274
}
12941275

12951276
~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
@@ -9188,7 +9169,7 @@ bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
91889169
// value for use outside this evaluation.
91899170
APValue *Value;
91909171
if (E->getStorageDuration() == SD_Static) {
9191-
if (Info.EvalMode == EvalInfo::EM_ConstantFold)
9172+
if (Info.EvalMode == EvaluationMode::ConstantFold)
91929173
return false;
91939174
// FIXME: What about SD_Thread?
91949175
Value = E->getOrCreateValue(true);
@@ -13552,12 +13533,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1355213533
// Expression had no side effects, but we couldn't statically determine the
1355313534
// size of the referenced object.
1355413535
switch (Info.EvalMode) {
13555-
case EvalInfo::EM_ConstantExpression:
13556-
case EvalInfo::EM_ConstantFold:
13557-
case EvalInfo::EM_IgnoreSideEffects:
13536+
case EvaluationMode::ConstantExpression:
13537+
case EvaluationMode::ConstantFold:
13538+
case EvaluationMode::IgnoreSideEffects:
1355813539
// Leave it to IR generation.
1355913540
return Error(E);
13560-
case EvalInfo::EM_ConstantExpressionUnevaluated:
13541+
case EvaluationMode::ConstantExpressionUnevaluated:
1356113542
// Reduce it to a constant now.
1356213543
return Success((Type & 2) ? 0 : -1, E);
1356313544
}
@@ -17563,7 +17544,7 @@ bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
1756317544
assert(!isValueDependent() &&
1756417545
"Expression evaluator can't be called on a dependent expression.");
1756517546
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsRValue");
17566-
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17547+
EvalInfo Info(Ctx, Result, EvaluationMode::IgnoreSideEffects);
1756717548
Info.InConstantContext = InConstantContext;
1756817549
return ::EvaluateAsRValue(this, Result, Ctx, Info);
1756917550
}
@@ -17584,7 +17565,7 @@ bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
1758417565
assert(!isValueDependent() &&
1758517566
"Expression evaluator can't be called on a dependent expression.");
1758617567
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsInt");
17587-
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17568+
EvalInfo Info(Ctx, Result, EvaluationMode::IgnoreSideEffects);
1758817569
Info.InConstantContext = InConstantContext;
1758917570
return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
1759017571
}
@@ -17595,7 +17576,7 @@ bool Expr::EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
1759517576
assert(!isValueDependent() &&
1759617577
"Expression evaluator can't be called on a dependent expression.");
1759717578
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsFixedPoint");
17598-
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17579+
EvalInfo Info(Ctx, Result, EvaluationMode::IgnoreSideEffects);
1759917580
Info.InConstantContext = InConstantContext;
1760017581
return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info);
1760117582
}
@@ -17626,7 +17607,7 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
1762617607
"Expression evaluator can't be called on a dependent expression.");
1762717608

1762817609
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsLValue");
17629-
EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
17610+
EvalInfo Info(Ctx, Result, EvaluationMode::ConstantFold);
1763017611
Info.InConstantContext = InConstantContext;
1763117612
LValue LV;
1763217613
CheckedTemporaries CheckedTemps;
@@ -17646,8 +17627,8 @@ static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base,
1764617627
SourceLocation Loc, Expr::EvalStatus &EStatus,
1764717628
bool IsConstantDestruction) {
1764817629
EvalInfo Info(Ctx, EStatus,
17649-
IsConstantDestruction ? EvalInfo::EM_ConstantExpression
17650-
: EvalInfo::EM_ConstantFold);
17630+
IsConstantDestruction ? EvaluationMode::ConstantExpression
17631+
: EvaluationMode::ConstantFold);
1765117632
Info.setEvaluatingDecl(Base, DestroyedValue,
1765217633
EvalInfo::EvaluatingDeclKind::Dtor);
1765317634
Info.InConstantContext = IsConstantDestruction;
@@ -17675,7 +17656,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
1767517656
return true;
1767617657

1767717658
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsConstantExpr");
17678-
EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
17659+
EvaluationMode EM = EvaluationMode::ConstantExpression;
1767917660
EvalInfo Info(Ctx, Result, EM);
1768017661
Info.InConstantContext = true;
1768117662

@@ -17752,8 +17733,8 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
1775217733
EvalInfo Info(Ctx, EStatus,
1775317734
(IsConstantInitialization &&
1775417735
(Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().C23))
17755-
? EvalInfo::EM_ConstantExpression
17756-
: EvalInfo::EM_ConstantFold);
17736+
? EvaluationMode::ConstantExpression
17737+
: EvaluationMode::ConstantFold);
1775717738
Info.setEvaluatingDecl(VD, Value);
1775817739
Info.InConstantContext = IsConstantInitialization;
1775917740

@@ -17848,7 +17829,7 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
1784817829
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateKnownConstInt");
1784917830
EvalResult EVResult;
1785017831
EVResult.Diag = Diag;
17851-
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17832+
EvalInfo Info(Ctx, EVResult, EvaluationMode::IgnoreSideEffects);
1785217833
Info.InConstantContext = true;
1785317834

1785417835
bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
@@ -17867,7 +17848,7 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
1786717848
ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateKnownConstIntCheckOverflow");
1786817849
EvalResult EVResult;
1786917850
EVResult.Diag = Diag;
17870-
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17851+
EvalInfo Info(Ctx, EVResult, EvaluationMode::IgnoreSideEffects);
1787117852
Info.InConstantContext = true;
1787217853
Info.CheckingForUndefinedBehavior = true;
1787317854

@@ -17887,7 +17868,7 @@ void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
1788717868
bool IsConst;
1788817869
EvalResult EVResult;
1788917870
if (!FastEvaluateAsRValue(this, EVResult.Val, Ctx, IsConst)) {
17890-
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17871+
EvalInfo Info(Ctx, EVResult, EvaluationMode::IgnoreSideEffects);
1789117872
Info.CheckingForUndefinedBehavior = true;
1789217873
(void)::EvaluateAsRValue(Info, this, EVResult.Val);
1789317874
}
@@ -17941,7 +17922,7 @@ static ICEDiag Worst(ICEDiag A, ICEDiag B) { return A.Kind >= B.Kind ? A : B; }
1794117922
static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) {
1794217923
Expr::EvalResult EVResult;
1794317924
Expr::EvalStatus Status;
17944-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17925+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantExpression);
1794517926

1794617927
Info.InConstantContext = true;
1794717928
if (!::EvaluateAsRValue(E, EVResult, Ctx, Info) || EVResult.HasSideEffects ||
@@ -18425,7 +18406,7 @@ Expr::getIntegerConstantExpr(const ASTContext &Ctx) const {
1842518406
// value.
1842618407
EvalResult ExprResult;
1842718408
Expr::EvalStatus Status;
18428-
EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
18409+
EvalInfo Info(Ctx, Status, EvaluationMode::IgnoreSideEffects);
1842918410
Info.InConstantContext = true;
1843018411

1843118412
if (!::EvaluateAsInt(this, ExprResult, Ctx, SE_AllowSideEffects, Info))
@@ -18461,7 +18442,7 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result) const {
1846118442
Expr::EvalStatus Status;
1846218443
SmallVector<PartialDiagnosticAt, 8> Diags;
1846318444
Status.Diag = &Diags;
18464-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
18445+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantExpression);
1846518446

1846618447
bool IsConstExpr =
1846718448
::EvaluateAsRValue(Info, this, Result ? *Result : Scratch) &&
@@ -18488,7 +18469,7 @@ bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
1848818469
});
1848918470

1849018471
Expr::EvalStatus Status;
18491-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
18472+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantExpressionUnevaluated);
1849218473
Info.InConstantContext = true;
1849318474

1849418475
LValue ThisVal;
@@ -18564,7 +18545,8 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
1856418545
Expr::EvalStatus Status;
1856518546
Status.Diag = &Diags;
1856618547

18567-
EvalInfo Info(FD->getASTContext(), Status, EvalInfo::EM_ConstantExpression);
18548+
EvalInfo Info(FD->getASTContext(), Status,
18549+
EvaluationMode::ConstantExpression);
1856818550
Info.InConstantContext = true;
1856918551
Info.CheckingPotentialConstantExpression = true;
1857018552

@@ -18614,7 +18596,7 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
1861418596
Status.Diag = &Diags;
1861518597

1861618598
EvalInfo Info(FD->getASTContext(), Status,
18617-
EvalInfo::EM_ConstantExpressionUnevaluated);
18599+
EvaluationMode::ConstantExpressionUnevaluated);
1861818600
Info.InConstantContext = true;
1861918601
Info.CheckingPotentialConstantExpression = true;
1862018602

@@ -18638,7 +18620,7 @@ bool Expr::tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
1863818620
return false;
1863918621

1864018622
Expr::EvalStatus Status;
18641-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18623+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantFold);
1864218624
return tryEvaluateBuiltinObjectSize(this, Type, Info, Result);
1864318625
}
1864418626

@@ -18696,7 +18678,7 @@ static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
1869618678

1869718679
std::optional<std::string> Expr::tryEvaluateString(ASTContext &Ctx) const {
1869818680
Expr::EvalStatus Status;
18699-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18681+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantFold);
1870018682
uint64_t Result;
1870118683
std::string StringResult;
1870218684

@@ -18711,7 +18693,7 @@ static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result,
1871118693
const Expr *PtrExpression,
1871218694
ASTContext &Ctx,
1871318695
Expr::EvalResult &Status) {
18714-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
18696+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantExpression);
1871518697
Info.InConstantContext = true;
1871618698

1871718699
if (Info.EnableNewConstInterp)
@@ -18779,7 +18761,7 @@ bool Expr::EvaluateCharRangeAsString(APValue &Result,
1877918761

1878018762
bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const {
1878118763
Expr::EvalStatus Status;
18782-
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18764+
EvalInfo Info(Ctx, Status, EvaluationMode::ConstantFold);
1878318765

1878418766
if (Info.EnableNewConstInterp)
1878518767
return Info.Ctx.getInterpContext().evaluateStrlen(Info, this, Result);

0 commit comments

Comments
 (0)