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

>From 3b874f53ac31c9fa05568aeecaf2734d6601bc07 Mon Sep 17 00:00:00 2001
From: Sirraide <[email protected]>
Date: Wed, 26 Nov 2025 18:03:57 +0100
Subject: [PATCH 1/4] [Clang] [C++26] Expansion Statements (Part 11)

---
 clang/docs/ReleaseNotes.rst                   |   2 +
 .../clang/Basic/DiagnosticCommonKinds.td      |   4 -
 clang/test/AST/ast-dump-expansion-stmt.cpp    |  49 +++++++++
 clang/test/AST/ast-print-expansion-stmts.cpp  | 104 ++++++++++++++++++
 clang/www/cxx_status.html                     |   2 +-
 5 files changed, 156 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-expansion-stmt.cpp
 create mode 100644 clang/test/AST/ast-print-expansion-stmts.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 51f07256c5d9f..14f31c0ee5a2b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -187,6 +187,8 @@ C++2c Feature Support
   At this timem, references to constexpr and decomposition of *tuple-like* 
types are not supported
   (only arrays and aggregates are).
 
+- Implemented `P1306R5 <https://wg21.link/P1306R5>`_ Expansion Statements.
+
 C++23 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 0b9225980e826..6e50e225a8cc1 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -22,10 +22,6 @@ def select_constexpr_spec_kind : TextSubstitution<
 def fatal_too_many_errors
   : Error<"too many errors emitted, stopping now">, DefaultFatal;
 
-// TODO: Remove this.
-def err_expansion_statements_todo : Error<
-  "TODO (expansion statements)">;
-
 def warn_stack_exhausted : Warning<
   "stack nearly exhausted; compilation time may suffer, and "
   "crashes due to stack overflow are likely">,
