================
@@ -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.
+  auto HasADLCandidate = [&](DeclarationName Name) {
+    OverloadCandidateSet Candidates(ColonLoc, 
OverloadCandidateSet::CSK_Normal);
+    OverloadCandidateSet::iterator Best;
+
+    S.AddArgumentDependentLookupCandidates(Name, ColonLoc, 
ExpansionInitializer,
+                                           /*ExplicitTemplateArgs=*/nullptr,
+                                           Candidates);
+
+    return Candidates.BestViableFunction(S, ColonLoc, Best) !=
+           OR_No_Viable_Function;
+  };
+
+  if (!FoundBeginEnd && (!HasADLCandidate(BeginName.getName()) ||
+                         !HasADLCandidate(EndName.getName())))
+    return Data;
+
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+    Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
----------------
Sirraide wrote:

See
- https://github.com/llvm/llvm-project/pull/169681#discussion_r3182730176
- https://github.com/llvm/llvm-project/pull/169682#discussion_r3182774060

tl;dr that helper was meant only for `Parser::ParseForStatement()`

https://github.com/llvm/llvm-project/pull/169684
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to