This patch adds support for serializing and deserializing SPLICE_SCOPE trees in
C++20 modules implementation. SPLICE_SCOPE is introduced by C++26 reflection,
notably used for dependent splice types, thus needing to be exported/imported
as part of the module interface. Not handling SPLICE_SCOPE leads to ICE.

This patch also includes 2 simple test cases: one for exporting splice scope
types and another for importing them.

gcc/cp/

* module.cc (trees_out::type_node): Add case for SPLICE_SCOPE.
* module.cc (trees_in::tree_node): Add case for SPLICE_SCOPE.

gcc/testsuite/

* g++.dg/modules/splice-scope-tree_a.C: New test case for exporting splice 
scope types.
* g++.dg/modules/splice-scope-tree_b.C: New test case for importing splice 
scope types.

Signed-off-by: vspefs <[email protected]>
---
gcc/cp/module.cc | 16 ++++++++++++++++
.../g++.dg/modules/splice-scope-tree_a.C | 11 +++++++++++
.../g++.dg/modules/splice-scope-tree_b.C | 11 +++++++++++
3 files changed, 38 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C
create mode 100644 gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index c786519c1c0..609f5444bd5 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -9847,6 +9847,12 @@ trees_out::type_node (tree type)
case META_TYPE:
/* No additional data. */
break;
+
+ case SPLICE_SCOPE:
+ if (streaming_p ())
+ u (SPLICE_SCOPE_TYPE_P (type));
+ tree_node (SPLICE_SCOPE_EXPR (type));
+ break;
}

tree_node (TYPE_ATTRIBUTES (type));
@@ -10697,6 +10703,16 @@ trees_in::tree_node (bool is_use)
if (!get_overrun ())
res = meta_info_type_node;
break;
+
+ case SPLICE_SCOPE:
+ {
+ bool type = u ();
+ tree expr = tree_node ();
+
+ if (!get_overrun ())
+ res = make_splice_scope (expr, type);
+ }
+ break;
}

/* In the exporting TU, a derived type with attributes was built by
diff --git a/gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C 
b/gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C
new file mode 100644
index 00000000000..64045666e0e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/splice-scope-tree_a.C
@@ -0,0 +1,11 @@
+// { dg-additional-options "-fmodules" }
+
+export module exporting_splice_scope;
+// { dg-module-cmi exporting_splice_scope }
+
+export template <typename T>
+using dependent_splice_type = typename [: ^^T :];
+
+export template <bool Cond, typename T, typename U>
+using somehow_more_complicated_dependent_splice_type =
+ typename [: Cond ? ^^T : ^^U :];
\ No newline at end of file
diff --git a/gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C 
b/gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C
new file mode 100644
index 00000000000..548e8bb63ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/splice-scope-tree_b.C
@@ -0,0 +1,11 @@
+// { dg-additional-options "-fmodules" }
+
+import exporting_splice_scope;
+
+int
+main ()
+{
+ static_assert (^^dependent_splice_type<int> == ^^int);
+ static_assert (^^somehow_more_complicated_dependent_splice_type<true, int, 
double> == ^^int);
+ static_assert (^^somehow_more_complicated_dependent_splice_type<false, int, 
double> == ^^double);
+}
\ No newline at end of file
--
2.52.0

Reply via email to