From c8f44c08afd8fa2c818bcf563b8182c904790ad6 Mon Sep 17 00:00:00 2001 From: Sirraide 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 f31e1c343e8aa..918515dbf127c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -189,6 +189,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 `_ 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/ //" -e "s/ imported//" + +template +struct Array { + T data[size]{}; + constexpr const T* begin() const { return data; } + constexpr const T* end() const { return data + size; } +}; + +void foo(int); + +template +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 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 +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 void test(T t) { +template +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 a; + // CHECK-NEXT: template for (auto x : a) { + // CHECK-NEXT: foo(x); + // CHECK-NEXT: } + static constexpr Array 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 void test2(T t) { +template +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 a; + // CHECK-NEXT: template for (int x : a) { + // CHECK-NEXT: foo(x); + // CHECK-NEXT: } + static constexpr Array 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 @@

C++2c implementation status

Expansion Statements P1306R5 - No + Clang 22 constexpr virtual inheritance From 73cabd929e059e269e027a8a819eae37f4443bc9 Mon Sep 17 00:00:00 2001 From: Sirraide 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 a; - // CHECK-NEXT: template for (auto x : a) { + // CHECK-NEXT: template for (auto x : (a)) { // CHECK-NEXT: foo(x); // CHECK-NEXT: } static constexpr Array a; @@ -74,7 +74,7 @@ void test2(T t) { // Iterating expansion statement. // // CHECK: static constexpr Array a; - // CHECK-NEXT: template for (int x : a) { + // CHECK-NEXT: template for (int x : (a)) { // CHECK-NEXT: foo(x); // CHECK-NEXT: } static constexpr Array a; From 5f6fb414ace10c9d59f4edec685888eddc69fddc Mon Sep 17 00:00:00 2001 From: Sirraide 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 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 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 b2ede3fd9bbfe398337ba49b846c89cbfc2b320c Mon Sep 17 00:00:00 2001 From: Sirraide 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 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 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);