[clang] [Clang] [C++26] Expansion Statements (Part 1: AST) (PR #169680)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 1 07:36:02 PST 2025


================
@@ -125,3 +126,155 @@ CoroutineBodyStmt::CoroutineBodyStmt(CoroutineBodyStmt::CtorArgs const &Args)
       Args.ReturnStmtOnAllocFailure;
   llvm::copy(Args.ParamMoves, const_cast<Stmt **>(getParamMoves().data()));
 }
+
+CXXExpansionStmtPattern::CXXExpansionStmtPattern(StmtClass SC, EmptyShell Empty)
+    : Stmt(SC, Empty) {}
+
+CXXExpansionStmtPattern::CXXExpansionStmtPattern(
+    StmtClass SC, CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVar,
+
+    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation RParenLoc)
+    : Stmt(SC), ParentDecl(ESD), LParenLoc(LParenLoc), ColonLoc(ColonLoc),
+      RParenLoc(RParenLoc) {
+  setInit(Init);
+  setExpansionVarStmt(ExpansionVar);
+  setBody(nullptr);
+}
+
+CXXEnumeratingExpansionStmtPattern::CXXEnumeratingExpansionStmtPattern(
+    EmptyShell Empty)
+    : CXXExpansionStmtPattern(CXXEnumeratingExpansionStmtPatternClass, Empty) {}
+
+CXXEnumeratingExpansionStmtPattern::CXXEnumeratingExpansionStmtPattern(
+    CXXExpansionStmtDecl *ESD, Stmt *Init, DeclStmt *ExpansionVar,
+    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation RParenLoc)
+    : CXXExpansionStmtPattern(CXXEnumeratingExpansionStmtPatternClass, ESD,
+                              Init, ExpansionVar, LParenLoc, ColonLoc,
+                              RParenLoc) {}
+
+SourceLocation CXXExpansionStmtPattern::getBeginLoc() const {
+  return ParentDecl->getLocation();
+}
+
+VarDecl *CXXExpansionStmtPattern::getExpansionVariable() {
+  Decl *LV = cast<DeclStmt>(getExpansionVarStmt())->getSingleDecl();
+  assert(LV && "No expansion variable in CXXExpansionStmtPattern");
+  return cast<VarDecl>(LV);
+}
+
+bool CXXExpansionStmtPattern::hasDependentSize() const {
+  if (isa<CXXEnumeratingExpansionStmtPattern>(this))
+    return cast<CXXExpansionInitListSelectExpr>(
+               getExpansionVariable()->getInit())
+        ->getRangeExpr()
+        ->containsPackExpansion();
+
+  if (auto *Iterating = dyn_cast<CXXIteratingExpansionStmtPattern>(this)) {
+    const Expr *Begin = Iterating->getBeginVar()->getInit();
+    const Expr *End = Iterating->getBeginVar()->getInit();
+    return Begin->isTypeDependent() || Begin->isValueDependent() ||
----------------
Sirraide wrote:

> If it is Type dependent, it is ALSO value dependent)

Not in the general case I believe (e.g. sizeof(T)` is not type-dependent afaik, only value-dependent), but here yeah, you’re probably right, and I think we only care about type-dependence here.

> You probably just want isInstantiationDependent which covers all dependent cases.

Shouldn’t we check for type dependence specifically? Because as I understand it it’s possible for this to be instantiation-dependent even if the type is known (and potentially the value too), in which case we still want to instantiate it? Maybe I’m just overthinking this and those are hypothetical scenarios that we don’t care too much about though...

> Also, what is going on? Aren't `Begin` and `End` the same thing here?

Goddamn copy-paste errors; thanks for spotting that.

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


More information about the cfe-commits mailing list