diff --git a/clang/test/AST/ast-dump-expansion-stmt.cpp 
b/clang/test/AST/ast-dump-expansion-stmt.cpp
new file mode 100644
index 0000000000000..146157e2c13e6
--- /dev/null
+++ b/clang/test/AST/ast-dump-expansion-stmt.cpp
@@ -0,0 +1,49 @@
+// Test without serialization:
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-unknown-unknown -ast-dump %s
+//
+// Test with serialization:
+// RUN: %clang_cc1 -std=c++26 -triple x86_64-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -triple x86_64-unknown-unknown 
-include-pch %t -ast-dump-all /dev/null \
+// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//"
+
+template <typename T, __SIZE_TYPE__ size>
+struct Array {
+  T data[size]{};
+  constexpr const T* begin() const { return data; }
+  constexpr const T* end() const { return data + size; }
+};
+
+void foo(int);
+
+template <typename T>
+void test(T t) {
+  // CHECK:      CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXEnumeratingExpansionStmtPattern
+  // CHECK:        CXXExpansionStmtInstantiation
+  template for (auto x : {1, 2, 3}) {
+    foo(x);
+  }
+
+  // CHECK:      CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXIteratingExpansionStmtPattern
+  // CHECK:        CXXExpansionStmtInstantiation
+  static constexpr Array<int, 3> a;
+  template for (auto x : a) {
+    foo(x);
+  }
+
+  // CHECK:      CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXDestructuringExpansionStmtPattern
+  // CHECK:        CXXExpansionStmtInstantiation
+  int arr[3]{1, 2, 3};
+  template for (auto x : arr) {
+    foo(x);
+  }
+
+  // CHECK:      CXXExpansionStmtDecl
+  // CHECK-NEXT:   CXXDependentExpansionStmtPattern
+  // CHECK-NOT:    CXXExpansionStmtInstantiation
+  template for (auto x : t) {
+    foo(x);
+  }
+}
diff --git a/clang/test/AST/ast-print-expansion-stmts.cpp 
b/clang/test/AST/ast-print-expansion-stmts.cpp
new file mode 100644
index 0000000000000..bb9f79c6644c0
--- /dev/null
+++ b/clang/test/AST/ast-print-expansion-stmts.cpp
@@ -0,0 +1,104 @@
+// Without serialization:
+// RUN: %clang_cc1 -std=c++26 -ast-print %s | FileCheck %s
+//
+// With serialization:
+// RUN: %clang_cc1 -std=c++26 -emit-pch -o %t %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -include-pch %t -ast-print  /dev/null | 
FileCheck %s
+
+template <typename T, __SIZE_TYPE__ size>
+struct Array {
+  T data[size]{};
+  constexpr const T* begin() const { return data; }
+  constexpr const T* end() const { return data + size; }
+};
+
+// CHECK: void foo(int);
+void foo(int);
+
+// CHECK: template <typename T> void test(T t) {
+template <typename T>
+void test(T t) {
+  // Enumerating expansion statement.
+  //
+  // CHECK:      template for (auto x : { 1, 2, 3 }) {
+  // CHECK-NEXT:     foo(x);
+  // CHECK-NEXT: }
+  template for (auto x : {1, 2, 3}) {
+    foo(x);
+  }
+
+  // Iterating expansion statement.
+  //
+  // CHECK:      static constexpr Array<int, 3> a;
+  // CHECK-NEXT: template for (auto x : a) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  static constexpr Array<int, 3> a;
+  template for (auto x : a) {
+    foo(x);
+  }
+
+  // Destructuring expansion statement.
+  //
+  // CHECK:      int arr[3]{1, 2, 3};
+  // CHECK-NEXT: template for (auto x : arr) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  int arr[3]{1, 2, 3};
+  template for (auto x : arr) {
+    foo(x);
+  }
+
+  // Dependent expansion statement.
+  //
+  // CHECK:      template for (auto x : t) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  template for (auto x : t) {
+    foo(x);
+  }
+}
+
+// CHECK: template <typename T> void test2(T t) {
+template <typename T>
+void test2(T t) {
+  // Enumerating expansion statement.
+  //
+  // CHECK:      template for (int x : { 1, 2, 3 }) {
+  // CHECK-NEXT:     foo(x);
+  // CHECK-NEXT: }
+  template for (int x : {1, 2, 3}) {
+    foo(x);
+  }
+
+  // Iterating expansion statement.
+  //
+  // CHECK:      static constexpr Array<int, 3> a;
+  // CHECK-NEXT: template for (int x : a) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  static constexpr Array<int, 3> a;
+  template for (int x : a) {
+    foo(x);
+  }
+
+  // Destructuring expansion statement.
+  //
+  // CHECK:      int arr[3]{1, 2, 3};
+  // CHECK-NEXT: template for (int x : arr) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  int arr[3]{1, 2, 3};
+  template for (int x : arr) {
+    foo(x);
+  }
+
+  // Dependent expansion statement.
+  //
+  // CHECK:      template for (int x : t) {
+  // CHECK-NEXT:   foo(x);
+  // CHECK-NEXT: }
+  template for (int x : t) {
+    foo(x);
+  }
+}
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 2618ff930a0e4..0bb2d5440775a 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -317,7 +317,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
  <tr>
   <td>Expansion Statements</td>
   <td><a href="https://wg21.link/P1306";>P1306R5</a></td>
-  <td class="none" align="center">No</td>
+  <td class="unreleased" align="center">Clang 22</td>
   </tr>
   <tr>
    <td>constexpr virtual inheritance</td>

>From 55a9d031eedd97bfc9dc38f210218fe3ced333a2 Mon Sep 17 00:00:00 2001
From: Sirraide <[email protected]>
Date: Wed, 3 Dec 2025 03:15:55 +0100
Subject: [PATCH 2/4] CWG 3131

---
 clang/test/AST/ast-print-expansion-stmts.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/AST/ast-print-expansion-stmts.cpp 
