https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/205033
>From f7c4c63f8f4fa553464ecc1bcb1b73b5de56dde3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Mon, 22 Jun 2026 06:29:10 +0200 Subject: [PATCH] [clang][AST] Refactor `EvaluatedStmt` accessors in `VarDecl` 1) Return the evaluated APValue as a const pointer since it may not be modified by callers. 2) Only return a non-nullptr from `getEvaluatedValue()` if the APValue not absent. --- clang/include/clang/AST/Decl.h | 15 ++++++++------- clang/lib/AST/Decl.cpp | 15 ++++++++------- clang/lib/AST/ExprConstant.cpp | 4 ++-- clang/lib/CodeGen/CGExprConstant.cpp | 2 +- clang/lib/Serialization/ASTWriter.cpp | 2 +- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index e0623d0cb324d..20919e696dfcd 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1422,18 +1422,19 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { /// Attempt to evaluate the value of the initializer attached to this /// declaration, and produce notes explaining why it cannot be evaluated. - /// Returns a pointer to the value if evaluation succeeded, 0 otherwise. - APValue *evaluateValue() const; + /// Returns a pointer to the value if evaluation succeeded, \c nullptr + /// otherwise. + const APValue *evaluateValue() const; private: - APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> *Notes, - bool IsConstantInitialization) const; + const APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> *Notes, + bool IsConstantInitialization) const; public: /// Return the already-evaluated value of this variable's - /// initializer, or NULL if the value is not yet known. Returns pointer - /// to untyped APValue if the value could not be evaluated. - APValue *getEvaluatedValue() const; + /// initializer, or \c nullptr if the value is not yet known or couldn't be + /// evaluated. + const APValue *getEvaluatedValue() const; /// Evaluate the destruction of this variable to determine if it constitutes /// constant destruction. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 7ab4235717dde..b23bf73ae803c 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2551,12 +2551,13 @@ EvaluatedStmt *VarDecl::getEvaluatedStmt() const { return dyn_cast_if_present<EvaluatedStmt *>(Init); } -APValue *VarDecl::evaluateValue() const { +const APValue *VarDecl::evaluateValue() const { return evaluateValueImpl(/*Notes=*/nullptr, hasConstantInitialization()); } -APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> *Notes, - bool IsConstantInitialization) const { +const APValue * +VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> *Notes, + bool IsConstantInitialization) const { EvaluatedStmt *Eval = ensureEvaluatedStmt(); const auto *Init = getInit(); @@ -2606,10 +2607,10 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> *Notes, return Result ? &Eval->Evaluated : nullptr; } -APValue *VarDecl::getEvaluatedValue() const { - if (EvaluatedStmt *Eval = getEvaluatedStmt()) - if (Eval->WasEvaluated) - return &Eval->Evaluated; +const APValue *VarDecl::getEvaluatedValue() const { + if (EvaluatedStmt *Eval = getEvaluatedStmt(); + Eval && Eval->WasEvaluated && !Eval->Evaluated.isAbsent()) + return &Eval->Evaluated; return nullptr; } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6ac16c2b831d2..538f9fe6e7f44 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -3502,7 +3502,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, return false; } - Result = VD->getEvaluatedValue(); + Result = const_cast<APValue *>(VD->getEvaluatedValue()); if (!Result && !AllowConstexprUnknown) return false; @@ -21617,7 +21617,7 @@ bool VarDecl::evaluateDestruction( // Otherwise, treat the value as default-initialized; if the destructor works // anyway, then the destruction is constant (and must be essentially empty). APValue DestroyedValue; - if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent()) + if (getEvaluatedValue()) DestroyedValue = *getEvaluatedValue(); else if (!handleDefaultInitValue(getType(), DestroyedValue)) return false; diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index ffcd3fef9cd52..a8c5985cde705 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1923,7 +1923,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) { // Try to emit the initializer. Note that this can allow some things that // are not allowed by tryEmitPrivateForMemory alone. - if (APValue *value = D.evaluateValue()) { + if (const APValue *value = D.evaluateValue()) { assert(!value->allowConstexprUnknown() && "Constexpr unknown values are not allowed in CodeGen"); return tryEmitPrivateForMemory(*value, destType); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 21dda6f3733e4..357a7f7e95fa0 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -7526,7 +7526,7 @@ void ASTRecordWriter::AddVarDeclInit(const VarDecl *VD) { assert(ES->CheckedForSideEffects); Val |= (ES->HasConstantInitialization ? 2 : 0); Val |= (ES->HasConstantDestruction ? 4 : 0); - APValue *Evaluated = VD->getEvaluatedValue(); + const APValue *Evaluated = VD->getEvaluatedValue(); // If the evaluated result is constant, emit it. if (Evaluated && (Evaluated->isInt() || Evaluated->isFloat())) Val |= 8; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
