[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-03-31 Thread via llvm-branch-commits


@@ -274,6 +274,51 @@ static IterableExpansionStmtData 
TryBuildIterableExpansionStmtInitializer(
   return Data;
 }
 
+static StmtResult BuildDestructuringDecompositionDecl(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;

Sirraide wrote:

So at least when it comes to this file, `VarIsConstexpr` is used for more than 
just deciding what expression evaluation context to push (e.g. it’s used to 
make the `__range` variable `constexpr` iff it is declared `constexpr`), and I 
feel like passing the expression evaluation context enum as a parameter would 
make it a lot less obvious as to what’s going on there

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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-03-24 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From e4abcd3e0fa975ea764e57a39f89bdf43f18bf67 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/lib/Sema/SemaExpand.cpp | 111 +-
 clang/lib/Sema/TreeTransform.h|  26 +++-
 3 files changed, 130 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9142afb95b89d..7f6fd47b3bb71 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3730,6 +3730,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index f821f73cb1e55..27878377f934f 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -86,7 +86,7 @@ static bool HasDependentSize(const DeclContext *CurContext,
 return true;
 
   case CXXExpansionStmtPattern::ExpansionStmtKind::Destructuring:
-llvm_unreachable("TODO");
+return false;
   }
 
   llvm_unreachable("invalid pattern kind");
@@ -274,6 +274,51 @@ static IterableExpansionStmtData 
TryBuildIterableExpansionStmtInitializer(
   return Data;
 }
 
+static StmtResult BuildDestructuringDecompositionDecl(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(S, S.CurContext->getParent(),
+ /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -435,8 +480,59 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.IterDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringDecompositionDecl(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  // Synthesise an InitListExpr to store the bindings; this essentially lets us
+  // desugar the expansion of a destructuring expansion statement to that of an
+  // enumerating expansion statement.
+  SmallVector Bindings;
+  for (BindingDecl *BD : DD->bindings()) {
+Expr *Element = BuildDeclRefExpr(BD, BD->getType().getNonReferenceType(),
+ VK_LValue, ColonLoc);
+
+// CWG 3149: If the expansion-initializer is an lvalue, then vi is ui;
+// otherwise, vi is static_cast(ui).
+if (!ExpansionInitializer->isLValue()) {
+  QualType Ty =
+  BuildReferenceType(getDecltypeForExpr

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-03-23 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 7de4b68bbe9ccdb391c3afb8cabc3df308384d52 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/lib/Sema/SemaExpand.cpp | 109 +-
 clang/lib/Sema/TreeTransform.h|  26 -
 3 files changed, 128 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9142afb95b89d..7f6fd47b3bb71 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3730,6 +3730,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index c51b9df082352..16028812dab41 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -86,7 +86,7 @@ static bool HasDependentSize(const DeclContext *CurContext,
 return true;
 
   case CXXExpansionStmtPattern::ExpansionStmtKind::Destructuring:
-llvm_unreachable("TODO");
+return false;
   }
 
   llvm_unreachable("invalid pattern kind");
@@ -284,6 +284,51 @@ static IterableExpansionStmtData 
TryBuildIterableExpansionStmtInitializer(
   return Data;
 }
 
+static StmtResult BuildDestructuringDecompositionDecl(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(S, S.CurContext->getParent(),
+ /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -445,8 +490,57 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.IterDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringDecompositionDecl(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  // Synthesise an InitListExpr to store the bindings; this essentially lets us
+  // desugar the expansion of a destructuring expansion statement to that of an
+  // enumerating expansion statement.
+  SmallVector Bindings;
+  for (BindingDecl *BD : DD->bindings()) {
+Expr *Element = BuildDeclRefExpr(BD, BD->getType().getNonReferenceType(),
+ VK_LValue, ColonLoc);
+
+// CWG 3149: If the expansion-initializer is an lvalue, then vi is ui;
+// otherwise, vi is static_cast(ui).
+if (!ExpansionInitializer->isLValue()) {
+  TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(
+

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-03-18 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From ae93fdd0b4999283f4002dddaade64d8bfadb160 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/lib/Sema/SemaExpand.cpp | 110 +-
 clang/lib/Sema/TreeTransform.h|  55 +++--
 3 files changed, 151 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9142afb95b89d..7f6fd47b3bb71 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3730,6 +3730,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index ca286854b4002..231f6e657e55e 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -85,7 +85,7 @@ static bool HasDependentSize(const CXXExpansionStmtPattern 
*Pattern) {
 return true;
 
   case CXXExpansionStmtPattern::ExpansionStmtKind::Destructuring:
-llvm_unreachable("TODO");
+return false;
   }
 
   llvm_unreachable("invalid pattern kind");
@@ -281,6 +281,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringDecompositionDecl(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -442,8 +488,57 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, Data.IterDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringDecompositionDecl(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  // Synthesise an InitListExpr to store the bindings; this essentially lets us
+  // desugar the expansion of a destructuring expansion statement to that of an
+  // enumerating expansion statement.
+  SmallVector Bindings;
+  for (BindingDecl *BD : DD->bindings()) {
+Expr *Element = BuildDeclRefExpr(BD, BD->getType().getNonReferenceType(),
+ VK_LValue, ColonLoc);
+
+// CWG 3149: If the expansion-initializer is an lvalue, then vi is ui;
+// otherwise, vi is static_cast(ui).
+if (!ExpansionInitializer->isLValue()) {
+  TypeSourceI

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-03-18 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From ae93fdd0b4999283f4002dddaade64d8bfadb160 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/lib/Sema/SemaExpand.cpp | 110 +-
 clang/lib/Sema/TreeTransform.h|  55 +++--
 3 files changed, 151 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9142afb95b89d..7f6fd47b3bb71 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3730,6 +3730,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index ca286854b4002..231f6e657e55e 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -85,7 +85,7 @@ static bool HasDependentSize(const CXXExpansionStmtPattern 
*Pattern) {
 return true;
 
   case CXXExpansionStmtPattern::ExpansionStmtKind::Destructuring:
-llvm_unreachable("TODO");
+return false;
   }
 
   llvm_unreachable("invalid pattern kind");
@@ -281,6 +281,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringDecompositionDecl(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -442,8 +488,57 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, Data.IterDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringDecompositionDecl(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  // Synthesise an InitListExpr to store the bindings; this essentially lets us
+  // desugar the expansion of a destructuring expansion statement to that of an
+  // enumerating expansion statement.
+  SmallVector Bindings;
+  for (BindingDecl *BD : DD->bindings()) {
+Expr *Element = BuildDeclRefExpr(BD, BD->getType().getNonReferenceType(),
+ VK_LValue, ColonLoc);
+
+// CWG 3149: If the expansion-initializer is an lvalue, then vi is ui;
+// otherwise, vi is static_cast(ui).
+if (!ExpansionInitializer->isLValue()) {
+  TypeSourceI

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-01-15 Thread Yanzuo Liu via llvm-branch-commits

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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2026-01-15 Thread Yanzuo Liu via llvm-branch-commits

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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-05 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 07d55ff90ee97ed9393f5b2d0aeadc43f0fc196f Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH 1/6] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 100 +-
 clang/lib/Sema/TreeTransform.h|  81 ++
 4 files changed, 162 insertions(+), 24 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a92a3a6a7c331..208c885909b00 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3712,6 +3712,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0adc570c73011..409e1d4e1b8ae 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15713,6 +15713,9 @@ class Sema final : public SemaBase {
 
   ExprResult BuildCXXExpansionSelectExpr(InitListExpr *Range, Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 40891e96e97de..315a4bdfd3a6c 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -220,6 +220,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -368,8 +414,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtE

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-05 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 07d55ff90ee97ed9393f5b2d0aeadc43f0fc196f Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH 1/6] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 100 +-
 clang/lib/Sema/TreeTransform.h|  81 ++
 4 files changed, 162 insertions(+), 24 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a92a3a6a7c331..208c885909b00 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3712,6 +3712,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0adc570c73011..409e1d4e1b8ae 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15713,6 +15713,9 @@ class Sema final : public SemaBase {
 
   ExprResult BuildCXXExpansionSelectExpr(InitListExpr *Range, Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 40891e96e97de..315a4bdfd3a6c 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -220,6 +220,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -368,8 +414,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtE

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-03 Thread via llvm-branch-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff origin/main HEAD --extensions h,cpp -- 
clang/lib/Sema/SemaExpand.cpp clang/lib/Sema/TreeTransform.h 
--diff_from_common_commit
``

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 6fa1ad985..daea18321 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -438,8 +438,7 @@ StmtResult Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
   }
 
   ExprResult Select = BuildCXXExpansionSelectExpr(
-  new (Context) InitListExpr(Context, ColonLoc, Bindings, ColonLoc),
-  Index);
+  new (Context) InitListExpr(Context, ColonLoc, Bindings, ColonLoc), 
Index);
 
   if (Select.isInvalid()) {
 ActOnInitializerError(ExpansionVar);

``




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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-03 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From e3c61804686c4239d6ad53d4170ccb2563dac0cd Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH 1/6] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 100 +-
 clang/lib/Sema/TreeTransform.h|  81 ++
 4 files changed, 162 insertions(+), 24 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3c3589e0ae22a..d91e1526ae47f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3700,6 +3700,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f5a36626a9dad..48bf7ba1083b7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15712,6 +15712,9 @@ class Sema final : public SemaBase {
 
   ExprResult BuildCXXExpansionSelectExpr(InitListExpr *Range, Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 40891e96e97de..315a4bdfd3a6c 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -220,6 +220,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -368,8 +414,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtE

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 13fb7c82109cb09d60cbc7f49fd6b85171f51b9e Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3c3589e0ae22a..d91e1526ae47f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3700,6 +3700,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6685f891be77b..268c81351e744 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15714,6 +15714,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index c4bc38bf1e465..532797c68b534 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -191,6 +191,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -339,8 +385,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, E

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-02 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 13fb7c82109cb09d60cbc7f49fd6b85171f51b9e Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3c3589e0ae22a..d91e1526ae47f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3700,6 +3700,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_vla : Error<
   "cannot expand variable length array type %0">;
 def err_expansion_stmt_incomplete : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6685f891be77b..268c81351e744 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15714,6 +15714,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index c4bc38bf1e465..532797c68b534 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -191,6 +191,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -339,8 +385,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, E

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-01 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From b874722179a89969b706fb8f03769abec998ac91 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 96292d0a4e306..0ddaa461deff5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3702,6 +3702,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f001851b36ff7..b102544342416 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15703,6 +15703,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 228551c27d2d8..fcc951503deb9 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -173,6 +173,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -309,8 +355,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtError();
+

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-12-01 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From b874722179a89969b706fb8f03769abec998ac91 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 96292d0a4e306..0ddaa461deff5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3702,6 +3702,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f001851b36ff7..b102544342416 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15703,6 +15703,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 228551c27d2d8..fcc951503deb9 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -173,6 +173,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -309,8 +355,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtError();
+

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 45151d137b01d1fa9b3a451bb1c5e72ce02d71c7 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 96292d0a4e306..0ddaa461deff5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3702,6 +3702,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f001851b36ff7..b102544342416 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15703,6 +15703,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 228551c27d2d8..fcc951503deb9 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -173,6 +173,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -309,8 +355,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtError();
+

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/169685

>From 45151d137b01d1fa9b3a451bb1c5e72ce02d71c7 Mon Sep 17 00:00:00 2001
From: Sirraide 
Date: Wed, 26 Nov 2025 17:00:57 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 6)

---
 .../clang/Basic/DiagnosticSemaKinds.td|   2 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaExpand.cpp | 101 +-
 clang/lib/Sema/TreeTransform.h|  63 +--
 4 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 96292d0a4e306..0ddaa461deff5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3702,6 +3702,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f001851b36ff7..b102544342416 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15703,6 +15703,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 228551c27d2d8..fcc951503deb9 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -173,6 +173,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -309,8 +355,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtError();
+

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: None (Sirraide)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/169685.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/include/clang/Sema/Sema.h (+3) 
- (modified) clang/lib/Sema/SemaExpand.cpp (+96-5) 
- (modified) clang/lib/Sema/TreeTransform.h (+52-11) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 96292d0a4e306..0ddaa461deff5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3702,6 +3702,8 @@ def err_conflicting_codeseg_attribute : Error<
 def warn_duplicate_codeseg_attribute : Warning<
   "duplicate code segment specifiers">, InGroup;
 
+def err_expansion_stmt_invalid_init : Error<
+  "cannot expand expression of type %0">;
 def err_expansion_stmt_lambda : Error<
   "cannot expand lambda closure type">;
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f001851b36ff7..b102544342416 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -15703,6 +15703,9 @@ class Sema final : public SemaBase {
   BuildCXXExpansionInitListSelectExpr(CXXExpansionInitListExpr *Range,
   Expr *Idx);
 
+  ExprResult BuildCXXDestructuringExpansionSelectExpr(DecompositionDecl *DD,
+  Expr *Idx);
+
   std::optional
   ComputeExpansionSize(CXXExpansionStmtPattern *Expansion);
   ///@}
diff --git a/clang/lib/Sema/SemaExpand.cpp b/clang/lib/Sema/SemaExpand.cpp
index 228551c27d2d8..fcc951503deb9 100644
--- a/clang/lib/Sema/SemaExpand.cpp
+++ b/clang/lib/Sema/SemaExpand.cpp
@@ -173,6 +173,52 @@ TryBuildIterableExpansionStmtInitializer(Sema &S, Expr 
*ExpansionInitializer,
   return Data;
 }
 
+static StmtResult BuildDestructuringCXXExpansionStmt(
+Sema &S, Expr *ExpansionInitializer, SourceLocation ColonLoc,
+bool VarIsConstexpr,
+ArrayRef LifetimeExtendTemps) {
+  auto Ctx = Sema::ExpressionEvaluationContext::PotentiallyEvaluated;
+  if (VarIsConstexpr)
+Ctx = Sema::ExpressionEvaluationContext::ImmediateFunctionContext;
+  EnterExpressionEvaluationContext ExprEvalCtx(S, Ctx);
+
+  // The declarations should be attached to the parent decl context.
+  Sema::ContextRAII CtxGuard(
+  S, S.CurContext->getEnclosingNonExpansionStatementContext(),
+  /*NewThis=*/false);
+
+  UnsignedOrNone Arity =
+  S.GetDecompositionElementCount(ExpansionInitializer->getType(), 
ColonLoc);
+
+  if (!Arity) {
+S.Diag(ExpansionInitializer->getBeginLoc(),
+   diag::err_expansion_stmt_invalid_init)
+<< ExpansionInitializer->getType()
+<< ExpansionInitializer->getSourceRange();
+return StmtError();
+  }
+
+  QualType AutoRRef = S.Context.getAutoRRefDeductType();
+  SmallVector Bindings;
+  for (unsigned I = 0; I < *Arity; ++I)
+Bindings.push_back(BindingDecl::Create(
+S.Context, S.CurContext, ColonLoc,
+S.getPreprocessor().getIdentifierInfo("__u" + std::to_string(I)),
+AutoRRef));
+
+  TypeSourceInfo *TSI = S.Context.getTrivialTypeSourceInfo(AutoRRef);
+  auto *DD =
+  DecompositionDecl::Create(S.Context, S.CurContext, ColonLoc, ColonLoc,
+AutoRRef, TSI, SC_Auto, Bindings);
+
+  if (VarIsConstexpr)
+DD->setConstexpr(true);
+
+  S.ApplyForRangeOrExpansionStatementLifetimeExtension(DD, 
LifetimeExtendTemps);
+  S.AddInitializerToDecl(DD, ExpansionInitializer, false);
+  return S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(DD), ColonLoc, ColonLoc);
+}
+
 CXXExpansionStmtDecl *
 Sema::ActOnCXXExpansionStmtDecl(unsigned TemplateDepth,
 SourceLocation TemplateKWLoc) {
@@ -309,8 +355,31 @@ StmtResult 
Sema::BuildNonEnumeratingCXXExpansionStmtPattern(
 Data.EndDecl, LParenLoc, ColonLoc, RParenLoc);
   }
 
-  Diag(ESD->getLocation(), diag::err_expansion_statements_todo);
-  return StmtError();
+  // If not, try destructuring.
+  StmtResult DecompDeclStmt = BuildDestructuringCXXExpansionStmt(
+  *this, ExpansionInitializer, ColonLoc, ExpansionVar->isConstexpr(),
+  LifetimeExtendTemps);
+  if (DecompDeclStmt.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  auto *DS = DecompDeclStmt.getAs();
+  auto *DD = cast(DS->getSingleDecl());
+  if (DD->isInvalidDecl())
+return StmtError();
+
+  ExprResult Select = BuildCXXDestructuringExpansionSelectExpr(DD, Index);
+  if (Select.isInvalid()) {
+ActOnInitializerError(ExpansionVar);
+return StmtError();
+  }
+
+  if (FinaliseExpansionVar(*this, ExpansionVar, Select))
+return StmtError();
+
+  return new (Context) CXXDestructuringExpansionStmtPattern(
+  ESD, Init, ExpansionVarStmt, DS, LParenLoc, ColonLoc, RParenLoc);
 }
 
 StmtResult Sema::

[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

* 3053 tests passed
* 7 tests skipped

All tests passed but another part of the build **failed**. Click on a failure 
below to see the details.


tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGDecl.cpp.o

```
FAILED: tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGDecl.cpp.o
sccache /opt/llvm/bin/clang++ -DCLANG_EXPORTS -DGTEST_HAS_RTTI=0 -D_DEBUG 
-D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/lib/CodeGen
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt 
-fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror 
-Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported 
-fdiagnostics-color -ffunction-sections -fdata-sections -fno-common 
-Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17  
-fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT 
tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGDecl.cpp.o -MF 
tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGDecl.cpp.o.d -o 
tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGDecl.cpp.o -c 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen/CGDecl.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen/CGDecl.cpp:53:11:
 error: enumeration value 'CXXExpansionStmt' not handled in switch 
[-Werror,-Wswitch]
53 |   switch (D.getKind()) {
|   ^~~
1 error generated.
```


tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGStmt.cpp.o

```
FAILED: tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGStmt.cpp.o
sccache /opt/llvm/bin/clang++ -DCLANG_EXPORTS -DGTEST_HAS_RTTI=0 -D_DEBUG 
-D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/lib/CodeGen
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt 
-fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror 
-Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported 
-fdiagnostics-color -ffunction-sections -fdata-sections -fno-common 
-Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17  
-fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT 
tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGStmt.cpp.o -MF 
tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGStmt.cpp.o.d -o 
tools/clang/lib/CodeGen/CMakeFiles/obj.clangCodeGen.dir/CGStmt.cpp.o -c 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen/CGStmt.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/CodeGen/CGStmt.cpp:100:11:
 error: 5 enumeration values not handled in switch: 
'CXXIteratingExpansionStmtPatternClass', 
'CXXEnumeratingExpansionStmtPatternClass', 
'CXXDestructuringExpansionStmtPatternClass'... [-Werror,-Wswitch]
100 |   switch (S->getStmtClass()) {
|   ^
1 error generated.
```


If these failures are unrelated to your changes (for example tests are broken 
or flaky at HEAD), please open an issue at 
https://github.com/llvm/llvm-project/issues and add the `infrastructure` label.

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


[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 6: Destructuring Expansion Statements) (PR #169685)

2025-11-28 Thread via llvm-branch-commits

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