[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 2: Parsing and Parser Tests) (PR #169681)

Daniel M. Katz via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon May 4 09:53:51 PDT 2026


================
@@ -1895,8 +1937,56 @@ bool Parser::isForRangeIdentifier() {
   return false;
 }
 
-StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,
-                                     LabelDecl *PrecedingLabel) {
+void Parser::ParseForRangeInitializerAfterColon(ForRangeInit &FRI,
+                                                ParsingDeclSpec *VarDeclSpec) {
+  // Use an immediate function context if this is the initializer for a
+  // constexpr variable in an expansion statement.
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (FRI.ExpansionStmt && VarDeclSpec && VarDeclSpec->hasConstexprSpecifier())
+    Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+
----------------
katzdm wrote:

I'm not sure whether Clang's use of "immediate function context" deviates from the Standard, but initializers of constexpr variables are in an immediate function context. Except for some funky cases, constexpr variables are "usable in constant expressions" ([[expr.const.init]/7.1](https://eel.is/c++draft/expr.const.init#7.1)); therefore, their initializers are manifestly constant-evaluated ([[expr.const.defns]/1.6](https://eel.is/c++draft/expr.const.defns#1.6)); therefore, all subexpressions of their initializers are in an immediate function context ([[expr.const.imm]/1.2](https://eel.is/c++draft/expr.const.imm#1.2)).

Anyway - I think that was my logic.

https://github.com/llvm/llvm-project/pull/169681


More information about the llvm-branch-commits mailing list