https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/177738
>From b5a702ece74dd1f53ebbb3d74497b5bb788fc081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Fri, 23 Jan 2026 14:29:38 +0100 Subject: [PATCH] State --- clang/lib/AST/ByteCode/InterpState.cpp | 13 ++- clang/lib/AST/ByteCode/InterpState.h | 37 +------ clang/lib/AST/ByteCode/State.cpp | 74 ++++++++++--- clang/lib/AST/ByteCode/State.h | 84 +++++++++++--- clang/lib/AST/ExprConstant.cpp | 145 +++---------------------- 5 files changed, 156 insertions(+), 197 deletions(-) diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index a95916cd63981..837d5fef91b8e 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -17,10 +17,10 @@ using namespace clang; using namespace clang::interp; -InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk, +InterpState::InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx, SourceMapper *M) - : Parent(Parent), M(M), P(P), Stk(Stk), Ctx(Ctx), BottomFrame(*this), - Current(&BottomFrame) { + : State(Ctx.getASTContext(), Parent.getEvalStatus()), M(M), P(P), Stk(Stk), + Ctx(Ctx), BottomFrame(*this), Current(&BottomFrame) { InConstantContext = Parent.InConstantContext; CheckingPotentialConstantExpression = Parent.CheckingPotentialConstantExpression; @@ -28,9 +28,10 @@ InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk, EvalMode = Parent.EvalMode; } -InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk, +InterpState::InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx, const Function *Func) - : Parent(Parent), M(nullptr), P(P), Stk(Stk), Ctx(Ctx), + : State(Ctx.getASTContext(), Parent.getEvalStatus()), M(nullptr), P(P), + Stk(Stk), Ctx(Ctx), BottomFrame(*this, Func, nullptr, CodePtr(), Func->getArgSize()), Current(&BottomFrame) { InConstantContext = Parent.InConstantContext; @@ -75,7 +76,7 @@ void InterpState::cleanup() { Alloc->cleanup(); } -Frame *InterpState::getCurrentFrame() { return Current; } +const Frame *InterpState::getCurrentFrame() { return Current; } void InterpState::deallocate(Block *B) { assert(B); diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h index 231b51124c70d..98dc5cfd3b3c4 100644 --- a/clang/lib/AST/ByteCode/InterpState.h +++ b/clang/lib/AST/ByteCode/InterpState.h @@ -35,9 +35,9 @@ struct StdAllocatorCaller { /// Interpreter context. class InterpState final : public State, public SourceMapper { public: - InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, + InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx, SourceMapper *M = nullptr); - InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, + InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx, const Function *Func); ~InterpState(); @@ -50,41 +50,14 @@ class InterpState final : public State, public SourceMapper { bool diagnosing() const { return getEvalStatus().Diag != nullptr; } // Stack frame accessors. - Frame *getCurrentFrame() override; + const Frame *getCurrentFrame() override; unsigned getCallStackDepth() override { return Current ? (Current->getDepth() + 1) : 1; } const Frame *getBottomFrame() const override { return &BottomFrame; } - // Access objects from the walker context. - Expr::EvalStatus &getEvalStatus() const override { - return Parent.getEvalStatus(); - } - ASTContext &getASTContext() const override { return Ctx.getASTContext(); } - const LangOptions &getLangOpts() const { - return Ctx.getASTContext().getLangOpts(); - } - - // Forward status checks and updates to the walker. - bool keepEvaluatingAfterFailure() const override { - return Parent.keepEvaluatingAfterFailure(); - } - bool keepEvaluatingAfterSideEffect() const override { - return Parent.keepEvaluatingAfterSideEffect(); - } - bool noteUndefinedBehavior() override { - return Parent.noteUndefinedBehavior(); - } + bool stepsLeft() const override { return true; } bool inConstantContext() const; - bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); } - void setActiveDiagnostic(bool Flag) override { - Parent.setActiveDiagnostic(Flag); - } - void setFoldFailureDiagnostic(bool Flag) override { - Parent.setFoldFailureDiagnostic(Flag); - } - bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); } - bool noteSideEffect() override { return Parent.noteSideEffect(); } /// Deallocates a pointer. void deallocate(Block *B); @@ -149,8 +122,6 @@ class InterpState final : public State, public SourceMapper { private: friend class EvaluationResult; friend class InterpStateCCOverride; - /// AST Walker state. - State &Parent; /// Dead block chain. DeadBlock *DeadBlocks = nullptr; /// Reference to the offset-source mapping. diff --git a/clang/lib/AST/ByteCode/State.cpp b/clang/lib/AST/ByteCode/State.cpp index 323231fbf8236..f1192f1d07ebd 100644 --- a/clang/lib/AST/ByteCode/State.cpp +++ b/clang/lib/AST/ByteCode/State.cpp @@ -25,15 +25,15 @@ OptionalDiagnostic State::FFDiag(SourceLocation Loc, diag::kind DiagId, OptionalDiagnostic State::FFDiag(const Expr *E, diag::kind DiagId, unsigned ExtraNotes) { - if (getEvalStatus().Diag) + if (EvalStatus.Diag) return diag(E->getExprLoc(), DiagId, ExtraNotes, false); setActiveDiagnostic(false); return OptionalDiagnostic(); } -OptionalDiagnostic State::FFDiag(const SourceInfo &SI, diag::kind DiagId, +OptionalDiagnostic State::FFDiag(SourceInfo SI, diag::kind DiagId, unsigned ExtraNotes) { - if (getEvalStatus().Diag) + if (EvalStatus.Diag) return diag(SI.getLoc(), DiagId, ExtraNotes, false); setActiveDiagnostic(false); return OptionalDiagnostic(); @@ -43,7 +43,7 @@ OptionalDiagnostic State::CCEDiag(SourceLocation Loc, diag::kind DiagId, unsigned ExtraNotes) { // Don't override a previous diagnostic. Don't bother collecting // diagnostics if we're evaluating for overflow. - if (!getEvalStatus().Diag || !getEvalStatus().Diag->empty()) { + if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) { setActiveDiagnostic(false); return OptionalDiagnostic(); } @@ -55,7 +55,7 @@ OptionalDiagnostic State::CCEDiag(const Expr *E, diag::kind DiagId, return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes); } -OptionalDiagnostic State::CCEDiag(const SourceInfo &SI, diag::kind DiagId, +OptionalDiagnostic State::CCEDiag(SourceInfo SI, diag::kind DiagId, unsigned ExtraNotes) { return CCEDiag(SI.getLoc(), DiagId, ExtraNotes); } @@ -68,31 +68,29 @@ OptionalDiagnostic State::Note(SourceLocation Loc, diag::kind DiagId) { void State::addNotes(ArrayRef<PartialDiagnosticAt> Diags) { if (hasActiveDiagnostic()) - llvm::append_range(*getEvalStatus().Diag, Diags); + llvm::append_range(*EvalStatus.Diag, Diags); } DiagnosticBuilder State::report(SourceLocation Loc, diag::kind DiagId) { - return getASTContext().getDiagnostics().Report(Loc, DiagId); + return Ctx.getDiagnostics().Report(Loc, DiagId); } /// Add a diagnostic to the diagnostics list. PartialDiagnostic &State::addDiag(SourceLocation Loc, diag::kind DiagId) { - PartialDiagnostic PD(DiagId, getASTContext().getDiagAllocator()); - getEvalStatus().Diag->push_back(std::make_pair(Loc, PD)); - return getEvalStatus().Diag->back().second; + PartialDiagnostic PD(DiagId, Ctx.getDiagAllocator()); + EvalStatus.Diag->push_back(std::make_pair(Loc, PD)); + return EvalStatus.Diag->back().second; } OptionalDiagnostic State::diag(SourceLocation Loc, diag::kind DiagId, unsigned ExtraNotes, bool IsCCEDiag) { - Expr::EvalStatus &EvalStatus = getEvalStatus(); if (EvalStatus.Diag) { if (hasPriorDiagnostic()) { return OptionalDiagnostic(); } unsigned CallStackNotes = getCallStackDepth() - 1; - unsigned Limit = - getASTContext().getDiagnostics().getConstexprBacktraceLimit(); + unsigned Limit = Ctx.getDiagnostics().getConstexprBacktraceLimit(); if (Limit) CallStackNotes = std::min(CallStackNotes, Limit + 1); if (checkingPotentialConstantExpression()) @@ -158,3 +156,53 @@ void State::addCallStack(unsigned Limit) { << Out.str() << CallRange; } } + +bool State::hasPriorDiagnostic() { + if (!EvalStatus.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; +} + +bool State::keepEvaluatingAfterFailure() const { + uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; + if (Limit != 0 && !stepsLeft()) + return false; + + switch (EvalMode) { + case EvaluationMode::ConstantExpression: + case EvaluationMode::ConstantExpressionUnevaluated: + case EvaluationMode::ConstantFold: + case EvaluationMode::IgnoreSideEffects: + return checkingPotentialConstantExpression() || + checkingForUndefinedBehavior(); + } + llvm_unreachable("Missed EvalMode case"); +} + +bool State::keepEvaluatingAfterSideEffect() const { + switch (EvalMode) { + case EvaluationMode::IgnoreSideEffects: + return true; + + case EvaluationMode::ConstantExpression: + case EvaluationMode::ConstantExpressionUnevaluated: + case EvaluationMode::ConstantFold: + // By default, assume any side effect might be valid in some other + // evaluation of this expression from a different context. + return checkingPotentialConstantExpression() || + checkingForUndefinedBehavior(); + } + llvm_unreachable("Missed EvalMode case"); +} diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h index 2d30ff4596cc7..c0d32fba7fd9b 100644 --- a/clang/lib/AST/ByteCode/State.h +++ b/clang/lib/AST/ByteCode/State.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_INTERP_STATE_H #define LLVM_CLANG_AST_INTERP_STATE_H +#include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/Expr.h" #include "clang/AST/OptionalDiagnostic.h" @@ -79,21 +80,40 @@ 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 bool noteUndefinedBehavior() = 0; - virtual bool keepEvaluatingAfterFailure() const = 0; - virtual bool keepEvaluatingAfterSideEffect() const = 0; - virtual Frame *getCurrentFrame() = 0; + virtual const 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; + 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? @@ -105,8 +125,6 @@ class State { return CheckingForUndefinedBehavior; } -public: - State() = default; /// Diagnose that the evaluation could not be folded (FF => FoldFailure) OptionalDiagnostic FFDiag(SourceLocation Loc, @@ -119,7 +137,7 @@ class State { unsigned ExtraNotes = 0); OptionalDiagnostic - FFDiag(const SourceInfo &SI, + FFDiag(SourceInfo SI, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes = 0); @@ -139,7 +157,7 @@ class State { unsigned ExtraNotes = 0); OptionalDiagnostic - CCEDiag(const SourceInfo &SI, + CCEDiag(SourceInfo SI, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes = 0); @@ -170,14 +188,50 @@ class State { bool CheckingForUndefinedBehavior = false; EvaluationMode EvalMode; + ASTContext &Ctx; + Expr::EvalStatus &EvalStatus; private: + /// HasActiveDiagnostic - Was the previous diagnostic stored? If so, further + /// notes attached to it will also be stored, otherwise they will not be. + bool HasActiveDiagnostic = false; + + /// Have we emitted a diagnostic explaining why we couldn't constant + /// fold (not just why it's not strictly a constant expression)? + bool HasFoldFailureDiagnostic = false; + void addCallStack(unsigned Limit); PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId); OptionalDiagnostic diag(SourceLocation Loc, diag::kind DiagId, unsigned ExtraNotes, bool IsCCEDiag); + + /// Should we continue evaluation after encountering undefined behavior? + bool keepEvaluatingAfterUndefinedBehavior() const { + switch (EvalMode) { + case EvaluationMode::IgnoreSideEffects: + case EvaluationMode::ConstantFold: + return true; + + case EvaluationMode::ConstantExpression: + case EvaluationMode::ConstantExpressionUnevaluated: + return checkingForUndefinedBehavior(); + } + llvm_unreachable("Missed EvalMode case"); + } + + // 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(); + + void setFoldFailureDiagnostic(bool Flag) { HasFoldFailureDiagnostic = Flag; }; + void setActiveDiagnostic(bool Flag) { HasActiveDiagnostic = Flag; }; + bool hasActiveDiagnostic() const { return HasActiveDiagnostic; } }; } // namespace interp diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 58748fa5ba49b..91d0c655abfc6 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -794,13 +794,8 @@ namespace { /// rules. For example, the RHS of (0 && foo()) is not evaluated. We can /// evaluate the expression regardless of what the RHS is, but C only allows /// certain things in certain situations. - class EvalInfo : public interp::State { + class EvalInfo final : public interp::State { public: - ASTContext &Ctx; - - /// EvalStatus - Contains information about the evaluation. - Expr::EvalStatus &EvalStatus; - /// CurrentCall - The top of the constexpr call stack. CallStackFrame *CurrentCall; @@ -919,16 +914,8 @@ namespace { /// initialization. uint64_t ArrayInitIndex = -1; - /// HasActiveDiagnostic - Was the previous diagnostic stored? If so, further - /// notes attached to it will also be stored, otherwise they will not be. - bool HasActiveDiagnostic; - - /// Have we emitted a diagnostic explaining why we couldn't constant - /// fold (not just why it's not strictly a constant expression)? - bool HasFoldFailureDiagnostic; - EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode) - : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr), + : State(const_cast<ASTContext &>(C), S), CurrentCall(nullptr), CallStackDepth(0), NextCallIndex(1), StepsLeft(C.getLangOpts().ConstexprStepLimit), EnableNewConstInterp(C.getLangOpts().EnableNewConstInterp), @@ -936,8 +923,7 @@ namespace { /*This=*/nullptr, /*CallExpr=*/nullptr, CallRef()), EvaluatingDecl((const ValueDecl *)nullptr), - EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false), - HasFoldFailureDiagnostic(false) { + EvaluatingDeclValue(nullptr) { EvalMode = Mode; } @@ -945,9 +931,6 @@ namespace { discardCleanups(); } - ASTContext &getASTContext() const override { return Ctx; } - const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); } - void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value, EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) { EvaluatingDecl = Base; @@ -990,7 +973,7 @@ namespace { // We use the number of constexpr steps as a proxy for the maximum size // of arrays to avoid exhausting the system resources, as initialization // of each element is likely to take some number of steps anyway. - uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; + uint64_t Limit = getLangOpts().ConstexprStepLimit; if (Limit != 0 && ElemCount > Limit) { if (Diag) FFDiag(Loc, diag::note_constexpr_new_exceeds_limits) @@ -1017,7 +1000,7 @@ namespace { } bool nextStep(const Stmt *S) { - if (Ctx.getLangOpts().ConstexprStepLimit == 0) + if (getLangOpts().ConstexprStepLimit == 0) return true; if (!StepsLeft) { @@ -1101,110 +1084,13 @@ namespace { } private: - interp::Frame *getCurrentFrame() override { return CurrentCall; } + const interp::Frame *getCurrentFrame() override { return CurrentCall; } const interp::Frame *getBottomFrame() const override { return &BottomFrame; } - bool hasActiveDiagnostic() override { return HasActiveDiagnostic; } - void setActiveDiagnostic(bool Flag) override { HasActiveDiagnostic = Flag; } - - void setFoldFailureDiagnostic(bool Flag) override { - HasFoldFailureDiagnostic = Flag; - } - - Expr::EvalStatus &getEvalStatus() const override { return EvalStatus; } - - // 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() override { - if (!EvalStatus.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; - } - unsigned getCallStackDepth() override { return CallStackDepth; } + bool stepsLeft() const override { return StepsLeft > 0; } public: - /// Should we continue evaluation after encountering a side-effect that we - /// couldn't model? - bool keepEvaluatingAfterSideEffect() const override { - switch (EvalMode) { - case EvaluationMode::IgnoreSideEffects: - return true; - - case EvaluationMode::ConstantExpression: - case EvaluationMode::ConstantExpressionUnevaluated: - case EvaluationMode::ConstantFold: - // By default, assume any side effect might be valid in some other - // evaluation of this expression from a different context. - return checkingPotentialConstantExpression() || - checkingForUndefinedBehavior(); - } - llvm_unreachable("Missed EvalMode case"); - } - - /// Note that we have had a side-effect, and determine whether we should - /// keep evaluating. - bool noteSideEffect() override { - EvalStatus.HasSideEffects = true; - return keepEvaluatingAfterSideEffect(); - } - - /// Should we continue evaluation after encountering undefined behavior? - bool keepEvaluatingAfterUndefinedBehavior() { - switch (EvalMode) { - case EvaluationMode::IgnoreSideEffects: - case EvaluationMode::ConstantFold: - return true; - - case EvaluationMode::ConstantExpression: - case EvaluationMode::ConstantExpressionUnevaluated: - return checkingForUndefinedBehavior(); - } - llvm_unreachable("Missed EvalMode case"); - } - - /// 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() override { - EvalStatus.HasUndefinedBehavior = true; - return keepEvaluatingAfterUndefinedBehavior(); - } - - /// Should we continue evaluation as much as possible after encountering a - /// construct which can't be reduced to a value? - bool keepEvaluatingAfterFailure() const override { - uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; - if (Limit != 0 && !StepsLeft) - return false; - - switch (EvalMode) { - case EvaluationMode::ConstantExpression: - case EvaluationMode::ConstantExpressionUnevaluated: - case EvaluationMode::ConstantFold: - case EvaluationMode::IgnoreSideEffects: - return checkingPotentialConstantExpression() || - checkingForUndefinedBehavior(); - } - llvm_unreachable("Missed EvalMode case"); - } - /// Notes that we failed to evaluate an expression that other expressions /// directly depend on, and determine if we should keep evaluating. This /// should only be called if we actually intend to keep evaluating. @@ -2412,9 +2298,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, // In CUDA/HIP device compilation, only device side variables have // constant addresses. - if (Info.getASTContext().getLangOpts().CUDA && - Info.getASTContext().getLangOpts().CUDAIsDevice && - Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) { + if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice && + Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) { if ((!Var->hasAttr<CUDADeviceAttr>() && !Var->hasAttr<CUDAConstantAttr>() && !Var->getType()->isCUDADeviceBuiltinSurfaceType() && @@ -2767,7 +2652,7 @@ static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, /// So return "tonearest" mode instead of "dynamic". static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E) { llvm::RoundingMode RM = - E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode(); + E->getFPFeaturesInEffect(Info.getLangOpts()).getRoundingMode(); if (RM == llvm::RoundingMode::Dynamic) RM = llvm::RoundingMode::NearestTiesToEven; return RM; @@ -2781,7 +2666,7 @@ static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, if (Info.InConstantContext) return true; - FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()); + FPOptions FPO = E->getFPFeaturesInEffect(Info.getLangOpts()); if ((St & APFloat::opInexact) && FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) { // Inexact result means that it depends on rounding mode. If the requested @@ -6326,7 +6211,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) && isa<ReturnStmt>(SS)); - auto LO = Info.getASTContext().getLangOpts(); + auto LO = Info.Ctx.getLangOpts(); if (LO.CXXAssumptions && !LO.MSVCCompat) { for (auto *Attr : AS->getAttrs()) { auto *AA = dyn_cast<CXXAssumeAttr>(Attr); @@ -6337,7 +6222,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, if (Assumption->isValueDependent()) return ESR_Failed; - if (Assumption->HasSideEffects(Info.getASTContext())) + if (Assumption->HasSideEffects(Info.Ctx)) continue; bool Value; @@ -9325,8 +9210,8 @@ class LValueExprEvaluator bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); bool VisitMemberExpr(const MemberExpr *E); bool VisitStringLiteral(const StringLiteral *E) { - return Success(APValue::LValueBase( - E, 0, Info.getASTContext().getNextStringLiteralVersion())); + return Success( + APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion())); } bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); } bool VisitCXXTypeidExpr(const CXXTypeidExpr *E); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
