[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 5: Iterating Expansion Statements) (PR #169684)
Corentin Jabot via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 5 03:21:36 PDT 2026
================
@@ -55,14 +75,204 @@ static bool HasDependentSize(const CXXExpansionStmtPattern *Pattern) {
}
case CXXExpansionStmtPattern::ExpansionStmtKind::Iterating:
- case CXXExpansionStmtPattern::ExpansionStmtKind::Destructuring:
+ // Even if the size isn't technically dependent, delay expansion until
+ // we're no longer in a template since evaluating a lambda declared in
+ // a template doesn't work too well.
+ assert(CurContext->isExpansionStmt());
+ return CurContext->getParent()->isDependentContext();
+
case CXXExpansionStmtPattern::ExpansionStmtKind::Dependent:
+ return true;
+
+ case CXXExpansionStmtPattern::ExpansionStmtKind::Destructuring:
llvm_unreachable("TODO");
}
llvm_unreachable("invalid pattern kind");
}
+static IterableExpansionStmtData TryBuildIterableExpansionStmtInitializer(
+ Sema &S, Expr *ExpansionInitializer, Expr *Index, SourceLocation ColonLoc,
+ bool VarIsConstexpr,
+ ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
+ IterableExpansionStmtData Data;
+
+ // C++26 [stmt.expand]p3: An expression is expansion-iterable if it does not
+ // have array type [...]
+ QualType Ty = ExpansionInitializer->getType().getNonReferenceType();
+ if (Ty->isArrayType())
+ return Data;
+
+ // Lookup member and ADL 'begin()'/'end()'. Only check if they exist; even if
+ // they're deleted, inaccessible, etc., this is still an iterating expansion
+ // statement, albeit an ill-formed one.
+ DeclarationNameInfo BeginName(&S.PP.getIdentifierTable().get("begin"),
+ ColonLoc);
+ DeclarationNameInfo EndName(&S.PP.getIdentifierTable().get("end"), ColonLoc);
+
+ // Try member lookup first.
+ bool FoundBeginEnd = false;
+ if (auto *Record = Ty->getAsCXXRecordDecl()) {
+ LookupResult BeginLR(S, BeginName, Sema::LookupMemberName);
+ LookupResult EndLR(S, EndName, Sema::LookupMemberName);
+ FoundBeginEnd = S.LookupQualifiedName(BeginLR, Record) &&
+ S.LookupQualifiedName(EndLR, Record);
+ }
+
+ // Try ADL.
+ //
+ // If overload resolution for 'begin()' *and* 'end()' succeeds (irrespective
+ // of whether it results in a usable candidate), then assume this is an
+ // iterating expansion statement.
----------------
cor3ntin wrote:
There are weird things going on with the order and duplication of comments.
https://github.com/llvm/llvm-project/pull/169684
More information about the llvm-branch-commits
mailing list