b/clang/test/AST/ast-print-expansion-stmts.cpp
index bb9f79c6644c0..19ffe2f3028e4 100644
--- a/clang/test/AST/ast-print-expansion-stmts.cpp
+++ b/clang/test/AST/ast-print-expansion-stmts.cpp
@@ -30,7 +30,7 @@ void test(T t) {
   // Iterating expansion statement.
   //
   // CHECK:      static constexpr Array<int, 3> a;
-  // CHECK-NEXT: template for (auto x : a) {
+  // CHECK-NEXT: template for (auto x : (a)) {
   // CHECK-NEXT:   foo(x);
   // CHECK-NEXT: }
   static constexpr Array<int, 3> a;
@@ -74,7 +74,7 @@ void test2(T t) {
   // Iterating expansion statement.
   //
   // CHECK:      static constexpr Array<int, 3> a;
-  // CHECK-NEXT: template for (int x : a) {
+  // CHECK-NEXT: template for (int x : (a)) {
   // CHECK-NEXT:   foo(x);
   // CHECK-NEXT: }
   static constexpr Array<int, 3> a;

>From 526887fcde5914a32e54535821846a1389d323d7 Mon Sep 17 00:00:00 2001
From: Sirraide <[email protected]>
Date: Wed, 3 Dec 2025 18:10:06 +0100
Subject: [PATCH 3/4] Eliminate CXXExpansionInitListExpr

---
 clang/test/AST/ast-print-expansion-stmts.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/AST/ast-print-expansion-stmts.cpp 
b/clang/test/AST/ast-print-expansion-stmts.cpp
index 19ffe2f3028e4..014da274af093 100644
--- a/clang/test/AST/ast-print-expansion-stmts.cpp
+++ b/clang/test/AST/ast-print-expansion-stmts.cpp
@@ -20,7 +20,7 @@ template <typename T>
 void test(T t) {
   // Enumerating expansion statement.
   //
-  // CHECK:      template for (auto x : { 1, 2, 3 }) {
+  // CHECK:      template for (auto x : {1, 2, 3}) {
   // CHECK-NEXT:     foo(x);
   // CHECK-NEXT: }
   template for (auto x : {1, 2, 3}) {
@@ -64,7 +64,7 @@ template <typename T>
 void test2(T t) {
   // Enumerating expansion statement.
   //
-  // CHECK:      template for (int x : { 1, 2, 3 }) {
+  // CHECK:      template for (int x : {1, 2, 3}) {
   // CHECK-NEXT:     foo(x);
   // CHECK-NEXT: }
   template for (int x : {1, 2, 3}) {

>From 3c9893b215ad93239216733cac021600947f11a1 Mon Sep 17 00:00:00 2001
From: Sirraide <[email protected]>
Date: Wed, 3 Dec 2025 20:08:01 +0100
Subject: [PATCH 4/4] Merge all pattern kinds into a single AST node

---
 clang/test/AST/ast-dump-expansion-stmt.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/AST/ast-dump-expansion-stmt.cpp 
b/clang/test/AST/ast-dump-expansion-stmt.cpp
index 146157e2c13e6..eb9acd5e0b652 100644
--- a/clang/test/AST/ast-dump-expansion-stmt.cpp
+++ b/clang/test/AST/ast-dump-expansion-stmt.cpp
@@ -18,14 +18,14 @@ void foo(int);
 template <typename T>
 void test(T t) {
   // CHECK:      CXXExpansionStmtDecl
-  // CHECK-NEXT:   CXXEnumeratingExpansionStmtPattern
+  // CHECK-NEXT:   CXXExpansionStmtPattern {{.*}} enumerating
   // CHECK:        CXXExpansionStmtInstantiation
   template for (auto x : {1, 2, 3}) {
     foo(x);
   }
 
   // CHECK:      CXXExpansionStmtDecl
-  // CHECK-NEXT:   CXXIteratingExpansionStmtPattern
+  // CHECK-NEXT:   CXXExpansionStmtPattern {{.*}} iterating
   // CHECK:        CXXExpansionStmtInstantiation
   static constexpr Array<int, 3> a;
   template for (auto x : a) {
@@ -33,7 +33,7 @@ void test(T t) {
   }
 
   // CHECK:      CXXExpansionStmtDecl
-  // CHECK-NEXT:   CXXDestructuringExpansionStmtPattern
+  // CHECK-NEXT:   CXXExpansionStmtPattern {{.*}} destructuring
   // CHECK:        CXXExpansionStmtInstantiation
   int arr[3]{1, 2, 3};
   template for (auto x : arr) {
@@ -41,7 +41,7 @@ void test(T t) {
   }
 
   // CHECK:      CXXExpansionStmtDecl
-  // CHECK-NEXT:   CXXDependentExpansionStmtPattern
+  // CHECK-NEXT:   CXXExpansionStmtPattern {{.*}} dependent
   // CHECK-NOT:    CXXExpansionStmtInstantiation
   template for (auto x : t) {
     foo(x);

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

Reply via email to