Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.0/patches/2175270/?format=api
{ "id": 2175270, "url": "http://patchwork.ozlabs.org/api/1.0/patches/2175270/?format=api", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/1.0/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<aULfAZWPr7sGe7JD@redhat.com>", "date": "2025-12-17T16:49:05", "name": "[8/9,v2] c++: C++26 Reflection [PR120775]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "9c265ca5171ebf3b6b00cf29224c634cc1ce2d40", "submitter": { "id": 14370, "url": "http://patchwork.ozlabs.org/api/1.0/people/14370/?format=api", "name": "Marek Polacek", "email": "polacek@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/aULfAZWPr7sGe7JD@redhat.com/mbox/", "series": [ { "id": 485726, "url": "http://patchwork.ozlabs.org/api/1.0/series/485726/?format=api", "date": "2025-12-17T16:42:41", "name": "c++: C++26 Reflection [PR120775]", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/485726/mbox/" } ], "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2175270/checks/", "tags": {}, "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=V60OBujo;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=V60OBujo", "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com", "sourceware.org; spf=pass smtp.mailfrom=redhat.com", "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dWftt6dbjz1xpw\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 03:50:46 +1100 (AEDT)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id D5ABB4BA2E3B\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 17 Dec 2025 16:50:44 +0000 (GMT)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id E7C874BA2E2B\n for <gcc-patches@gcc.gnu.org>; Wed, 17 Dec 2025 16:49:16 +0000 (GMT)", "from mail-qk1-f199.google.com (mail-qk1-f199.google.com\n [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-564-3dLBahkHMQKjn4IqCVdgdw-1; Wed, 17 Dec 2025 11:49:14 -0500", "by mail-qk1-f199.google.com with SMTP id\n af79cd13be357-8b22ab98226so1920825585a.2\n for <gcc-patches@gcc.gnu.org>; Wed, 17 Dec 2025 08:49:14 -0800 (PST)", "from redhat.com ([2603:7000:9500:10::1db4])\n by smtp.gmail.com with ESMTPSA id\n af79cd13be357-8be31c75e9esm435416185a.50.2025.12.17.08.49.06\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 17 Dec 2025 08:49:07 -0800 (PST)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org D5ABB4BA2E3B", "OpenDKIM Filter v2.11.0 sourceware.org E7C874BA2E2B" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org E7C874BA2E2B", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org E7C874BA2E2B", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1765990157; cv=none;\n b=HM1pUjEL9w8rmkBAemke/ex5cUpboyKZ6Oq3SYZgIn55dNrlC9joPsh4spNNUDNE4A551XZjQSJdb87I4q68hXOjnkAZCV8DwtdrbltjeRoAITIJXFDetlETuzNOk9QG2DzbEVwaS/FACm3lbnyFZHJkgdDk5kpgjpsQHEjU9KY=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1765990157; c=relaxed/simple;\n bh=H4vcpZmuMFEgmp6vamoXK+lv3nMuBVA1Whnes6XrOZA=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=t+kiYJ2MqwLmFLaeur6i+hIp+UBQZVSlDbvUCJ2CI6+lA4i5P28LmBXY3nWnv2R57bcG5O+i8l6pCHpD618KXgqMOhqkcJ3H7YO8MkZEMM24DevMuaO+bOJr8h8MKGr/6dpUYnVQX45LB/Bu2UYS981Bl0/oQ3tposjWqdlFsIA=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1765990156;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=H46xu5qBm63b1AqA4YdFkOImKANMfs5NCJgGvcqUtDc=;\n b=V60OBujo/rC8l8ufwV6EdsqBO6QqKrWyI28xmwyWn9ASZVMq2oqSgrLjmNGOaYOjxx28ts\n ZLy4ggSE3A+G9BTauwG1qhANnGIWiBvYz6H+w+i/sy9WWHJcoUY1xFj5k3MiFDfAXDvWEL\n t6G6vhclF/ETevtN4TwuVK3nQcrdCjA=", "X-MC-Unique": "3dLBahkHMQKjn4IqCVdgdw-1", "X-Mimecast-MFC-AGG-ID": "3dLBahkHMQKjn4IqCVdgdw_1765990154", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1765990153; x=1766594953;\n h=user-agent:in-reply-to:content-disposition:mime-version:references\n :message-id:subject:to:from:date:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=H46xu5qBm63b1AqA4YdFkOImKANMfs5NCJgGvcqUtDc=;\n b=MnNC29/U50N7swdYf2D2utR/ybrR+yfNe5UQXKTL4H32/6xr4FIeg5rRTj+mB9vVto\n MsUM5SiJTEATUewHLmZsRYVjW3Xh5QsXdOW00xHUhBRlYYb+AEodPUFqV+vTCn8o2TkF\n 8ymsnr7ODMGHZLLilswxrNKfNHm/Bo46OgFxDdLX6Ya9hkM3lmiAB55Tgt/+pHs+bm+q\n X6nVJG4KfBkR50EvL6+P2Th9NVVwnkhcQKqQoexMHL43j4h/tExq/K6b7AGW8LIoKP8w\n /ppL+tj98stfFOdk7KVoKg0kMtriksF3drU/FwnNdNcbeAX16YtH02ciNVduhD6uSPC6\n ChtA==", "X-Gm-Message-State": "AOJu0YyDJaCS6mp9wvFN9Vuf1XPj9uxUTi8QxxvOptEkmG0Bvb865dJB\n bHj+v/wahgXEb9O2L7tfzYPgau+zYRY/3BXA+As3Oc+rfifGFrOzCWV9Ujxe0mF1hrvHTn//rRp\n VFpFxXtr73ZR0G90temou0yJ+3yYQYlksE4QfQ9n2m9ykZjC77AD1koXW7619NhcOQ2NECmyfZK\n cS067eyZsp6El5tcEOTbJdJOP8pH7UyUgeg4JkzvRyig==", "X-Gm-Gg": "AY/fxX7OIknDRYH435rQo0Gsv5RX4CynXgaqPYq82mJimyD+uN0EQnbbd2ZswIxIG4b\n 6X7zlxxPj/3mMs9080cwBHSnCKuu5gUBOjH5SGTS3nkntJ3uCXIHZjiTeBnSiNnt6+qbWAKTRzH\n toDroKx1K0qFKj2aw2rvssj1/dyV1ePdyYC+tYH0u2o6iNFO0ZyHZBo7POIrnhRgAbg1XX3Pnh4\n /X3GjTBGSu90WmjCyZa4nMDv5nRxwSAEbEX02H0Shg5B5HhmyXnjia3Ga5pNWZ3boiu3JwKkPRK\n qL4fnX66EI+fD5+L4Qkki791ufBUEylq8CX6FFuHxVBq8mrhpL1dhmLA9WXXnqHSaw==", "X-Received": [ "by 2002:a05:620a:1a92:b0:8b2:ed02:21ea with SMTP id\n af79cd13be357-8bb3a3878demr2467850485a.67.1765990150321;\n Wed, 17 Dec 2025 08:49:10 -0800 (PST)", "by 2002:a05:620a:1a92:b0:8b2:ed02:21ea with SMTP id\n af79cd13be357-8bb3a3878demr2467836785a.67.1765990148587;\n Wed, 17 Dec 2025 08:49:08 -0800 (PST)" ], "X-Google-Smtp-Source": "\n AGHT+IFepPQAG5w6EgyEpXJ4tVOm0mNZXHHncoxxz6MGA0G4MdmvsVCLtVN+c6ypQGC7QqZsjQCcFg==", "Date": "Wed, 17 Dec 2025 11:49:05 -0500", "From": "Marek Polacek <polacek@redhat.com>", "To": "GCC Patches <gcc-patches@gcc.gnu.org>, Jason Merrill <jason@redhat.com>,\n Jakub Jelinek <jakub@redhat.com>, Jonathan Wakely <jwakely@redhat.com>", "Subject": "[PATCH 8/9 v2] c++: C++26 Reflection [PR120775]", "Message-ID": "<aULfAZWPr7sGe7JD@redhat.com>", "References": "<aULdgYtbcyGQIxK1@redhat.com>", "MIME-Version": "1.0", "In-Reply-To": "<aULdgYtbcyGQIxK1@redhat.com>", "User-Agent": "Mutt/2.2.14 (2025-02-20)", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "CaJNYfYJbFDIjE8RCYnp89g6XeRFYKKgw--acrFauSw_1765990154", "X-Mimecast-Originator": "redhat.com", "Content-Type": "text/plain; charset=us-ascii", "Content-Disposition": "inline", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "Testsuite bits part #4.\n\n-- >8 --", "diff": "diff --git a/gcc/testsuite/g++.dg/reflect/p2996-1.C b/gcc/testsuite/g++.dg/reflect/p2996-1.C\nnew file mode 100644\nindex 00000000000..d89b9b06292\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-1.C\n@@ -0,0 +1,20 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from the P2996 paper.\n+\n+#include <meta>\n+\n+static_assert(std::meta::is_type(^^int())); // ^^ applies to the type-id \"int()\"\n+\n+template<bool> struct X {};\n+consteval bool operator<(std::meta::info, X<false>) { return false; }\n+consteval void g(std::meta::info r, X<false> xv) {\n+ r == ^^int && true; // { dg-error \"expected\" }\n+ r == ^^int & true; // { dg-error \"expected\" }\n+ r == (^^int) && true; // OK\n+ r == ^^int &&&& true; // { dg-error \"expected|cannot declare\" }\n+ ^^X < xv; // { dg-error \"could not convert\" }\n+\t\t\t // error: reflect-expression whose terminal name is a\n+ // template-name is followed by <\n+ (^^X) < xv; // OK\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-10.C b/gcc/testsuite/g++.dg/reflect/p2996-10.C\nnew file mode 100644\nindex 00000000000..d3369e2882c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-10.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [dcl.type.splice].\n+\n+struct S { using type = int; };\n+template <auto R> struct TCls {\n+ typename [:R:]::type member; // typename applies to the qualified name\n+};\n+\n+void fn() {\n+ [:^^S::type:] *var; // { dg-error \"expected a reflection of an expression|not declared\" }\n+ typename [:^^S::type:] *var; // OK, declares variable with type int*\n+}\n+\n+using alias = [:^^S::type:]; // OK, type-only context\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-11.C b/gcc/testsuite/g++.dg/reflect/p2996-11.C\nnew file mode 100644\nindex 00000000000..5341f1f9d76\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-11.C\n@@ -0,0 +1,16 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.prim.id.qual].\n+\n+template<int V>\n+struct TCls {\n+ static constexpr int s = V;\n+ using type = int;\n+};\n+\n+int v1 = [:^^TCls<1>:]::s;\n+int v2 = template [:^^TCls:]<2>::s;\t // OK, template binds to splice-scope-specifier\n+typename [:^^TCls:]<3>::type v3 = 3;\t // OK, typename binds to the qualified name\n+template [:^^TCls:]<3>::type v4 = 4;\t // OK, template binds to the splice-scope-specifier\n+typename template [:^^TCls:]<3>::type v5 = 5; // OK, same as v3\n+[:^^TCls:]<3>::type v6 = 6;\t // { dg-error \"missing .template.|expected\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-12.C b/gcc/testsuite/g++.dg/reflect/p2996-12.C\nnew file mode 100644\nindex 00000000000..58a145693f4\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-12.C\n@@ -0,0 +1,24 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [basic.splice].\n+\n+using info = decltype(^^int);\n+\n+constexpr int v = 1;\n+template<int V> struct TCls {\n+ static constexpr int s = V + 1;\n+};\n+\n+// OK, a splice-specialization-specifier with a splice-expression as a template argument\n+using alias = [:^^TCls:]<([:^^v:])>;\n+\n+static_assert(alias::s == 2);\n+\n+// error: < means less than\n+auto o1 = [:^^TCls:]<([:^^v:])>(); // { dg-error \"reflection .TCls<1>. not usable\" }\n+// OK, o2 is an object of type TCls<1>\n+auto o2 = typename [:^^TCls:]<([:^^v:])>();\n+\n+consteval int bad_splice(info v) {\n+ return [:v:];\t // { dg-error \".v. is not a constant expression\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-13.C b/gcc/testsuite/g++.dg/reflect/p2996-13.C\nnew file mode 100644\nindex 00000000000..5d95871d86b\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-13.C\n@@ -0,0 +1,19 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.prim.req.type].\n+\n+template<typename T, typename T::type = 0> struct S;\n+template<typename T> using Ref = T&;\n+template<typename T> concept C = requires {\n+ typename T::inner;\n+ // required nested member name\n+ typename S<T>;\n+ // required valid (13.3) template-id; fails if T::type does not exist as a type\n+ // to which 0 can be implicitly converted\n+ typename Ref<T>;\n+ // required alias template substitution, fails if T is void\n+ typename [:T::r1:];\n+ // fails if T::r1 is not a reflection of a type\n+ typename [:T::r2:]<int>;\n+ // fails if T::r2 is not a reflection of a template Z for which Z<int> is a type\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-14.C b/gcc/testsuite/g++.dg/reflect/p2996-14.C\nnew file mode 100644\nindex 00000000000..a296c3b9300\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-14.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.reflect]/5.\n+\n+using info = decltype(^^void);\n+\n+struct A { struct S {}; };\n+struct B : A { using A::S; };\n+constexpr info r1 = ^^B::S;\t// { dg-error \"cannot be applied to a using-declarator\" }\n+struct C : virtual B { struct S {}; };\n+struct D : virtual B, C {};\n+D::S s;\n+constexpr info r2 = ^^D::S;// OK, names C::S per 6.5.2\n+// OK, result C::S not found through using-declarator\n+\n+struct E : A { };\n+constexpr info r3 = ^^E::S;\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-15.C b/gcc/testsuite/g++.dg/reflect/p2996-15.C\nnew file mode 100644\nindex 00000000000..3ced17647ae\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-15.C\n@@ -0,0 +1,16 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.const].\n+\n+using info = decltype(^^int);\n+\n+struct Base { };\n+struct Derived : Base { info r; };\n+\n+consteval const Base& fn(const Derived& derived) { return derived; }\n+\n+constexpr Derived obj{.r=^^::}; // OK\n+constexpr const Derived& d = obj; // OK\n+constexpr const Base& b1 = fn(obj); // { dg-error \"reference into an object of consteval-only\" }\n+constexpr const Base& b2 = obj;\t // { dg-error \"reference into an object of consteval-only\" }\n+constexpr Base b3 = obj;\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-16.C b/gcc/testsuite/g++.dg/reflect/p2996-16.C\nnew file mode 100644\nindex 00000000000..91506d327b6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-16.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// List of Types to List of Sizes\n+\n+#include <algorithm>\n+#include <array>\n+#include <meta>\n+#include <ranges>\n+\n+constexpr std::array types = {^^int, ^^float, ^^double};\n+constexpr std::array sizes = []{\n+ std::array<std::size_t, types.size()> r;\n+ std::ranges::transform(types, r.begin(), std::meta::size_of);\n+ return r;\n+}();\n+static_assert (sizes[0] == sizeof (int));\n+static_assert (sizes[1] == sizeof (float));\n+static_assert (sizes[2] == sizeof (double));\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-17.C b/gcc/testsuite/g++.dg/reflect/p2996-17.C\nnew file mode 100644\nindex 00000000000..e9dabb0d799\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-17.C\n@@ -0,0 +1,32 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2996r13.html#compile-time-ticket-counter\n+\n+#include <meta>\n+\n+template<int N> struct Helper;\n+\n+struct TU_Ticket {\n+ static consteval int latest ()\n+ {\n+ int k = 0;\n+ while (is_complete_type (substitute (^^Helper,\n+\t\t\t\t\t { std::meta::reflect_constant (k) })))\n+ ++k;\n+ return k;\n+ }\n+ static consteval void increment ()\n+ {\n+ define_aggregate (substitute (^^Helper,\n+\t\t\t\t { std::meta::reflect_constant (latest ()) }),\n+\t\t {});\n+ }\n+};\n+constexpr int x = TU_Ticket::latest (); // x initialized to 0.\n+consteval { TU_Ticket::increment (); }\n+constexpr int y = TU_Ticket::latest (); // y initialized to 1.\n+consteval { TU_Ticket::increment (); }\n+constexpr int z = TU_Ticket::latest (); // z initialized to 2.\n+static_assert (x == 0);\n+static_assert (y == 1);\n+static_assert (z == 2);\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-18.C b/gcc/testsuite/g++.dg/reflect/p2996-18.C\nnew file mode 100644\nindex 00000000000..ec72e44d80f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-18.C\n@@ -0,0 +1,46 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [meta.reflection.access.context].\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A {\n+ int a = 0;\n+ consteval A(int p) : a(p) {}\n+};\n+struct B : A {\n+ using A::A;\n+ consteval B(int p, int q) : A(p * q) {}\n+ info s = access_context::current().scope();\n+};\n+struct C : B { using B::B; };\n+\n+struct Agg {\n+ consteval bool eq(info rhs = access_context::current().scope()) {\n+ return s == rhs;\n+ }\n+ info s = access_context::current().scope();\n+};\n+\n+namespace NS {\n+ static_assert(Agg{}.s == access_context::current().scope()); // OK\n+ static_assert(Agg{}.eq()); // OK\n+ static_assert(B(1).s == ^^B); // OK\n+ static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); // OK\n+ static_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); // OK\n+\n+ auto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:];\n+ static_assert(return_type_of(type_of(^^fn)) == ^^int);\n+ static_assert(type_of(^^fn) == ^^auto()->int); // OK\n+\n+ template<auto R>\n+ struct TCls {\n+ consteval bool fn()\n+ requires (is_type(access_context::current().scope())) {\n+ return true; // OK, scope is TCls<R>.\n+ }\n+ };\n+ static_assert(TCls<0>{}.fn()); // OK\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-19.C b/gcc/testsuite/g++.dg/reflect/p2996-19.C\nnew file mode 100644\nindex 00000000000..e859a08eb80\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-19.C\n@@ -0,0 +1,22 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [meta.reflection.access.queries].\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval access_context fn() {\n+ return access_context::current();\n+}\n+\n+class Cls {\n+ int mem;\n+ friend consteval access_context fn();\n+public:\n+ static constexpr auto r = ^^mem;\n+};\n+\n+static_assert(is_accessible(Cls::r, fn())); // OK\n+static_assert(!is_accessible(Cls::r, access_context::current())); // OK\n+static_assert(is_accessible(Cls::r, access_context::unchecked())); // OK\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-2.C b/gcc/testsuite/g++.dg/reflect/p2996-2.C\nnew file mode 100644\nindex 00000000000..a4edaf4ecc1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-2.C\n@@ -0,0 +1,27 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from the P2996 paper.\n+\n+#include <vector>\n+\n+template <typename T> void fn() requires (^^T != ^^int);\n+template <typename T> void fn() requires (^^T == ^^int);\n+template <typename T> void fn() requires (sizeof(T) == sizeof(int));\n+\n+constexpr auto a = ^^fn<char>; // OK\n+constexpr auto b = ^^fn<int>; // { dg-error \"insufficient contextual information to determine type\" }\n+\n+constexpr auto c = ^^std::vector; // OK\n+\n+template <typename T>\n+struct S {\n+ static constexpr auto r = ^^T;\n+ using type = T;\n+};\n+static_assert(S<int>::r == ^^int);\n+static_assert(^^S<int>::type != ^^int);\n+\n+typedef struct X {} Y;\n+typedef struct Z {} Z;\n+constexpr auto e = ^^Y; // OK, represents the type alias Y\n+constexpr auto f = ^^Z; // OK, represents the type Z (not the type alias)\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-20.C b/gcc/testsuite/g++.dg/reflect/p2996-20.C\nnew file mode 100644\nindex 00000000000..2c87776e9d5\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-20.C\n@@ -0,0 +1,61 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <functional>\n+#include <meta>\n+#include <utility>\n+#include <vector>\n+#include <initializer_list>\n+#include <tuple>\n+\n+template<std::pair<std::size_t, std::size_t>... indices>\n+struct Indexer {\n+ template<typename Tuples>\n+ // Can use tuple indexing instead of tuple of tuples\n+ constexpr auto operator()(Tuples&& tuples) const {\n+ using ResultType = std::tuple<\n+ std::tuple_element_t<\n+ indices.second,\n+ std::remove_cvref_t<std::tuple_element_t<indices.first, std::remove_cvref_t<Tuples>>>\n+ >...\n+ >;\n+ return ResultType(std::get<indices.second>(std::get<indices.first>(std::forward<Tuples>(tuples)))...);\n+ }\n+};\n+\n+template <class T>\n+consteval auto subst_by_value(std::meta::info tmpl, std::vector<T> args)\n+ -> std::meta::info\n+{\n+ std::vector<std::meta::info> a2;\n+ for (T x : args) {\n+ a2.push_back(std::meta::reflect_constant(x));\n+ }\n+\n+ return substitute(tmpl, a2);\n+}\n+\n+consteval auto make_indexer(std::vector<std::size_t> sizes)\n+ -> std::meta::info\n+{\n+ std::vector<std::pair<int, int>> args;\n+\n+ for (std::size_t tidx = 0; tidx < sizes.size(); ++tidx) {\n+ for (std::size_t eidx = 0; eidx < sizes[tidx]; ++eidx) {\n+ args.push_back({tidx, eidx});\n+ }\n+ }\n+\n+ return subst_by_value(^^Indexer, args);\n+}\n+\n+template<typename... Tuples>\n+constexpr auto my_tuple_cat(Tuples&&... tuples) {\n+ constexpr typename [: make_indexer({tuple_size(remove_cvref(^^Tuples))...}) :] indexer;\n+ return indexer(std::forward_as_tuple(std::forward<Tuples>(tuples)...));\n+}\n+\n+int r;\n+constexpr auto x = my_tuple_cat(std::make_tuple(10, std::ref(r)), std::make_tuple(21.0, 22, 23, 24));\n+static_assert(std::same_as<decltype(x), const std::tuple<int, int&, double, int, int, int>>);\n+static_assert(std::get<5>(x) == 24);\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-21.C b/gcc/testsuite/g++.dg/reflect/p2996-21.C\nnew file mode 100644\nindex 00000000000..8a9f7895d59\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-21.C\n@@ -0,0 +1,68 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.const]/31.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S0 {\n+ consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+ std::meta::define_aggregate(^^S0, {});\t\t// error: scope associated with S0 encloses the consteval block\n+ }\t\t\t\t\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S0' being defined\" \"\" { target *-*-* } .-1 }\n+};\n+\n+struct S1;\n+consteval { std::meta::define_aggregate(^^S1, {}); }\t// OK\n+\n+template <std::meta::info R> consteval void tfn1() {\n+ std::meta::define_aggregate(R, {});\n+}\n+\n+struct S2;\n+consteval { tfn1<^^S2>(); }\t\t\t\t// OK\n+\n+template <std::meta::info R> consteval void tfn2() {\n+ consteval { std::meta::define_aggregate(R, {}); }\t// { dg-error \"'consteval void tfn2\\\\\\(\\\\\\) \\\\\\[with std::meta::info R = \\\\\\^\\\\\\^S3\\\\\\]' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'S3' scope\" }\n+}\t\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" \"\" { target *-*-* } .-1 }\n+\n+struct S3;\n+consteval { tfn2<^^S3>(); }\n+ // error: function parameter scope of tfn2<^^S3> intervenes between the declaration of S3\n+ // and the consteval block that produces the injected declaration\n+\n+template <typename> struct TCls {\n+ struct S4;\n+ static void sfn() requires ([] {\n+ consteval { std::meta::define_aggregate(^^S4, {}); } // { dg-error \"TCls<void>::<lambda\\\\\\(\\\\\\)>' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'TCls<void>::S4' scope\" }\n+ return true;\t\t\t\t\t// { dg-message \"'consteval' block defined here\" \"\" { target *-*-* } .-1 }\n+ }()) { }\n+};\n+\n+consteval { TCls<void>::sfn(); }\t// error: TCls<void>::S4 is not enclosed by requires-clause lambda\n+// { dg-error \"call to non-'constexpr' function 'static void TCls< <template-parameter-1-1> >::sfn\\\\\\(\\\\\\) requires \\\\\\(<lambda>\\\\\\)\\\\\\(\\\\\\) \\\\\\[with <template-parameter-1-1> = void\\\\\\]'\" \"\" { target *-*-* } .-1 }\n+\n+struct S5;\n+struct Cls {\n+ consteval { std::meta::define_aggregate(^^S5, {}); } // error: S5 is not enclosed by class Cls\n+};\t\t\t\t\t\t// { dg-error \"'Cls' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'S5' scope\" \"\" { target *-*-* } .-1 }\n+\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" \"\" { target *-*-* } .-2 }\n+\n+struct S6;\t\t\t\t\t// { dg-message \"'consteval' block defined here\" \"\" { target *-*-* } .+1 }\n+consteval {\t\t\t\t\t// #1\n+ struct S7;\t\t\t\t\t// local class\n+\n+ std::meta::define_aggregate(^^S7, {});\t// error: consteval block #1 does not enclose itself,\n+\t\t\t\t\t\t// but encloses S7\n+\t\t\t\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block which encloses '<lambda\\\\\\(\\\\\\)> static::S7' being defined\" \"\" { target *-*-* } .-2 }\n+\n+ struct S8;\n+ consteval {\t\t\t \t\t// #2\n+ std::meta::define_aggregate(^^S6, {});\t// error: consteval block #1 encloses\n+\t\t\t\t\t\t// consteval block #2 but not S6\n+\t\t\t\t\t\t// { dg-error \"'<lambda\\\\\\(\\\\\\)> static' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'S6' scope\" \"\" { target *-*-* } .-2 }\n+\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" \"\" { target *-*-* } .-4 }\n+\n+ std::meta::define_aggregate(^^S8, {});\t// OK, consteval block #1 encloses both #2 and S8\n+ }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-3.C b/gcc/testsuite/g++.dg/reflect/p2996-3.C\nnew file mode 100644\nindex 00000000000..c61bb02c690\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-3.C\n@@ -0,0 +1,23 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test that was in [expr.prim.id.qual].\n+\n+template <int V>\n+struct TCls {\n+ static constexpr int s = V;\n+ using type = int;\n+};\n+\n+constexpr int v1 = [:^^TCls<1>:]::s;\n+static_assert (v1 == 1);\n+constexpr int v2 = template [:^^TCls:]<2>::s;\n+ // OK, template binds to splice-scope-specifier\n+static_assert (v2 == 2);\n+\n+constexpr typename [:^^TCls:]<3>::type v3 = 3;\n+ // OK, typename binds to the qualified name\n+static_assert (v3 == 3);\n+\n+constexpr [:^^TCls:]<3>::type v4 = 4; // { dg-error \"missing .template.|expected\" }\n+ // error: [:^^TCls:]< is parsed as a splice-expression followed\n+ // by a comparison operator\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-4.C b/gcc/testsuite/g++.dg/reflect/p2996-4.C\nnew file mode 100644\nindex 00000000000..4d0ee97a638\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-4.C\n@@ -0,0 +1,27 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.prim.splice].\n+\n+struct S { static constexpr int a = 1; };\n+template <typename> struct TCls { static constexpr int b = 2; };\n+\n+constexpr int c = [:^^S:]::a; // [:^^S:] is not an expression\n+static_assert(c == 1);\n+\n+constexpr int d = template [:^^TCls:]<int>::b; // template [:^^TCls:]<int> is not\n+ // an expression\n+static_assert(d == 2);\n+\n+template <auto V> constexpr int e = [:V:]; // splice-expression\n+constexpr int f1 = e<^^S::a>; // splice-expression\n+constexpr int f2 = template [:^^e:]<^^S::a>; // splice-expression\n+static_assert(f1 == 1);\n+static_assert(f2 == 1);\n+\n+constexpr auto g = typename [:^^int:](42);\n+ // [:^^int:] forms part of a type, not a splice-expression\n+static_assert(g == 42);\n+\n+constexpr auto h = ^^g;\n+constexpr auto i = e<[:^^h:]>;\t // { dg-error \"unparenthesized splice|invalid\" }\n+constexpr auto j = e<([:^^h:])>;\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-5.C b/gcc/testsuite/g++.dg/reflect/p2996-5.C\nnew file mode 100644\nindex 00000000000..e9bbbc9bfd8\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-5.C\n@@ -0,0 +1,50 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [basic.fundamental].\n+\n+#include <meta>\n+\n+int arr[] = {1, 2, 3};\n+auto [a1, a2, a3] = arr;\n+void fn();\n+enum Enum { A };\n+using Alias = int;\n+struct B {};\n+struct S : B {\n+ int mem;\n+ int : 0;\n+};\n+template <auto> struct TCls {};\n+template <auto> void TFn();\n+template <auto> int TVar;\n+template <auto> concept Concept = requires { true; };\n+namespace NS {};\n+namespace NSAlias = NS;\n+\n+constexpr auto r1 = std::meta::reflect_constant(42); // represents int value of 42\n+\n+constexpr auto r2 = std::meta::reflect_object(arr[1]); // represents int object\n+\n+constexpr auto r3 = ^^arr; // represents a variable\n+constexpr auto r4 = ^^a3; // represents a structured binding\n+constexpr auto r5 = ^^fn; // represents a function\n+constexpr auto r6 = ^^Enum::A; // represents an enumerator\n+constexpr auto r7 = ^^Alias; // represents a type alias\n+constexpr auto r8 = ^^S; // represents a type\n+constexpr auto r9 = ^^S::mem; // represents a class member\n+\n+constexpr auto r10 = std::meta::members_of (^^S, std::meta::access_context::current ())[1];\n+ // represents an unnamed bit-field\n+\n+constexpr auto r11 = ^^TCls; // represents a class template\n+constexpr auto r12 = ^^TFn; // represents a function template\n+constexpr auto r13 = ^^TVar; // represents a variable template\n+constexpr auto r14 = ^^Concept; // represents a concept\n+constexpr auto r15 = ^^NSAlias; // represents a namespace alias\n+constexpr auto r16 = ^^NS; // represents a namespace\n+\n+constexpr auto r17 = std::meta::bases_of(^^S, std::meta::access_context::current ())[0];\n+ // represents a direct base class relationship\n+\n+constexpr auto r18 = std::meta::data_member_spec(^^int, {.name=\"member\"});\n+ // represents a data member description\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-6.C b/gcc/testsuite/g++.dg/reflect/p2996-6.C\nnew file mode 100644\nindex 00000000000..4f98e211b45\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-6.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [temp.dep.splice].\n+\n+template <auto T, auto NS>\n+void fn() {\n+ using a = [:T:]<1>; // [:T:] and [:T:]<1> are dependent\n+\n+ static_assert([:NS:]::template TCls<1>::v == a::v); // [:NS:] is dependent\n+}\n+\n+namespace NS {\n+template <auto V> struct TCls { static constexpr int v = V; };\n+}\n+\n+int main() {\n+ fn<^^NS::TCls, ^^NS>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-7.C b/gcc/testsuite/g++.dg/reflect/p2996-7.C\nnew file mode 100644\nindex 00000000000..6d9a632f9b3\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-7.C\n@@ -0,0 +1,16 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [temp.dep.namespace].\n+\n+using info = decltype(^^int);\n+\n+template <info R> int fn() {\n+ namespace Alias = [:R:]; // [:R:] is dependent\n+ return Alias::v; // Alias is dependent\n+}\n+\n+namespace NS {\n+ int v = 1;\n+}\n+\n+int a = fn<^^NS>();\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-8.C b/gcc/testsuite/g++.dg/reflect/p2996-8.C\nnew file mode 100644\nindex 00000000000..38a9db49437\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-8.C\n@@ -0,0 +1,14 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [temp.dep.splice].\n+\n+template<template<class> class X>\n+struct S {\n+ typename [: ^^X :]<int, float> m; // { dg-error \"wrong number of template arguments\" }\n+};\n+\n+template<class> struct V1 {};\n+template<class, class = int> struct V2 {};\n+\n+S<V1> s1; // { dg-message \"required from here\" }\n+S<V2> s2; // OK\ndiff --git a/gcc/testsuite/g++.dg/reflect/p2996-9.C b/gcc/testsuite/g++.dg/reflect/p2996-9.C\nnew file mode 100644\nindex 00000000000..6b659cc3e49\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p2996-9.C\n@@ -0,0 +1,24 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [over.match.viable].\n+// FIXME We should give the errors below.\n+\n+namespace A {\n+ extern \"C\" void f(int = 5);\n+}\n+namespace B {\n+ extern \"C\" void f(int = 5);\n+}\n+\n+void splice() {\n+ [:^^A::f:](3); // OK, default argument was not used for viability\n+ [:^^A::f:](); // error: found default argument twice\n+}\n+\n+using A::f;\n+using B::f;\n+\n+void use() {\n+ f(3); // OK, default argument was not used for viability\n+ f(); // error: found default argument twice\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p3394-1.C b/gcc/testsuite/g++.dg/reflect/p3394-1.C\nnew file mode 100644\nindex 00000000000..23e676f8b7c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p3394-1.C\n@@ -0,0 +1,174 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Slightly tweaked test from P3394R4 3.2\n+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3394r4.html#test-parametrization\n+// TODO: Doesn't link currently, once it does, it should be dg-do run test\n+// with output checking or something like that.\n+\n+#include <meta>\n+#include <array>\n+#include <print>\n+\n+namespace impl {\n+ template <auto... vals>\n+ struct replicator_type {\n+ template <typename F>\n+ constexpr void operator >> (F body) const\n+ {\n+ (body.template operator () <vals> (), ...);\n+ }\n+ };\n+\n+ template <auto... vals>\n+ replicator_type <vals...> replicator = {};\n+}\n+\n+template <typename R>\n+consteval auto\n+expand (R range)\n+{\n+ std::vector<std::meta::info> args;\n+ for (auto r : range)\n+ args.push_back (std::meta::reflect_constant (r));\n+ return substitute (^^impl::replicator, args);\n+}\n+\n+template <size_t N, class F>\n+constexpr decltype (auto)\n+with_indices (F f)\n+{\n+ return [&] <size_t... Is> (std::index_sequence <Is...>) -> decltype (auto) {\n+\t return f(std::integral_constant<size_t, Is>{}...);\n+\t } (std::make_index_sequence <N> {});\n+}\n+\n+template <typename... Ts>\n+struct Tuple {\n+ struct storage;\n+ consteval {\n+ define_aggregate (^^storage, { data_member_spec (^^Ts, { .name = \"_\" })... });\n+ }\n+ static constexpr auto ctx = std::meta::access_context::current ();\n+ static constexpr auto nsdms\n+ = define_static_array (nonstatic_data_members_of (^^storage, ctx));\n+\n+ storage s;\n+\n+ template <class F>\n+ decltype (auto) apply (F f)\n+ {\n+ return with_indices <sizeof... (Ts)> ([&] (auto... Is) -> decltype (auto) {\n+\t\t\t\t\t return f (s.[: nsdms[Is] :]...);\n+\t\t\t\t\t });\n+ }\n+};\n+\n+template <typename... Ts>\n+Tuple (Ts...) -> Tuple <Ts...>;\n+\n+template <size_t N, typename... Ts>\n+struct Parametrize {\n+ Tuple <Ts...> arr[N];\n+ auto begin () const { return arr; }\n+ auto end () const { return arr + N; }\n+};\n+\n+template <typename... Ts, size_t N>\n+constexpr auto\n+parametrize (Tuple<Ts...> (&&arr) [N])\n+{\n+ return with_indices <N> ([&] (auto... Is) {\n+\t\t\t return Parametrize <N, Ts...> { { arr[Is]... } };\n+\t\t\t });\n+}\n+\n+consteval auto\n+nonstatic_member_functions_of (std::meta::info type)\n+{\n+ auto ctx = std::meta::access_context::current ();\n+ auto members = members_of (type, ctx);\n+ std::erase_if (members, [] (std::meta::info m) {\n+\t\t\t return not (is_function (m)\n+\t\t\t\t\tand not is_static_member (m)\n+\t\t\t\t\tand not is_special_member_function (m));\n+\t\t\t });\n+ return members;\n+}\n+\n+consteval std::meta::info\n+parametrization_of (std::meta::info M)\n+{\n+ for (auto a : annotations_of (M))\n+ {\n+ auto t = type_of (a);\n+ if (has_template_arguments (t) and template_of (t) == ^^Parametrize)\n+\treturn a;\n+ }\n+ return std::meta::info ();\n+}\n+\n+template <std::meta::info M, class F>\n+void\n+invoke_single_test (F f)\n+{\n+ constexpr auto A = parametrization_of (M);\n+\n+ if constexpr (A != std::meta::info ())\n+ {\n+ constexpr auto Params = extract <typename [: type_of (A) :]> (A);\n+ for (auto P : Params)\n+\tP.apply (f);\n+ }\n+ else\n+ f ();\n+}\n+\n+template <std::meta::info M>\n+void\n+invoke_single_test ()\n+{\n+ invoke_single_test <M> ([: M :]);\n+}\n+\n+template <std::meta::info Namespace>\n+void\n+invoke_all ()\n+{\n+ [: expand (members_of (Namespace, std::meta::access_context::current ())) :]\n+ >> [] <std::meta::info M> {\n+\t if constexpr (is_function(M) and identifier_of (M).starts_with (\"test_\"))\n+\t invoke_single_test <M> ();\n+\t else if constexpr (is_type (M))\n+\t [: expand (nonstatic_member_functions_of (M)) :]\n+\t >> [] <std::meta::info F> {\n+\t\t if constexpr (identifier_of (F).starts_with (\"test_\"))\n+\t\t invoke_single_test <F> ([&] (auto... args) {\n+\t\t\t\t\t typename [: M :] fixture;\n+\t\t\t\t\t fixture.[: F :] (args...);\n+\t\t\t\t\t });\n+\t\t};\n+ };\n+}\n+\n+namespace N\n+{\n+ [[=parametrize ({ Tuple {1, 1, 2}, Tuple {1, 2, 3} })]]\n+ void test_sum (int x, int y, int z)\n+ {\n+ std::println (\"Called test_sum (x={}, y={}, z={})\", x, y, z);\n+ }\n+\n+ struct Fixture {\n+ Fixture () { std::println (\"setup fixture\"); }\n+ ~Fixture() { std::println (\"teardown fixture\"); }\n+ [[=parametrize ({ Tuple {1}, Tuple {2} })]]\n+ void test_one (int x) { std::println (\"test one({})\", x); }\n+ void test_two () { std::println(\"test two\"); }\n+ };\n+}\n+\n+int\n+main ()\n+{\n+ invoke_all <^^N> ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/p3491-1.C b/gcc/testsuite/g++.dg/reflect/p3491-1.C\nnew file mode 100644\nindex 00000000000..d8e5722da4e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p3491-1.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from P3491R3 3.3\n+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html#return-type-and-layering\n+\n+#include <meta>\n+#include <ranges>\n+#include <type_traits>\n+\n+template <std::size_t N>\n+struct FixedString {\n+ char data[N] = {};\n+\n+ constexpr FixedString (char const (&str) [N]) { std::ranges::copy (str, str + N, data); }\n+};\n+\n+template <FixedString S>\n+struct Test { };\n+\n+using A = Test <\"foo\">;\n+using E = Test <([: std::meta::reflect_constant_string (\"foo\") :])>;\n+using F = [: substitute (^^Test, { std::meta::reflect_constant_string (\"foo\") }) :];\n+\n+static_assert (std::is_same_v <A, E>);\n+static_assert (std::is_same_v <A, F>);\ndiff --git a/gcc/testsuite/g++.dg/reflect/p3491-2.C b/gcc/testsuite/g++.dg/reflect/p3491-2.C\nnew file mode 100644\nindex 00000000000..b0de7a90a52\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p3491-2.C\n@@ -0,0 +1,50 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from P3491R3 3.5.4\n+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html#with-expansion-statements\n+\n+#include <meta>\n+#include <ranges>\n+#include <type_traits>\n+\n+constexpr auto foo() -> std::vector<int> { return {1, 2, 3}; }\n+\n+consteval void bar() {\n+ template for (constexpr int I : foo()) {\n+ // doesn't work\n+ }\t\t// { dg-error \"modification of '<temporary>' from outside current evaluation is not a constant expression\" }\n+}\n+\n+consteval int baz() {\n+ int r = 0;\n+#if 0\n+ // TODO: This doesn't work yet.\n+ template for (constexpr int I : std::define_static_array(foo())) {\n+\tr += I;\n+ }\n+#else\n+ // Ugly workaround for that.\n+ template for (constexpr int I : (const std::span<const int>)std::define_static_array(foo())) {\n+\tr += I;\n+ }\n+#endif\n+ return r;\n+}\n+\n+consteval int qux() {\n+ int r = 0;\n+ template for (constexpr int I : [: std::meta::reflect_constant_array(foo()) :]) {\n+ r += I;\n+ }\n+ return r;\n+}\n+\n+template <typename>\n+consteval int fred() {\n+ constexpr auto [...m] = [: std::meta::reflect_constant_array(foo()) :];\n+ return (... + m);\n+}\n+\n+static_assert (baz() == 6);\n+static_assert (qux() == 6);\n+static_assert (fred<int>() == 6);\ndiff --git a/gcc/testsuite/g++.dg/reflect/p3491-3.C b/gcc/testsuite/g++.dg/reflect/p3491-3.C\nnew file mode 100644\nindex 00000000000..77d16b86fa9\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/p3491-3.C\n@@ -0,0 +1,45 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from P3491R3 3.5.5\n+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html#implementing-source_location\n+\n+#include <meta>\n+\n+class source_location {\n+ struct impl {\n+\tchar const* filename;\n+\tint line;\n+ };\n+ impl const* p_;\n+ constexpr source_location(impl const* x) noexcept : p_{x} {}\n+\n+public:\n+ static consteval auto current(char const* file = __builtin_FILE(),\n+\t\t\t\t int line = __builtin_LINE()) noexcept\n+\t-> source_location\n+ {\n+\t// first, we canonicalize the file\n+\t// Note, the paper uses just define_static_string(file), but that\n+\t// doesn't work, char const* argument isn't a valid input_range.\n+\timpl data = {.filename = std::define_static_string(std::string_view(file)), .line = line};\n+\n+\t// then we canonicalize the data\n+\timpl const* p = std::define_static_object(data);\n+\n+\t// and now we have an external linkage object mangled with this location\n+\treturn source_location{p};\n+ }\n+ constexpr source_location() noexcept : p_{nullptr} { }\n+ constexpr int line() const noexcept { return p_ ? p_->line : 0; }\n+ constexpr const char* file_name() const noexcept { return p_ ? p_->filename : \"\"; }\n+};\n+\n+static_assert (::source_location::current ().line() == std::source_location::current ().line ());\n+static_assert (::source_location::current ().line() == std::source_location::current ().line ());\n+static_assert (::source_location::current ().line()\n+\t == std::source_location::current ().line () - 1);\n+static_assert (std::string_view (::source_location::current ().file_name ())\n+\t == std::string_view (std::source_location::current ().file_name ()));\n+static_assert (::source_location().line() == 0);\n+static_assert (std::string_view (::source_location ().file_name ())\n+\t == std::string_view (\"\"));\ndiff --git a/gcc/testsuite/g++.dg/reflect/pack-index1.C b/gcc/testsuite/g++.dg/reflect/pack-index1.C\nnew file mode 100644\nindex 00000000000..f68705b1299\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/pack-index1.C\n@@ -0,0 +1,28 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections and pack indexing.\n+\n+struct S {\n+ int x;\n+ static int sx;\n+ using type = int;\n+};\n+\n+template<typename... Ts>\n+void\n+f ()\n+{\n+ constexpr auto r1 = ^^Ts...[0]::sx;\n+ constexpr auto r2 = ^^typename Ts...[0]::type;\n+\n+ // NTTPs and pack-index-expressions cannot appear as operands\n+ // of the reflection operator.\n+ constexpr auto e = ^^Ts...[0]; // { dg-error \"cannot be applied\" }\n+}\n+\n+\n+void\n+g ()\n+{\n+ f<S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/parameters_of1.C b/gcc/testsuite/g++.dg/reflect/parameters_of1.C\nnew file mode 100644\nindex 00000000000..eb5481eedd6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parameters_of1.C\n@@ -0,0 +1,35 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::parameters_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template<class, class> struct same_type;\n+template<class T> struct same_type<T, T> {};\n+\n+void fun (int, float, double, char);\n+\n+consteval void\n+f ()\n+{\n+ auto parms = parameters_of (^^fun);\n+\n+ same_type<decltype(parms), std::vector<info>>();\n+\n+ constexpr auto p0 = parameters_of (^^fun)[0];\n+ static_assert (is_function_parameter (p0));\n+ constexpr auto p1 = parameters_of (^^fun)[1];\n+ static_assert (is_function_parameter (p1));\n+ constexpr auto p2 = parameters_of (^^fun)[2];\n+ static_assert (is_function_parameter (p2));\n+ constexpr auto p3 = parameters_of (^^fun)[3];\n+ static_assert (is_function_parameter (p3));\n+}\n+\n+void\n+g ()\n+{\n+ f ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/parameters_of2.C b/gcc/testsuite/g++.dg/reflect/parameters_of2.C\nnew file mode 100644\nindex 00000000000..3cccfab2cce\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parameters_of2.C\n@@ -0,0 +1,41 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::parameters_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+void fn0 ();\n+void fn1 (int);\n+void fn2 (int, int);\n+void fn3 (int, int, int);\n+void fn4 (int, int, int, int);\n+template<typename... Ts>\n+void tfn (Ts...);\n+\n+static_assert (parameters_of (^^void()).size() == 0);\n+static_assert (parameters_of (^^void(void)).size() == 0);\n+static_assert (parameters_of (^^void(...)).size() == 0);\n+static_assert (parameters_of (^^void(int)).size() == 1);\n+static_assert (parameters_of (^^void(int, ...)).size() == 1);\n+static_assert (parameters_of (^^void(int, int)).size() == 2);\n+static_assert (parameters_of (^^void(int, int, ...)).size() == 2);\n+static_assert (parameters_of (^^void(int, int, int)).size() == 3);\n+static_assert (parameters_of (^^void(int, int, int, ...)).size() == 3);\n+static_assert (parameters_of (^^void(int, int, int, int)).size() == 4);\n+static_assert (parameters_of (^^void(int, int, int, int, ...)).size() == 4);\n+static_assert (parameters_of (^^void(int, int, int, int, int)).size() == 5);\n+static_assert (parameters_of (^^void(int, int, int, int, int, ...)).size() == 5);\n+static_assert (parameters_of (^^void(int, int, int, int, int, int)).size() == 6);\n+static_assert (parameters_of (^^void(int, int, int, int, int, int, ...)).size() == 6);\n+static_assert (parameters_of (^^void(int, int, int, int, int, int, int)).size() == 7);\n+static_assert (parameters_of (^^void(int, int, int, int, int, int, int, ...)).size() == 7);\n+\n+static_assert (parameters_of (^^fn0).size() == 0);\n+static_assert (parameters_of (^^fn1).size() == 1);\n+static_assert (parameters_of (^^fn2).size() == 2);\n+static_assert (parameters_of (^^fn3).size() == 3);\n+static_assert (parameters_of (^^fn4).size() == 4);\n+\n+static_assert (parameters_of (^^tfn<>).size() == 0);\ndiff --git a/gcc/testsuite/g++.dg/reflect/parameters_of3.C b/gcc/testsuite/g++.dg/reflect/parameters_of3.C\nnew file mode 100644\nindex 00000000000..3bb2a2cd735\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parameters_of3.C\n@@ -0,0 +1,41 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::parameters_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+void lox (int = 0, int = 0, int = 0);\n+static_assert (parameters_of (^^lox).size() == 3);\n+\n+struct C {\n+ ~C();\n+ void foo (int, bool = false);\n+ bool bar (this C &self, int, ...);\n+ static C &baz (int, ...);\n+ using U = void(int, int, int);\n+};\n+\n+static_assert (parameters_of (^^C::foo).size() == 2);\n+static_assert (parameters_of (^^C::bar).size() == 2);\n+static_assert (parameters_of (^^C::baz).size() == 1);\n+static_assert (parameters_of (^^C::~C).size() == 0);\n+\n+template<typename... Ts>\n+void pack (Ts...) { }\n+static_assert (parameters_of (^^pack<>).size() == 0);\n+static_assert (parameters_of (^^pack<int>).size() == 1);\n+static_assert (parameters_of (^^pack<int, char>).size() == 2);\n+static_assert (parameters_of (^^pack<int, char, float>).size() == 3);\n+static_assert (parameters_of (^^pack<int, char, float, unsigned>).size() == 4);\n+static_assert (parameters_of (^^pack<int, char, float, unsigned, short>).size() == 5);\n+\n+void fn (int a, bool b);\n+void fn (int a, bool b = false);\n+void fn (int a, bool b);\n+static_assert (parameters_of (^^fn).size() == 2);\n+\n+using A = void(int, int);\n+static_assert (parameters_of (dealias(^^A)).size() == 2);\n+static_assert (parameters_of (dealias(^^C::U)).size() == 3);\ndiff --git a/gcc/testsuite/g++.dg/reflect/parameters_of4.C b/gcc/testsuite/g++.dg/reflect/parameters_of4.C\nnew file mode 100644\nindex 00000000000..a5b4230db77\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parameters_of4.C\n@@ -0,0 +1,12 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::parameters_of.\n+\n+#include <meta>\n+\n+template<auto R> void foo () {} // { dg-message \"sorry, unimplemented: mangling\" }\n+void\n+g ()\n+{\n+ foo<std::meta::parameters_of(^^g)[0]>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/parameters_of5.C b/gcc/testsuite/g++.dg/reflect/parameters_of5.C\nnew file mode 100644\nindex 00000000000..0519189612c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parameters_of5.C\n@@ -0,0 +1,43 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::parameters_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct C {\n+ ~C();\n+};\n+\n+consteval void\n+f1 ()\n+{\n+ parameters_of (^^C);\n+}\n+\n+consteval bool\n+test1 ()\n+{\n+ try { f1 (); }\n+ catch (std::meta::exception &) { return true; }\n+ catch (...) { return false; }\n+ return false;\n+}\n+\n+consteval void\n+f2 ()\n+{\n+ parameters_of (^^int);\n+}\n+\n+consteval bool\n+test2 ()\n+{\n+ try { f2 (); }\n+ catch (std::meta::exception &) { return true; }\n+ catch (...) { return false; }\n+ return false;\n+}\n+\n+static_assert (test1 () && test2 ());\ndiff --git a/gcc/testsuite/g++.dg/reflect/parameters_of6.C b/gcc/testsuite/g++.dg/reflect/parameters_of6.C\nnew file mode 100644\nindex 00000000000..0fbeee3bff1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parameters_of6.C\n@@ -0,0 +1,8 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+constexpr auto x = ^^std::meta::type_of;\n+constexpr auto m = parameters_of(x)[0];\n+static_assert (std::meta::type_of (m) == dealias (^^std::meta::info));\ndiff --git a/gcc/testsuite/g++.dg/reflect/parent_of1.C b/gcc/testsuite/g++.dg/reflect/parent_of1.C\nnew file mode 100644\nindex 00000000000..38b6b2df07c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parent_of1.C\n@@ -0,0 +1,238 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::parent_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr info null_reflection;\n+struct cls {\n+ int dm;\n+ static int static_dm;\n+ void mem_fun ();\n+ static void static_mem_fun ();\n+ int &ref_dm = dm;\n+ using type = int;\n+} cls_var;\n+union onion { };\n+static union { int anon; };\n+using alias = cls;\n+void fun ();\n+int var;\n+int &ref = var;\n+int &&rref = 42;\n+int *ptr = &var;\n+namespace ns {}\n+namespace ns_alias = ns;\n+enum Enum { A };\n+enum class Enum_class { A };\n+\n+template<typename> struct incomplete_cls;\n+template<typename> struct cls_tmpl {};\n+template<typename> void fun_tmpl ();\n+template<typename> concept conc = requires { true; };\n+template<typename> int var_tmpl;\n+template<typename T> using cls_tmpl_alias = cls_tmpl<T>;\n+\n+int arr[] = { 42 };\n+auto [ decomp ] = arr;\n+auto &[ decomp_ref ] = arr;\n+\n+consteval bool\n+has_parent_of (info r)\n+{\n+ try { parent_of (r); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (!has_parent_of (null_reflection));\n+static_assert (!has_parent_of (^^::));\n+static_assert (parent_of (^^ns) == ^^::);\n+static_assert (parent_of (^^std) == ^^::);\n+static_assert (parent_of (^^ns_alias) == ^^::);\n+static_assert (!has_parent_of (reflect_constant (3)));\n+static_assert (parent_of (^^cls) == ^^::);\n+static_assert (parent_of (^^cls::dm) == ^^cls);\n+static_assert (parent_of (^^cls::ref_dm) == ^^cls);\n+static_assert (parent_of (^^cls::static_dm) == ^^cls);\n+static_assert (parent_of (^^cls::mem_fun) == ^^cls);\n+static_assert (parent_of (^^cls::static_mem_fun) == ^^cls);\n+static_assert (parent_of (^^cls::type) == ^^cls);\n+static_assert (parent_of (^^cls_var) == ^^::);\n+static_assert (parent_of (^^onion) == ^^::);\n+static_assert (is_union_type (parent_of (^^anon)));\n+static_assert (parent_of (parent_of (^^anon)) == ^^::);\n+static_assert (parent_of (^^fun) == ^^::);\n+static_assert (parent_of (^^alias) == ^^::);\n+static_assert (parent_of (^^var) == ^^::);\n+static_assert (parent_of (^^ref) == ^^::);\n+static_assert (parent_of (^^rref) == ^^::);\n+static_assert (parent_of (^^ptr) == ^^::);\n+static_assert (parent_of (^^cls_tmpl) == ^^::);\n+static_assert (parent_of (^^cls_tmpl<int>) == ^^::);\n+static_assert (parent_of (^^incomplete_cls<int>) == ^^::);\n+static_assert (parent_of (^^fun_tmpl) == ^^::);\n+static_assert (parent_of (^^fun_tmpl<int>) == ^^::);\n+static_assert (parent_of (^^conc) == ^^::);\n+static_assert (!has_parent_of (substitute (^^conc, { ^^int })));\n+static_assert (parent_of (^^var_tmpl) == ^^::);\n+static_assert (parent_of (^^var_tmpl<int>) == ^^::);\n+static_assert (parent_of (^^cls_tmpl_alias) == ^^::);\n+static_assert (parent_of (^^cls_tmpl_alias<int>) == ^^::);\n+static_assert (parent_of (^^Enum) == ^^::);\n+static_assert (parent_of (^^Enum::A) == ^^Enum);\n+static_assert (parent_of (^^A) == ^^Enum);\n+static_assert (parent_of (^^Enum_class) == ^^::);\n+static_assert (parent_of (^^Enum_class::A) == ^^Enum_class);\n+static_assert (parent_of (^^decomp) == ^^::);\n+static_assert (parent_of (^^decomp_ref) == ^^::);\n+static_assert (parent_of (^^arr) == ^^::);\n+\n+constexpr auto dms = data_member_spec (^^int, { .name = \"dms\" });\n+static_assert (!has_parent_of (dms));\n+\n+constexpr auto ctx = std::meta::access_context::current ();\n+\n+struct Base {};\n+struct Derived : Base {};\n+static_assert (parent_of (bases_of (^^Derived, ctx)[0]) == ^^Derived);\n+\n+consteval {\n+ int a = 42;\n+ static_assert (parent_of (^^a) == ^^::);\n+ consteval {\n+ int b = 42;\n+ static_assert (parent_of (^^b) == ^^::);\n+ }\n+}\n+\n+template<typename T, info R, info R2, info R3>\n+void\n+f ()\n+{\n+ static_assert (!has_parent_of (^^T));\n+// static_assert (parent_of (R));\n+// static_assert (parent_of (R2));\n+// static_assert (parent_of (R3));\n+}\n+\n+void\n+g (int p, cls c)\n+{\n+ f<int, ^^var, ^^ns, ^^cls>();\n+ static_assert (parent_of (^^p) == ^^g);\n+ static_assert (parent_of (^^c) == ^^g);\n+ static_assert (parent_of (parameters_of (^^g)[0]) == ^^g);\n+ static_assert (parent_of (^^g) == ^^::);\n+ consteval {\n+ int a = 42;\n+ static_assert (parent_of (^^a) == ^^g);\n+ consteval {\n+ int b = 42;\n+ static_assert (parent_of (^^b) == ^^g);\n+ consteval {\n+\tint c = 42;\n+\tstatic_assert (parent_of (^^c) == ^^g);\n+ }\n+ }\n+ }\n+}\n+\n+int\n+main ()\n+{\n+}\n+\n+namespace N\n+{\n+ extern \"C\" void foo (int);\n+ void baz (int);\n+ namespace M\n+ {\n+ namespace O\n+ {\n+ struct S {};\n+ }\n+ }\n+ consteval {\n+ int a = 42;\n+ static_assert (parent_of (^^a) == ^^N);\n+ consteval {\n+ int b = 42;\n+ static_assert (parent_of (^^b) == ^^N);\n+ }\n+ }\n+}\n+extern \"C\" void bar ();\n+\n+static_assert (!has_parent_of (^^main));\n+static_assert (!has_parent_of (^^N::foo));\n+static_assert (!has_parent_of (^^bar));\n+static_assert (parent_of (^^N::baz) == ^^N);\n+static_assert (parent_of (^^N::M::O::S) == ^^N::M::O);\n+static_assert (parent_of (^^N::M::O) == ^^N::M);\n+static_assert (parent_of (^^N::M) == ^^N);\n+static_assert (parent_of (^^N) == ^^::);\n+\n+enum F {\n+ F1,\n+ F2 = parent_of (^^F1) == ^^F,\n+ F3 = (parent_of (^^F2) == ^^F) + 1,\n+};\n+static_assert (F2 == 1 && F3 == 2);\n+\n+void\n+qux ()\n+{\n+ auto a = [] ()\n+ {\n+ int b;\n+ static_assert (is_function (parent_of (^^b)));\n+ static_assert (is_class_type (parent_of (parent_of (^^b))));\n+ static_assert (parent_of (parent_of (parent_of (^^b))) == ^^qux);\n+ };\n+ static_assert (parent_of (^^a) == ^^qux);\n+ static_assert (parent_of (type_of (^^a)) == ^^qux);\n+}\n+\n+struct I { };\n+\n+struct J : I {\n+ union {\n+ int o;\n+ };\n+\n+ enum N {\n+ A\n+ };\n+\n+ consteval {\n+ int a = 42;\n+ static_assert (parent_of (^^a) == ^^J);\n+ consteval {\n+ int b = 42;\n+ static_assert (parent_of (^^b) == ^^J);\n+ consteval {\n+\tint c = 42;\n+\tstatic_assert (parent_of (^^c) == ^^J);\n+ }\n+ }\n+ }\n+};\n+\n+static_assert (parent_of (^^J) == ^^::);\n+static_assert (parent_of (bases_of (^^J, ctx)[0]) == ^^J);\n+static_assert (is_union_type (parent_of (^^J::o)));\n+static_assert (parent_of(^^J::N) == ^^J);\n+static_assert (parent_of(^^J::A) == ^^J::N);\n+\n+static union { union { int anon2; union { int anon3; }; }; };\n+static_assert (is_union_type (parent_of (^^anon2)));\n+static_assert (is_union_type (parent_of (parent_of (^^anon2))));\n+static_assert (parent_of (parent_of (parent_of (^^anon2))) == ^^::);\n+static_assert (is_union_type (parent_of (^^anon3)));\n+static_assert (is_union_type (parent_of (parent_of (^^anon3))));\n+static_assert (is_union_type (parent_of (parent_of (parent_of (^^anon3)))));\n+static_assert (parent_of (parent_of (parent_of (parent_of (^^anon3)))) == ^^::);\ndiff --git a/gcc/testsuite/g++.dg/reflect/parm1.C b/gcc/testsuite/g++.dg/reflect/parm1.C\nnew file mode 100644\nindex 00000000000..8416be5b0db\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parm1.C\n@@ -0,0 +1,56 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections as function parameters.\n+\n+#include <meta>\n+\n+// FIXME PR62244\n+//consteval int fn(decltype(^^::) x = ^^x) { return 0; }\n+//constexpr int x = fn ();\n+\n+consteval auto\n+ref (std::meta::info r)\n+{\n+ return r;\n+}\n+\n+consteval std::meta::info\n+def (std::meta::info r = std::meta::info(^^int))\n+{\n+ return r;\n+}\n+\n+consteval std::meta::info\n+def2 (std::meta::info r = ^^int)\n+{\n+ return r;\n+}\n+\n+void\n+g (int p)\n+{\n+ constexpr auto r = ref (^^int);\n+ [: r :] i1 = 42; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r :] i2 = 42;\n+ [: ref (r) :] i3 = 42; // { dg-error \"expected a reflection of an expression\" }\n+\n+ constexpr auto r2 = def ();\n+ [: r2 :] i4 = 42; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r2 :] i5 = 42;\n+ [: def () :] i6 = 42; // { dg-error \"expected a reflection of an expression\" }\n+\n+ constexpr auto r3 = def2 ();\n+ [: r3 :] i7 = 42; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r3 :] i8 = 42;\n+ [: def2 () :] i9 = 42; // { dg-error \"expected a reflection of an expression\" }\n+\n+ constexpr auto r4 = std::meta::info(^^int);\n+ [: r4 :] i10 = 42; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r4 :] i11 = 42;\n+\n+ constexpr auto r5 = std::meta::info(r4);\n+ [: r5 :] i12 = 42; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r5 :] i13 = 42;\n+\n+ constexpr auto r6 = ^^p;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/parm2.C b/gcc/testsuite/g++.dg/reflect/parm2.C\nnew file mode 100644\nindex 00000000000..60a11d018f9\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parm2.C\n@@ -0,0 +1,16 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// From [dcl.fct.default].\n+\n+using info = decltype(^^int);\n+\n+int b;\n+class X {\n+ int a;\n+ int mem1(int i = a); // { dg-error \"invalid use of non-static data member .X::a.\" }\n+ int mem2(int i = b); // OK; use X::b\n+ consteval void mem3(info r = ^^a) {}; // OK\n+ int mem4(int i = [:^^a:]); // { dg-error \"cannot implicitly reference\" }\n+\n+ static int b;\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/parm3.C b/gcc/testsuite/g++.dg/reflect/parm3.C\nnew file mode 100644\nindex 00000000000..1ff9357dc3d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parm3.C\n@@ -0,0 +1,33 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test invoking functions with a reflection argument.\n+\n+using info = decltype(^^int);\n+\n+consteval void foo (info) { }\n+constexpr void bar (info) { } // { dg-error \"function of consteval-only type must be declared .consteval.\" }\n+void baz (info) { } // { dg-error \"function of consteval-only type must be declared .consteval.\" }\n+\n+void\n+f ()\n+{\n+ foo (^^void);\n+ bar (^^void); // { dg-error \"consteval-only expressions\" }\n+ baz (^^void); // { dg-error \"consteval-only expressions\" }\n+}\n+\n+constexpr void\n+g ()\n+{\n+ foo (^^void);\n+ bar (^^void); // { dg-error \"consteval-only expressions\" }\n+ baz (^^void); // { dg-error \"consteval-only expressions\" }\n+}\n+\n+consteval void\n+h ()\n+{\n+ foo (^^void);\n+ bar (^^void);\n+ baz (^^void);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/parm4.C b/gcc/testsuite/g++.dg/reflect/parm4.C\nnew file mode 100644\nindex 00000000000..dd7606231b4\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/parm4.C\n@@ -0,0 +1,32 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test invoking functions with a reflection argument.\n+\n+using info = decltype(^^int);\n+\n+struct S {\n+ int mfn0 (info) { return 0; } // { dg-error \"function of consteval-only type must be declared .consteval.\" }\n+ constexpr int mfn1 (info) { return 1; } // { dg-error \"function of consteval-only type must be declared .consteval.\" }\n+ consteval int mfn2 (info) { return 2; }\n+ int mfn3 (int, info) { return 0; } // { dg-error \"function of consteval-only type must be declared .consteval.\" }\n+ info mfn4 () { return ^^int; } // { dg-error \"consteval-only expressions|function of consteval-only type must be declared .consteval.\" }\n+};\n+\n+void\n+g (S s)\n+{\n+ int i0 = s.mfn0 (^^int); // { dg-error \"consteval-only expressions\" }\n+ constexpr int i1 = s.mfn1 (^^int);\n+ constexpr int i2 = s.mfn2 (^^int);\n+ int i3 = s.mfn3 (42, ^^int); // { dg-error \"consteval-only expressions\" }\n+ info i4 = s.mfn4 (); // { dg-error \"consteval-only variable\" }\n+}\n+\n+template<typename T>\n+int fn (T) { return 4; } // { dg-error \"function of consteval-only type must be declared .consteval.\" }\n+const int a = fn (^^int); // { dg-error \"consteval-only expressions\" }\n+int b = fn (^^int); // { dg-error \"consteval-only expressions\" }\n+\n+template<typename T>\n+T fn2 () { return ^^void; } // { dg-error \"consteval-only\" }\n+const info i = fn2<info>(); // { dg-error \"consteval-only variable\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/pr122634-1.C b/gcc/testsuite/g++.dg/reflect/pr122634-1.C\nnew file mode 100644\nindex 00000000000..6f36abf8958\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/pr122634-1.C\n@@ -0,0 +1,65 @@\n+// PR c++/122634\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A { int a; };\n+namespace N { struct B { int b; }; }\n+struct C : typename [: ^^A :] {};\n+struct D : [: ^^A :] {};\n+struct E : [: ^^N :] :: B {};\n+struct F : [: ^^:: :] :: A {};\n+struct G : public typename [: ^^A :] {};\n+struct H : public [: ^^A :] {};\n+struct I : public [: ^^N :] :: B {};\n+struct J : public [: ^^:: :] :: A {};\n+template <auto I>\n+struct K : typename [: I :] {};\n+template <auto I>\n+struct L : [: I :] {};\n+template <auto I>\n+struct M : [: I :] :: B {};\n+template <auto I>\n+struct O : [: I :] :: A {};\n+template <auto I>\n+struct P : public typename [: I :] {};\n+template <auto I>\n+struct Q : public [: I :] {};\n+template <auto I>\n+struct R : public [: I :] :: B {};\n+template <auto I>\n+struct S : public [: I :] :: A {};\n+\n+constexpr access_context ctx = access_context::unprivileged ();\n+static_assert (type_of (bases_of (^^C, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^D, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^E, ctx)[0]) == ^^N::B);\n+static_assert (type_of (bases_of (^^F, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^G, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^H, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^I, ctx)[0]) == ^^N::B);\n+static_assert (type_of (bases_of (^^J, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^K <^^A>, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^L <^^A>, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^M <^^N>, ctx)[0]) == ^^N::B);\n+static_assert (type_of (bases_of (^^O <^^::>, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^P <^^A>, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^Q <^^A>, ctx)[0]) == ^^A);\n+static_assert (type_of (bases_of (^^R <^^N>, ctx)[0]) == ^^N::B);\n+static_assert (type_of (bases_of (^^S <^^::>, ctx)[0]) == ^^A);\n+\n+int\n+foo (C &c, D &d, E &e, F &f, G &g, H &h, I &i, J &j)\n+{\n+ return c.a + d.a + e.b + f.a + g.a + h.a + i.b + j.a;\n+}\n+\n+int\n+bar (K <^^A> &k, L <^^A> &l, M <^^N> &m, O <^^::> &o,\n+ P <^^A> &p, Q <^^A> &q, R <^^N> &r, S <^^::> &s)\n+{\n+ return k.a + l.a + m.b + o.a + p.a + q.a + r.b + s.a;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/pr122634-2.C b/gcc/testsuite/g++.dg/reflect/pr122634-2.C\nnew file mode 100644\nindex 00000000000..7db5b1930aa\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/pr122634-2.C\n@@ -0,0 +1,10 @@\n+// PR c++/122634\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+namespace N { struct A {}; }\n+struct B : typename [: ^^N :] :: A {};\t// { dg-error \"keyword 'typename' not allowed outside of templates\" }\n+template <auto I>\n+struct C : typename [: ^^N :] :: A {}; \t// { dg-error \"keyword 'typename' not allowed in this context\" }\n+template <auto I>\n+struct D : typename [: I :] :: A {}; \t// { dg-error \"keyword 'typename' not allowed in this context\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/qrn1.C b/gcc/testsuite/g++.dg/reflect/qrn1.C\nnew file mode 100644\nindex 00000000000..7864a1573e0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/qrn1.C\n@@ -0,0 +1,272 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on reflection-names.\n+// reflection-name:\n+// nested-name-specifier[opt] identifier\n+// nested-name-specifier template identifier\n+\n+int i;\n+using T = int;\n+typedef int TY;\n+\n+template<typename T>\n+concept F = requires { typename T::type; };\n+\n+template<typename T>\n+void foo (T) { }\n+\n+void bar () { }\n+\n+template<typename T>\n+T V{};\n+\n+enum E { E1 };\n+struct S {\n+ static constexpr int i = 42;\n+ using type = int;\n+};\n+template<typename T>\n+struct C {\n+ static constexpr T t{};\n+ using type = T;\n+};\n+\n+using US = S;\n+using UC = C<int>;\n+\n+template<typename T>\n+using AT = C<T>;\n+\n+namespace N {\n+ int n;\n+ using W = int;\n+\n+ template<typename T>\n+ concept FF = requires { typename T::type; };\n+\n+ namespace M {\n+ int m;\n+ using WW = int;\n+ enum EE { EE1 };\n+ struct SS {\n+ static constexpr int i = 42;\n+ using type = int;\n+ };\n+ template<typename T>\n+ struct CC {\n+ static constexpr T t{};\n+ using type = T;\n+ };\n+\n+ using NMSS = SS;\n+ using NMCC = CC<int>;\n+ }\n+};\n+\n+namespace NN = N;\n+\n+// nested-name-specifier[opt] identifier\n+void\n+f1 (S s)\n+{\n+ constexpr auto m0 = ^^::N::M;\n+ constexpr auto m1 = ^^N::M;\n+ constexpr auto m2 = ^^N;\n+ constexpr auto m3 = ^^NN;\n+ constexpr auto m4 = ^^::N;\n+ constexpr auto m5 = ^^::NN;\n+\n+ [: m0 :]::m = 0;\n+ [: m0 :]::WW v37 = 0;\n+ [: m1 :]::m = 0;\n+ [: m1 :]::WW v32 = 0;\n+ [: m2 :]::n = 0;\n+ [: m2 :]::W v33 = 0;\n+ [: m3 :]::n = 0;\n+ [: m3 :]::W v34 = 0;\n+ [: m4 :]::n = 0;\n+ [: m4 :]::W v35 = 0;\n+ [: m5 :]::n = 0;\n+ [: m5 :]::W v36 = 0;\n+\n+ constexpr auto r1 = ^^i;\n+ constexpr auto r2 = ^^::i;\n+ constexpr auto r3 = ^^T;\n+ constexpr auto r4 = ^^::T;\n+ constexpr auto r5 = ^^::TY;\n+ constexpr auto r6 = ^^E::E1;\n+ constexpr auto r7 = ^^S::i;\n+ constexpr auto r8 = ^^S::type;\n+ constexpr auto r9 = ^^C<int>::t;\n+ constexpr auto r10 = ^^C<int>::type;\n+ constexpr auto r11 = ^^US::i;\n+ constexpr auto r12 = ^^US::type;\n+ constexpr auto r13 = ^^UC::t;\n+ constexpr auto r14 = ^^UC::type;\n+ constexpr auto r15 = ^^N::n;\n+ constexpr auto r16 = ^^N::W;\n+ constexpr auto r17 = ^^NN::n;\n+ constexpr auto r18 = ^^NN::W;\n+ constexpr auto r19 = ^^decltype(s)::i;\n+ constexpr auto r20 = ^^decltype(s)::type;\n+ // For pack-indexing, see pack-index1.C.\n+ constexpr auto rs = ^^S;\n+ constexpr auto r21 = ^^[: rs :]::type;\n+ constexpr auto r22 = ^^typename [: rs :]::type;\n+ constexpr auto rc = ^^C;\n+ constexpr auto r23 = ^^[: rc :]<int>::type; // { dg-error \"missing .template.|declared\" }\n+ constexpr auto r24 = ^^typename [: rc :]<int>::type;\n+ constexpr auto r25 = ^^::N::n;\n+ constexpr auto r26 = ^^::N::W;\n+ constexpr auto r27 = ^^N::M::m;\n+ constexpr auto r28 = ^^N::M::WW;\n+ constexpr auto r29 = ^^N::M::EE;\n+ constexpr auto r30 = ^^N::M::EE::EE1;\n+ constexpr auto r31 = ^^[: m1 :]::EE::EE1;\n+ constexpr N::M::SS ss{};\n+ constexpr auto r32 = ^^decltype(ss)::type;\n+ constexpr N::M::CC<int> cc{};\n+ constexpr auto r33 = ^^decltype(cc)::type;\n+ constexpr auto r34 = ^^N::M::SS::type;\n+ constexpr auto r35 = ^^N::M::CC<int>::type;\n+ constexpr auto r36 = ^^N::M::NMSS::type;\n+ constexpr auto r37 = ^^N::M::NMCC::type;\n+ constexpr auto r38 = ^^[: m1 :]::SS::type;\n+ constexpr auto r39 = ^^typename [: m1 :]::SS::type;\n+ constexpr auto r40 = ^^[: m1 :]::CC<int>::type;\n+ constexpr auto r41 = ^^typename [: m1 :]::CC<int>::type;\n+ constexpr auto r42 = ^^::C<int>::type;\n+\n+ [: r1 :] = 42;\n+ ++[: r2 :];\n+ typename [: r3 :] v1 = 3;\n+ typename [: r4 :] v2 = 2;\n+ typename [: r5 :] v3 = 1;\n+ int n = [: r6 :];\n+ n += [: r7 :];\n+ typename [: r8 :] v5 = 1;\n+ n += [: r9 :];\n+ typename [: r10 :] v6 = 4;\n+ n += [: r11 :];\n+ typename [: r12 :] v7 = 4;\n+ n += [: r13 :];\n+ typename [: r14 :] v8 = 4;\n+ [: r15 :]++;\n+ typename [: r16 :] v9 = 4;\n+ --[: r17 :];\n+ typename [: r18 :] v10 = 4;\n+ n *= [: r19 :];\n+ typename [: r20 :] v11 = 4;\n+ typename [: r21 :] v12 = 4;\n+ typename [: r22 :] v13 = 4;\n+ typename [: r24 :] v15 = 4;\n+ [: r25 :]--;\n+ typename [: r26 :] v16 = 7;\n+ [: r27 :] = 1;\n+ typename [: r28 :] v17 = 7;\n+ typename [: r29 :] v18;\n+ v18 = [: r30 :];\n+ v18 = [: r31 :];\n+ typename [: r32 :] v19 = 7;\n+ typename [: r33 :] v20 = 7;\n+ typename [: r34 :] v21 = 7;\n+ typename [: r35 :] v22 = 7;\n+ typename [: r36 :] v23 = 7;\n+ typename [: r37 :] v24 = 7;\n+ typename [: r38 :] v25 = 7;\n+ typename [: r39 :] v26 = 7;\n+ typename [: r40 :] v27 = 7;\n+ typename [: r41 :] v28 = 7;\n+ typename [: r42 :] v29 = 7;\n+\n+ constexpr auto r46 = ^^::F;\n+ constexpr auto r47 = ^^::F;\n+ constexpr auto r48 = ^^N::FF;\n+ constexpr auto r49 = ^^::N::FF;\n+ constexpr auto r50 = ^^NN::FF;\n+ constexpr auto r51 = ^^::NN::FF;\n+\n+ constexpr auto r52 = ^^C;\n+ constexpr auto r53 = ^^C<int>;\n+ constexpr auto r54 = ^^::C;\n+ constexpr auto r55 = ^^::template C;\n+ constexpr auto r56 = ^^::C<int>;\n+ constexpr auto r57 = ^^::template C<int>;\n+\n+ typename [: r53 :] c1;\n+ typename [: r56 :] c2;\n+ typename [: r57 :] c3;\n+\n+ constexpr auto r58 = ^^foo;\n+ constexpr auto r59 = ^^::foo;\n+\n+ constexpr auto r60 = ^^V;\n+ constexpr auto r61 = ^^::V;\n+\n+ constexpr auto r62 = ^^AT;\n+ constexpr auto r63 = ^^::AT;\n+\n+ constexpr auto r64 = ^^bar;\n+ constexpr auto r65 = ^^::bar;\n+}\n+\n+// nested-name-specifier template identifier\n+consteval void\n+f2 ()\n+{\n+ constexpr auto r1 = ^^::template C<int>;\n+ constexpr auto r2 = ^^::template C<int>::type;\n+ constexpr auto r3 = ^^N::M::template CC<int>::type;\n+ constexpr auto r4 = ^^N::M::template CC<int>::t;\n+ constexpr auto r5 = ^^N::M::template CC;\n+ constexpr auto r6 = ^^NN::M::template CC<int>::type;\n+ constexpr auto r7 = ^^NN::M::template CC<int>::t;\n+ constexpr auto r8 = ^^NN::M::template CC;\n+\n+ // clang rejects these.\n+ constexpr auto r9 = ^^N::M::template NMCC::type;\n+ constexpr auto r10 = ^^N::M::template NMCC::t;\n+ constexpr auto r11 = ^^N::M::template NMCC;\n+ constexpr auto r12 = ^^NN::M::template NMCC::type;\n+ constexpr auto r13 = ^^NN::M::template NMCC::t;\n+ constexpr auto r14 = ^^NN::M::template NMCC;\n+ //constexpr auto r15 = ^^::template UC;\n+ constexpr auto r16 = ^^::template UC::type;\n+\n+ typename [: r2 :] v1 = 7;\n+ typename [: r3 :] v2 = 7;\n+ int n = [: r4 :];\n+ typename [: r6 :] v3 = 1;\n+ n += [: r7 :];\n+}\n+\n+template<typename T>\n+void\n+f3 (T t)\n+{\n+ /* Otherwise, if the identifier names a type alias that was introduced\n+ by the declaration of a template parameter, R represents the underlying\n+ entity of that type alias.\n+ So the reflection here should reflect the targ (int), not T itself? */\n+ constexpr auto r = ^^T;\n+ static_assert (r == ^^int);\n+}\n+\n+struct B {\n+ unsigned int a:32;\n+ unsigned int:32;\n+};\n+\n+void\n+f4 ()\n+{\n+ constexpr auto r = ^^B::a;\n+}\n+\n+void\n+g ()\n+{\n+ f1 (S{});\n+ f2 ();\n+ f3 (42);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/qrn2.C b/gcc/testsuite/g++.dg/reflect/qrn2.C\nnew file mode 100644\nindex 00000000000..d28ae1c14c1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/qrn2.C\n@@ -0,0 +1,43 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on reflection-names. Invalid code.\n+\n+class A { int x; };\n+template<typename T>\n+class B { T x; };\n+struct C { int x; };\n+template<typename T>\n+struct D { T x; };\n+\n+template<typename T>\n+void foo (T) { }\n+\n+template<typename T>\n+void foo (T, T) { }\n+\n+void bar (int) { }\n+void bar (int, int) { }\n+\n+void\n+g ()\n+{\n+ constexpr auto r1 = ^^A::x;\t // { dg-error \"private within this context\" }\n+ constexpr auto r2 = ^^B<int>::x; // { dg-error \"private within this context\" }\n+\n+ constexpr auto r3 = ^^C::x;\n+ int i1 = [: r3 :];\t // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+ [: r3 :];\t\t // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+ [: r3 :] = 0;\t\t // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+\n+ constexpr auto r4 = ^^foo; // { dg-error \"reflection of an overload set\" }\n+ constexpr auto r5 = ^^bar; // { dg-error \"reflection of an overload set\" }\n+ constexpr auto r6 = ^^D::x; // { dg-error \"expected\" }\n+ constexpr auto r7 = ^^D<int>::x;\n+ [: r7 :]; // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+}\n+\n+void\n+f ()\n+{\n+ g ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/range_args.C b/gcc/testsuite/g++.dg/reflect/range_args.C\nnew file mode 100644\nindex 00000000000..fa06cf0ebc7\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/range_args.C\n@@ -0,0 +1,96 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::is_constructible_type.\n+\n+#include <array>\n+#include <forward_list>\n+#include <list>\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+#include <vector>\n+\n+using namespace std::meta;\n+\n+template <class... Args>\n+struct SupportArgs { \n+ SupportArgs (Args...) noexcept;\n+\n+ int operator() (Args...) noexcept;\n+};\n+\n+void error();\n+\n+template<typename Rg>\n+consteval bool\n+test_type_range(Rg&& rg)\n+{\n+ info _ = common_type(rg);\n+ info _ = common_reference(rg);\n+ \n+ if (!can_substitute (^^SupportArgs, rg)) error();\n+ auto target = substitute(^^SupportArgs, rg);\n+ if (!is_constructible_type (target, rg)) error();\n+ if (!is_nothrow_constructible_type (target, rg)) error();\n+ if (!!is_trivially_constructible_type (target, rg)) error();\n+\n+ auto result = invoke_result(target, rg);\n+ if (!is_invocable_type (target, rg)) error();\n+ if (!is_invocable_r_type (result, target, rg)) error();\n+ if (!is_nothrow_invocable_type (target, rg)) error();\n+ if (!is_nothrow_invocable_r_type (result, target, rg)) error();\n+ return true;\n+}\n+\n+constexpr info vt[] = {^^int, ^^int, ^^float, ^^int, ^^float, ^^double};\n+static_assert (test_type_range (vt | std::views::filter (is_integral_type))); // bidirectional\n+static_assert (test_type_range (vt | std::views::take_while (is_integral_type))); // non-common\n+static_assert (test_type_range (vt | std::views::to_input)); // input\n+static_assert (test_type_range (vt | std::views::cache_latest)); // input, move-only\n+\n+template<typename Rg>\n+consteval bool\n+test_value_range(Rg&& rg)\n+{\n+ using V = std::ranges::range_value_t<Rg>;\n+\n+ info ra = reflect_constant_array(rg);\n+ std::span<const V> va = define_static_array(rg);\n+ if (extract<const V*>(ra) != va.data())\n+ error();\n+\n+ info rs = reflect_constant_string(rg);\n+ const V* vs = define_static_string(rg);\n+ if (extract<const V*>(rs) != vs)\n+ error();\n+\n+ return true;\n+}\n+\n+constexpr std::span<const char> vv = \"abcd01234\";\n+constexpr bool not_digit(char c) {\n+ return c < '0' || c > '9';\n+}\n+\n+static_assert (test_value_range (vv | std::views::filter (not_digit))); // bidirectional\n+static_assert (test_value_range (vv | std::views::take_while (not_digit))); // non-common\n+static_assert (test_value_range (vv | std::views::to_input)); // input\n+static_assert (test_value_range (vv | std::views::cache_latest)); // input, move-only\n+\t\t\t\t\t\t\t\t \n+template<int> struct Aggr;\n+constexpr info dmt[] = {\n+ data_member_spec(^^int, {.name = \"a\"}),\n+ data_member_spec(^^int, {.name = \"b\"}),\n+ data_member_spec(^^float, {.name = \"c\"}),\n+ data_member_spec(^^double, {.name = \"d\"}),\n+};\n+consteval bool of_int_type(info dm) {\n+ return type_of(dm) == ^^int;\n+}\n+\n+consteval {\n+ define_aggregate (^^Aggr<0>, dmt | std::views::filter (of_int_type)); // bidirectional\n+ define_aggregate (^^Aggr<1>, dmt | std::views::take_while (of_int_type)); // non-common\n+ define_aggregate (^^Aggr<2>, dmt | std::views::to_input); // input\n+ define_aggregate (^^Aggr<3>, dmt | std::views::cache_latest); // input, move-only\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant1.C b/gcc/testsuite/g++.dg/reflect/reflect_constant1.C\nnew file mode 100644\nindex 00000000000..adae634380a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant1.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+template<auto D>\n+ struct A { };\n+\n+struct N { int x; };\n+struct K { char const* p; };\n+\n+\n+constexpr info r1 = reflect_constant(42);\n+static_assert(is_value(r1));\n+static_assert(r1 == template_arguments_of(^^A<42>)[0]);\n+\n+constexpr info r2 = reflect_constant(N{42});\n+static_assert(is_object(r2));\n+static_assert(r2 == template_arguments_of(^^A<N{42}>)[0]);\n+\n+constexpr info r3 = reflect_constant(K{nullptr}); // OK\n+static_assert(is_object(r3));\n+constexpr info r4 = reflect_constant(K{\"ebab\"}); // { dg-error \"uncaught exception\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant2.C b/gcc/testsuite/g++.dg/reflect/reflect_constant2.C\nnew file mode 100644\nindex 00000000000..95b58529877\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant2.C\n@@ -0,0 +1,31 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr auto one = reflect_constant(1);\n+static_assert ([:one:] == 1);\n+\n+template<info> struct S {};\n+template<info> void foo () {}\n+\n+template<int P>\n+void\n+fn_tmpl ()\n+{\n+ static_assert(is_value(reflect_constant(P)));\n+ static_assert(!is_object(reflect_constant(P)));\n+ static_assert(type_of(reflect_constant(P)) == ^^int);\n+ static_assert([:reflect_constant(P):] == 1);\n+}\n+\n+void\n+g ()\n+{\n+ S<reflect_constant (nullptr)> s;\n+ foo<reflect_constant (nullptr)>();\n+ fn_tmpl<1>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant3.C b/gcc/testsuite/g++.dg/reflect/reflect_constant3.C\nnew file mode 100644\nindex 00000000000..c362b03c3ed\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant3.C\n@@ -0,0 +1,67 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+static_assert ([:reflect_constant (42):] == 42);\n+static_assert (type_of (reflect_constant (42)) == ^^int);\n+static_assert (is_value (reflect_constant (42)));\n+static_assert (!is_object (reflect_constant (42)));\n+\n+enum E { A = 42 };\n+static_assert ([:reflect_constant (A):] == A);\n+static_assert (type_of (reflect_constant (E::A)) == ^^E);\n+static_assert (is_value (reflect_constant (E::A)));\n+static_assert (!is_object (reflect_constant (E::A)));\n+\n+enum class EC { A = 42 };\n+static_assert ([:reflect_constant (EC::A):] == EC::A);\n+static_assert (type_of (reflect_constant (EC::A)) == ^^EC);\n+static_assert (is_value (reflect_constant (EC::A)));\n+static_assert (!is_object (reflect_constant (EC::A)));\n+\n+const int i = 42;\n+static_assert ([:reflect_constant (i):] == i);\n+static_assert (type_of (reflect_constant (i)) == ^^int);\n+static_assert (is_value (reflect_constant (i)));\n+static_assert (!is_object (reflect_constant (i)));\n+\n+const int &r = 42;\n+static_assert ([:reflect_constant (r):] == r);\n+static_assert (type_of (reflect_constant (r)) == ^^int);\n+static_assert (is_value (reflect_constant (r)));\n+static_assert (!is_object (reflect_constant (r)));\n+\n+constexpr int ci = 42;\n+static_assert ([:reflect_constant (ci):] == ci);\n+static_assert (type_of (reflect_constant (ci)) == ^^int);\n+static_assert (is_value (reflect_constant (ci)));\n+static_assert (!is_object (reflect_constant (ci)));\n+\n+void fn() {}\n+static_assert ([:reflect_constant (&fn):] == &fn);\n+static_assert (type_of (reflect_constant (&fn)) == ^^void(*)());\n+static_assert (is_value (reflect_constant (&fn)));\n+static_assert (!is_object (reflect_constant (&fn)));\n+\n+constexpr int cfn () { return 42; }\n+static_assert ([:reflect_constant (cfn ()):] == 42);\n+static_assert (type_of (reflect_constant (cfn ())) == ^^int);\n+static_assert (is_value (reflect_constant (cfn ())));\n+static_assert (!is_object (reflect_constant (cfn ())));\n+\n+struct S {\n+ int k;\n+ void fn();\n+};\n+static_assert ([:reflect_constant (&S::k):] == &S::k);\n+static_assert (type_of (reflect_constant (&S::k)) == ^^int (S::*));\n+static_assert (is_value (reflect_constant (&S::k)));\n+static_assert (!is_object (reflect_constant (&S::k)));\n+static_assert ([:reflect_constant (&S::fn):] == &S::fn);\n+static_assert (type_of (reflect_constant (&S::fn)) == ^^void (S::*)());\n+static_assert (is_value (reflect_constant (&S::fn)));\n+static_assert (!is_object (reflect_constant (&S::fn)));\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant4.C b/gcc/testsuite/g++.dg/reflect/reflect_constant4.C\nnew file mode 100644\nindex 00000000000..1ffaa5b0a14\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant4.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+int i;\n+int foo ();\n+struct S {};\n+\n+constexpr auto r1 = reflect_constant (i); // { dg-error \"not usable in a constant expression\" }\n+constexpr auto r2 = reflect_constant (foo ()); // { dg-error \"call to non-.constexpr.\" }\n+constexpr auto r3 = reflect_constant (S); // { dg-error \"expected\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant5.C b/gcc/testsuite/g++.dg/reflect/reflect_constant5.C\nnew file mode 100644\nindex 00000000000..35c0bfeac7f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant5.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S {};\n+constexpr auto r = reflect_constant (S{});\n+S s = [:r:];\n+static_assert (!is_value (r));\n+static_assert (is_object (r));\n+\n+struct R { int i; };\n+constexpr auto rr = reflect_constant (R{42});\n+static_assert ([:rr:].i == 42);\n+static_assert (!is_value (rr));\n+static_assert (is_object (rr));\n+\n+static_assert (is_value (reflect_constant (nullptr_t{})));\n+static_assert (!is_object (reflect_constant (nullptr_t{})));\n+static_assert (is_value (reflect_constant (auto(42))));\n+static_assert (!is_object (reflect_constant (auto(42))));\n+constexpr int foo () { return 42; }\n+static_assert (is_value (reflect_constant (foo ())));\n+static_assert (!is_object (reflect_constant (foo ())));\n+static constexpr int i = 0;\n+static_assert (is_value (reflect_constant (&i)));\n+static_assert (!is_object (reflect_constant (&i)));\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant6.C b/gcc/testsuite/g++.dg/reflect/reflect_constant6.C\nnew file mode 100644\nindex 00000000000..6f12be7d417\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant6.C\n@@ -0,0 +1,46 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant. The glvalue-to-prvalue conversion may have\n+// side-effects as part of the constant expression evaluation that the call to\n+// reflect_constant is part of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct B {\n+ int *const p;\n+ consteval B(int *p) : p(p) {}\n+};\n+\n+consteval int g() {\n+ int x = 42;\n+ B b(&x);\n+ reflect_constant (b);\n+ return x;\n+}\n+static_assert(g() == 43); // { dg-error \"uncaught exception|non-constant\" }\n+\n+struct A {\n+ int *const p;\n+ consteval A(int *p) : p(p) {}\n+ consteval A(const A &oth) : p(nullptr) {\n+ if (oth.p) {\n+ ++*oth.p;\n+ }\n+ }\n+};\n+\n+consteval int f() {\n+ int x = 42;\n+ A a(&x);\n+ reflect_constant (a);\n+ return x;\n+}\n+\n+// FIXME Clang++ accepts this, but we throw: we think that the temporary\n+// argument to reflect_constant can't be a NTTP.\n+// As reflect_constant accept by value, the parameter of reflect_constant(a)\n+// is copy-initialized with a, which set p to nullptr, i.e. we no longer \n+// have pointer to stack variable.\n+static_assert(f() == 43); // { dg-error \"uncaught exception|non-constant\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant7.C b/gcc/testsuite/g++.dg/reflect/reflect_constant7.C\nnew file mode 100644\nindex 00000000000..d83088788a1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant7.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+struct A {\n+ int *const p;\n+ constexpr A(int *p) : p(p) { delete p; }\n+ constexpr A(const A &) : p(0) {}\n+};\n+\n+consteval info f() {\n+ return reflect_constant<A>(new int);\n+}\n+\n+const A &a = [:f():];\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant8.C b/gcc/testsuite/g++.dg/reflect/reflect_constant8.C\nnew file mode 100644\nindex 00000000000..0cad276599c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant8.C\n@@ -0,0 +1,33 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+// Not copy-constructible.\n+struct S {\n+ S();\n+ S(const S&) = delete;\n+};\n+\n+constexpr info r1 = reflect_constant (S{}); // { dg-error \"no matching function for call\" }\n+\n+// Not copy-constructible.\n+struct S2 {\n+ S2();\n+ S2(S2&) = delete;\n+};\n+\n+constexpr info r2 = reflect_constant (S2{}); // { dg-error \"no matching function for call\" }\n+\n+volatile constexpr int vi = 42;\n+constexpr info r3 = reflect_constant (vi); // { dg-error \"lvalue-to-rvalue conversion\" }\n+\n+// Not a structural type.\n+struct M {\n+ mutable int i;\n+};\n+constexpr info r4 = reflect_constant (M{42}); // { dg-error \".M. must be a cv-unqualified structural type\" }\n+\n+// { dg-error \"use of deleted function\" \"\" { target *-*-* } 0 }\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant9.C b/gcc/testsuite/g++.dg/reflect/reflect_constant9.C\nnew file mode 100644\nindex 00000000000..1055c74f98c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant9.C\n@@ -0,0 +1,33 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Per N5014 [temp.arg.nontype] copying an template\n+// parameter object of class type must produce structurally\n+// equivalent values, but both clang and GCC does not seem\n+// to implement that.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A {\n+ int x;\n+ constexpr A(int p) : x(p) {}\n+ constexpr A(const A &oth) : x(oth.x ? oth.x-1 : oth.x) {\n+ }\n+};\n+\n+consteval bool\n+can_reflect_constant (int x)\n+{\n+ try { reflect_constant (A(x)); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+// FIXME\n+// This should pass, with A::x being zero, copies are equivalent.\n+static_assert(!can_reflect_constant(0));\n+// As neither GCC and clang see to implement the aforementioned\n+// rule, I believe all should work.\n+static_assert(!can_reflect_constant(1));\n+static_assert(!can_reflect_constant(4));\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_array1.C b/gcc/testsuite/g++.dg/reflect/reflect_constant_array1.C\nnew file mode 100644\nindex 00000000000..1d95891355d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_array1.C\n@@ -0,0 +1,110 @@\n+// { dg-do run { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant_array.\n+\n+#include <array>\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+using namespace std::meta;\n+\n+struct V { int a, b, c; };\n+constexpr auto a = reflect_constant_array (\"abcd\");\n+constexpr auto b = reflect_constant_array (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\");\n+constexpr auto c = reflect_constant_array (std::vector <char> {});\n+constexpr auto d = reflect_constant_array (std::array { 1, 2, 42, 3 });\n+constexpr float ea[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };\n+constexpr auto e = reflect_constant_array (ea);\n+constexpr int fb[] = { 1, 2, 3, 4, 5, 6 };\n+constexpr std::span <const int> fa (fb);\n+constexpr auto f = reflect_constant_array (fa);\n+constexpr auto g = reflect_constant_array (fa.subspan (1, 4));\n+constexpr auto h = reflect_constant_array (fa.subspan (1, 4) | std::views::reverse);\n+constexpr auto i = reflect_constant_array (std::vector <V> { V { 1, 2, 3 }, V { 2, 3, 4 }, V { 3, 4, 5 } });\n+static_assert (a == reflect_constant_string (\"abcd\"));\n+static_assert (b == reflect_constant_string (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\"));\n+static_assert (c == reflect_constant_array (std::vector <char> {}));\n+static_assert (d == reflect_constant_array (std::vector <int> { 1, 2, 42, 3 }));\n+static_assert (e == reflect_constant_array (std::array { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f }));\n+static_assert (f == reflect_constant_array (std::vector <int> { 1, 2, 3, 4, 5, 6 }));\n+static_assert (d != f);\n+static_assert (g == reflect_constant_array (std::array { 2, 3, 4, 5 }));\n+static_assert (h == reflect_constant_array (std::vector <int> { 5, 4, 3, 2 }));\n+//static_assert (i == reflect_constant_array (std::vector <V> { V { 1, 2, 3 }, V { 2, 3, 4 }, V { 3, 4, 5 } }));\n+static_assert (is_variable (a));\n+static_assert (is_variable (b));\n+static_assert (is_variable (c));\n+static_assert (is_variable (d));\n+static_assert (is_variable (e));\n+static_assert (is_variable (f));\n+static_assert (is_variable (g));\n+static_assert (is_variable (h));\n+static_assert (is_variable (i));\n+static_assert (type_of (a) == ^^const char [5]);\n+static_assert (type_of (b) == ^^const char32_t [9]);\n+static_assert (type_of (c) == ^^const std::array <char, 0>);\n+static_assert (type_of (d) == ^^const int [4]);\n+static_assert (type_of (e) == ^^const float [6]);\n+static_assert (type_of (f) == ^^const int [6]);\n+static_assert (type_of (g) == ^^const int [4]);\n+static_assert (type_of (h) == ^^const int [4]);\n+static_assert (type_of (i) == ^^const V [3]);\n+auto as = &[: a :];\n+auto bs = &[: b :];\n+auto cs = &[: c :];\n+auto ds = &[: d :];\n+auto es = &[: e :];\n+auto fs = &[: f :];\n+auto gs = &[: g :];\n+auto hs = &[: h :];\n+auto is = &[: i :];\n+\n+int\n+main ()\n+{\n+ if (std::string_view (*as) != std::string_view (\"abcd\"))\n+ __builtin_abort ();\n+ if (std::u32string_view (*bs) != std::u32string_view (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\"))\n+ __builtin_abort ();\n+ for (const char &x : *cs)\n+ __builtin_abort ();\n+ int i = 0;\n+ for (const int &x : *ds)\n+ if (x != \"\\x{1}\\x{2}\\x{2a}\\x{3}\"[i++])\n+ __builtin_abort ();\n+ if (i != 4)\n+ __builtin_abort ();\n+ i = 0;\n+ for (const float &x : *es)\n+ if (x != ++i)\n+ __builtin_abort ();\n+ if (i != 6)\n+ __builtin_abort ();\n+ i = 0;\n+ for (const int &x : *fs)\n+ if (x != ++i)\n+ __builtin_abort ();\n+ if (i != 6)\n+ __builtin_abort ();\n+ i = 1;\n+ for (const int &x : *gs)\n+ if (x != ++i)\n+ __builtin_abort ();\n+ if (i != 5)\n+ __builtin_abort ();\n+ i = 6;\n+ for (const int &x : *hs)\n+ if (x != --i)\n+ __builtin_abort ();\n+ if (i != 2)\n+ __builtin_abort ();\n+ i = 0;\n+ for (const V &x : *is)\n+ if (x.a != i + 1 || x.b != i + 2 || x.c != i + 3)\n+ __builtin_abort ();\n+ else\n+ ++i;\n+ if (i != 3)\n+ __builtin_abort ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_array2.C b/gcc/testsuite/g++.dg/reflect/reflect_constant_array2.C\nnew file mode 100644\nindex 00000000000..4d2e36f353c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_array2.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant_string.\n+\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+using namespace std::meta;\n+\n+struct A { int a, b; mutable int c; };\n+constexpr auto a = reflect_constant_array (std::vector <A> { A { 1, 2, 3 } });\n+// { dg-error \"'reflect_constant_array' argument with 'A' 'std::ranges::range_value_t' which is not a structural type\" \"\" { target *-*-* } .-1 }\n+struct B { constexpr B (int x, int y) : a (x), b (y) {} constexpr ~B () {} B (const B &) = delete; int a, b; };\n+constexpr B b[2] = { { 1, 2 }, { 2, 3 } };\n+constexpr auto c = reflect_constant_array (b);\n+// { dg-error \"'reflect_constant_array' argument with 'B' 'std::ranges::range_value_t' which is not copy constructible\" \"\" { target *-*-* } .-1 }\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_array3.C b/gcc/testsuite/g++.dg/reflect/reflect_constant_array3.C\nnew file mode 100644\nindex 00000000000..3805671870f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_array3.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant_array.\n+\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+using namespace std::meta;\n+\n+constexpr int arr[4]{1, 2, 3, 4};\n+constexpr info rarr = reflect_constant_array(std::span<const int, 4>(arr));\n+static_assert (constant_of(^^arr) == rarr);\n+\n+constexpr int marr[2][2]{1, 2, 3, 4};\n+// LWG4483 multidimensional arrays\n+// constexpr info mrarr = reflect_constant_array(std::span<const int[2], 2>(marr));\n+// static_assert (constant_of(^^marr) == mrarr);\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_array4.C b/gcc/testsuite/g++.dg/reflect/reflect_constant_array4.C\nnew file mode 100644\nindex 00000000000..faf2c4a988e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_array4.C\n@@ -0,0 +1,20 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant_array.\n+\n+#include <meta>\n+#include <ranges>\n+\n+using namespace std::meta;\n+\n+constexpr int x[]{1,2,3,4,5};\n+constexpr int y[]{11,12,13,14,15};\n+constexpr auto as_pair = []<typename T1, typename T2>(const std::tuple<T1, T2>& t) static\n+{ return std::pair<T1, T2>(t); };\n+\n+constexpr info r = reflect_constant_array(std::views::zip (x, y) | std::views::transform (as_pair));\n+// FIXME this should be pass\n+// static_assert (type_of (^^r) == ^^const std::pair<int, int>[5]);\n+// static_assert ([: r :][2].first == 3);\n+// static_assert ([: r :][2].second == 13);\n+\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_string1.C b/gcc/testsuite/g++.dg/reflect/reflect_constant_string1.C\nnew file mode 100644\nindex 00000000000..92656e9b615\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_string1.C\n@@ -0,0 +1,133 @@\n+// { dg-do run { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant_string.\n+\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+using namespace std::meta;\n+\n+constexpr auto a = reflect_constant_string (\"abcd\");\n+constexpr auto b = reflect_constant_string (u8\"abcd\\N{LATIN SMALL LETTER AE}\");\n+constexpr auto c = reflect_constant_string (L\"abcd\");\n+constexpr auto d = reflect_constant_string (u\"abcd\\0ef\");\n+constexpr auto e = reflect_constant_string (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\");\n+constexpr auto f = reflect_constant_string (std::string_view (\"abcd\", 5));\n+constexpr auto g = reflect_constant_string (std::string_view (\"abcdefg\", 4));\n+constexpr auto h = reflect_constant_string (std::u8string_view (u8\"ab\\0\\N{LATIN SMALL LETTER AE}\", 5));\n+constexpr auto i = reflect_constant_string (std::string_view (\"abcdefgh\", 9).substr (0, 5));\n+constexpr auto j = reflect_constant_string (std::string_view (\"abcdefgh\", 9).substr (4, 3));\n+constexpr auto k = reflect_constant_string (std::u32string_view (U\"abcdefgh\", 9).substr (3, 4));\n+constexpr char8_t la[] = { u8'h', u8'e', u8'l', u8'l', u8'o', u8'\\0' };\n+constexpr auto l = reflect_constant_string (la);\n+constexpr std::span <const char8_t> ma (la);\n+constexpr auto m = reflect_constant_string (ma);\n+constexpr auto n = reflect_constant_string (ma.subspan (1, 4));\n+constexpr auto o = reflect_constant_string (ma.subspan (1, 4) | std::views::reverse);\n+constexpr auto p = reflect_constant_string (std::vector <wchar_t> { L'W', L'o', L'r', L'l', L'd' });\n+constexpr auto q = reflect_constant_string (std::vector <char16_t> { u'e', u'x', u't', u'r', u'e', u'm', u'e', u'l', u'y',\n+\t\t\t\t\t\t\t\t u' ', u'l', u'o', u'n', u'g',\n+\t\t\t\t\t\t\t\t u' ', u's', u't', u'r', u'i', u'n', u'g',\n+\t\t\t\t\t\t\t\t u' ', u'w', u'i', u't', u'h',\n+\t\t\t\t\t\t\t\t u' ', u'n', u'o', u'n', u'-', u'A', u'S', u'C', u'I', u'I',\n+\t\t\t\t\t\t\t\t u' ', u'c', u'h', u'a', u'r', u'a', u'c', u't', u'e', u'r', u's',\n+\t\t\t\t\t\t\t\t u' ', u'\\N{LATIN SMALL LETTER A WITH ACUTE}' });\n+static_assert (a == reflect_constant_string (\"abcd\"));\n+static_assert (b == reflect_constant_string (u8\"abcd\\N{LATIN SMALL LETTER AE}\"));\n+static_assert (c == reflect_constant_string (L\"abcd\"));\n+static_assert (d == reflect_constant_string (u\"abcd\\0ef\"));\n+static_assert (e == reflect_constant_string (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\"));\n+static_assert (f == reflect_constant_string (\"abcd\\0\"));\n+static_assert (a != f);\n+static_assert (g == a);\n+static_assert (h == reflect_constant_string (u8\"ab\\0\\N{LATIN SMALL LETTER AE}\"));\n+static_assert (i == reflect_constant_string (\"abcde\"));\n+static_assert (a != i);\n+static_assert (j == reflect_constant_string (\"efg\"));\n+static_assert (a != j);\n+static_assert (k == reflect_constant_string (U\"defg\"));\n+static_assert (l == reflect_constant_string (u8\"hello\\0\"));\n+static_assert (m == l);\n+static_assert (n == reflect_constant_string (u8\"ello\"));\n+static_assert (o == reflect_constant_string (u8\"olle\"));\n+static_assert (p == reflect_constant_string (L\"World\"));\n+static_assert (q == reflect_constant_string (u\"extremely long string with non-ASCII characters \\N{LATIN SMALL LETTER A WITH ACUTE}\"));\n+static_assert (reflect_constant_string (\"bar\") != reflect_constant_string (\"baz\"));\n+static_assert (is_variable (a));\n+static_assert (is_variable (b));\n+static_assert (is_variable (c));\n+static_assert (is_variable (d));\n+static_assert (is_variable (e));\n+static_assert (is_variable (f));\n+static_assert (is_variable (g));\n+static_assert (is_variable (h));\n+static_assert (type_of (a) == ^^const char [5]);\n+static_assert (type_of (b) == ^^const char8_t [sizeof u8\"abcd\\N{LATIN SMALL LETTER AE}\"]);\n+static_assert (type_of (c) == ^^const wchar_t [5]);\n+static_assert (type_of (d) == ^^const char16_t [8]);\n+static_assert (type_of (e) == ^^const char32_t [9]);\n+static_assert (type_of (f) == ^^const char [6]);\n+static_assert (type_of (g) == ^^const char [5]);\n+static_assert (type_of (h) == ^^const char8_t [6]);\n+static_assert (type_of (q) == ^^const char16_t [50]);\n+auto as = &[: a :];\n+auto bs = &[: b :];\n+auto cs = &[: c :];\n+auto ds = &[: d :];\n+auto es = &[: e :];\n+auto fs = &[: f :];\n+auto gs = &[: g :];\n+auto hs = &[: h :];\n+auto is = &[: i :];\n+auto js = &[: j :];\n+auto ks = &[: k :];\n+auto ls = &[: l :];\n+auto ms = &[: m :];\n+auto ns = &[: n :];\n+auto os = &[: o :];\n+auto ps = &[: p :];\n+auto qs = &[: q :];\n+\n+int\n+main ()\n+{\n+ if (std::string_view (*as) != std::string_view (\"abcd\"))\n+ __builtin_abort ();\n+ if (std::u8string_view (*bs) != std::u8string_view (u8\"abcd\\N{LATIN SMALL LETTER AE}\"))\n+ __builtin_abort ();\n+ if (std::wstring_view (*cs) != std::wstring_view (L\"abcd\"))\n+ __builtin_abort ();\n+ if (std::u16string_view (*ds) != std::u16string_view (u\"abcd\\0ef\"))\n+ __builtin_abort ();\n+ if (std::u32string_view (*es) != std::u32string_view (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\"))\n+ __builtin_abort ();\n+ if (std::string_view (*fs) != std::string_view (\"abcd\\0\"))\n+ __builtin_abort ();\n+ if (gs != as)\n+ __builtin_abort ();\n+ if (std::u8string_view (*hs) != std::u8string_view (u8\"ab\\0\\N{LATIN SMALL LETTER AE}\"))\n+ __builtin_abort ();\n+ if (std::string_view (*is) != std::string_view (\"abcde\"))\n+ __builtin_abort ();\n+ if ((const char *) as == (const char *) is)\n+ __builtin_abort ();\n+ if (std::string_view (*js) != std::string_view (\"efg\"))\n+ __builtin_abort ();\n+ if ((const char *) as == (const char *) js)\n+ __builtin_abort ();\n+ if (std::u32string_view (*ks) != std::u32string_view (U\"defg\"))\n+ __builtin_abort ();\n+ if (std::u8string_view (*ls) != std::u8string_view (u8\"hello\\0\"))\n+ __builtin_abort ();\n+ if (ms != ls)\n+ __builtin_abort ();\n+ if (std::u8string_view (*ns) != std::u8string_view (u8\"ello\"))\n+ __builtin_abort ();\n+ if (std::u8string_view (*os) != std::u8string_view (u8\"olle\"))\n+ __builtin_abort ();\n+ if (std::wstring_view (*ps) != std::wstring_view (L\"World\"))\n+ __builtin_abort ();\n+ if (std::u16string_view (*qs) != std::u16string_view (u\"extremely long string with non-ASCII characters \\N{LATIN SMALL LETTER A WITH ACUTE}\"))\n+ __builtin_abort ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_constant_string2.C b/gcc/testsuite/g++.dg/reflect/reflect_constant_string2.C\nnew file mode 100644\nindex 00000000000..c64be053c2a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_constant_string2.C\n@@ -0,0 +1,14 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_constant_string.\n+\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+using namespace std::meta;\n+\n+struct V { int a, b, c; };\n+constexpr auto a = reflect_constant_string (std::vector <int> { 42, 43, 44 });\t// { dg-error \"'reflect_constant_string' called with 'int' 'std::ranges::range_value_t' rather than 'char', 'wchar_t', 'char8_t', 'char16_t' or 'char32_t'\" }\n+constexpr auto b = reflect_constant_string (std::vector <float> {});\t\t// { dg-error \"'reflect_constant_string' called with 'float' 'std::ranges::range_value_t' rather than 'char', 'wchar_t', 'char8_t', 'char16_t' or 'char32_t'\" }\n+constexpr auto c = reflect_constant_string (std::vector <V> { V { 1, 2, 3 } });\t// { dg-error \"'reflect_constant_string' called with 'V' 'std::ranges::range_value_t' rather than 'char', 'wchar_t', 'char8_t', 'char16_t' or 'char32_t'\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_function1.C b/gcc/testsuite/g++.dg/reflect/reflect_function1.C\nnew file mode 100644\nindex 00000000000..cf24a17b100\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_function1.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_function.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S {\n+ void foo(this S) {}\n+};\n+\n+int\n+main ()\n+{\n+ [:reflect_function(*&S::foo):](S()); // { dg-error \"cannot implicitly reference\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_function2.C b/gcc/testsuite/g++.dg/reflect/reflect_function2.C\nnew file mode 100644\nindex 00000000000..f9885a82c8e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_function2.C\n@@ -0,0 +1,74 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_function.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+using namespace std::literals;\n+\n+void foo ();\n+static_assert (reflect_function (::foo) == ^^::foo);\n+static_assert (is_function (reflect_function (::foo)));\n+static_assert (!is_object (reflect_function (::foo)));\n+static_assert (!is_value (reflect_function (::foo)));\n+static_assert (type_of (reflect_function (::foo)) == ^^void ());\n+static_assert (identifier_of (reflect_function (::foo)) == \"foo\"sv);\n+\n+const auto &ref = ::foo;\n+static_assert (reflect_function (ref) == ^^::foo);\n+static_assert (is_function (reflect_function (ref)));\n+static_assert (!is_object (reflect_function (ref)));\n+static_assert (!is_value (reflect_function (ref)));\n+static_assert (type_of (reflect_function (ref)) == ^^void());\n+static_assert (identifier_of (reflect_function (ref)) == \"foo\"sv);\n+\n+constexpr void (*fp)() = ::foo;\n+static_assert (reflect_function (*fp) == ^^::foo);\n+static_assert (is_function (reflect_function (*fp)));\n+static_assert (!is_object (reflect_function (*fp)));\n+static_assert (!is_value (reflect_function (*fp)));\n+static_assert (type_of (reflect_function (*fp)) == ^^void());\n+static_assert (identifier_of (reflect_function (*fp)) == \"foo\"sv);\n+\n+template <void(&P)()>\n+void\n+fn_fn_ref_param ()\n+{\n+ static constexpr auto R = reflect_function (P);\n+ static_assert (is_function (R));\n+ static_assert (type_of (R) == ^^void ());\n+ static_assert (identifier_of (R) == \"doit\"sv);\n+}\n+\n+constexpr int bar (int i) { return i + 42; }\n+static_assert ([:reflect_function (bar):](0) == 42);\n+\n+template<int N>\n+constexpr int\n+baz (int i)\n+{\n+ return i + N;\n+}\n+static_assert ([:reflect_function (baz<1>):](1) == 2);\n+\n+void\n+doit ()\n+{\n+ fn_fn_ref_param<doit>();\n+ [:reflect_function (::foo):]();\n+ [:reflect_function (::ref):]();\n+ [:reflect_function (*::fp):]();\n+}\n+\n+extern int (&fref)();\n+\n+consteval bool\n+can_reflect_extern_reference ()\n+{\n+ try { reflect_function (fref); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert(!can_reflect_extern_reference());\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_object1.C b/gcc/testsuite/g++.dg/reflect/reflect_object1.C\nnew file mode 100644\nindex 00000000000..6079c185ca1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_object1.C\n@@ -0,0 +1,86 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_object.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S { int m; };\n+\n+template <int &> void fn();\n+int p[2];\n+static_assert(template_arguments_of(^^fn<p[1]>)[0] == reflect_object(p[1]));\n+\n+template <const int &P>\n+void\n+fn_int_ref ()\n+{\n+ static constexpr auto R = reflect_object(P);\n+\n+ static_assert(is_object(R));\n+ static_assert(!is_value(R));\n+ static_assert(!is_variable(R));\n+ if constexpr (is_const(R)) {\n+ static_assert(type_of(R) == ^^const int);\n+ static_assert([:R:] == 2);\n+ } else {\n+ static_assert(type_of(R) == ^^int);\n+ }\n+}\n+\n+template <const int &P>\n+void\n+fn_int_subobject_ref ()\n+{\n+ static constexpr auto R = reflect_object(P);\n+\n+ static_assert(is_object(R));\n+ static_assert(!is_value(R));\n+ static_assert(!is_variable(R));\n+ static_assert(type_of(R) == ^^const int);\n+ static_assert([:R:] == 3);\n+}\n+\n+template <S P>\n+void\n+fn_cls_value ()\n+{\n+ static constexpr auto R = reflect_object(P);\n+\n+ static_assert(is_object(R));\n+ static_assert(!is_value(R));\n+ static_assert(!is_variable(R));\n+ static_assert(type_of(R) == ^^const S);\n+ static_assert([:R:].m == 5);\n+}\n+\n+template <S &P>\n+void\n+fn_cls_ref ()\n+{\n+ static constexpr auto R = reflect_object(P);\n+\n+ static_assert(is_object(R));\n+ static_assert(!is_value(R));\n+ static_assert(!is_variable(R));\n+ static_assert(type_of(R) == ^^S);\n+}\n+\n+void\n+doit ()\n+{\n+ static constexpr int k = 2;\n+ fn_int_ref<k>();\n+\n+ static int k2;\n+ fn_int_ref<k2>();\n+\n+ static constexpr std::pair<int, int> p {3, 4};\n+ fn_int_subobject_ref<p.first>();\n+\n+ fn_cls_value<{5}>();\n+\n+ static S s;\n+ fn_cls_ref<s>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_object2.C b/gcc/testsuite/g++.dg/reflect/reflect_object2.C\nnew file mode 100644\nindex 00000000000..adf17a20a8f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_object2.C\n@@ -0,0 +1,115 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_object.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+static int obj = 42;\n+constexpr auto robj = reflect_object (obj);\n+static const int cobj = 42;\n+constexpr auto rcobj = reflect_object (cobj);\n+static_assert ([:rcobj:] == 42);\n+static constexpr int ceobj = 42;\n+constexpr auto rceobj = reflect_object (ceobj);\n+static_assert ([:rceobj:] == 42);\n+\n+static_assert (reflect_object (obj) != ^^obj);\n+static_assert (type_of (reflect_object (obj)) == ^^int);\n+static_assert (is_object (reflect_object (obj)));\n+static_assert (!is_value (reflect_object (obj)));\n+static_assert (!is_variable (reflect_object (obj)));\n+static_assert (reflect_object (cobj) != ^^cobj);\n+static_assert (type_of (reflect_object (cobj)) == ^^const int);\n+static_assert (is_object (reflect_object (cobj)));\n+static_assert (!is_value (reflect_object (cobj)));\n+static_assert (!is_variable (reflect_object (cobj)));\n+static_assert (reflect_object (ceobj) != ^^ceobj);\n+static_assert (type_of (reflect_object (ceobj)) == ^^const int);\n+static_assert (is_object (reflect_object (ceobj)));\n+static_assert (!is_value (reflect_object (ceobj)));\n+static_assert (!is_variable (reflect_object (ceobj)));\n+\n+static_assert (!is_const (reflect_object (obj)));\n+static_assert (is_const (reflect_object (cobj)));\n+static_assert (is_const (reflect_object (ceobj)));\n+\n+const int &ref = obj;\n+static_assert (reflect_object (ref) != ^^obj);\n+static_assert (type_of (reflect_object (ref)) == ^^int);\n+static_assert (is_object (reflect_object (ref)));\n+static_assert (!is_value (reflect_object (ref)));\n+static_assert (!is_variable (reflect_object (ref)));\n+static_assert (!is_const (reflect_object (ref)));\n+\n+constexpr const int *pobj = &ceobj;\n+static_assert (reflect_object (pobj) != ^^pobj);\n+static_assert (type_of (reflect_object (pobj)) == ^^const int *const);\n+static_assert (is_object (reflect_object (pobj)));\n+static_assert (!is_value (reflect_object (pobj)));\n+static_assert (!is_variable (reflect_object (pobj)));\n+static_assert (is_const (reflect_object (pobj)));\n+\n+static constexpr std::pair<int, short> p = {1, 2};\n+static_assert (reflect_object (p) != ^^p);\n+static_assert (reflect_object (p.first) != ^^p);\n+static_assert (type_of (reflect_object (p)) == ^^const std::pair<int, short>);\n+static_assert (&[:reflect_object (p.first):] == &p.first);\n+static_assert ([:reflect_object (p.first):] == 1);\n+static_assert (type_of (reflect_object (p.first)) == ^^const int);\n+static_assert (&[:reflect_object (p.second):] == &p.second);\n+static_assert ([:reflect_object (p.second):] == 2);\n+static_assert (type_of(reflect_object (p.second)) == ^^const short);\n+static_assert (is_object (reflect_object (p)));\n+static_assert (!is_value (reflect_object (p)));\n+static_assert (is_object (reflect_object (p.first)));\n+static_assert (!is_value (reflect_object (p.first)));\n+\n+struct B {};\n+struct D : B {};\n+D d;\n+static_assert (type_of (reflect_object (d)) == ^^D);\n+// TODO\n+//static_assert (type_of (reflect_object (static_cast<B &>(d))) == ^^B);\n+\n+template<typename T>\n+constexpr T\n+bar (T a)\n+{\n+ return a + 42;\n+}\n+\n+constexpr int (*barp)(int) = &bar<int>;\n+constexpr auto rbar = reflect_object (barp);\n+static_assert ([:rbar:](0) == 42);\n+\n+unsigned long letter;\n+static_assert (size_of (reflect_object (letter)) == sizeof (unsigned long));\n+\n+template<auto K> constexpr auto R = reflect_object (K);\n+B b = [:R<B{}>:];\n+\n+struct S { int m; };\n+constexpr S s{42};\n+static_assert (reflect_object (s) != ^^s);\n+static_assert (type_of (reflect_object (s)) == ^^const S);\n+static_assert (is_object (reflect_object (s)));\n+static_assert (!is_variable (reflect_object (s)));\n+static_assert (is_const (reflect_object (s)));\n+\n+template<auto V>\n+ requires (is_class_type (^^decltype(V)))\n+consteval bool\n+fn ()\n+{\n+ return reflect_constant (V) == reflect_object (V);\n+}\n+static_assert (fn<s>());\n+\n+void\n+g ()\n+{\n+ int i = [:robj:];\n+ [:rbar:](42);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_object3.C b/gcc/testsuite/g++.dg/reflect/reflect_object3.C\nnew file mode 100644\nindex 00000000000..baa8adbec47\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_object3.C\n@@ -0,0 +1,61 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_object.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+const char *s = \"foo\";\n+constexpr auto r1 = reflect_object (s);\n+extern int x;\n+constexpr auto r2 = reflect_object (x);\n+int ai[10];\n+constexpr auto r3 = reflect_object (ai);\n+\n+constexpr auto e1 = reflect_object (42); // { dg-error \"cannot bind\" }\n+\n+struct J1 {\n+ J1 *self = this;\n+};\n+constexpr auto e2 = reflect_object (J1{}); // { dg-error \"cannot bind\" }\n+\n+struct J2 {\n+ J2 *self = this;\n+ constexpr J2() {}\n+ constexpr J2(const J2&) {}\n+};\n+constexpr auto e3 = reflect_object (J2{}); // { dg-error \"cannot bind\" }\n+\n+struct X { int n; };\n+struct Y { const int &r; };\n+constexpr auto e4 = reflect_object (Y{X{1}.n}); // { dg-error \"cannot bind\" }\n+\n+void\n+f1 ()\n+{\n+ constexpr int& ref = x;\n+ constexpr auto rref = reflect_object (ref);\n+}\n+\n+consteval bool\n+can_reflect_object_on_str ()\n+{\n+ try { reflect_object (\"foo\"); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (!can_reflect_object_on_str ());\n+\n+extern int& vref;\n+\n+consteval bool\n+can_reflect_extern_reference ()\n+{\n+ try { reflect_object (vref); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert(!can_reflect_extern_reference());\ndiff --git a/gcc/testsuite/g++.dg/reflect/reflect_object4.C b/gcc/testsuite/g++.dg/reflect/reflect_object4.C\nnew file mode 100644\nindex 00000000000..a220ab4b538\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/reflect_object4.C\n@@ -0,0 +1,10 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::reflect_object.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+void fn();\n+constexpr auto e = reflect_object (fn); // { dg-error \"no matching function for call\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/return_type_of1.C b/gcc/testsuite/g++.dg/reflect/return_type_of1.C\nnew file mode 100644\nindex 00000000000..a74ca7f2643\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/return_type_of1.C\n@@ -0,0 +1,99 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::return_type_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+int arr[] = {1, 2, 3};\n+auto [a1, a2, a3] = arr;\n+void fn();\n+int &fn2();\n+enum Enum { A };\n+using Alias = int;\n+struct B {};\n+struct S : B {\n+ int mem;\n+ int : 0;\n+};\n+struct T {\n+ T ();\n+ T (const T &);\n+ ~T ();\n+};\n+struct U {\n+ int u;\n+};\n+template<auto> struct TCls {};\n+template<auto> void TFn();\n+template<auto> int TVar;\n+template<auto> concept Concept = requires { true; };\n+namespace NS {};\n+namespace NSAlias = NS;\n+U fn3 (int);\n+using fn4 = unsigned long (int, long);\n+using fn5 = U (...);\n+auto fn6 (int);\n+auto &fn7 (long long);\n+\n+constexpr auto ctx = std::meta::access_context::current ();\n+\n+consteval bool\n+has_return_type_of (info r)\n+{\n+ try { return_type_of (r); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (!has_return_type_of (std::meta::reflect_constant (42)));\n+static_assert (!has_return_type_of (std::meta::reflect_object (arr[1])));\n+static_assert (!has_return_type_of (^^arr));\n+static_assert (!has_return_type_of (^^a3));\n+static_assert (has_return_type_of (^^fn));\n+static_assert (has_return_type_of (^^fn2));\n+static_assert (has_return_type_of (^^fn3));\n+static_assert (has_return_type_of (^^fn4));\n+static_assert (has_return_type_of (^^fn5));\n+static_assert (!has_return_type_of (^^fn6));\n+static_assert (!has_return_type_of (^^fn7));\n+using intref = int &;\n+static_assert (return_type_of (^^fn) == ^^void);\n+static_assert (return_type_of (^^fn2) == dealias (^^intref));\n+using ulong = unsigned long;\n+static_assert (return_type_of (^^fn3) == ^^U);\n+static_assert (return_type_of (^^fn4) == dealias (^^ulong));\n+static_assert (return_type_of (^^fn5) == ^^U);\n+static_assert (!has_return_type_of (^^Enum::A));\n+static_assert (!has_return_type_of (^^Alias));\n+static_assert (!has_return_type_of (^^S));\n+static_assert (!has_return_type_of (^^S::mem));\n+static_assert (!has_return_type_of (members_of (^^S, ctx)[1]));\n+static_assert (!has_return_type_of (^^TCls));\n+static_assert (!has_return_type_of (^^TFn));\n+static_assert (!has_return_type_of (^^TVar));\n+static_assert (!has_return_type_of (^^Concept));\n+static_assert (!has_return_type_of (^^NSAlias));\n+static_assert (!has_return_type_of (^^NS));\n+static_assert (!has_return_type_of (std::meta::bases_of (^^S, ctx)[0]));\n+static_assert (!has_return_type_of (std::meta::data_member_spec (^^int, { .name = \"member\" })));\n+\n+struct V\n+{\n+ V ()\n+ {\n+ int i = 42;\n+// static_assert (!has_return_type_of (parent_of (^^i)));\n+ }\n+ ~V ()\n+ {\n+ int i = 42;\n+// static_assert (!has_return_type_of (parent_of (^^i)));\n+ }\n+ V (int, long)\n+ {\n+ int i = 42;\n+// static_assert (!has_return_type_of (parent_of (^^i)));\n+ }\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/serialize1.C b/gcc/testsuite/g++.dg/reflect/serialize1.C\nnew file mode 100644\nindex 00000000000..a1d50b85b1b\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/serialize1.C\n@@ -0,0 +1,151 @@\n+// { dg-do run { target c++26 } }\n+// { dg-additional-options \"-freflection -O0\" }\n+\n+#include <meta>\n+#include <cstdlib>\n+\n+namespace impl {\n+ template <auto... vals>\n+ struct replicator_type {\n+ template <typename F>\n+ constexpr void operator >> (F body) const\n+ { (body.template operator()<vals>(), ...); }\n+ };\n+\n+ template <auto... vals>\n+ replicator_type <vals...> replicator = {};\n+}\n+\n+template <typename R>\n+consteval auto\n+expand (R range)\n+{\n+ std::vector <std::meta::info> args;\n+ for (auto r : range)\n+ args.push_back (std::meta::reflect_constant (r));\n+ return substitute (^^impl::replicator, args);\n+}\n+\n+struct Person1 {\n+ std::string name;\n+ int age;\n+};\n+\n+constexpr std::string\n+serialize1 (Person1 s)\n+{\n+ std::string result = \" \";\n+ impl::replicator <^^Person1::name, ^^Person1::age> >> [&] <auto m> {\n+ result += identifier_of (m);\n+ result += \"=\";\n+ if constexpr (type_of (m) == ^^int)\n+ result += std::string (s.[: m :] / 10, 'X');\n+ else\n+ result += s.[: m :];\n+ result += \" \";\n+ };\n+ return result;\n+}\n+\n+struct Person2 {\n+ int age;\n+ std::string name;\n+};\n+\n+constexpr std::string\n+serialize2 (Person2 s)\n+{\n+ std::string result = \" \";\n+ constexpr auto ctx = std::meta::access_context::current ();\n+ [: expand (nonstatic_data_members_of (^^Person2, ctx)) :] >> [&] <auto m> {\n+ result += identifier_of (m);\n+ result += \"=\";\n+ if constexpr (type_of (m) == ^^int)\n+ result += std::string (s.[: m :] / 10, 'X');\n+ else\n+ result += s.[: m :];\n+ result += \" \";\n+ };\n+ return result;\n+}\n+\n+struct Person3 {\n+ std::string name, surname;\n+ int age;\n+};\n+\n+template <typename S>\n+constexpr std::string\n+serialize3 (S s)\n+{\n+ std::string result = \" \";\n+ constexpr auto ctx = std::meta::access_context::current ();\n+ [: expand (nonstatic_data_members_of (^^S, ctx)) :] >> [&] <auto m> {\n+ result += identifier_of (m);\n+ result += \"=\";\n+ if constexpr (type_of (m) == ^^int)\n+ result += std::string (s.[: m :] / 10, 'X');\n+ else\n+ result += s.[: m :];\n+ result += \" \";\n+ };\n+ return result;\n+}\n+\n+template <typename S>\n+constexpr std::string\n+serialize4 (S s)\n+{\n+ std::string result = \" \";\n+ constexpr auto ctx = std::meta::access_context::current ();\n+ template for (constexpr auto m : [: reflect_constant_array (nonstatic_data_members_of (^^S, ctx)) :]) {\n+ result += identifier_of (m);\n+ result += \"=\";\n+ if constexpr (type_of (m) == ^^int)\n+ result += std::string (s.[: m :] / 10, 'X');\n+ else\n+ result += s.[: m :];\n+ result += \" \";\n+ };\n+ return result;\n+}\n+\n+constexpr Person1 john { \"John\", 42 };\n+constexpr Person2 joe { 37, \"Joe\" };\n+constexpr Person3 john_smith { \"John\", \"Smith\", 71 };\n+\n+static_assert (serialize1 (john) == \" name=John age=XXXX \");\n+static_assert (serialize2 (joe) == \" age=XXX name=Joe \");\n+static_assert (serialize3 (john) == \" name=John age=XXXX \");\n+static_assert (serialize3 (joe) == \" age=XXX name=Joe \");\n+static_assert (serialize3 (john_smith) == \" name=John surname=Smith age=XXXXXXX \");\n+static_assert (serialize4 (john) == \" name=John age=XXXX \");\n+static_assert (serialize4 (joe) == \" age=XXX name=Joe \");\n+static_assert (serialize4 (john_smith) == \" name=John surname=Smith age=XXXXXXX \");\n+\n+int\n+main ()\n+{\n+ Person1 jack { \"Jack\", 53 };\n+ std::string s1 = serialize1 (jack);\n+ if (s1 != \" name=Jack age=XXXXX \")\n+ std::abort ();\n+ Person2 harry { 28, \"Harry\" };\n+ std::string s2 = serialize2 (harry);\n+ if (s2 != \" age=XX name=Harry \")\n+ std::abort ();\n+ if (serialize3 (jack) != s1)\n+ std::abort ();\n+ if (serialize3 (harry) != s2)\n+ std::abort ();\n+ Person3 jane_doe { \"Jane\", \"Doe\", 19 };\n+ std::string s3 = serialize3 (jane_doe);\n+ if (s3 != \" name=Jane surname=Doe age=X \")\n+ std::abort ();\n+ if (serialize4 (jack) != s1)\n+ std::abort ();\n+ if (serialize4 (harry) != s2)\n+ std::abort ();\n+ if (serialize4 (jane_doe) != s3)\n+ std::abort ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/serialize2.C b/gcc/testsuite/g++.dg/reflect/serialize2.C\nnew file mode 100644\nindex 00000000000..9b3ae685589\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/serialize2.C\n@@ -0,0 +1,67 @@\n+// { dg-do run { target c++26 } }\n+// { dg-additional-options \"-freflection -O0\" }\n+\n+#include <meta>\n+#include <cstdlib>\n+\n+namespace impl {\n+ template <auto... vals>\n+ struct replicator_type {\n+ template <typename F>\n+ constexpr void operator >> (F body) const\n+ { (body.template operator()<vals>(), ...); }\n+ };\n+\n+ template <auto... vals>\n+ replicator_type <vals...> replicator = {};\n+}\n+\n+template <typename R>\n+consteval auto\n+expand (R range)\n+{\n+ std::vector <std::meta::info> args;\n+ for (auto r : range)\n+ args.push_back (std::meta::reflect_constant (r));\n+ return substitute (^^impl::replicator, args);\n+}\n+\n+struct Person {\n+ std::string name;\n+ int age;\n+};\n+\n+template <typename S>\n+constexpr std::string\n+serialize (S s)\n+{\n+ std::string result = \" \";\n+#if 0\n+ // TODO, this ICEs in tsubst_expr.\n+ impl::replicator <^^S::age, ^^S::name> >> [&] <auto m> {\n+#else\n+ impl::replicator <^^Person::age, ^^Person::name> >> [&] <auto m> {\n+#endif\n+ result += identifier_of (m);\n+ result += \"=\";\n+ if constexpr (type_of (m) == ^^int)\n+ result += std::string (s.[: m :] / 10, 'X');\n+ else\n+ result += s.[: m :];\n+ result += \" \";\n+ };\n+ return result;\n+}\n+\n+constexpr Person john { \"John\", 42 };\n+\n+static_assert (serialize (john) == \" age=XXXX name=John \");\n+\n+int\n+main ()\n+{\n+ Person jack { \"Jack\", 53 };\n+ std::string s = serialize (jack);\n+ if (s != \" age=XXXXX name=Jack \")\n+ std::abort ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/size_of1.C b/gcc/testsuite/g++.dg/reflect/size_of1.C\nnew file mode 100644\nindex 00000000000..f1500684809\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/size_of1.C\n@@ -0,0 +1,122 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::size_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+int arr[] = {1, 2, 3};\n+auto [a1, a2, a3] = arr;\n+extern int arr2[];\n+extern int arr3[2];\n+void fn();\n+auto &fn2();\n+enum Enum { A };\n+using Alias = int;\n+struct B {};\n+struct S : B {\n+ int mem;\n+ int : 0;\n+};\n+struct T {\n+ T ();\n+ T (const T &);\n+ ~T ();\n+};\n+struct U {\n+ int u;\n+};\n+template<auto> struct TCls {};\n+template<auto> void TFn();\n+template<auto> int TVar;\n+template<auto> concept Concept = requires { true; };\n+namespace NS {};\n+namespace NSAlias = NS;\n+int &ref = arr[0];\n+\n+constexpr auto ctx = std::meta::access_context::current ();\n+\n+consteval bool\n+has_size_of (info r)\n+{\n+ try { size_of (r); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (has_size_of (std::meta::reflect_constant (42)));\n+static_assert (has_size_of (std::meta::reflect_object (arr[1])));\n+static_assert (has_size_of (^^arr));\n+static_assert (!has_size_of (^^a3));\n+static_assert (!has_size_of (^^fn));\n+static_assert (!has_size_of (^^fn2));\n+static_assert (!has_size_of (^^Enum::A));\n+static_assert (has_size_of (^^Alias));\n+static_assert (has_size_of (^^S));\n+static_assert (has_size_of (^^S::mem));\n+static_assert (!has_size_of (members_of (^^S, access_context::current ())[1]));\n+static_assert (!has_size_of (^^TCls));\n+static_assert (!has_size_of (^^TFn));\n+static_assert (!has_size_of (^^TVar));\n+static_assert (!has_size_of (^^Concept));\n+static_assert (!has_size_of (^^NSAlias));\n+static_assert (!has_size_of (^^NS));\n+static_assert (has_size_of (std::meta::bases_of (^^S, ctx)[0]));\n+static_assert (has_size_of (std::meta::data_member_spec (^^int, { .name = \"member\" })));\n+static_assert (!has_size_of (std::meta::data_member_spec (^^int, { .name = \"member\", .bit_width = 6 })));\n+static_assert (!has_size_of (std::meta::data_member_spec (^^int, { .bit_width = 15 })));\n+static_assert (!has_size_of (^^arr2));\n+static_assert (has_size_of (^^arr3));\n+static_assert (!has_size_of (^^ref));\n+static_assert (size_of (^^arr) == sizeof (arr));\n+static_assert (size_of (std::meta::reflect_constant (42)) == sizeof (int));\n+static_assert (size_of (^^Alias) == sizeof (int));\n+static_assert (size_of (^^S) == sizeof (S));\n+static_assert (size_of (^^S::mem) == sizeof (S::mem));\n+static_assert (size_of (std::meta::bases_of (^^S, ctx)[0]) == sizeof (B));\n+static_assert (size_of (std::meta::data_member_spec (^^int, { .name = \"member\" })) == sizeof (int));\n+static_assert (size_of (^^arr3) == sizeof (arr3));\n+using fnt = int (int, int);\n+static_assert (!has_size_of (^^fnt));\n+void bar (long, const T f, int g[2], T &);\n+\n+int\n+foo (int a, const long b, T c, int d[4], T &e, int f)\n+{\n+ static_assert (has_size_of (^^a));\n+ static_assert (has_size_of (^^b));\n+ static_assert (has_size_of (^^c));\n+ static_assert (has_size_of (^^d));\n+ static_assert (!has_size_of (^^e));\n+ static_assert (!has_size_of (parameters_of (^^foo)[0]));\n+ static_assert (!has_size_of (parameters_of (^^foo)[5]));\n+ static_assert (!has_size_of (parameters_of (^^bar)[0]));\n+ static_assert (size_of (^^a) == sizeof (int));\n+ static_assert (size_of (^^b) == sizeof (long));\n+ static_assert (size_of (^^c) == sizeof (T));\n+ static_assert (size_of (^^d) == sizeof (int *));\n+ return 0;\n+}\n+\n+struct V\n+{\n+ char a;\n+ long long f;\n+ int : 2;\n+ int g : 3;\n+ int &h;\n+};\n+using CV = const V;\n+\n+static_assert (size_of (^^int) == sizeof (int));\n+static_assert (size_of (^^char) == sizeof (char));\n+static_assert (size_of (^^V) == sizeof (V));\n+static_assert (size_of (^^CV) == sizeof (V));\n+static_assert (size_of (^^char *) == sizeof (char *));\n+static_assert (size_of (^^char &) == sizeof (char *));\n+static_assert (sizeof (char) == sizeof (char *) || size_of (^^char &) != sizeof (char &));\n+static_assert (size_of (^^V::a) == sizeof (char));\n+static_assert (size_of (^^V::f) == sizeof (long long));\n+static_assert (!has_size_of (^^V::g));\n+static_assert (size_of (^^V::h) == sizeof (int *));\ndiff --git a/gcc/testsuite/g++.dg/reflect/source_location_of1.C b/gcc/testsuite/g++.dg/reflect/source_location_of1.C\nnew file mode 100644\nindex 00000000000..8ba34dbbaa7\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/source_location_of1.C\n@@ -0,0 +1,113 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::source_location_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+static_assert (source_location_of (^^::).line () == std::source_location ().line ());\n+static_assert (source_location_of (^^int).line () == std::source_location ().line ());\n+struct S {};\n+static_assert (source_location_of (^^S).line () == std::source_location::current ().line () - 1);\n+int x;\n+static_assert (source_location_of (^^x).line () == std::source_location::current ().line () - 1);\n+enum E {\n+ E1,\n+ E2\n+};\n+static_assert (source_location_of (^^E).line () == std::source_location::current ().line () - 4);\n+static_assert (source_location_of (^^E1).line () == std::source_location::current ().line () - 4);\n+static_assert (source_location_of (^^E2).line () == std::source_location::current ().line () - 4);\n+union U {};\n+static_assert (source_location_of (^^U).line () == std::source_location::current ().line () - 1);\n+void foo (int, int) {}\n+static_assert (source_location_of (^^foo).line () == std::source_location::current ().line () - 1);\n+namespace N { namespace O {} }\n+static_assert (source_location_of (^^N).line () == std::source_location::current ().line () - 1);\n+static_assert (source_location_of (^^N::O).line () == std::source_location::current ().line () - 2);\n+using I = int;\n+static_assert (source_location_of (^^I).line () == std::source_location::current ().line () - 1);\n+static_assert (source_location_of (dealias (^^I)).line () == std::source_location ().line ());\n+typedef S J;\n+static_assert (source_location_of (dealias (^^J)).line () == source_location_of (^^S).line ());\n+static_assert (source_location_of (data_member_spec (^^int, { .name = \"_\" })).line () == std::source_location ().line ());\n+constexpr auto ctx = access_context::current ();\n+struct V {};\n+struct Y { int a, b, c; };\n+struct W : [[=1]] public S, [[=2, =Y { 42, 42, 42 }]] virtual V {};\n+static_assert (source_location_of (bases_of (^^W, ctx)[0]).line () == std::source_location::current ().line () - 1);\n+static_assert (source_location_of (bases_of (^^W, ctx)[1]).line () == std::source_location::current ().line () - 2);\n+static_assert (source_location_of (annotations_of (bases_of (^^W, ctx)[0])[0]).line () == std::source_location::current ().line () - 3);\n+static_assert (source_location_of (annotations_of (bases_of (^^W, ctx)[1])[1]).line () == std::source_location::current ().line () - 4);\n+struct X : public S,\n+\t [[=3]] public V\n+{\n+};\n+static_assert (source_location_of (bases_of (^^X, ctx)[0]).line () == std::source_location::current ().line () - 4);\n+// TODO: we don't track location of base specifiers, so just location of the derived class definition is used.\n+static_assert (source_location_of (bases_of (^^X, ctx)[1]).line () == std::source_location::current ().line () - 6);\n+static_assert (source_location_of (annotations_of (bases_of (^^X, ctx)[1])[0]).line () == std::source_location::current ().line () - 6);\n+[[=1]]\n+[[=2]] extern int an;\n+[[=Y { 1, 2, 3 }]] extern int an;\n+[[=3.0f + 4.0f]] int an;\n+static_assert (source_location_of (annotations_of (^^an)[0]).line () == std::source_location::current ().line () - 4);\n+static_assert (source_location_of (annotations_of (^^an)[1]).line () == std::source_location::current ().line () - 4);\n+static_assert (source_location_of (annotations_of (^^an)[2]).line () == std::source_location::current ().line () - 4);\n+static_assert (source_location_of (annotations_of (^^an)[3]).line () == std::source_location::current ().line () - 4);\n+\n+#include <string_view>\n+\n+int baz (int x, int y);\n+static_assert (source_location_of (parameters_of (^^baz)[0]).line () == std::source_location::current ().line () - 1);\n+\n+void\n+bar (int a, int b)\n+{\n+ static_assert (source_location_of (^^a).line ()\n+\t\t == std::source_location::current ().line () - 3);\n+ static_assert (source_location_of (^^b).line ()\n+\t\t == source_location_of (^^a).line ());\n+ static_assert (std::string_view (source_location_of (^^bar).file_name ())\n+\t\t == std::string_view (std::source_location::current ().file_name ()));\n+ static_assert (std::string_view (source_location_of (^^a).function_name ())\n+\t\t == std::string_view (std::source_location::current ().function_name ()));\n+ static_assert (std::string_view (source_location_of (^^b).function_name ())\n+\t\t == std::string_view (std::source_location::current ().function_name ()));\n+ int c;\n+ static_assert (source_location_of (^^c).line ()\n+\t\t == std::source_location::current ().line () - 2);\n+ static_assert (std::string_view (source_location_of (^^c).file_name ())\n+\t\t == std::string_view (std::source_location::current ().file_name ()));\n+ static_assert (std::string_view (source_location_of (^^a).function_name ())\n+\t\t == std::string_view (std::source_location::current ().function_name ()));\n+ constexpr auto d = parameters_of (^^bar)[0];\n+ static_assert (source_location_of (d).line ()\n+\t\t == source_location_of (^^a).line ());\n+ static_assert (std::string_view (source_location_of (d).file_name ())\n+\t\t == std::string_view (source_location_of (^^a).file_name ()));\n+ static_assert (std::string_view (source_location_of (d).function_name ())\n+\t\t == std::string_view (source_location_of (^^a).function_name ()));\n+}\n+\n+template <int N>\n+void\n+qux ()\n+{\n+ [[=1]]\n+ [[=N + 42]]\n+ [[=Y { N, N + 1, N + 2 }]]\n+ [[=Y { 1, 2, 3 }]] int an;\n+ static_assert (N && source_location_of (annotations_of (^^an)[0]).line () == std::source_location::current ().line () - 4);\n+ static_assert (N && source_location_of (annotations_of (^^an)[1]).line () == std::source_location::current ().line () - 4);\n+// static_assert (N && source_location_of (annotations_of (^^an)[2]).line () == std::source_location::current ().line () - 4);\n+// static_assert (N && source_location_of (annotations_of (^^an)[3]).line () == std::source_location::current ().line () - 4);\n+}\n+\n+void\n+plugh ()\n+{\n+ qux <1> ();\n+ qux <2> ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/source_location_of2.C b/gcc/testsuite/g++.dg/reflect/source_location_of2.C\nnew file mode 100644\nindex 00000000000..7ea4d9e652e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/source_location_of2.C\n@@ -0,0 +1,44 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::source_location_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template <typename F>\n+consteval info\n+select_mem (info clazz, F f)\n+{\n+ for (info x : members_of (clazz, access_context::unchecked ()))\n+ if (f (x))\n+ return x;\n+}\n+\n+consteval auto is_operator (operators op)\n+{\n+ return [op] (info mem) { return is_operator_function (mem) && operator_of (mem) == op; };\n+}\n+\n+constexpr auto implicitDefLine = std::source_location::current ().line ()+2;\n+struct\n+ImplicitDef\n+{};\n+\n+static_assert (source_location_of (select_mem (^^ImplicitDef, is_default_constructor)).line () == implicitDefLine);\n+static_assert (source_location_of (select_mem (^^ImplicitDef, is_copy_constructor)).line () == implicitDefLine);\n+static_assert (source_location_of (select_mem (^^ImplicitDef, is_move_constructor)).line () == implicitDefLine);\n+static_assert (source_location_of (select_mem (^^ImplicitDef, is_copy_assignment)).line () == implicitDefLine);\n+static_assert (source_location_of (select_mem (^^ImplicitDef, is_move_assignment)).line () == implicitDefLine);\n+static_assert (source_location_of (select_mem (^^ImplicitDef, is_destructor)).line () == implicitDefLine);\n+\n+constexpr auto implicitEqLine = std::source_location::current ().line ()+3;\n+struct ImplicitEq\n+{\n+ auto operator<=> (const ImplicitEq&) const = default;\n+};\n+\n+// Would expect either class head, or operator<=> line\n+static_assert (source_location_of (^^ImplicitEq::operator==).line () == 0);\n+static_assert (source_location_of (select_mem (^^ImplicitEq, is_operator (op_equals_equals))).line () == implicitEqLine);\n+static_assert (source_location_of (select_mem (^^ImplicitEq, is_operator (op_spaceship))).line () == implicitEqLine);\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice1.C b/gcc/testsuite/g++.dg/reflect/splice1.C\nnew file mode 100644\nindex 00000000000..6eb1f6f857d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice1.C\n@@ -0,0 +1,28 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+#include <ranges>\n+\n+using namespace std::meta;\n+\n+struct S {\n+ int mem;\n+ int : 5;\n+};\n+struct T : public S {\n+};\n+\n+[[=1]] void\n+foo ()\n+{\n+ S s = { 0 }, t = { 0 };\n+ constexpr auto ctx = access_context::unchecked ();\n+ s.[: members_of (^^S, ctx)[1] :] = 1;\t// { dg-error \"cannot use an unnamed bit-field in a splice expression\" }\n+ s.[: (members_of (^^S, ctx) | std::views::filter (is_default_constructor) | std::ranges::to <std::vector> ())[0] :] ();\t// { dg-error \"cannot use constructor or destructor in a splice expression\" }\n+ s.[: (members_of (^^S, ctx) | std::views::filter (is_copy_constructor) | std::ranges::to <std::vector> ())[0] :] (t);\t\t// { dg-error \"cannot use constructor or destructor in a splice expression\" }\n+ s.[: (members_of (^^S, ctx) | std::views::filter (is_destructor) | std::ranges::to <std::vector> ())[0] :] ();\t\t// { dg-error \"cannot use constructor or destructor in a splice expression\" }\n+ [: annotations_of (^^foo)[0] :]; // { dg-error \"cannot use an annotation in a splice expression\" }\n+ [: data_member_spec (^^S, { .name = \"name\" }) :]; // { dg-error \"cannot use a data member specification in a splice expression\" }\n+ [: bases_of (^^T, ctx)[0] :];\t\t\t\t\t\t\t\t\t\t\t\t\t// { dg-error \"\" \"\" { xfail *-*-* } }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice2.C b/gcc/testsuite/g++.dg/reflect/splice2.C\nnew file mode 100644\nindex 00000000000..73de0ab019f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice2.C\n@@ -0,0 +1,13 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+constexpr int foo (int) { return 42; };\n+constexpr auto bar = ^^foo;\n+constexpr int foo (long) { return 43; }\n+constexpr int foo (long long) { return 44; }\n+static_assert (foo (0) == 42);\n+static_assert (foo (0L) == 43);\n+static_assert (foo (0LL) == 44);\n+static_assert ([: bar :] (0) == 42);\n+static_assert ([: bar :] (0L) == 42);\n+static_assert ([: bar :] (0LL) == 42);\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice3.C b/gcc/testsuite/g++.dg/reflect/splice3.C\nnew file mode 100644\nindex 00000000000..88434444a2d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice3.C\n@@ -0,0 +1,5 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct A { static int x; };\n+int q = A ().[: ^^x :]; // { dg-error \"'x' has not been declared\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice4.C b/gcc/testsuite/g++.dg/reflect/splice4.C\nnew file mode 100644\nindex 00000000000..29567d2df35\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice4.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+namespace M\n+{\n+ template <int N>\n+ constexpr int foo () { return N; }\n+}\n+\n+static_assert (template [: ^^M::foo :] <42> () == 42);\n+static_assert (template [: members_of (^^M, std::meta::access_context::unchecked ())[0] :] <43> () == 43);\n+int a = [: ^^M::foo :] <44> ();\n+// { dg-error \"reflection 'M::foo<44>' not usable in a splice expression with template arguments\" \"\" { target *-*-* } .-1 }\n+int b = [: members_of (^^M, std::meta::access_context::unchecked ())[0] :] <45> ();\n+// { dg-error \"reflection 'M::foo<45>' not usable in a splice expression with template arguments\" \"\" { target *-*-* } .-1 }\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice5.C b/gcc/testsuite/g++.dg/reflect/splice5.C\nnew file mode 100644\nindex 00000000000..f06e2270785\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice5.C\n@@ -0,0 +1,39 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+void foo (int);\n+template <typename T>\n+void bar (T);\n+struct S {\n+ void foo (int);\n+ template <typename T>\n+ void bar (T);\n+};\n+\n+void\n+baz (S &s)\n+{\n+ template [: ^^foo :] (0);\t\t\t// { dg-error \"reflection 'foo' not usable in a template splice\" }\n+ template [: ^^bar :] (0);\t\t\t// { dg-message \"only function templates are allowed here\" \"\" { target *-*-* } .-1 }\n+ s.template [: ^^S::foo :] (0);\t\t// { dg-error \"reflection 'S::foo' not usable in a template splice\" }\n+ s.template [: ^^S::bar :] (0);\t\t// { dg-message \"only function templates are allowed here\" \"\" { target *-*-* } .-1 }\n+}\n+\n+template <int N>\n+void\n+qux (S &s)\n+{\n+ // TODO: We don't reject this one.\n+ template [: N == 0 ? ^^foo : ^^:: :] (0);\t// { dg-error \"reflection 'foo' not usable in a template splice\" \"\" { xfail *-*-* } }\n+ template [: N == 0 ? ^^bar : ^^:: :] (0);\t// { dg-message \"only function templates are allowed here\" \"\" { xfail *-*-* } .-1 }\n+ // TODO: The first one should be rejected, the second one accepted.\n+ // We emit nonsensical unrelated errors.\n+ // s.template [: N == 0 ? ^^S::foo : ^^:: :] (0);\n+ // s.template [: N == 0 ? ^^S::bar : ^^:: :] (0);\n+}\n+\n+void\n+corge (S &s)\n+{\n+ qux <0> (s);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice6.C b/gcc/testsuite/g++.dg/reflect/splice6.C\nnew file mode 100644\nindex 00000000000..798bd48589e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice6.C\n@@ -0,0 +1,48 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+template <typename U>\n+constexpr int foo (int x, const U &) { return 41 + x; }\n+constexpr auto foo1 = ^^foo;\n+template <typename U>\n+constexpr int foo (long x, const U &) { return 42 + x; }\n+template <typename U>\n+constexpr int foo (long long x, const U &) { return 43 + x; }\n+\n+static_assert (template [:foo1:] (1, 1.0f) == 42);\n+static_assert (template [:foo1:] (1L, 1.0) == 42);\n+static_assert (template [:foo1:] (1LL, 1.0L) == 42);\n+static_assert (template [:foo1:] <float> (1, 1.0f) == 42);\n+static_assert (template [:foo1:] <double> (1L, 1.0) == 42);\n+static_assert (template [:foo1:] <long double> (1LL, 1.0L) == 42);\n+\n+template <int N>\n+void\n+bar ()\n+{\n+ static_assert (template [:foo1:] (1, 1.0f) == N);\n+ static_assert (template [:foo1:] (1L, 1.0) == N);\n+ static_assert (template [:foo1:] (1LL, 1.0L) == N);\n+ static_assert (template [:foo1:] <float> (1, 1.0f) == N);\n+ static_assert (template [:foo1:] <double> (1L, 1.0) == N);\n+ static_assert (template [:foo1:] <long double> (1LL, 1.0L) == N);\n+}\n+\n+template <auto f>\n+void\n+baz ()\n+{\n+ static_assert (template [:f:] (1, 1.0f) == 42);\n+ static_assert (template [:f:] (1L, 1.0) == 42);\n+ static_assert (template [:f:] (1LL, 1.0L) == 42);\n+ static_assert (template [:f:] <float> (1, 1.0f) == 42);\n+ static_assert (template [:f:] <double> (1L, 1.0) == 42);\n+ static_assert (template [:f:] <long double> (1LL, 1.0L) == 42);\n+}\n+\n+void\n+qux ()\n+{\n+ bar <42> ();\n+ baz <foo1> ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/splice7.C b/gcc/testsuite/g++.dg/reflect/splice7.C\nnew file mode 100644\nindex 00000000000..50426c9785e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splice7.C\n@@ -0,0 +1,6 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+constexpr int x = 42;\n+struct S { static constexpr int x = 20; template <int N> static constexpr int a = N; };\n+static_assert (S {}.template [:^^S::a:]<x> == 42);\ndiff --git a/gcc/testsuite/g++.dg/reflect/splicing-base1.C b/gcc/testsuite/g++.dg/reflect/splicing-base1.C\nnew file mode 100644\nindex 00000000000..0838750e21c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splicing-base1.C\n@@ -0,0 +1,24 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test from [expr.ref].\n+\n+#include <meta>\n+\n+struct B {\n+ int b;\n+};\n+struct C : B {\n+ constexpr int get() const { return b; }\n+};\n+struct D : B, C { }; // { dg-warning \"inaccessible\" }\n+\n+constexpr int f() {\n+ D d = {1, {}};\n+\n+ // b unambiguously refers to the direct base class of type B,\n+ // not the indirect base class of type B\n+ B& b = d.[: std::meta::bases_of(^^D, std::meta::access_context::current())[0] :];\n+ b.b += 10;\n+ return 10 * b.b + d.get();\n+}\n+static_assert(f() == 110);\ndiff --git a/gcc/testsuite/g++.dg/reflect/splicing-base2.C b/gcc/testsuite/g++.dg/reflect/splicing-base2.C\nnew file mode 100644\nindex 00000000000..d7b96e6c6af\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splicing-base2.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+struct B {\n+ int b;\n+};\n+struct D : B { };\n+\n+template<info R>\n+constexpr int\n+f ()\n+{\n+ D d = {42};\n+ B& b = d.[:R:];\n+ return b.b;\n+}\n+static_assert (f<bases_of(^^D, access_context::current ())[0]> () == 42);\n+\n+template<info R>\n+constexpr int\n+g ()\n+{\n+ D d = {42};\n+ B *bp = &d.[:R:];\n+ return bp->b;\n+}\n+static_assert (g<bases_of(^^D, access_context::current ())[0]> () == 42);\ndiff --git a/gcc/testsuite/g++.dg/reflect/splicing-base3.C b/gcc/testsuite/g++.dg/reflect/splicing-base3.C\nnew file mode 100644\nindex 00000000000..92faa11c73d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splicing-base3.C\n@@ -0,0 +1,112 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A { int a; };\n+struct B { int b; };\n+struct C { int c; };\n+struct D { int d; };\n+struct E { int e; };\n+struct F { int f; };\n+struct G { int g; };\n+struct H { int h; };\n+struct I : public A, protected B, private C { int i; };\n+struct J : protected D, private E, public F { int j; };\n+struct K : public G, protected I, private H, public J { int k; };\n+struct L : virtual A { int l; };\n+struct M : virtual A { int m; };\n+struct N : public L, protected M, public virtual A { int n; };\n+\n+constexpr access_context gctx = access_context::current ();\n+constexpr access_context uctx = access_context::unchecked ();\n+\n+void\n+g ()\n+{\n+ I i;\n+ A &a1 = i.[: bases_of(^^I, gctx)[0] :];\n+ a1.a++;\n+ A &a2 = i.[: bases_of(^^I, uctx)[0] :];\n+ a2.a++;\n+ B &b = i.[: bases_of(^^I, uctx)[1] :];\n+ b.b++;\n+ C &c = i.[: bases_of(^^I, uctx)[2] :];\n+ c.c++;\n+ A *ap1 = &i.[: bases_of(^^I, gctx)[0] :];\n+ ap1->a++;\n+ A *ap2 = &i.[: bases_of(^^I, uctx)[0] :];\n+ ap2->a++;\n+ B *bp = &i.[: bases_of(^^I, uctx)[1] :];\n+ bp->b++;\n+ C *cp = &i.[: bases_of(^^I, uctx)[2] :];\n+ cp->c++;\n+\n+ J j;\n+ F &f1 = j.[: bases_of(^^J, gctx)[0] :];\n+ f1.f++;\n+ D &d = j.[: bases_of(^^J, uctx)[0] :];\n+ d.d++;\n+ E &e = j.[: bases_of(^^J, uctx)[1] :];\n+ e.e++;\n+ F &f2 = j.[: bases_of(^^J, uctx)[2] :];\n+ f2.f++;\n+ F *fp1 = &j.[: bases_of(^^J, gctx)[0] :];\n+ fp1->f++;\n+ D *dp = &j.[: bases_of(^^J, uctx)[0] :];\n+ dp->d++;\n+ E *ep = &j.[: bases_of(^^J, uctx)[1] :];\n+ ep->e++;\n+ F *fp2 = &j.[: bases_of(^^J, uctx)[2] :];\n+ fp2->f++;\n+\n+ K k;\n+ G &g1 = k.[: bases_of(^^K, gctx)[0] :];\n+ g1.g++;\n+ J &j1 = k.[: bases_of(^^K, gctx)[1] :];\n+ j1.j++;\n+ G *gp = &k.[: bases_of(^^K, gctx)[0] :];\n+ gp->g++;\n+ J *jp1 = &k.[: bases_of(^^K, gctx)[1] :];\n+ jp1->j++;\n+ G &g2 = k.[: bases_of(^^K, uctx)[0] :];\n+ g2.g++;\n+ I &i2 = k.[: bases_of(^^K, uctx)[1] :];\n+ i2.i++;\n+ H &h = k.[: bases_of(^^K, uctx)[2] :];\n+ h.h++;\n+ J &j3 = k.[: bases_of(^^K, uctx)[3] :];\n+ j3.j++;\n+ G *gp2 = &k.[: bases_of(^^K, uctx)[0] :];\n+ gp2->g++;\n+ I *ip2 = &k.[: bases_of(^^K, uctx)[1] :];\n+ ip2->i++;\n+ H *hp = &k.[: bases_of(^^K, uctx)[2] :];\n+ hp->h++;\n+ J *jp3 = &k.[: bases_of(^^K, uctx)[3] :];\n+ jp3->j++;\n+\n+ N n;\n+ L &l = n.[: bases_of(^^N, gctx)[0] :];\n+ l.l++;\n+ A &a3 = n.[: bases_of(^^N, gctx)[1] :];\n+ a3.a++;\n+ L *lp = &n.[: bases_of(^^N, gctx)[0] :];\n+ lp->l++;\n+ A *ap3 = &n.[: bases_of(^^N, gctx)[1] :];\n+ ap3->a++;\n+ L &l2 = n.[: bases_of(^^N, uctx)[0] :];\n+ l2.l++;\n+ M &m = n.[: bases_of(^^N, uctx)[1] :];\n+ m.m++;\n+ A &a4 = n.[: bases_of(^^N, uctx)[2] :];\n+ a4.a++;\n+ L *lp2 = &n.[: bases_of(^^N, uctx)[0] :];\n+ lp2->l++;\n+ M *mp = &n.[: bases_of(^^N, uctx)[1] :];\n+ mp->m++;\n+ A *ap4 = &n.[: bases_of(^^N, uctx)[2] :];\n+ ap4->a++;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/splicing-base4.C b/gcc/testsuite/g++.dg/reflect/splicing-base4.C\nnew file mode 100644\nindex 00000000000..1f9bd3d8199\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/splicing-base4.C\n@@ -0,0 +1,28 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A { int a; };\n+struct B { int b; };\n+struct C : A, B { };\n+struct D : A, B { };\n+\n+constexpr access_context uctx = access_context::unchecked ();\n+\n+void\n+g ()\n+{\n+ A a{1};\n+ A &ar = a.[: bases_of(^^A, uctx)[0] :];\n+ C c;\n+ A &a2 = c.[: bases_of(^^C, uctx)[0] :];\n+ B &b = c.[: bases_of(^^C, uctx)[0] :]; // { dg-error \"invalid initialization of reference\" }\n+ A *ap = &c.[: bases_of(^^C, uctx)[1] :]; // { dg-error \"cannot convert\" }\n+ A &a3 = c.[: bases_of(^^D, uctx)[0] :]; // { dg-error \"not a base type for type\" }\n+ B &b2 = c.[: bases_of(^^D, uctx)[1] :]; // { dg-error \"not a base type for type\" }\n+}\n+\n+// { dg-error \"call to non-.constexpr.\" \"\" { target *-*-* } 0 }\ndiff --git a/gcc/testsuite/g++.dg/reflect/storage_duration1.C b/gcc/testsuite/g++.dg/reflect/storage_duration1.C\nnew file mode 100644\nindex 00000000000..ca643466203\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/storage_duration1.C\n@@ -0,0 +1,141 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::has_{static,thread,automatic}_storage_duration.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S {\n+ int nsdm;\n+ static_assert (!has_static_storage_duration (^^nsdm));\n+ static_assert (!has_thread_storage_duration (^^nsdm));\n+ static_assert (!has_automatic_storage_duration (^^nsdm));\n+\n+ static inline int sdm;\n+ static_assert (has_static_storage_duration (^^sdm));\n+ static_assert (!has_thread_storage_duration (^^sdm));\n+ static_assert (!has_automatic_storage_duration (^^sdm));\n+\n+ static thread_local int stdm;\n+ static_assert (!has_static_storage_duration (^^stdm));\n+ static_assert (has_thread_storage_duration (^^stdm));\n+ static_assert (!has_automatic_storage_duration (^^stdm));\n+\n+ static void smemfn ();\n+ static_assert (!has_static_storage_duration (^^smemfn));\n+ static_assert (!has_thread_storage_duration (^^smemfn));\n+ static_assert (!has_automatic_storage_duration (^^smemfn));\n+\n+ void memfn ();\n+ static_assert (!has_static_storage_duration (^^memfn));\n+ static_assert (!has_thread_storage_duration (^^memfn));\n+ static_assert (!has_automatic_storage_duration (^^memfn));\n+};\n+\n+extern int i0;\n+static_assert (has_static_storage_duration (^^i0));\n+static_assert (!has_thread_storage_duration (^^i0));\n+static_assert (!has_automatic_storage_duration (^^i0));\n+\n+int i1;\n+static_assert (has_static_storage_duration (^^i1));\n+static_assert (!has_thread_storage_duration (^^i1));\n+static_assert (!has_automatic_storage_duration (^^i1));\n+\n+static int i2;\n+static_assert (has_static_storage_duration (^^i2));\n+static_assert (!has_thread_storage_duration (^^i2));\n+static_assert (!has_automatic_storage_duration (^^i2));\n+\n+thread_local int i3;\n+static_assert (!has_static_storage_duration (^^i3));\n+static_assert (has_thread_storage_duration (^^i3));\n+static_assert (!has_automatic_storage_duration (^^i3));\n+\n+static thread_local int i4;\n+static_assert (!has_static_storage_duration (^^i4));\n+static_assert (has_thread_storage_duration (^^i4));\n+static_assert (!has_automatic_storage_duration (^^i4));\n+\n+void\n+foo (float parm)\n+{\n+ static_assert (!has_static_storage_duration (^^foo));\n+ static_assert (!has_thread_storage_duration (^^foo));\n+ static_assert (!has_automatic_storage_duration (^^foo));\n+\n+ static_assert (!has_static_storage_duration (^^parm));\n+ static_assert (!has_thread_storage_duration (^^parm));\n+ static_assert (has_automatic_storage_duration (^^parm));\n+\n+ int nonstatic_var;\n+ static_assert (!has_static_storage_duration (^^nonstatic_var));\n+ static_assert (!has_thread_storage_duration (^^nonstatic_var));\n+ static_assert (has_automatic_storage_duration (^^nonstatic_var));\n+\n+ int& ref_to_nonstatic_var = nonstatic_var;\n+ static_assert (!has_static_storage_duration (^^ref_to_nonstatic_var));\n+ static_assert (!has_thread_storage_duration (^^ref_to_nonstatic_var));\n+ static_assert (has_automatic_storage_duration (^^ref_to_nonstatic_var));\n+\n+ static int& static_ref_to_var = nonstatic_var;\n+ static_assert (has_static_storage_duration (^^static_ref_to_var));\n+ static_assert (!has_thread_storage_duration (^^static_ref_to_var));\n+ static_assert (!has_automatic_storage_duration (^^static_ref_to_var));\n+\n+ static int static_var;\n+ static_assert (has_static_storage_duration (^^static_var));\n+ static_assert (!has_thread_storage_duration (^^static_var));\n+ static_assert (!has_automatic_storage_duration (^^static_var));\n+\n+ int& ref_to_static_var = static_var;\n+ static_assert (!has_static_storage_duration (^^ref_to_static_var));\n+ static_assert (!has_thread_storage_duration (^^ref_to_static_var));\n+ static_assert (has_automatic_storage_duration (^^ref_to_static_var));\n+\n+ thread_local int tl_var;\n+ static_assert (!has_static_storage_duration (^^tl_var));\n+ static_assert (has_thread_storage_duration (^^tl_var));\n+ static_assert (!has_automatic_storage_duration (^^tl_var));\n+\n+ std::pair<int, int> p;\n+ auto [aa, ab] = p;\n+ static_assert (!has_static_storage_duration (^^aa));\n+ static_assert (!has_thread_storage_duration (^^aa));\n+ static_assert (!has_automatic_storage_duration (^^aa));\n+\n+ static auto [sa, sb] = p;\n+ static_assert (!has_static_storage_duration (^^sa));\n+ static_assert (!has_thread_storage_duration (^^sa));\n+ static_assert (!has_automatic_storage_duration (^^sa));\n+\n+ thread_local auto [ta, tb] = p;\n+ static_assert (!has_static_storage_duration (^^ta));\n+ static_assert (!has_thread_storage_duration (^^ta));\n+ static_assert (!has_automatic_storage_duration (^^ta));\n+}\n+\n+template<auto V> struct TCls {};\n+static_assert (!has_static_storage_duration (template_arguments_of (^^TCls<5>)[0]));\n+static_assert (!has_thread_storage_duration (template_arguments_of (^^TCls<5>)[0]));\n+static_assert (!has_automatic_storage_duration (template_arguments_of (^^TCls<5>)[0]));\n+\n+static_assert (has_static_storage_duration (template_arguments_of (^^TCls<S{}>)[0]));\n+static_assert (!has_thread_storage_duration (template_arguments_of (^^TCls<S{}>)[0]));\n+static_assert (!has_automatic_storage_duration (template_arguments_of (^^TCls<S{}>)[0]));\n+\n+template<auto K> constexpr auto R = reflect_object (K);\n+static_assert (has_static_storage_duration (R<S{}>));\n+static_assert (!has_thread_storage_duration (R<S{}>));\n+static_assert (!has_automatic_storage_duration (R<S{}>));\n+\n+static std::pair<int, int> p;\n+constexpr auto first = reflect_object (p.first);\n+static_assert (has_static_storage_duration (first));\n+static_assert (!has_thread_storage_duration (first));\n+static_assert (!has_automatic_storage_duration (first));\n+\n+static_assert (!has_static_storage_duration (reflect_constant(4)));\n+static_assert (!has_thread_storage_duration (reflect_constant(4)));\n+static_assert (!has_automatic_storage_duration (reflect_constant(4)));\ndiff --git a/gcc/testsuite/g++.dg/reflect/storage_duration2.C b/gcc/testsuite/g++.dg/reflect/storage_duration2.C\nnew file mode 100644\nindex 00000000000..62d045c7a44\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/storage_duration2.C\n@@ -0,0 +1,218 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::has_{static,thread,automatic}_storage_duration.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr info null_reflection;\n+struct cls {\n+ int dm;\n+ static int static_dm;\n+ void mem_fun ();\n+ static void static_mem_fun ();\n+ int &ref_dm = dm;\n+ using type = int;\n+} cls_var;\n+union onion { };\n+static union { int anon; };\n+using alias = cls;\n+void fun ();\n+int var;\n+int &ref = var;\n+int &&rref = 42;\n+int *ptr = &var;\n+namespace ns {}\n+namespace ns_alias = ns;\n+enum Enum { A };\n+enum class Enum_class { A };\n+\n+template<typename> struct incomplete_cls;\n+template<typename> struct cls_tmpl {};\n+template<typename> void fun_tmpl ();\n+template<typename> concept conc = requires { true; };\n+template<typename> int var_tmpl;\n+template<typename T> using cls_tmpl_alias = cls_tmpl<T>;\n+\n+int arr[] = { 42 };\n+auto [ decomp ] = arr;\n+auto &[ decomp_ref ] = arr;\n+\n+static_assert (!has_static_storage_duration (null_reflection));\n+static_assert (!has_thread_storage_duration (null_reflection));\n+static_assert (!has_automatic_storage_duration (null_reflection));\n+\n+static_assert (!has_static_storage_duration (^^::));\n+static_assert (!has_thread_storage_duration (^^::));\n+static_assert (!has_automatic_storage_duration (^^::));\n+\n+static_assert (!has_static_storage_duration (reflect_constant (3)));\n+static_assert (!has_thread_storage_duration (reflect_constant (3)));\n+static_assert (!has_automatic_storage_duration (reflect_constant (3)));\n+\n+static_assert (!has_static_storage_duration (^^cls));\n+static_assert (!has_thread_storage_duration (^^cls));\n+static_assert (!has_automatic_storage_duration (^^cls));\n+\n+static_assert (!has_static_storage_duration (^^cls::dm));\n+static_assert (!has_thread_storage_duration (^^cls::dm));\n+static_assert (!has_automatic_storage_duration (^^cls::dm));\n+\n+static_assert (!has_static_storage_duration (^^cls::ref_dm));\n+static_assert (!has_thread_storage_duration (^^cls::ref_dm));\n+static_assert (!has_automatic_storage_duration (^^cls::ref_dm));\n+\n+static_assert (has_static_storage_duration (^^cls::static_dm));\n+static_assert (!has_thread_storage_duration (^^cls::static_dm));\n+static_assert (!has_automatic_storage_duration (^^cls::static_dm));\n+\n+\n+static_assert (!has_static_storage_duration (^^cls::mem_fun));\n+static_assert (!has_thread_storage_duration (^^cls::mem_fun));\n+static_assert (!has_automatic_storage_duration (^^cls::mem_fun));\n+\n+static_assert (!has_static_storage_duration (^^cls::static_mem_fun));\n+static_assert (!has_thread_storage_duration (^^cls::static_mem_fun));\n+static_assert (!has_automatic_storage_duration (^^cls::static_mem_fun));\n+\n+static_assert (!has_static_storage_duration (^^cls::type));\n+static_assert (!has_thread_storage_duration (^^cls::type));\n+static_assert (!has_automatic_storage_duration (^^cls::type));\n+\n+static_assert (has_static_storage_duration (^^cls_var));\n+static_assert (!has_thread_storage_duration (^^cls_var));\n+static_assert (!has_automatic_storage_duration (^^cls_var));\n+\n+static_assert (!has_static_storage_duration (^^onion));\n+static_assert (!has_thread_storage_duration (^^onion));\n+static_assert (!has_automatic_storage_duration (^^onion));\n+\n+static_assert (!has_static_storage_duration (^^anon));\n+static_assert (!has_thread_storage_duration (^^anon));\n+static_assert (!has_automatic_storage_duration (^^anon));\n+\n+static_assert (!has_static_storage_duration (^^fun));\n+static_assert (!has_thread_storage_duration (^^fun));\n+static_assert (!has_automatic_storage_duration (^^fun));\n+\n+static_assert (!has_static_storage_duration (^^alias));\n+static_assert (!has_thread_storage_duration (^^alias));\n+static_assert (!has_automatic_storage_duration (^^alias));\n+\n+static_assert (has_static_storage_duration (^^var));\n+static_assert (!has_thread_storage_duration (^^var));\n+static_assert (!has_automatic_storage_duration (^^var));\n+\n+static_assert (has_static_storage_duration (^^ref));\n+static_assert (!has_thread_storage_duration (^^ref));\n+static_assert (!has_automatic_storage_duration (^^ref));\n+\n+static_assert (has_static_storage_duration (^^rref));\n+static_assert (!has_thread_storage_duration (^^rref));\n+static_assert (!has_automatic_storage_duration (^^rref));\n+\n+static_assert (has_static_storage_duration (^^ptr));\n+static_assert (!has_thread_storage_duration (^^ptr));\n+static_assert (!has_automatic_storage_duration (^^ptr));\n+\n+static_assert (!has_static_storage_duration (^^cls_tmpl));\n+static_assert (!has_thread_storage_duration (^^cls_tmpl));\n+static_assert (!has_automatic_storage_duration (^^cls_tmpl));\n+\n+static_assert (!has_static_storage_duration (^^cls_tmpl<int>));\n+static_assert (!has_thread_storage_duration (^^cls_tmpl<int>));\n+static_assert (!has_automatic_storage_duration (^^cls_tmpl<int>));\n+\n+static_assert (!has_static_storage_duration (^^incomplete_cls<int>));\n+static_assert (!has_thread_storage_duration (^^incomplete_cls<int>));\n+static_assert (!has_automatic_storage_duration (^^incomplete_cls<int>));\n+\n+static_assert (!has_static_storage_duration (^^fun_tmpl));\n+static_assert (!has_thread_storage_duration (^^fun_tmpl));\n+static_assert (!has_automatic_storage_duration (^^fun_tmpl));\n+\n+static_assert (!has_static_storage_duration (^^fun_tmpl<int>));\n+static_assert (!has_thread_storage_duration (^^fun_tmpl<int>));\n+static_assert (!has_automatic_storage_duration (^^fun_tmpl<int>));\n+\n+static_assert (!has_static_storage_duration (^^conc));\n+static_assert (!has_thread_storage_duration (^^conc));\n+static_assert (!has_automatic_storage_duration (^^conc));\n+\n+//static_assert (!has_static_storage_duration (substitute (^^conc, {^^int})));\n+//static_assert (!has_thread_storage_duration (substitute (^^conc, {^^int})));\n+//static_assert (!has_automatic_storage_duration (substitute (^^conc, {^^int})));\n+\n+static_assert (!has_static_storage_duration (^^var_tmpl));\n+static_assert (!has_thread_storage_duration (^^var_tmpl));\n+static_assert (!has_automatic_storage_duration (^^var_tmpl));\n+\n+static_assert (has_static_storage_duration (^^var_tmpl<int>));\n+static_assert (!has_thread_storage_duration (^^var_tmpl<int>));\n+static_assert (!has_automatic_storage_duration (^^var_tmpl<int>));\n+\n+static_assert (!has_static_storage_duration (^^cls_tmpl_alias));\n+static_assert (!has_thread_storage_duration (^^cls_tmpl_alias));\n+static_assert (!has_automatic_storage_duration (^^cls_tmpl_alias));\n+\n+static_assert (!has_static_storage_duration (^^cls_tmpl_alias<int>));\n+static_assert (!has_thread_storage_duration (^^cls_tmpl_alias<int>));\n+static_assert (!has_automatic_storage_duration (^^cls_tmpl_alias<int>));\n+\n+static_assert (!has_static_storage_duration (^^Enum));\n+static_assert (!has_thread_storage_duration (^^Enum));\n+static_assert (!has_automatic_storage_duration (^^Enum));\n+\n+static_assert (!has_static_storage_duration (^^Enum::A));\n+static_assert (!has_thread_storage_duration (^^Enum::A));\n+static_assert (!has_automatic_storage_duration (^^Enum::A));\n+\n+static_assert (!has_static_storage_duration (^^Enum_class));\n+static_assert (!has_thread_storage_duration (^^Enum_class));\n+static_assert (!has_automatic_storage_duration (^^Enum_class));\n+\n+static_assert (!has_static_storage_duration (^^Enum_class::A));\n+static_assert (!has_thread_storage_duration (^^Enum_class::A));\n+static_assert (!has_automatic_storage_duration (^^Enum_class::A));\n+\n+static_assert (!has_static_storage_duration (^^decomp));\n+static_assert (!has_thread_storage_duration (^^decomp));\n+static_assert (!has_automatic_storage_duration (^^decomp));\n+\n+static_assert (!has_static_storage_duration (^^decomp_ref));\n+static_assert (!has_thread_storage_duration (^^decomp_ref));\n+static_assert (!has_automatic_storage_duration (^^decomp_ref));\n+\n+static_assert (has_static_storage_duration (^^arr));\n+static_assert (!has_thread_storage_duration (^^arr));\n+static_assert (!has_automatic_storage_duration (^^arr));\n+\n+constexpr auto dms = data_member_spec (^^int, { .name = \"dms\" });\n+static_assert (!has_static_storage_duration (dms));\n+static_assert (!has_thread_storage_duration (dms));\n+static_assert (!has_automatic_storage_duration (dms));\n+\n+template<typename T, info R, info R2, info R3>\n+void\n+f ()\n+{\n+ static_assert (!has_static_storage_duration (^^T));\n+ static_assert (!has_thread_storage_duration (^^T));\n+ static_assert (!has_automatic_storage_duration (^^T));\n+ static_assert (has_static_storage_duration (R));\n+ static_assert (!has_thread_storage_duration (R));\n+ static_assert (!has_automatic_storage_duration (R));\n+ static_assert (!has_static_storage_duration (R2));\n+ static_assert (!has_thread_storage_duration (R2));\n+ static_assert (!has_automatic_storage_duration (R2));\n+ static_assert (!has_static_storage_duration (R3));\n+ static_assert (!has_thread_storage_duration (R3));\n+ static_assert (!has_automatic_storage_duration (R3));\n+}\n+\n+void\n+g ()\n+{\n+ f<int, ^^var, ^^ns, ^^cls>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/storage_duration3.C b/gcc/testsuite/g++.dg/reflect/storage_duration3.C\nnew file mode 100644\nindex 00000000000..0fb71c850d5\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/storage_duration3.C\n@@ -0,0 +1,19 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::has_{static,thread,automatic}_storage_duration.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A { const int ci = 0; int nci; };\n+struct B : A { mutable int i; };\n+\n+B arr[2];\n+const A &r = arr[1];\n+static_assert (has_static_storage_duration (^^arr));\n+static_assert (!has_thread_storage_duration (^^arr));\n+static_assert (!has_automatic_storage_duration (^^arr));\n+static_assert (has_static_storage_duration (^^r));\n+static_assert (!has_thread_storage_duration (^^r));\n+static_assert (!has_automatic_storage_duration (^^r));\ndiff --git a/gcc/testsuite/g++.dg/reflect/subobjects_of1.C b/gcc/testsuite/g++.dg/reflect/subobjects_of1.C\nnew file mode 100644\nindex 00000000000..bf8f4efd6b1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/subobjects_of1.C\n@@ -0,0 +1,214 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::subobjects_of and has_inaccessible_subobjects.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A { int a; };\n+struct B { int b; };\n+struct C { int c; };\n+struct D { int d; };\n+struct E { int e; };\n+struct F { int f; };\n+struct G { int g; };\n+struct H { int h; };\n+struct I : public A, protected B, private C { int i; };\n+struct J : protected D, private E, public F { int j; };\n+struct K : public G, protected I, private H, public J {\n+public:\n+ int Za;\n+ static int Zb;\n+ enum ZE { ZE0 };\n+ using Zc = int;\n+ typedef long Zd;\n+ template <typename T>\n+ struct ZA {};\n+ template <typename T>\n+ static consteval bool Zfoo (const T &) { return true; }\n+ template <int N>\n+ static constexpr int Ze = N;\n+ template <typename T>\n+ using Zf = const T &;\n+ void Zbar () {}\n+ auto Zbaz ();\n+ int Zg : 5;\n+ long : 4;\n+ int : 0;\n+ consteval {\n+ ZA <int> z = {};\n+ static_assert (Ze <42> == 42);\n+ Zf <int> w = 42;\n+ }\n+protected:\n+ int Xa;\n+ static int Xb;\n+ enum XE { XE0 };\n+ using Xc = int;\n+ typedef long Xd;\n+ template <typename T>\n+ struct XA {};\n+ template <typename T>\n+ static consteval bool Xfoo (const T &) { return true; }\n+ template <int N>\n+ static constexpr int Xe = N;\n+ template <typename T>\n+ using Xf = const T &;\n+ void Xbar () {}\n+ auto Xbaz ();\n+ int Xg : 5;\n+ long : 4;\n+ int : 0;\n+private:\n+ int Ya;\n+ static int Yb;\n+ enum YE { YE0 };\n+ using Yc = int;\n+ typedef long Yd;\n+ template <typename T>\n+ struct YA {};\n+ template <typename T>\n+ static consteval bool Yfoo (const T &) { return true; }\n+ template <int N>\n+ static constexpr int Ye = N;\n+ template <typename T>\n+ using Yf = const T &;\n+ void Ybar () {}\n+ auto Ybaz ();\n+ int Yg : 7;\n+ long : 6;\n+ int : 0;\n+};\n+struct L : virtual A { int l; };\n+struct M : virtual A { int m; };\n+struct N : public L, protected M, public virtual A { int n; };\n+struct O : public L, public M, public virtual A { int o; };\n+struct P : public L, public M, public virtual A { protected: int p; };\n+\n+constexpr access_context gctx = access_context::current ();\n+constexpr access_context uctx = access_context::unchecked ();\n+\n+static_assert (subobjects_of (^^A, uctx).size () == 1);\n+static_assert (subobjects_of (^^A, uctx)[0] == nonstatic_data_members_of (^^A, uctx)[0]);\n+static_assert (subobjects_of (^^B, uctx).size () == 1);\n+static_assert (subobjects_of (^^B, uctx)[0] == nonstatic_data_members_of (^^B, uctx)[0]);\n+static_assert (subobjects_of (^^C, uctx).size () == 1);\n+static_assert (subobjects_of (^^C, uctx)[0] == nonstatic_data_members_of (^^C, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^C, uctx));\n+static_assert (subobjects_of (^^D, uctx).size () == 1);\n+static_assert (subobjects_of (^^D, uctx)[0] == nonstatic_data_members_of (^^D, uctx)[0]);\n+static_assert (subobjects_of (^^E, uctx).size () == 1);\n+static_assert (subobjects_of (^^E, uctx)[0] == nonstatic_data_members_of (^^E, uctx)[0]);\n+static_assert (subobjects_of (^^F, uctx).size () == 1);\n+static_assert (subobjects_of (^^F, uctx)[0] == nonstatic_data_members_of (^^F, uctx)[0]);\n+static_assert (subobjects_of (^^G, uctx).size () == 1);\n+static_assert (subobjects_of (^^G, uctx)[0] == nonstatic_data_members_of (^^G, uctx)[0]);\n+static_assert (subobjects_of (^^H, uctx).size () == 1);\n+static_assert (subobjects_of (^^H, uctx)[0] == nonstatic_data_members_of (^^H, uctx)[0]);\n+static_assert (subobjects_of (^^I, uctx).size () == 4);\n+static_assert (subobjects_of (^^I, uctx)[0] == bases_of (^^I, uctx)[0]);\n+static_assert (subobjects_of (^^I, uctx)[1] == bases_of (^^I, uctx)[1]);\n+static_assert (subobjects_of (^^I, uctx)[2] == bases_of (^^I, uctx)[2]);\n+static_assert (subobjects_of (^^I, uctx)[3] == nonstatic_data_members_of (^^I, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^I, uctx));\n+static_assert (subobjects_of (^^J, uctx).size () == 4);\n+static_assert (subobjects_of (^^J, uctx)[0] == bases_of (^^J, uctx)[0]);\n+static_assert (subobjects_of (^^J, uctx)[1] == bases_of (^^J, uctx)[1]);\n+static_assert (subobjects_of (^^J, uctx)[2] == bases_of (^^J, uctx)[2]);\n+static_assert (subobjects_of (^^J, uctx)[3] == nonstatic_data_members_of (^^J, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^J, uctx));\n+static_assert (subobjects_of (^^K, uctx).size () == 10);\n+static_assert (subobjects_of (^^K, uctx)[0] == bases_of (^^K, uctx)[0]);\n+static_assert (subobjects_of (^^K, uctx)[1] == bases_of (^^K, uctx)[1]);\n+static_assert (subobjects_of (^^K, uctx)[2] == bases_of (^^K, uctx)[2]);\n+static_assert (subobjects_of (^^K, uctx)[3] == bases_of (^^K, uctx)[3]);\n+static_assert (subobjects_of (^^K, uctx)[4] == nonstatic_data_members_of (^^K, uctx)[0]);\n+static_assert (subobjects_of (^^K, uctx)[5] == nonstatic_data_members_of (^^K, uctx)[1]);\n+static_assert (subobjects_of (^^K, uctx)[6] == nonstatic_data_members_of (^^K, uctx)[2]);\n+static_assert (subobjects_of (^^K, uctx)[7] == nonstatic_data_members_of (^^K, uctx)[3]);\n+static_assert (subobjects_of (^^K, uctx)[8] == nonstatic_data_members_of (^^K, uctx)[4]);\n+static_assert (subobjects_of (^^K, uctx)[9] == nonstatic_data_members_of (^^K, uctx)[5]);\n+static_assert (!has_inaccessible_subobjects (^^K, uctx));\n+static_assert (subobjects_of (^^L, uctx).size () == 2);\n+static_assert (subobjects_of (^^L, uctx)[0] == bases_of (^^L, uctx)[0]);\n+static_assert (subobjects_of (^^L, uctx)[1] == nonstatic_data_members_of (^^L, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^L, uctx));\n+static_assert (subobjects_of (^^M, uctx).size () == 2);\n+static_assert (subobjects_of (^^M, uctx)[0] == bases_of (^^M, uctx)[0]);\n+static_assert (subobjects_of (^^M, uctx)[1] == nonstatic_data_members_of (^^M, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^M, uctx));\n+static_assert (subobjects_of (^^N, uctx).size () == 4);\n+static_assert (subobjects_of (^^N, uctx)[0] == bases_of (^^N, uctx)[0]);\n+static_assert (subobjects_of (^^N, uctx)[1] == bases_of (^^N, uctx)[1]);\n+static_assert (subobjects_of (^^N, uctx)[2] == bases_of (^^N, uctx)[2]);\n+static_assert (subobjects_of (^^N, uctx)[3] == nonstatic_data_members_of (^^N, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^N, uctx));\n+static_assert (subobjects_of (^^O, uctx).size () == 4);\n+static_assert (subobjects_of (^^O, uctx)[0] == bases_of (^^O, uctx)[0]);\n+static_assert (subobjects_of (^^O, uctx)[1] == bases_of (^^O, uctx)[1]);\n+static_assert (subobjects_of (^^O, uctx)[2] == bases_of (^^O, uctx)[2]);\n+static_assert (subobjects_of (^^O, uctx)[3] == nonstatic_data_members_of (^^O, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^O, uctx));\n+static_assert (subobjects_of (^^P, uctx).size () == 4);\n+static_assert (subobjects_of (^^P, uctx)[0] == bases_of (^^P, uctx)[0]);\n+static_assert (subobjects_of (^^P, uctx)[1] == bases_of (^^P, uctx)[1]);\n+static_assert (subobjects_of (^^P, uctx)[2] == bases_of (^^P, uctx)[2]);\n+static_assert (subobjects_of (^^P, uctx)[3] == nonstatic_data_members_of (^^P, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^P, uctx));\n+\n+static_assert (subobjects_of (^^A, gctx).size () == 1);\n+static_assert (subobjects_of (^^A, gctx)[0] == nonstatic_data_members_of (^^A, uctx)[0]);\n+static_assert (subobjects_of (^^B, gctx).size () == 1);\n+static_assert (subobjects_of (^^B, gctx)[0] == nonstatic_data_members_of (^^B, uctx)[0]);\n+static_assert (subobjects_of (^^C, gctx).size () == 1);\n+static_assert (subobjects_of (^^C, gctx)[0] == nonstatic_data_members_of (^^C, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^C, gctx));\n+static_assert (subobjects_of (^^D, gctx).size () == 1);\n+static_assert (subobjects_of (^^D, gctx)[0] == nonstatic_data_members_of (^^D, uctx)[0]);\n+static_assert (subobjects_of (^^E, gctx).size () == 1);\n+static_assert (subobjects_of (^^E, gctx)[0] == nonstatic_data_members_of (^^E, uctx)[0]);\n+static_assert (subobjects_of (^^F, gctx).size () == 1);\n+static_assert (subobjects_of (^^F, gctx)[0] == nonstatic_data_members_of (^^F, uctx)[0]);\n+static_assert (subobjects_of (^^G, gctx).size () == 1);\n+static_assert (subobjects_of (^^G, gctx)[0] == nonstatic_data_members_of (^^G, uctx)[0]);\n+static_assert (subobjects_of (^^H, gctx).size () == 1);\n+static_assert (subobjects_of (^^H, gctx)[0] == nonstatic_data_members_of (^^H, uctx)[0]);\n+static_assert (subobjects_of (^^I, gctx).size () == 2);\n+static_assert (subobjects_of (^^I, gctx)[0] == bases_of (^^I, uctx)[0]);\n+static_assert (subobjects_of (^^I, gctx)[1] == nonstatic_data_members_of (^^I, uctx)[0]);\n+static_assert (has_inaccessible_subobjects (^^I, gctx));\n+static_assert (subobjects_of (^^J, gctx).size () == 2);\n+static_assert (subobjects_of (^^J, gctx)[0] == bases_of (^^J, uctx)[2]);\n+static_assert (subobjects_of (^^J, gctx)[1] == nonstatic_data_members_of (^^J, uctx)[0]);\n+static_assert (has_inaccessible_subobjects (^^J, gctx));\n+static_assert (subobjects_of (^^K, gctx).size () == 4);\n+static_assert (subobjects_of (^^K, gctx)[0] == bases_of (^^K, uctx)[0]);\n+static_assert (subobjects_of (^^K, gctx)[1] == bases_of (^^K, uctx)[3]);\n+static_assert (subobjects_of (^^K, gctx)[2] == ^^K::Za);\n+static_assert (subobjects_of (^^K, gctx)[3] == ^^K::Zg);\n+static_assert (has_inaccessible_subobjects (^^K, gctx));\n+static_assert (subobjects_of (^^L, gctx).size () == 2);\n+static_assert (subobjects_of (^^L, gctx)[0] == bases_of (^^L, uctx)[0]);\n+static_assert (subobjects_of (^^L, gctx)[1] == nonstatic_data_members_of (^^L, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^L, uctx));\n+static_assert (subobjects_of (^^M, gctx).size () == 2);\n+static_assert (subobjects_of (^^M, gctx)[0] == bases_of (^^M, uctx)[0]);\n+static_assert (subobjects_of (^^M, gctx)[1] == nonstatic_data_members_of (^^M, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^M, gctx));\n+static_assert (subobjects_of (^^N, gctx).size () == 3);\n+static_assert (subobjects_of (^^N, gctx)[0] == bases_of (^^N, uctx)[0]);\n+static_assert (subobjects_of (^^N, gctx)[1] == bases_of (^^N, uctx)[2]);\n+static_assert (subobjects_of (^^N, gctx)[2] == nonstatic_data_members_of (^^N, uctx)[0]);\n+static_assert (has_inaccessible_subobjects (^^N, gctx));\n+static_assert (subobjects_of (^^O, gctx).size () == 4);\n+static_assert (subobjects_of (^^O, gctx)[0] == bases_of (^^O, uctx)[0]);\n+static_assert (subobjects_of (^^O, gctx)[1] == bases_of (^^O, uctx)[1]);\n+static_assert (subobjects_of (^^O, gctx)[2] == bases_of (^^O, uctx)[2]);\n+static_assert (subobjects_of (^^O, gctx)[3] == nonstatic_data_members_of (^^O, uctx)[0]);\n+static_assert (!has_inaccessible_subobjects (^^O, gctx));\n+static_assert (subobjects_of (^^P, gctx).size () == 3);\n+static_assert (subobjects_of (^^P, gctx)[0] == bases_of (^^P, uctx)[0]);\n+static_assert (subobjects_of (^^P, gctx)[1] == bases_of (^^P, uctx)[1]);\n+static_assert (subobjects_of (^^P, gctx)[2] == bases_of (^^P, uctx)[2]);\n+static_assert (has_inaccessible_subobjects (^^P, gctx));\ndiff --git a/gcc/testsuite/g++.dg/reflect/substitute1.C b/gcc/testsuite/g++.dg/reflect/substitute1.C\nnew file mode 100644\nindex 00000000000..76958ee5ad0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/substitute1.C\n@@ -0,0 +1,238 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::substitute.\n+\n+#include <meta>\n+#include <ranges>\n+#include <vector>\n+\n+using namespace std::meta;\n+\n+constexpr info null_reflection;\n+struct cls {\n+ int dm;\n+ static int static_dm;\n+ void mem_fun ();\n+ static void static_mem_fun ();\n+ int &ref_dm = dm;\n+ using type = int;\n+} cls_var;\n+union onion { };\n+static union { int anon; };\n+using alias = cls;\n+void fun ();\n+int var;\n+int &ref = var;\n+int &&rref = 42;\n+int *ptr = &var;\n+namespace ns {}\n+namespace ns_alias = ns;\n+enum Enum { A };\n+enum class Enum_class { A };\n+\n+template<typename> struct incomplete_cls;\n+template<typename> struct cls_tmpl {};\n+template<typename> void fun_tmpl ();\n+template<typename> concept conc = requires { true; };\n+template<typename> int var_tmpl;\n+template<typename T> using cls_tmpl_alias = cls_tmpl<T>;\n+\n+int arr[] = { 42 };\n+auto [ decomp ] = arr;\n+auto &[ decomp_ref ] = arr;\n+\n+template <reflection_range R = std::initializer_list <info>>\n+consteval bool\n+could_substitute (info r, R &&args)\n+{\n+ try { substitute (r, args); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (!could_substitute (null_reflection, {}));\n+static_assert (!could_substitute (^^::, {}));\n+static_assert (!could_substitute (^^ns, {}));\n+static_assert (!could_substitute (^^ns_alias, {}));\n+static_assert (!could_substitute (reflect_constant (3), {}));\n+static_assert (!could_substitute (^^cls, {}));\n+static_assert (!could_substitute (^^cls::dm, {}));\n+static_assert (!could_substitute (^^cls::ref_dm, {}));\n+static_assert (!could_substitute (^^cls::static_dm, {}));\n+static_assert (!could_substitute (^^cls::mem_fun, {}));\n+static_assert (!could_substitute (^^cls::static_mem_fun, {}));\n+static_assert (!could_substitute (^^cls::type, {}));\n+static_assert (!could_substitute (^^cls_var, {}));\n+static_assert (!could_substitute (^^onion, {}));\n+static_assert (!could_substitute (^^anon, {}));\n+static_assert (!could_substitute (^^fun, {}));\n+static_assert (!could_substitute (^^alias, {}));\n+static_assert (!could_substitute (^^var, {}));\n+static_assert (!could_substitute (^^ref, {}));\n+static_assert (!could_substitute (^^rref, {}));\n+static_assert (!could_substitute (^^ptr, {}));\n+static_assert (!could_substitute (^^cls_tmpl, {}));\n+static_assert (!could_substitute (^^cls_tmpl<int>, {}));\n+static_assert (!could_substitute (^^incomplete_cls<int>, {}));\n+static_assert (!could_substitute (^^fun_tmpl, {}));\n+static_assert (!could_substitute (^^fun_tmpl<int>, {}));\n+static_assert (!could_substitute (^^conc, {}));\n+static_assert (!could_substitute (substitute (^^conc, { ^^int }), {}));\n+static_assert (!could_substitute (^^var_tmpl, {}));\n+static_assert (!could_substitute (^^var_tmpl<int>, {}));\n+static_assert (!could_substitute (^^cls_tmpl_alias, {}));\n+static_assert (!could_substitute (^^cls_tmpl_alias<int>, {}));\n+static_assert (!could_substitute (^^Enum, {}));\n+static_assert (!could_substitute (^^Enum::A, {}));\n+static_assert (!could_substitute (^^Enum_class, {}));\n+static_assert (!could_substitute (^^Enum_class::A, {}));\n+static_assert (!could_substitute (^^decomp, {}));\n+static_assert (!could_substitute (^^decomp_ref, {}));\n+static_assert (!could_substitute (^^arr, {}));\n+\n+constexpr auto dms = data_member_spec (^^int, { .name = \"dms\" });\n+static_assert (!could_substitute (dms, {}));\n+\n+struct Base {};\n+struct Derived : Base {};\n+static_assert (!could_substitute (bases_of (^^Derived, access_context::current ())[0], {}));\n+\n+template<typename T, info R, info R2, info R3>\n+void\n+f ()\n+{\n+ static_assert (!could_substitute (^^T, {}));\n+ static_assert (!could_substitute (R, {}));\n+ static_assert (!could_substitute (R2, {}));\n+ static_assert (!could_substitute (R3, {}));\n+}\n+\n+void\n+g (int p, cls c)\n+{\n+ f<int, ^^var, ^^ns, ^^cls_tmpl_alias>();\n+ static_assert (!could_substitute (^^p, {}));\n+ static_assert (!could_substitute (^^c, {}));\n+}\n+\n+template <typename T>\n+struct S {};\n+\n+template <float F, int N>\n+struct T {};\n+\n+template <typename ...T>\n+struct U {};\n+\n+template <typename T>\n+T foo (T x) { return x; }\n+\n+template <int N>\n+constexpr int v = N;\n+\n+template <typename T>\n+concept C = requires { T::s; };\n+\n+struct V { int s; };\n+\n+struct NS {\n+ constexpr NS (int x) : ns (x) {}\n+ constexpr NS (const NS &x) : ns (x.ns) {}\n+ constexpr ~NS () {}\n+private:\n+ int ns;\n+};\n+[[=1]] void bar (int x);\n+\n+static_assert (!could_substitute (^^S, {}));\n+static_assert (!could_substitute (^^S, { null_reflection }));\n+static_assert (!could_substitute (^^S, { parameters_of (^^bar)[0] }));\n+static_assert (!could_substitute (^^S, { annotations_of (^^bar)[0] }));\n+static_assert (!could_substitute (^^S, { ^^:: }));\n+static_assert (!could_substitute (^^S, { ^^ns }));\n+static_assert (!could_substitute (^^S, { ^^ns_alias }));\n+static_assert (!could_substitute (^^S, { ^^NS::~NS }));\n+static_assert (!could_substitute (^^S, { reflect_constant (42) }));\n+constexpr int n = 42;\n+static_assert (!could_substitute (^^S, { ^^n }));\n+constexpr NS nsv (42);\n+static_assert (!could_substitute (^^S, { ^^nsv }));\n+\n+static_assert (!could_substitute (^^S, {}));\n+static_assert (substitute (^^S, { ^^int }) == ^^S <int>);\n+static_assert (substitute (^^S, { ^^V }) == ^^S <V>);\n+static_assert (substitute (^^S, { ^^NS }) == ^^S <NS>);\n+static_assert (!is_value (substitute (^^S, { ^^int })));\n+static_assert (!is_object (substitute (^^S, { ^^int })));\n+static_assert (!could_substitute (^^S, { ^^int, ^^long }));\n+static_assert (!could_substitute (^^S, { reflect_constant (42) }));\n+static_assert (!could_substitute (^^S, { ^^n }));\n+static_assert (!could_substitute (^^T, {}));\n+static_assert (!could_substitute (^^T, { ^^float, ^^int }));\n+constexpr float fv = 42.0f;\n+static_assert (substitute (^^T, { ^^fv, reflect_constant (42) }) == ^^T <42.0f, 42>);\n+static_assert (!is_value (substitute (^^T, { ^^fv, reflect_constant (42) })));\n+static_assert (!is_object (substitute (^^T, { ^^fv, reflect_constant (42) })));\n+static_assert (substitute (^^T, { ^^fv, reflect_constant (0) }) == ^^T <42.0f, 0>);\n+static_assert (!is_value (substitute (^^T, { ^^fv, reflect_constant (0) })));\n+static_assert (!is_object (substitute (^^T, { ^^fv, reflect_constant (0) })));\n+static_assert (substitute (^^T, { ^^fv, ^^n }) == ^^T <42.0f, 42>);\n+static_assert (!is_value (substitute (^^T, { ^^fv, ^^n })));\n+static_assert (!is_object (substitute (^^T, { ^^fv, ^^n })));\n+static_assert (!could_substitute (^^T, { ^^n, ^^fv }));\n+static_assert (!could_substitute (^^T, { ^^fv, ^^n, ^^fv }));\n+\n+static_assert (substitute (^^U, {}) == ^^U <>);\n+static_assert (!is_value (substitute (^^U, {})));\n+static_assert (!is_object (substitute (^^U, {})));\n+static_assert (substitute (^^U, { ^^int }) == ^^U <int>);\n+static_assert (substitute (^^U, { ^^int, ^^long, ^^const int &, ^^float, ^^double }) == ^^U <int, long, const int &, float, double>);\n+static_assert (substitute (^^U, std::vector <info> { ^^int, ^^long, ^^const int &, ^^float, ^^double } | std::views::reverse) == ^^U <double, float, const int &, long, int>);\n+static_assert (!could_substitute (^^U, { ^^int, ^^long, ^^const int &, ^^n, ^^float }));\n+\n+static_assert (!could_substitute (^^v, {}));\n+static_assert (substitute (^^v, { reflect_constant (15) }) == ^^v <15>);\n+static_assert (!is_value (substitute (^^v, { reflect_constant (15) })));\n+static_assert (!is_object (substitute (^^v, { reflect_constant (15) })));\n+static_assert (substitute (^^v, { ^^n }) == ^^v <42>);\n+static_assert (!is_value (substitute (^^v, { ^^n })));\n+static_assert (!is_object (substitute (^^v, { ^^n })));\n+static_assert (!could_substitute (^^v, { ^^n, ^^n }));\n+static_assert (!could_substitute (^^v, { ^^int }));\n+\n+static_assert (!could_substitute (^^C, {}));\n+static_assert (substitute (^^C, { ^^int }) == reflect_constant (false));\n+static_assert (is_value (substitute (^^C, { ^^int })));\n+static_assert (!is_object (substitute (^^C, { ^^int })));\n+static_assert (substitute (^^C, { ^^V }) == reflect_constant (true));\n+static_assert (is_value (substitute (^^C, { ^^V })));\n+static_assert (!is_object (substitute (^^C, { ^^V })));\n+static_assert (!could_substitute (^^C, { ^^int, ^^int }));\n+static_assert (!could_substitute (^^C, { reflect_constant (42) }));\n+static_assert (!could_substitute (^^C, { ^^n }));\n+\n+static_assert (!could_substitute (^^foo, {}));\n+static_assert (substitute (^^foo, { ^^int }) == ^^foo <int>);\n+static_assert (!is_value (substitute (^^foo, { ^^int })));\n+static_assert (!is_object (substitute (^^foo, { ^^int })));\n+static_assert (substitute (^^foo, { ^^int }) == ^^foo <int>);\n+static_assert (substitute (^^foo, { ^^V }) == ^^foo <V>);\n+static_assert (substitute (^^foo, { ^^NS }) == ^^foo <NS>);\n+static_assert (!could_substitute (^^foo, { ^^int, ^^long }));\n+static_assert (!could_substitute (^^foo, { reflect_constant (42) }));\n+static_assert (!could_substitute (^^foo, { ^^n }));\n+\n+template <class T, class U>\n+struct TU1 {};\n+template <class T, class U>\n+struct TU2 {};\n+\n+template <template <class, class> class T, class U, class V>\n+T <U, V> baz () { return T <U, V> {}; }\n+\n+static_assert (return_type_of (^^baz <TU1, int, long>) == ^^TU1 <int, long>);\n+static_assert (return_type_of (^^baz <TU2, double, int>) == ^^TU2 <double, int>);\n+static_assert (substitute (^^baz, { ^^TU1, ^^int, ^^long }) == ^^baz <TU1, int, long>);\n+static_assert (!is_value (substitute (^^baz, { ^^TU1, ^^int, ^^long })));\n+static_assert (!is_object (substitute (^^baz, { ^^TU1, ^^int, ^^long })));\n+static_assert (substitute (^^baz, { ^^TU2, ^^double, ^^int }) == ^^baz <TU2, double, int>);\ndiff --git a/gcc/testsuite/g++.dg/reflect/substitute2.C b/gcc/testsuite/g++.dg/reflect/substitute2.C\nnew file mode 100644\nindex 00000000000..064f08ed327\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/substitute2.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template <info R>\n+struct A {\n+ static constexpr auto value = R;\n+};\n+\n+template <class... R>\n+struct B { };\n+\n+template <size_t I, typename J>\n+using C = [: template_arguments_of (^^J)[I] :];\n+\n+template <class T>\n+using D = [: [] {\n+ std::vector<info> args;\n+ for (info b : bases_of (T::value, access_context::unchecked ()))\n+ args.push_back (substitute (^^A, { reflect_constant (b) }));\n+ return substitute (^^B, args); } () :];\n+\n+struct E { };\n+struct F : E { };\n+\n+constexpr auto b = bases_of (^^F, access_context::unchecked ())[0];\n+static_assert (std::same_as <C <0, D <A <^^F>>>, A <b>>);\ndiff --git a/gcc/testsuite/g++.dg/reflect/symbol_of1.C b/gcc/testsuite/g++.dg/reflect/symbol_of1.C\nnew file mode 100644\nindex 00000000000..7a3357c4253\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/symbol_of1.C\n@@ -0,0 +1,61 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::symbol_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval bool\n+has_symbol_of (operators op)\n+{\n+ try { symbol_of (op); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (!has_symbol_of (static_cast <operators> (4242)));\n+static_assert (symbol_of (op_new) == std::string_view (\"new\"));\n+static_assert (symbol_of (op_delete) == std::string_view (\"delete\"));\n+static_assert (symbol_of (op_array_new) == std::string_view (\"new[]\"));\n+static_assert (symbol_of (op_array_delete) == std::string_view (\"delete[]\"));\n+static_assert (symbol_of (op_co_await) == std::string_view (\"co_await\"));\n+static_assert (symbol_of (op_parentheses) == std::string_view (\"()\"));\n+static_assert (symbol_of (op_square_brackets) == std::string_view (\"[]\"));\n+static_assert (symbol_of (op_arrow) == std::string_view (\"->\"));\n+static_assert (symbol_of (op_arrow_star) == std::string_view (\"->*\"));\n+static_assert (symbol_of (op_tilde) == std::string_view (\"~\"));\n+static_assert (symbol_of (op_exclamation) == std::string_view (\"!\"));\n+static_assert (symbol_of (op_plus) == std::string_view (\"+\"));\n+static_assert (symbol_of (op_minus) == std::string_view (\"-\"));\n+static_assert (symbol_of (op_star) == std::string_view (\"*\"));\n+static_assert (symbol_of (op_slash) == std::string_view (\"/\"));\n+static_assert (symbol_of (op_percent) == std::string_view (\"%\"));\n+static_assert (symbol_of (op_caret) == std::string_view (\"^\"));\n+static_assert (symbol_of (op_ampersand) == std::string_view (\"&\"));\n+static_assert (symbol_of (op_equals) == std::string_view (\"=\"));\n+static_assert (symbol_of (op_pipe) == std::string_view (\"|\"));\n+static_assert (symbol_of (op_plus_equals) == std::string_view (\"+=\"));\n+static_assert (symbol_of (op_minus_equals) == std::string_view (\"-=\"));\n+static_assert (symbol_of (op_star_equals) == std::string_view (\"*=\"));\n+static_assert (symbol_of (op_slash_equals) == std::string_view (\"/=\"));\n+static_assert (symbol_of (op_percent_equals) == std::string_view (\"%=\"));\n+static_assert (symbol_of (op_caret_equals) == std::string_view (\"^=\"));\n+static_assert (symbol_of (op_ampersand_equals) == std::string_view (\"&=\"));\n+static_assert (symbol_of (op_pipe_equals) == std::string_view (\"|=\"));\n+static_assert (symbol_of (op_equals_equals) == std::string_view (\"==\"));\n+static_assert (symbol_of (op_exclamation_equals) == std::string_view (\"!=\"));\n+static_assert (symbol_of (op_less) == std::string_view (\"<\"));\n+static_assert (symbol_of (op_greater) == std::string_view (\">\"));\n+static_assert (symbol_of (op_less_equals) == std::string_view (\"<=\"));\n+static_assert (symbol_of (op_greater_equals) == std::string_view (\">=\"));\n+static_assert (symbol_of (op_spaceship) == std::string_view (\"<=>\"));\n+static_assert (symbol_of (op_ampersand_ampersand) == std::string_view (\"&&\"));\n+static_assert (symbol_of (op_pipe_pipe) == std::string_view (\"||\"));\n+static_assert (symbol_of (op_less_less) == std::string_view (\"<<\"));\n+static_assert (symbol_of (op_greater_greater) == std::string_view (\">>\"));\n+static_assert (symbol_of (op_less_less_equals) == std::string_view (\"<<=\"));\n+static_assert (symbol_of (op_greater_greater_equals) == std::string_view (\">>=\"));\n+static_assert (symbol_of (op_plus_plus) == std::string_view (\"++\"));\n+static_assert (symbol_of (op_minus_minus) == std::string_view (\"--\"));\n+static_assert (symbol_of (op_comma) == std::string_view (\",\"));\ndiff --git a/gcc/testsuite/g++.dg/reflect/symbol_of2.C b/gcc/testsuite/g++.dg/reflect/symbol_of2.C\nnew file mode 100644\nindex 00000000000..5e27aa6d373\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/symbol_of2.C\n@@ -0,0 +1,6 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-require-iconv \"IBM1047\" }\n+// { dg-additional-options \"-freflection -fexec-charset=IBM1047\" }\n+// Test std::meta::symbol_of.\n+\n+#include \"symbol_of1.C\"\ndiff --git a/gcc/testsuite/g++.dg/reflect/template_arguments_of1.C b/gcc/testsuite/g++.dg/reflect/template_arguments_of1.C\nnew file mode 100644\nindex 00000000000..02d0036066c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/template_arguments_of1.C\n@@ -0,0 +1,36 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::template_arguments_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template<class T, class U = T> struct Pair { };\n+template<class T> struct Pair<char, T> { };\n+template<class T> using PairPtr = Pair<T*>;\n+\n+static_assert(template_of(^^Pair<int>) == ^^Pair);\n+static_assert(template_of(^^Pair<char, char>) == ^^Pair);\n+static_assert(template_arguments_of(^^Pair<int>).size() == 2);\n+static_assert(template_arguments_of(^^Pair<int>)[0] == ^^int);\n+static_assert(template_arguments_of(^^Pair<int>)[1] == ^^int);\n+\n+static_assert(template_of(^^PairPtr<int>) == ^^PairPtr);\n+static_assert(template_arguments_of(^^PairPtr<int>).size() == 1);\n+static_assert(template_arguments_of(^^PairPtr<int>)[0] == ^^int);\n+\n+struct S { };\n+int i;\n+template<int, int&, S, template<class> class>\n+ struct X { };\n+constexpr auto T = ^^X<1, i, S{}, PairPtr>;\n+static_assert(is_value(template_arguments_of(T)[0]));\n+static_assert(!is_object(template_arguments_of(T)[0]));\n+static_assert(!is_value(template_arguments_of(T)[1]));\n+static_assert(is_object(template_arguments_of(T)[1]));\n+static_assert(is_object(template_arguments_of(T)[2]));\n+static_assert(!is_value(template_arguments_of(T)[2]));\n+static_assert(!is_value(template_arguments_of(T)[3]));\n+static_assert(!is_object(template_arguments_of(T)[3]));\n+static_assert(template_arguments_of(T)[3] == ^^PairPtr);\ndiff --git a/gcc/testsuite/g++.dg/reflect/template_arguments_of2.C b/gcc/testsuite/g++.dg/reflect/template_arguments_of2.C\nnew file mode 100644\nindex 00000000000..da5a44e2495\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/template_arguments_of2.C\n@@ -0,0 +1,107 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::template_arguments_of.\n+// Taken from test/std/experimental/reflection/template-arguments.pass.cpp\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+struct TCls {\n+ template <typename> struct TInnerCls {};\n+};\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+void TFn();\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+int TVar = 0;\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+using TAlias = int;\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+concept Concept = requires { true; };\n+\n+\n+static_assert(template_arguments_of(^^TCls<int, 9, std::vector>).size() == 3);\n+static_assert(template_arguments_of(^^TCls<int, 9, std::vector>)[0] == ^^int);\n+static_assert([:template_arguments_of(^^TCls<int, 9, std::vector>)[1]:] == 9);\n+static_assert(template_arguments_of(^^TCls<int, 9, std::vector>)[2] == ^^std::vector);\n+\n+static_assert(template_arguments_of(^^TFn<int, 9, std::vector>).size() == 3);\n+static_assert(template_arguments_of(^^TFn<int, 9, std::vector>)[0] == ^^int);\n+static_assert([:template_arguments_of(^^TFn<int, 9, std::vector>)[1]:] == 9);\n+static_assert(template_arguments_of(^^TFn<int, 9, std::vector>)[2] == ^^std::vector);\n+\n+static_assert(template_arguments_of(^^TVar<int, 9, std::vector>).size() == 3);\n+static_assert(template_arguments_of(^^TVar<int, 9, std::vector>)[0] == ^^int);\n+static_assert([:template_arguments_of(^^TVar<int, 9, std::vector>)[1]:] == 9);\n+static_assert(template_arguments_of(^^TVar<int, 9, std::vector>)[2] == ^^std::vector);\n+\n+static_assert(template_arguments_of(^^TAlias<int, 9, std::vector>).size() == 3);\n+static_assert(template_arguments_of(^^TAlias<int, 9, std::vector>)[0] == ^^int);\n+static_assert([:template_arguments_of(^^TAlias<int, 9, std::vector>)[1]:] == 9);\n+static_assert(template_arguments_of(^^TAlias<int, 9, std::vector>)[2] == ^^std::vector);\n+\n+template <typename T>\n+using DependentAlias = TCls<int, 9, std::vector>::template TInnerCls<T>;\n+static_assert(template_arguments_of(^^DependentAlias<int>).size() == 1);\n+static_assert(template_arguments_of(^^DependentAlias<int>)[0] == ^^int);\n+\n+template <typename T, T Val> struct WithDependentArgument {};\n+static_assert(template_arguments_of(^^WithDependentArgument<int, 5>).size() == 2);\n+static_assert(template_arguments_of(^^WithDependentArgument<int, 5>)[0] == ^^int);\n+\n+template <typename... Ts> struct WithTypeParamPack {};\n+static_assert(template_arguments_of(^^WithTypeParamPack<int, bool>).size() == 2);\n+static_assert(template_arguments_of(^^WithTypeParamPack<int, bool>)[0] == ^^int);\n+static_assert(template_arguments_of(^^WithTypeParamPack<int, bool>)[1] == ^^bool);\n+static_assert(template_arguments_of(^^WithTypeParamPack<>).size() == 0);\n+\n+struct S {\n+ int mem;\n+ bool operator==(const S&) const = default;\n+};\n+template <auto... Vs> struct WithAutoParamPack {};\n+\n+static_assert(template_arguments_of(^^WithAutoParamPack<4, S{3}>).size() == 2);\n+static_assert([:template_arguments_of(^^WithAutoParamPack<4, S{3}>)[0]:] == 4);\n+static_assert([:template_arguments_of(^^WithAutoParamPack<4, S{3}>)[1]:] == S{3});\n+static_assert(template_arguments_of(^^WithAutoParamPack<>).size() == 0);\n+\n+template <float> struct WithFloat {};\n+template <const float *> struct WithPtr {};\n+template <const int &> struct WithRef {};\n+template <info> struct WithReflection {};\n+\n+constexpr float F = 4.5f;\n+static_assert(template_arguments_of(^^WithFloat<F>).size() == 1);\n+static_assert([:template_arguments_of(^^WithFloat<F>)[0]:] == F);\n+\n+constexpr float Fs[] = {4.5, 5.5, 6.5};\n+static_assert(template_arguments_of(^^WithPtr<Fs>).size() == 1);\n+static_assert([:template_arguments_of(^^WithPtr<Fs>)[0]:] == +Fs);\n+\n+static_assert(template_arguments_of(^^WithPtr<nullptr>).size() == 1);\n+static_assert([:template_arguments_of(^^WithPtr<nullptr>)[0]:] == nullptr);\n+\n+const int I = 5;\n+using T = WithRef<I>;\n+static_assert(template_arguments_of(dealias(^^T)).size() == 1);\n+static_assert([:template_arguments_of(^^WithRef<I>)[0]:] == I);\n+\n+static_assert(template_arguments_of(^^WithReflection<^^int>).size() == 1);\n+static_assert(template_arguments_of(^^WithReflection<^^int>)[0] == reflect_constant(^^int));\n+\n+template <int &> void fn();\n+int p[2];\n+static_assert(template_arguments_of(^^fn<p[1]>)[0] == reflect_object(p[1]));\n+\n+template<class T> struct X {};\n+X<int> obj1;\n+X<decltype(obj1)> obj2;\n+\n+static_assert(has_template_arguments(template_arguments_of(^^decltype(obj2))[0])\n+\t == has_template_arguments(^^X<int>));\ndiff --git a/gcc/testsuite/g++.dg/reflect/template_arguments_of3.C b/gcc/testsuite/g++.dg/reflect/template_arguments_of3.C\nnew file mode 100644\nindex 00000000000..d6ad5cd4196\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/template_arguments_of3.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::template_arguments_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+using U = int;\n+typedef double V;\n+\n+template<typename T, typename U>\n+struct S {};\n+\n+static_assert (template_arguments_of (^^S<int, double>)[0] == ^^int);\n+static_assert (template_arguments_of (^^S<int, double>)[1] == ^^double);\n+static_assert (template_arguments_of (^^S<U, V>)[0] == ^^int);\n+static_assert (template_arguments_of (^^S<U, V>)[1] == ^^double);\ndiff --git a/gcc/testsuite/g++.dg/reflect/template_of1.C b/gcc/testsuite/g++.dg/reflect/template_of1.C\nnew file mode 100644\nindex 00000000000..2075946204d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/template_of1.C\n@@ -0,0 +1,119 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::template_of.\n+\n+#include <meta>\n+#include <vector>\n+\n+using namespace std::meta;\n+\n+template<typename> struct incomplete_cls;\n+template<typename> struct cls_tmpl {\n+ template <typename T> struct inner {};\n+};\n+template<typename> void fun_tmpl ();\n+template<typename> int var_tmpl;\n+template<typename T> using cls_tmpl_alias = cls_tmpl<T>;\n+template<typename> using int_alias = int;\n+template<typename U> using dep_alias = cls_tmpl<int>::template inner<U>;\n+\n+static_assert (template_of (^^cls_tmpl<int>) == ^^cls_tmpl);\n+static_assert (template_of (^^incomplete_cls<int>) == ^^incomplete_cls);\n+static_assert (template_of (^^int_alias<int>) == ^^int_alias);\n+static_assert (template_of (^^dep_alias<bool>) == ^^dep_alias);\n+static_assert (template_of (^^fun_tmpl<int>) == ^^fun_tmpl);\n+static_assert (template_of (^^var_tmpl<int>) == ^^var_tmpl);\n+static_assert (template_of (^^cls_tmpl_alias<int>) == ^^cls_tmpl_alias);\n+\n+struct W {\n+ using U = cls_tmpl<int>;\n+};\n+static_assert (template_of (dealias (^^W::U)) == ^^cls_tmpl);\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+struct class_tmpl {\n+ template <typename> struct inner {};\n+};\n+static_assert (template_of (^^class_tmpl<int, 9, std::vector>) == ^^class_tmpl);\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+void fn_tmpl ();\n+static_assert (template_of (^^fn_tmpl<int, 9, std::vector>) == ^^fn_tmpl);\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+int var_tmpl2 = 0;\n+static_assert (template_of (^^var_tmpl2<int, 9, std::vector>) == ^^var_tmpl2);\n+\n+template <typename P1, auto P2, template <typename...> class P3>\n+using alias = int;\n+static_assert (template_of (^^alias<int, 9, std::vector>) == ^^alias);\n+\n+template <typename T>\n+using dep_alias2 = class_tmpl<int, 9, std::vector>::template inner<T>;\n+static_assert (template_of (^^dep_alias2<int>) == ^^dep_alias2);\n+\n+template <typename T, T> struct A {};\n+static_assert (template_of (^^A<int, 5>) == ^^A);\n+\n+template <typename... Ts> struct B {};\n+static_assert (template_of (^^B<int, bool>) == ^^B);\n+\n+struct S {\n+ int mem;\n+ bool operator==(const S&) const = default;\n+};\n+template <auto... Vs> struct auto_pack {};\n+static_assert (template_of (^^auto_pack<4, S{3}>) == ^^auto_pack);\n+\n+template <float> struct float_targ {};\n+constexpr float F = 4.5f;\n+static_assert (template_of (^^float_targ<F>) == ^^float_targ);\n+\n+template <const float *> struct ptr_targ {};\n+constexpr float Fs[] = {4.5, 5.5, 6.5};\n+static_assert (template_of (^^ptr_targ<Fs>) == ^^ptr_targ);\n+static_assert (template_of (^^ptr_targ<nullptr>) == ^^ptr_targ);\n+\n+template <const int &> struct ref_targ {};\n+const int I = 5;\n+using T = ref_targ<I>;\n+static_assert (template_of (dealias(^^T)) == ^^ref_targ);\n+\n+template <std::meta::info> struct refl_targ {};\n+static_assert (template_of (^^refl_targ<^^int>) == ^^refl_targ);\n+\n+struct M {\n+ template<typename T>\n+ struct N { };\n+};\n+\n+template<typename T>\n+struct TS {\n+ template<typename U>\n+ struct N { };\n+};\n+\n+static_assert (template_of (^^M::N<int>) == ^^M::N);\n+static_assert (template_of (^^TS<int>::N<int>) == ^^TS<int>::N);\n+\n+template<typename T>\n+struct X { };\n+\n+template<typename T>\n+struct X<T*> { };\n+\n+template<>\n+struct X<int> { };\n+\n+static_assert (template_of (^^X<int>) == ^^X);\n+static_assert (template_of (^^X<int *>) == ^^X);\n+\n+template<typename = int>\n+struct Y { };\n+static_assert (template_of (^^Y<>) == ^^Y);\n+\n+struct Z {\n+ using Alias = X<int>;\n+};\n+\n+static_assert (template_of (dealias (^^Z::Alias)) == ^^X);\ndiff --git a/gcc/testsuite/g++.dg/reflect/template_of2.C b/gcc/testsuite/g++.dg/reflect/template_of2.C\nnew file mode 100644\nindex 00000000000..73aa0bcb019\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/template_of2.C\n@@ -0,0 +1,32 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::template_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S {\n+ template<typename T>\n+ void fn (T) { }\n+\n+ template<typename T>\n+ using U = int;\n+};\n+\n+template<typename T>\n+struct TS {\n+ template<typename U>\n+ void fn (T) { }\n+\n+ template<typename TT>\n+ using U = int;\n+};\n+\n+static_assert (template_of (^^S::fn<int>) == ^^S::fn);\n+static_assert (template_of (^^TS<int>::fn<int>) == ^^TS<int>::fn);\n+static_assert (template_of (^^S::U<int>) == ^^S::U);\n+// FIXME\n+// template<class T> template<class U> using TS<T>::W = int\n+// template<class U> using TS<int>::W = int\n+//static_assert (template_of (^^TS<int>::U<int>) == ^^TS<int>::U);\ndiff --git a/gcc/testsuite/g++.dg/reflect/template_of3.C b/gcc/testsuite/g++.dg/reflect/template_of3.C\nnew file mode 100644\nindex 00000000000..2f7239f4a98\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/template_of3.C\n@@ -0,0 +1,22 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::template_of.\n+\n+#include <meta>\n+\n+consteval void\n+foo ()\n+{\n+ template_of (^^int);\n+}\n+\n+consteval bool\n+test ()\n+{\n+ try { foo (); }\n+ catch (std::meta::exception &) { return true; }\n+ catch (...) { return false; }\n+ return false;\n+}\n+\n+static_assert (test ());\ndiff --git a/gcc/testsuite/g++.dg/reflect/tuple1.C b/gcc/testsuite/g++.dg/reflect/tuple1.C\nnew file mode 100644\nindex 00000000000..2357eeb64d7\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/tuple1.C\n@@ -0,0 +1,86 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::tuple_{size,element}.\n+\n+#include <array>\n+#include <complex>\n+#include <meta>\n+#include <ranges>\n+#include <tuple>\n+\n+using namespace std::meta;\n+\n+struct E {};\n+\n+using Tup0 = std::tuple<>;\n+static_assert (tuple_size (^^Tup0) == 0);\n+\n+using Tup1 = std::tuple<int>;\n+static_assert (tuple_size (^^Tup1) == 1);\n+static_assert (tuple_element (0, ^^Tup1) == ^^int);\n+\n+using Tup2 = std::tuple<int, bool>;\n+static_assert (tuple_size (^^Tup2) == 2);\n+static_assert (tuple_element (0, ^^Tup2) == ^^int);\n+static_assert (tuple_element (1, ^^Tup2) == ^^bool);\n+\n+using Tup3 = std::tuple<int, bool, char>;\n+static_assert (tuple_size (^^Tup3) == 3);\n+static_assert (tuple_element (0, ^^Tup3) == ^^int);\n+static_assert (tuple_element (1, ^^Tup3) == ^^bool);\n+static_assert (tuple_element (2, ^^Tup3) == ^^char);\n+\n+using Tup10 = std::tuple<int, int, int, int, int, int, int, int, int, int>;\n+static_assert (tuple_size (^^Tup10) == 10);\n+static_assert (tuple_element (0, ^^Tup10) == ^^int);\n+static_assert (tuple_element (9, ^^Tup10) == ^^int);\n+\n+using mytype1 = float;\n+using mytype2 = mytype1 *;\n+static_assert (tuple_size (^^std::tuple<mytype1, mytype2>) == 2);\n+static_assert (tuple_element (0, ^^std::tuple<mytype1>) == ^^float);\n+static_assert (tuple_element (1, ^^std::tuple<mytype1, mytype2>) == ^^float *);\n+\n+static_assert (tuple_size (^^std::tuple<>) == 0);\n+static_assert (tuple_size (^^std::tuple<int>) == 1);\n+static_assert (tuple_size (^^std::tuple<void>) == 1);\n+static_assert (tuple_size (^^std::tuple<std::tuple<void>>) == 1);\n+static_assert (tuple_size (^^const std::tuple<>) == 0);\n+static_assert (tuple_size (^^const std::tuple<int>) == 1);\n+static_assert (tuple_size (^^const std::tuple<void>) == 1);\n+static_assert (tuple_size (^^const std::tuple<std::tuple<void>>) == 1);\n+\n+using Arr5 = std::array<int, 5>;\n+static_assert (tuple_size (^^Arr5) == 5);\n+static_assert (tuple_size (^^const Arr5) == 5);\n+static_assert (tuple_element (0, ^^Arr5) == ^^int);\n+static_assert (tuple_element (1, ^^Arr5) == ^^int);\n+static_assert (tuple_element (2, ^^Arr5) == ^^int);\n+static_assert (tuple_element (3, ^^Arr5) == ^^int);\n+static_assert (tuple_element (4, ^^Arr5) == ^^int);\n+using Arr0 = std::array<int, 0>;\n+static_assert (tuple_size (^^Arr0) == 0);\n+\n+using Pair = std::pair<E, int>;\n+// Always 2.\n+static_assert (tuple_size (^^Pair) == 2);\n+static_assert (tuple_element (0, ^^Pair) == ^^E);\n+static_assert (tuple_element (1, ^^Pair) == ^^int);\n+\n+using C = std::complex<double>;\n+static_assert (tuple_size (^^C) == 2);\n+static_assert (tuple_element (0, ^^C) == ^^double);\n+static_assert (tuple_element (1, ^^C) == ^^double);\n+\n+using S1 = std::ranges::subrange<int *>;\n+using S2 = std::ranges::subrange<long *, void *>;\n+static_assert (tuple_size (^^S1) == 2);\n+static_assert (tuple_size (^^S2) == 2);\n+static_assert (tuple_element (0, ^^S1) == ^^int *);\n+static_assert (tuple_element (1, ^^S1) == ^^int *);\n+static_assert (tuple_element (0, ^^const S1) == ^^int *);\n+static_assert (tuple_element (1, ^^const S1) == ^^int *);\n+static_assert (tuple_element (0, ^^S2) == ^^long *);\n+static_assert (tuple_element (1, ^^S2) == ^^void *);\n+static_assert (tuple_element (0, ^^const S2) == ^^long *);\n+static_assert (tuple_element (1, ^^const S2) == ^^void *);\ndiff --git a/gcc/testsuite/g++.dg/reflect/tuple2.C b/gcc/testsuite/g++.dg/reflect/tuple2.C\nnew file mode 100644\nindex 00000000000..a4af2f53149\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/tuple2.C\n@@ -0,0 +1,21 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::tuple_{size,element}.\n+\n+#include <array>\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr auto s1 = tuple_size (^^int); // { dg-error \"couldn't instantiate 'std::tuple_size<int>'\" }\n+int x;\n+constexpr auto s2 = tuple_size (^^x); // { dg-error \"uncaught exception\" }\n+\n+constexpr auto r1 = tuple_element (666, ^^std::tuple<int>); // { dg-error \"uncaught exception\" }\n+\n+using Arr0 = std::array<int, 0>;\n+constexpr auto r2 = tuple_element (1, ^^Arr0);\n+\n+// { dg-error \"tuple index must be in range\" \"\" { target *-*-* } 0 }\n+// { dg-error \"array index is in range\" \"\" { target *-*-* } 0 }\n+// { dg-error \"pack index .666.\" \"\" { target *-*-* } 0 }\ndiff --git a/gcc/testsuite/g++.dg/reflect/type1.C b/gcc/testsuite/g++.dg/reflect/type1.C\nnew file mode 100644\nindex 00000000000..74bc27282b3\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type1.C\n@@ -0,0 +1,190 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on types.\n+\n+template<class, class> struct same_type;\n+template<class T> struct same_type<T, T> {};\n+\n+using size_t = decltype(sizeof(int));\n+using info = decltype(^^void);\n+using T = int;\n+\n+struct S { int i; };\n+\n+constexpr auto g1 = ^^unsigned;\n+constexpr auto g2 = ^^S;\n+constexpr static auto g3 = ^^unsigned;\n+constexpr static auto g4 = ^^S;\n+constexpr info g5 = ^^void;\n+constexpr info g6 = ^^decltype(42);\n+constexpr info g7 = ^^T;\n+constexpr info g8 = ^^decltype(^^int);\n+constexpr info g9 = ^^void() const & noexcept;\n+\n+[: g1 :] u1; // { dg-error \"expected unqualified-id\" }\n+typename [: g1 :] u2;\n+\n+namespace N {\n+ [: g1 :] nu1; // { dg-error \"expected unqualified-id\" }\n+ typename [: g1 :] nu2;\n+}\n+\n+void\n+f1 ()\n+{\n+ constexpr auto r1 = ^^int;\n+ [: r1 :] v1 = 42; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r1 :] v1t = 42;\n+ same_type<decltype(v1t), int>();\n+\n+ const typename [: r1 :] v2 = 42;\n+ same_type<decltype(v2), const int>();\n+\n+ const volatile typename [: r1 :] v3 = 42;\n+ same_type<decltype(v3), const volatile int>();\n+ const typename [: r1 :] *v4 = &v1t;\n+ same_type<decltype(v4), const int *>();\n+\n+ constexpr auto r2 = ^^double;\n+ [: r2 :] v5 = 42.2; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r2 :] v5t = 42.2;\n+ same_type<decltype(v5t), double>();\n+\n+ [: r2 :] &v6 = v5t; // { dg-error \"expected a reflection of an expression|.v6. was not declared\" }\n+ typename [: r2 :] &v6t = v5t;\n+ same_type<decltype(v6t), double &>();\n+\n+ constexpr auto r3 = ^^S;\n+ [: r3 :] v7 = { 42 }; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r3 :] v7t = { 42 };\n+ same_type<decltype(v7t), S>();\n+ const typename [: r3 :] v8 = { 42 };\n+ same_type<decltype(v8), const S>();\n+\n+ constexpr auto r4 = ^^long long int;\n+ [: r4 :] v9 = 0ll; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r4 :] v9t = 0ll;\n+ same_type<decltype(v9t), long long int>();\n+\n+ constexpr auto r5 = ^^const int;\n+ [: r5 :] v10 = 0; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r5 :] v10t = 0;\n+ same_type<decltype(v10t), const int>();\n+\n+ constexpr auto r6 = ^^volatile short;\n+ [: r6 :] v11 = 0; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r6 :] v11t = 0;\n+ same_type<decltype(v11t), volatile short>();\n+\n+ constexpr auto r7 = ^^bool;\n+ [: r7 :] v12 = 0; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r7 :] v12t = 0;\n+ same_type<decltype(v12t), bool>();\n+\n+ constexpr auto r8 = ^^wchar_t;\n+ [: r8 :] v13 = 0; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r8 :] v13t = 0;\n+ same_type<decltype(v13t), wchar_t>();\n+\n+ constexpr auto r9 = ^^decltype(sizeof 0);\n+ [: r9 :] v14 = 0; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r9 :] v14t = 0;\n+ same_type<decltype(v14t), size_t>();\n+\n+ constexpr auto r10 = ^^signed;\n+ [: r10 :] v15 = 0; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r10 :] v15t = 0;\n+ same_type<decltype(v15t), int>();\n+\n+}\n+\n+void\n+f2 ()\n+{\n+ typename [:^^char:] c1 = '*';\n+ same_type<decltype(c1), char>();\n+\n+ const typename [:^^char:] c2 = '*';\n+ same_type<decltype(c2), const char>();\n+\n+ typename [:^^int:]* c3 = nullptr;\n+ same_type<decltype(c3), int *>();\n+\n+ typename [:^^int:] c4 = 42;\n+ same_type<decltype(c4), int>();\n+\n+ typename [:^^int:] &c5 = c4;\n+ same_type<decltype(c5), int &>();\n+\n+ typename [:^^int:] arr1[10];\n+ same_type<decltype(arr1), int[10]>();\n+}\n+\n+void\n+f3 ()\n+{\n+ typename [: g1 :] v1 = 42;\n+ same_type<decltype(v1), unsigned>();\n+ typename [: g3 :] v2 = 42;\n+ same_type<decltype(v2), unsigned>();\n+ typename [: g2 :] v3 = { 42 };\n+ same_type<decltype(v3), S>();\n+ typename [: g4 :] v4 = { 42 };\n+ same_type<decltype(v4), S>();\n+}\n+\n+void\n+f4 ()\n+{\n+ static constexpr auto r = ^^unsigned;\n+ constexpr auto p = &r;\n+ [: *p :] i1 = 0u; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: *p :] i2 = 0u;\n+}\n+\n+constexpr void\n+f5 ()\n+{\n+ static constexpr auto r = ^^unsigned;\n+ constexpr auto p = &r;\n+ [: *p :] i1 = 0u; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: *p :] i2 = 0u;\n+}\n+\n+consteval void\n+f6 ()\n+{\n+ static constexpr auto r = ^^unsigned;\n+ constexpr auto p = &r;\n+ [: *p :] i1 = 0u; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: *p :] i2 = 0u;\n+ auto t = r;\n+ ^^int;\n+}\n+\n+void\n+f7 ()\n+{\n+ {\n+ {\n+ constexpr auto r = ^^int;\n+ typename [: r :] v = 42;\n+ same_type<decltype(v), int>();\n+ }\n+ }\n+}\n+\n+enum E { X, Y };\n+enum class SE { yay, nay };\n+\n+void\n+f8 ()\n+{\n+ constexpr auto r = ^^E;\n+ [: r :] e = Y; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r :] et;\n+\n+ constexpr auto r2 = ^^SE;\n+ [: r2 :] e2 = SE::yay; // { dg-error \"expected a reflection of an expression\" }\n+ typename [: r2 :] et2;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type10.C b/gcc/testsuite/g++.dg/reflect/type10.C\nnew file mode 100644\nindex 00000000000..21e2c4260be\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type10.C\n@@ -0,0 +1,31 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+void fn1 ([: ^^int :]); // { dg-error \"declared void|expected a reflection of an expression\" }\n+void fn2 ([: ^^int :][]); // { dg-error \"declared void|expected a reflection of an expression\" }\n+void fn3 (typename [: ^^int :]);\n+void fn4 (typename [: ^^int :] *);\n+\n+constexpr auto r = ^^fn3;\n+void fn3 ([: r :]); // { dg-error \"declared void|expected a reflection of an expression\" }\n+\n+template<info R, info T>\n+void\n+g ()\n+{\n+ void foo(typename [:R:]);\n+ foo (nullptr);\n+\n+ int bar(typename [:T:]);\n+ bar ({});\n+}\n+\n+struct X { };\n+\n+void\n+f ()\n+{\n+ g<^^int*, ^^X>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type2.C b/gcc/testsuite/g++.dg/reflect/type2.C\nnew file mode 100644\nindex 00000000000..7d1f16b981d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type2.C\n@@ -0,0 +1,58 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on types. Invalid cases.\n+\n+struct A;\n+\n+void\n+f1 ()\n+{\n+ const auto r = ^^double; // { dg-error \"consteval-only variable\" }\n+ constexpr auto r2 = ^^int;\n+ r2; // { dg-error \"consteval-only expressions\" }\n+ ^^void; // { dg-error \"consteval-only expressions\" }\n+ ^^int == ^^int; // { dg-error \"consteval-only expressions\" }\n+ (void) ^^float; // { dg-error \"consteval-only expressions\" }\n+ auto rr = r; // { dg-error \"consteval-only variable\" }\n+\n+ constexpr auto x = &(^^int); // { dg-error \"lvalue required\" }\n+\n+ // These are verboten.\n+ constexpr auto a = ^^auto; // { dg-error \"cannot be applied to\" }\n+ constexpr auto d = ^^decltype(auto); // { dg-error \"cannot be applied to\" }\n+\n+ constexpr auto r3 = ^^A;\n+ [: r3 :] inc;\t// { dg-error \"expected a reflection of an expression\" }\n+}\n+\n+constexpr void\n+f2 ()\n+{\n+ auto r = ^^int; // { dg-error \"consteval-only variable\" }\n+}\n+\n+void\n+f3 ()\n+{\n+ [: ^^:: :] i; // { dg-error \"expected\" }\n+ typename [: ^^:: :] i2; // { dg-error \"expected\" }\n+}\n+\n+void\n+f4 ()\n+{\n+ using T1 = ^^int; // { dg-error \"expected type-specifier\" }\n+}\n+\n+template<typename... T>\n+void\n+f5 ()\n+{\n+ constexpr auto r = ^^T; // { dg-error \"parameter packs not expanded with\" }\n+}\n+\n+void\n+g ()\n+{\n+ f2 ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type3.C b/gcc/testsuite/g++.dg/reflect/type3.C\nnew file mode 100644\nindex 00000000000..edf4d4da290\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type3.C\n@@ -0,0 +1,37 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on types.\n+\n+struct S { int i; };\n+\n+constexpr auto g1 = ^^int;\n+constexpr auto g2 = ^^S;\n+\n+// Create int foo (int, S *);\n+typename [: g1 :] foo (typename [: g1 :], typename [: g2 :] *);\n+\n+void\n+bar (S *s)\n+{\n+ foo (42, s);\n+}\n+\n+template<typename T>\n+constexpr int bar (T t) { return t; }\n+\n+void\n+g ()\n+{\n+ constexpr auto r = [: ^^bar<typename [: ^^int :]> :](42);\n+ static_assert (r == 42);\n+}\n+\n+struct A {\n+ int a;\n+ consteval A(int p) : a(p) {}\n+};\n+constexpr auto r = ^^A;\n+struct B : A {\n+ using [: r :]::A;\n+ consteval B([: ^^int :] p, [: ^^int :] q) : A(p * q) {}\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/type4.C b/gcc/testsuite/g++.dg/reflect/type4.C\nnew file mode 100644\nindex 00000000000..0f0c2c18046\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type4.C\n@@ -0,0 +1,136 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflect-expression -> ^^ type-id.\n+// type-id:\n+// type-specifier-seq abstract-declarator(opt)\n+\n+enum E { E1 };\n+struct S { };\n+using T = int;\n+template<typename T>\n+class C {\n+ using type = T;\n+};\n+union U { int i; };\n+\n+template<typename T>\n+using AT = C<T>;\n+\n+void\n+f1 ()\n+{\n+ // type-specifier -> simple-type-specifier\n+ constexpr auto r1 = ^^void;\n+ constexpr auto r2 = ^^void*;\n+ constexpr auto r3 = ^^int&;\n+ constexpr auto r4 = ^^int&&;\n+ constexpr auto r5 = ^^decltype(sizeof(0));\n+ constexpr auto r6 = ^^E*;\n+ constexpr auto r7 = ^^S*;\n+ constexpr auto r8 = ^^T*;\n+ constexpr auto r9 = ^^const void*;\n+ constexpr auto r10 = ^^const int&;\n+ constexpr auto r11 = ^^E const*;\n+ constexpr auto r12 = ^^S const*const;\n+ constexpr auto r13 = ^^const T *;\n+ constexpr auto r14 = ^^E;\n+ constexpr auto r15 = ^^S;\n+ constexpr auto r16 = ^^T;\n+ constexpr auto r17 = ^^T&&;\n+ constexpr auto r18 = ^^int*[3];\n+ constexpr auto r19 = ^^int (*)[3];\n+ constexpr auto r20 = ^^int *();\n+ constexpr auto r21 = ^^int (*)(double);\n+\n+ int i = 42;\n+ E e;\n+ S s;\n+ typename [: r1 :] fn1 ();\n+ typename [: r16 :] fn2 (typename [: r1 :]);\n+ typename [: r2 :] v1 = nullptr;\n+ typename [: r3 :] v2 = i;\n+ typename [: r4 :] v3 = 42;\n+ typename [: r5 :] v4 = 0U;\n+ typename [: r6 :] v5 = &e;\n+ typename [: r7 :] v6 = &s;\n+ typename [: r8 :] v7 = &i;\n+ typename [: r9 :] v8 = nullptr;\n+ typename [: r10 :] v9 = 42;\n+ typename [: r11 :] v10 = &e;\n+ typename [: r12 :] v11 = &s;\n+ typename [: r13 :] v12 = &i;\n+ typename [: r14 :] v13;\n+ typename [: r15 :] v14;\n+ typename [: r16 :] v15;\n+ typename [: r17 :] v16 = 42;\n+ typename [: r18 :] v17 = {nullptr};\n+ typename [: r19 :] v18;\n+ typename [: r20 :] v19;\n+ typename [: r21 :] v20;\n+\n+ // type-specifier -> elaborated-type-specifier\n+ constexpr auto r22 = ^^struct S;\n+ constexpr auto r23 = ^^struct ::S;\n+ constexpr auto r24 = ^^struct C<int>;\n+ constexpr auto r25 = ^^struct ::C<int>;\n+ constexpr auto r26 = ^^struct ::template C<int>;\n+ constexpr auto r27 = ^^union U;\n+ constexpr auto r28 = ^^union ::U;\n+ constexpr auto r29 = ^^enum E;\n+ constexpr auto r30 = ^^enum ::E;\n+ constexpr auto r31 = ^^const struct S;\n+ constexpr auto r32 = ^^const struct ::S;\n+ constexpr auto r33 = ^^const struct C<int>;\n+ constexpr auto r34 = ^^const struct ::C<int>;\n+ constexpr auto r35 = ^^const struct ::template C<int>;\n+ constexpr auto r36 = ^^const union U;\n+ constexpr auto r37 = ^^const union ::U;\n+ constexpr auto r38 = ^^const enum E;\n+ constexpr auto r39 = ^^const enum ::E;\n+\n+ typename [: r22 :] s1;\n+ typename [: r23 :] s2;\n+ typename [: r31 :] s3;\n+ typename [: r32 :] s4;\n+ typename [: r24 :] c1;\n+ typename [: r25 :] c2;\n+ typename [: r26 :] c3;\n+ typename [: r33 :] c4;\n+ typename [: r34 :] c5;\n+ typename [: r35 :] c6;\n+ typename [: r27 :] u1;\n+ typename [: r28 :] u2;\n+ typename [: r36 :] u3{1};\n+ typename [: r37 :] u4{1};\n+ typename [: r29 :] e1;\n+ typename [: r30 :] e2;\n+ typename [: r38 :] e3 = E1;\n+ typename [: r39 :] e4 = E1;\n+\n+ // type-specifier -> typename-specifier\n+ constexpr auto r40 = ^^typename ::E;\n+ constexpr auto r41 = ^^typename ::C<int>;\n+ constexpr auto r42 = ^^typename ::template C<int>;\n+ constexpr auto r43 = ^^typename ::S;\n+ constexpr auto r44 = ^^typename ::T;\n+ constexpr auto r45 = ^^typename ::U;\n+\n+ typename [: r40 :] e5;\n+ typename [: r41 :] c7;\n+ typename [: r42 :] c8;\n+ typename [: r43 :] s5;\n+ typename [: r44 :] i1;\n+ typename [: r45 :] u5;\n+\n+ constexpr auto r46 = ^^AT<int>;\n+ constexpr auto r47 = ^^::AT<int>;\n+ constexpr auto r48 = ^^::template AT<int>;\n+ constexpr auto r49 = ^^typename ::AT<int>;\n+ constexpr auto r50 = ^^typename ::template AT<int>;\n+\n+ typename [: r46 :] c9;\n+ typename [: r47 :] c10;\n+ typename [: r48 :] c11;\n+ typename [: r49 :] c12;\n+ typename [: r50 :] c13;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type5.C b/gcc/testsuite/g++.dg/reflect/type5.C\nnew file mode 100644\nindex 00000000000..8a7debbc888\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type5.C\n@@ -0,0 +1,10 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Distilled from [temp.res.general].\n+\n+enum class Enum { A, B, C };\n+template<class T> struct S {\n+ using Alias = [:^^int:];\n+ auto h() -> [:^^S:]<T*>;\n+ using enum [:^^Enum:];\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/type6.C b/gcc/testsuite/g++.dg/reflect/type6.C\nnew file mode 100644\nindex 00000000000..f2db8693dfa\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type6.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^int);\n+\n+template<typename T> concept C = requires {\n+ typename [:T::r1:];\n+ typename [:T::r2:]<int>;\n+};\n+\n+template<typename T>\n+struct Z { };\n+\n+struct S {\n+ static constexpr info r1 = ^^int;\n+ static constexpr info r2 = ^^Z;\n+};\n+\n+void\n+g (S s)\n+{\n+ typename [: S::r1 :] i = 42;\n+ typename [: S::r2 :]<int> z;\n+ C auto a = s;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type7.C b/gcc/testsuite/g++.dg/reflect/type7.C\nnew file mode 100644\nindex 00000000000..444df8e9d02\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type7.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection -fconcepts-diagnostics-depth=2\" }\n+\n+using info = decltype(^^int);\n+\n+template<typename T> concept C = requires {\n+ typename [:T::r1:]; // { dg-error \".r1. is not a member of .int.\" }\n+ typename [:T::r2:]<int>; // { dg-error \".r2. is not a member of .int.\" }\n+};\n+\n+void\n+g ()\n+{\n+ C auto a = 42; // { dg-error \"does not satisfy placeholder constraints\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type8.C b/gcc/testsuite/g++.dg/reflect/type8.C\nnew file mode 100644\nindex 00000000000..82243d71be3\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type8.C\n@@ -0,0 +1,76 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test splice-expressions in decltype.\n+\n+template<class, class> struct same_type;\n+template<class T> struct same_type<T, T> {};\n+\n+struct S {\n+ static const int &&mem();\n+ static int i;\n+ int j;\n+} s;\n+\n+const int && foo();\n+decltype(foo()) x1 = 17; // type is const int&&\n+same_type<decltype(x1), const int &&> s1;\n+decltype([: ^^x1 :]) x5 = 18; // type is const int&&\n+same_type<decltype(x5), const int &&> s2;\n+decltype(([: ^^x1 :])) x6 = 19; // type is const int&\n+same_type<decltype(x6), const int &> s3;\n+same_type<decltype(foo), const int&&()> s4a;\n+same_type<decltype([: ^^foo :]), const int&&()> s4b;\n+same_type<decltype(S::i), int> s5a;\n+same_type<decltype([: ^^S::i :]), int> s5b;\n+same_type<decltype((S::i)), int&> s6a;\n+same_type<decltype(([: ^^S::i :])), int&> s6b;\n+same_type<decltype(S::mem), const int&&()> s7a;\n+same_type<decltype([: ^^S::mem :]), const int&&()> s7b;\n+same_type<decltype((S::mem)), const int&& (&)()> s8a;\n+same_type<decltype(([: ^^S::mem :])), const int&& (&)()> s8b;\n+same_type<decltype(s.j), int> s9a;\n+same_type<decltype([: ^^s :].j), int> s9b;\n+same_type<decltype((s.j)), int&> s10a;\n+same_type<decltype(([: ^^s :].j)), int&> s10b;\n+\n+namespace N {\n+ struct A { } a;\n+}\n+\n+same_type<decltype(N::a), N::A> s11a;\n+same_type<decltype([: ^^N :]::a), N::A> s11b;\n+same_type<decltype([: ^^N::a :]), N::A> s11c;\n+\n+struct B {\n+ int i : 31;\n+} b;\n+\n+same_type<decltype(b.i), int> s12a;\n+same_type<decltype([: ^^b :].i), int> s12b;\n+same_type<decltype((b.i)), int&> s13a;\n+same_type<decltype(([: ^^b :].i)), int&> s13b;\n+\n+template<typename T>\n+struct C {\n+ static constexpr T t{};\n+};\n+\n+template<typename T>\n+void\n+g ()\n+{\n+ same_type<decltype(C<T>::t), const int>();\n+ same_type<decltype((C<T>::t)), const int&>();\n+ same_type<decltype([: ^^C<T>::t :]), const int>();\n+ same_type<decltype(([: ^^C<T>::t :])), const int&>();\n+ same_type<decltype([: ^^C<T> :]::t), const int>();\n+ same_type<decltype(([: ^^C<T> :]::t)), const int&>();\n+ same_type<decltype(template [: ^^C :]<T>::t), const int>();\n+ same_type<decltype((template [: ^^C :]<T>::t)), const int&>();\n+}\n+\n+void\n+doit ()\n+{\n+ g<int> ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type9.C b/gcc/testsuite/g++.dg/reflect/type9.C\nnew file mode 100644\nindex 00000000000..56bed4590a5\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type9.C\n@@ -0,0 +1,49 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+template<typename>\n+void foo () { }\n+void bar () { }\n+namespace N { }\n+namespace M = N;\n+template<typename T>\n+T vt{};\n+template<typename T>\n+concept C = true;\n+static int i;\n+enum E { X };\n+struct S { static int si; };\n+template<typename T>\n+struct D { static T di; };\n+template<typename T>\n+using Z = D<T>;\n+\n+template<info R> void fn1 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn2 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn3 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn4 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn5 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn6 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn7 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn8 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn9 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn10 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn11 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn12 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+template<info R> void fn13 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n+\n+template void fn1<^^foo<int>>(); // { dg-message \"required from here\" }\n+template void fn2<^^foo>();\t // { dg-message \"required from here\" }\n+template void fn3<^^N>();\t // { dg-message \"required from here\" }\n+template void fn4<^^M>();\t // { dg-message \"required from here\" }\n+template void fn5<^^bar>();\t // { dg-message \"required from here\" }\n+template void fn6<^^vt<int>>();\t // { dg-message \"required from here\" }\n+template void fn7<^^vt>();\t // { dg-message \"required from here\" }\n+template void fn8<^^C>();\t // { dg-message \"required from here\" }\n+template void fn9<^^i>();\t // { dg-message \"required from here\" }\n+template void fn10<^^X>();\t // { dg-message \"required from here\" }\n+template void fn11<^^S::si>();\t // { dg-message \"required from here\" }\n+template void fn12<^^D<int>::di>(); // { dg-message \"required from here\" }\n+template void fn13<^^Z>();\t // { dg-message \"required from here\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/type_of1.C b/gcc/testsuite/g++.dg/reflect/type_of1.C\nnew file mode 100644\nindex 00000000000..4433b7c222d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type_of1.C\n@@ -0,0 +1,190 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::type_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+int arr[] = {1, 2, 3};\n+auto [a1, a2, a3] = arr;\n+void fn();\n+auto &fn2();\n+enum Enum { A };\n+using Alias = int;\n+struct B {};\n+struct S : B {\n+ int mem;\n+ int : 0;\n+};\n+struct T {\n+ T ();\n+ T (const T &);\n+ ~T ();\n+};\n+struct U {\n+ int u;\n+ int v : 5;\n+};\n+template<auto> struct TCls {};\n+template<auto> void TFn();\n+template<auto> int TVar;\n+template<auto> concept Concept = requires { true; };\n+namespace NS {};\n+namespace NSAlias = NS;\n+\n+constexpr auto ctx = std::meta::access_context::current ();\n+\n+consteval bool\n+has_type (info r)\n+{\n+ try { type_of (r); }\n+ catch (std::meta::exception &) { return false; }\n+ return true;\n+}\n+\n+static_assert (has_type (std::meta::reflect_constant (42)));\n+static_assert (has_type (std::meta::reflect_object (arr[1])));\n+static_assert (has_type (^^arr));\n+static_assert (!has_type (^^a3));\n+static_assert (has_type (^^fn));\n+static_assert (!has_type (^^fn2));\n+static_assert (has_type (^^Enum::A));\n+static_assert (!has_type (^^Alias));\n+static_assert (!has_type (^^S));\n+static_assert (has_type (^^S::mem));\n+static_assert (has_type (std::meta::members_of (^^S, ctx)[1]));\n+static_assert (!has_type (^^TCls));\n+static_assert (!has_type (^^TFn));\n+static_assert (!has_type (^^TVar));\n+static_assert (!has_type (^^Concept));\n+static_assert (!has_type (^^NSAlias));\n+static_assert (!has_type (^^NS));\n+static_assert (has_type (std::meta::bases_of (^^S, ctx)[0]));\n+static_assert (has_type (std::meta::data_member_spec (^^int, { .name = \"member\" })));\n+static_assert (has_type (std::meta::data_member_spec (^^int, { .name = \"member\", .bit_width = 6 })));\n+static_assert (has_type (std::meta::data_member_spec (^^int, { .bit_width = 0 })));\n+static_assert (has_type (std::meta::data_member_spec (^^int, { .bit_width = 5 })));\n+void bar (long, const T f, int g[2], T &);\n+\n+int\n+foo (int a, const long b, T c, int d[4], T &e)\n+{\n+ static_assert (has_type (^^a));\n+ static_assert (has_type (^^b));\n+ static_assert (has_type (^^c));\n+ static_assert (has_type (^^d));\n+ static_assert (has_type (^^e));\n+ static_assert (has_type (parameters_of (^^foo)[0]));\n+ static_assert (has_type (parameters_of (^^foo)[1]));\n+ static_assert (has_type (parameters_of (^^foo)[2]));\n+ static_assert (has_type (parameters_of (^^foo)[3]));\n+ static_assert (has_type (parameters_of (^^foo)[4]));\n+ static_assert (has_type (parameters_of (^^bar)[0]));\n+ static_assert (has_type (parameters_of (^^bar)[1]));\n+ static_assert (has_type (parameters_of (^^bar)[2]));\n+ static_assert (has_type (parameters_of (^^bar)[3]));\n+ static_assert (type_of (^^a) == ^^int);\n+ using clong = const long;\n+ static_assert (type_of (^^b) == dealias(^^clong));\n+ static_assert (type_of (^^c) == ^^T);\n+ using ptr = int *;\n+ static_assert (type_of (^^d) == dealias (^^ptr));\n+ using ref = T &;\n+ static_assert (type_of (^^e) == dealias (^^ref));\n+ static_assert (type_of (parameters_of (^^foo)[0]) == ^^int);\n+ static_assert (type_of (parameters_of (^^foo)[1]) == ^^long);\n+ static_assert (type_of (parameters_of (^^foo)[2]) == ^^T);\n+ static_assert (type_of (parameters_of (^^foo)[3]) == dealias (^^ptr));\n+ static_assert (type_of (parameters_of (^^foo)[4]) == dealias (^^ref));\n+ static_assert (type_of (parameters_of (^^bar)[0]) == ^^long);\n+ static_assert (type_of (parameters_of (^^bar)[1]) == ^^T);\n+ static_assert (type_of (parameters_of (^^bar)[2]) == dealias (^^ptr));\n+ static_assert (type_of (parameters_of (^^bar)[3]) == dealias (^^ref));\n+ return 0;\n+}\n+\n+static_assert (type_of (std::meta::reflect_constant (42)) == ^^int);\n+static_assert (type_of (std::meta::reflect_constant (42.0)) == ^^double);\n+static_assert (type_of (std::meta::reflect_constant (U { 42 })) == ^^const U);\n+static_assert (type_of (std::meta::reflect_object (arr[1])) == ^^int);\n+using int3 = int[3];\n+static_assert (type_of (^^arr) == dealias (^^int3));\n+static_assert (type_of (^^fn) == ^^void ());\n+static_assert (type_of (^^Enum::A) == ^^Enum);\n+static_assert (type_of (^^A) == ^^Enum);\n+static_assert (type_of (^^S::mem) == ^^int);\n+static_assert (type_of (^^U::v) == ^^int);\n+static_assert (type_of (std::meta::members_of (^^S, ctx)[1]) == ^^int);\n+static_assert (type_of (std::meta::bases_of (^^S, ctx)[0]) == ^^B);\n+static_assert (type_of (std::meta::data_member_spec (^^int, { .name = \"member\" })) == ^^int);\n+static_assert (type_of (std::meta::data_member_spec (^^const long, { .name = \"member\", .bit_width = 8 })) == ^^const long);\n+static_assert (type_of (std::meta::data_member_spec (^^int3, { .name = \"member\" })) == ^^int[3]);\n+static_assert (type_of (std::meta::data_member_spec (^^int, { .bit_width = 7 })) == ^^int);\n+static_assert (type_of (std::meta::data_member_spec (^^int, { .bit_width = 0 })) == ^^int);\n+\n+consteval int\n+test (info x, info y)\n+{\n+ if (x == y)\n+ return 0;\n+ throw 1;\n+}\n+\n+static_assert (type_of (^^test) == ^^int (info, info));\n+\n+using ull = unsigned long long;\n+\n+enum Enum2 {\n+ E21,\n+ E22,\n+ E23 = 3L,\n+ E24,\n+ E25 = 5ULL,\n+ E26,\n+ E27 = 7 + test (type_of (^^E21), ^^int)\n+\t + test (type_of (^^E22), ^^int)\n+\t + test (type_of (^^E23), ^^long)\n+\t + test (type_of (^^E24), ^^long)\n+\t + test (type_of (^^E25), dealias (^^ull))\n+\t + test (type_of (^^E26), dealias (^^ull))\n+};\n+\n+static_assert (type_of (^^E21) == ^^Enum2);\n+static_assert (type_of (^^E22) == ^^Enum2);\n+static_assert (type_of (^^E23) == ^^Enum2);\n+static_assert (type_of (^^E24) == ^^Enum2);\n+static_assert (type_of (^^E25) == ^^Enum2);\n+static_assert (type_of (^^E26) == ^^Enum2);\n+static_assert (type_of (^^E27) == ^^Enum2);\n+\n+enum Enum3 : long {\n+ E31,\n+ E32,\n+ E33 = 3L,\n+ E34,\n+ E35 = 5ULL,\n+ E36,\n+ E37 = 7 + test (type_of (^^E31), ^^long)\n+\t + test (type_of (^^E32), ^^long)\n+\t + test (type_of (^^E33), ^^long)\n+\t + test (type_of (^^E34), ^^long)\n+\t + test (type_of (^^E35), ^^long)\n+\t + test (type_of (^^E36), ^^long)\n+};\n+\n+static_assert (type_of (^^E31) == ^^Enum3);\n+static_assert (type_of (^^E32) == ^^Enum3);\n+static_assert (type_of (^^E33) == ^^Enum3);\n+static_assert (type_of (^^E34) == ^^Enum3);\n+static_assert (type_of (^^E35) == ^^Enum3);\n+static_assert (type_of (^^E36) == ^^Enum3);\n+static_assert (type_of (^^E37) == ^^Enum3);\n+\n+constexpr auto a = reflect_constant_string (\"abcd\");\n+static_assert (type_of (a) == ^^const char [5]);\n+auto as = &[: a :];\n+static_assert (type_of (^^as) == ^^const char (*) [5]);\n+struct V { int a, b, c; };\n+auto bs = &[: reflect_constant (V { 2, 3, 4 }) :];\n+static_assert (type_of (^^bs) == ^^const V *);\ndiff --git a/gcc/testsuite/g++.dg/reflect/type_of2.C b/gcc/testsuite/g++.dg/reflect/type_of2.C\nnew file mode 100644\nindex 00000000000..29567918dc2\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type_of2.C\n@@ -0,0 +1,31 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::type_of.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+template<typename T>\n+consteval auto\n+foo ()\n+{\n+ auto Functions = std::vector<info>{};\n+ for (auto Info : members_of (^^T, access_context::current ()))\n+ if (!is_special_member_function (Info) && is_function (Info))\n+ Functions.push_back(Info);\n+ return Functions;\n+}\n+\n+struct F {\n+ auto f(int)->void;\n+};\n+\n+void\n+g ()\n+{\n+ constexpr auto fInfo = foo<F>()[0];\n+ using fType = [:type_of(fInfo):];\n+ // TODO Should work: non-const non-volatile member functions have ordinary\n+ // function types.\n+ //static_assert (std::same_as<fType, auto(int)->void>);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type_rels1.C b/gcc/testsuite/g++.dg/reflect/type_rels1.C\nnew file mode 100644\nindex 00000000000..ee5ca229da7\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type_rels1.C\n@@ -0,0 +1,141 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::is_same_type.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+using U = int;\n+using UU = U;\n+\n+static_assert (is_same_type (^^int, ^^int));\n+static_assert (is_same_type (^^int, ^^U));\n+static_assert (is_same_type (^^int, ^^UU));\n+static_assert (!is_same_type (^^int, ^^const int));\n+static_assert (!is_same_type (^^int, ^^const UU));\n+static_assert (!is_same_type (^^int *, ^^int[]));\n+static_assert (!is_same_type (^^int&, ^^int&&));\n+\n+struct incomplete;\n+struct B {};\n+struct D : B {};\n+struct E1 : D {};\n+struct E2 : D {};\n+static_assert (is_base_of_type (^^B, ^^D));\n+static_assert (is_base_of_type (^^D, ^^E1));\n+static_assert (is_base_of_type (^^B, ^^E1));\n+static_assert (is_base_of_type (^^B, ^^B));\n+static_assert (!is_base_of_type (^^D, ^^B));\n+static_assert (!is_base_of_type (^^E1, ^^D));\n+static_assert (!is_base_of_type (^^E1, ^^B));\n+static_assert (!is_base_of_type (^^B, ^^int));\n+static_assert (!is_base_of_type (^^incomplete, ^^D));\n+\n+struct V : virtual E1, virtual E2 {};\n+static_assert (!is_virtual_base_of_type (^^B, ^^D));\n+static_assert (!is_virtual_base_of_type (^^const B, ^^D));\n+static_assert (!is_virtual_base_of_type (^^D, ^^B));\n+static_assert (!is_virtual_base_of_type (^^D, ^^int));\n+static_assert (!is_virtual_base_of_type (^^B, ^^B));\n+static_assert (is_virtual_base_of_type (^^B, ^^V));\n+static_assert (is_virtual_base_of_type (^^D, ^^V));\n+static_assert (is_virtual_base_of_type (^^E1, ^^V));\n+static_assert (is_virtual_base_of_type (^^E2, ^^V));\n+\n+struct D1 : private virtual B {};\n+struct D2 : protected virtual B {};\n+struct D3 : private D1 {};\n+struct D4 : private D2 {};\n+struct D5 : protected D2 {};\n+struct D6 : protected D2 {};\n+static_assert (is_virtual_base_of_type (^^B, ^^D1));\n+static_assert (is_virtual_base_of_type (^^B, ^^D2));\n+static_assert (is_virtual_base_of_type (^^B, ^^D3));\n+static_assert (is_virtual_base_of_type (^^B, ^^D4));\n+static_assert (is_virtual_base_of_type (^^B, ^^D5));\n+static_assert (is_virtual_base_of_type (^^B, ^^D6));\n+\n+struct W : V {};\n+struct Y : virtual V {};\n+static_assert (is_virtual_base_of_type (^^E1, ^^W));\n+static_assert (is_virtual_base_of_type (^^E2, ^^W));\n+static_assert (is_virtual_base_of_type (^^E1, ^^Y));\n+static_assert (is_virtual_base_of_type (^^E2, ^^Y));\n+\n+struct X {};\n+struct Z { Z(int); };\n+struct Z2 { Z2(int) noexcept; };\n+static_assert (is_convertible_type (^^bool, ^^int));\n+static_assert (is_convertible_type (^^int, ^^double));\n+static_assert (!is_convertible_type (^^int, ^^X));\n+static_assert (is_convertible_type (^^int, ^^Z));\n+static_assert (!is_convertible_type (^^Z, ^^int));\n+\n+static_assert (is_nothrow_convertible_type (^^bool, ^^int));\n+static_assert (is_nothrow_convertible_type (^^int, ^^double));\n+static_assert (!is_nothrow_convertible_type (^^int, ^^X));\n+static_assert (!is_nothrow_convertible_type (^^int, ^^Z));\n+static_assert (!is_nothrow_convertible_type (^^Z, ^^int));\n+static_assert (is_nothrow_convertible_type (^^int, ^^Z2));\n+static_assert (!is_nothrow_convertible_type (^^Z2, ^^int));\n+\n+static_assert (is_layout_compatible_type (^^void, ^^void));\n+static_assert (is_layout_compatible_type (^^int, ^^int));\n+static_assert (!is_layout_compatible_type (^^int, ^^int[]));\n+static_assert (!is_layout_compatible_type (^^int, ^^int[1]));\n+static_assert (is_layout_compatible_type (^^int[], ^^int[]));\n+static_assert (is_layout_compatible_type (^^int[1], ^^int[1]));\n+static_assert (!is_layout_compatible_type (^^int[1], ^^int[]));\n+static_assert (!is_layout_compatible_type (^^int[1], ^^int[2]));\n+static_assert (is_layout_compatible_type (^^incomplete[], ^^incomplete[]));\n+\n+namespace LC {\n+ enum E1 : int { };\n+ enum E2 : int;\n+ static_assert (is_layout_compatible_type (^^E1, ^^E2));\n+ enum E3 : unsigned int;\n+ static_assert (!is_layout_compatible_type (^^E1, ^^E3));\n+ enum E4 : char { };\n+ enum E5 : signed char { };\n+ enum E6 : unsigned char { };\n+ static_assert (!is_layout_compatible_type (^^E4, ^^E5));\n+ static_assert (!is_layout_compatible_type (^^E4, ^^E6));\n+ static_assert (!is_layout_compatible_type (^^E5, ^^E6));\n+ struct A { int a; };\n+ struct B { const int b; };\n+ static_assert (is_layout_compatible_type (^^A, ^^B));\n+ static_assert (is_layout_compatible_type (^^B, ^^A));\n+ struct C : A { };\n+ struct D : B { };\n+ static_assert (is_layout_compatible_type (^^C, ^^D));\n+ struct E : A { int i; };\n+ static_assert (!is_layout_compatible_type (^^E, ^^A));\n+}\n+\n+namespace PI {\n+ struct B { };\n+ static_assert (is_pointer_interconvertible_base_of_type (^^B, ^^B));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^B, ^^const B));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^const B, ^^B));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^const B, ^^const B));\n+ struct D : B { int i; };\n+ static_assert (is_pointer_interconvertible_base_of_type (^^D, ^^D));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^B, ^^D));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^const B, ^^D));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^B, ^^const D));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^const B, ^^const D));\n+ static_assert (!is_pointer_interconvertible_base_of_type (^^D, ^^B));\n+ struct E : D { };\n+ static_assert (!is_pointer_interconvertible_base_of_type (^^E, ^^B));\n+ struct D1 : B { };\n+ struct D2 : B { };\n+ struct D3 : D1, D2 { };\n+ static_assert (!is_pointer_interconvertible_base_of_type (^^B, ^^D3));\n+ union U;\n+ static_assert (!is_pointer_interconvertible_base_of_type (^^U, ^^U));\n+ static_assert (!is_pointer_interconvertible_base_of_type (^^U, ^^D));\n+ struct I;\n+ static_assert (is_pointer_interconvertible_base_of_type (^^I, ^^I));\n+ static_assert (is_pointer_interconvertible_base_of_type (^^I, ^^const I));\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/type_trait1.C b/gcc/testsuite/g++.dg/reflect/type_trait1.C\nnew file mode 100644\nindex 00000000000..e70fa1fc2ea\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type_trait1.C\n@@ -0,0 +1,654 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflection type traits [meta.reflection.traits].\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+struct cls {\n+ using type = int;\n+ void mem_fun ();\n+ static void static_mem_fun ();\n+};\n+struct empty { };\n+using alias = cls;\n+struct derived : cls { };\n+union onion {\n+ onion &operator=(const cls&);\n+ onion &operator=(cls&&);\n+};\n+enum class Enum : short {};\n+enum class Enum_class { A };\n+class abstract_cls { virtual void fn() = 0; };\n+class final_cls final {};\n+struct ctor_cls {\n+ ctor_cls (int, bool) noexcept {}\n+};\n+struct trivial_cls {\n+ int i;\n+ bool b;\n+};\n+class virtual_dtor_cls {\n+ virtual ~virtual_dtor_cls () {}\n+};\n+int fun (bool, char) noexcept { return 0; }\n+\n+static_assert (!is_function_type (^^void));\n+static_assert (!is_function_type (^^int));\n+static_assert (!is_function_type (^^const int));\n+static_assert (!is_function_type (^^volatile int));\n+static_assert (!is_function_type (^^unsigned));\n+static_assert (!is_function_type (^^float));\n+static_assert (!is_function_type (^^int&));\n+static_assert (!is_function_type (^^int&&));\n+static_assert (!is_function_type (^^int *));\n+static_assert (!is_function_type (^^int[1]));\n+static_assert (!is_function_type (^^int[]));\n+static_assert (!is_function_type (^^nullptr_t));\n+static_assert (!is_function_type (^^std::meta::info));\n+static_assert (!is_function_type (^^int (cls::*)));\n+static_assert (!is_function_type (^^int (cls::*)()));\n+static_assert (!is_function_type (^^cls));\n+static_assert (is_function_type (type_of (^^cls::mem_fun)));\n+static_assert (is_function_type (type_of (^^cls::static_mem_fun)));\n+static_assert (!is_function_type (^^empty));\n+static_assert (!is_function_type (^^abstract_cls));\n+static_assert (!is_function_type (^^final_cls));\n+static_assert (!is_function_type (^^ctor_cls));\n+static_assert (!is_function_type (^^trivial_cls));\n+static_assert (!is_function_type (^^virtual_dtor_cls));\n+static_assert (!is_function_type (^^onion));\n+static_assert (!is_function_type (^^Enum));\n+static_assert (!is_function_type (^^Enum_class));\n+static_assert (is_function_type (^^void ()));\n+\n+static_assert (is_void_type (^^void));\n+static_assert (is_void_type (^^const void));\n+static_assert (is_void_type (^^volatile void));\n+static_assert (!is_void_type (^^void *));\n+static_assert (!is_void_type (^^int));\n+static_assert (!is_void_type (^^const int));\n+static_assert (!is_void_type (^^volatile int));\n+static_assert (!is_void_type (^^unsigned));\n+static_assert (!is_void_type (^^float));\n+static_assert (!is_void_type (^^int&));\n+static_assert (!is_void_type (^^int&&));\n+static_assert (!is_void_type (^^int *));\n+static_assert (!is_void_type (^^int[1]));\n+static_assert (!is_void_type (^^int[]));\n+static_assert (!is_void_type (^^nullptr_t));\n+static_assert (!is_void_type (^^std::meta::info));\n+static_assert (!is_void_type (^^int (cls::*)));\n+static_assert (!is_void_type (^^int (cls::*)()));\n+static_assert (!is_void_type (^^cls));\n+static_assert (!is_void_type (^^empty));\n+static_assert (!is_void_type (^^abstract_cls));\n+static_assert (!is_void_type (^^final_cls));\n+static_assert (!is_void_type (^^ctor_cls));\n+static_assert (!is_void_type (^^trivial_cls));\n+static_assert (!is_void_type (^^virtual_dtor_cls));\n+static_assert (!is_void_type (^^onion));\n+static_assert (!is_void_type (^^Enum));\n+static_assert (!is_void_type (^^Enum_class));\n+static_assert (!is_void_type (^^void ()));\n+\n+static_assert (!is_null_pointer_type (^^void));\n+static_assert (!is_null_pointer_type (^^int));\n+static_assert (!is_null_pointer_type (^^const int));\n+static_assert (!is_null_pointer_type (^^volatile int));\n+static_assert (!is_null_pointer_type (^^unsigned));\n+static_assert (!is_null_pointer_type (^^float));\n+static_assert (!is_null_pointer_type (^^int&));\n+static_assert (!is_null_pointer_type (^^int&&));\n+static_assert (!is_null_pointer_type (^^int *));\n+static_assert (!is_null_pointer_type (^^int[1]));\n+static_assert (!is_null_pointer_type (^^int[]));\n+static_assert (is_null_pointer_type (^^nullptr_t));\n+static_assert (!is_null_pointer_type (^^std::meta::info));\n+static_assert (!is_null_pointer_type (^^int (cls::*)));\n+static_assert (!is_null_pointer_type (^^int (cls::*)()));\n+static_assert (!is_null_pointer_type (^^cls));\n+static_assert (!is_null_pointer_type (^^empty));\n+static_assert (!is_null_pointer_type (^^abstract_cls));\n+static_assert (!is_null_pointer_type (^^final_cls));\n+static_assert (!is_null_pointer_type (^^ctor_cls));\n+static_assert (!is_null_pointer_type (^^trivial_cls));\n+static_assert (!is_null_pointer_type (^^virtual_dtor_cls));\n+static_assert (!is_null_pointer_type (^^onion));\n+static_assert (!is_null_pointer_type (^^Enum));\n+static_assert (!is_null_pointer_type (^^Enum_class));\n+static_assert (!is_null_pointer_type (^^void ()));\n+\n+static_assert (!is_integral_type (^^void));\n+static_assert (is_integral_type (^^bool));\n+static_assert (is_integral_type (^^wchar_t));\n+static_assert (is_integral_type (^^char8_t));\n+static_assert (is_integral_type (^^char16_t));\n+static_assert (is_integral_type (^^char32_t));\n+static_assert (is_integral_type (^^int));\n+static_assert (is_integral_type (^^const int));\n+static_assert (is_integral_type (^^volatile int));\n+static_assert (is_integral_type (^^unsigned));\n+static_assert (!is_integral_type (^^float));\n+static_assert (!is_integral_type (^^int&));\n+static_assert (!is_integral_type (^^int&&));\n+static_assert (!is_integral_type (^^int *));\n+static_assert (!is_integral_type (^^int[1]));\n+static_assert (!is_integral_type (^^int[]));\n+static_assert (!is_integral_type (^^nullptr_t));\n+static_assert (!is_integral_type (^^std::meta::info));\n+static_assert (!is_integral_type (^^int (cls::*)));\n+static_assert (!is_integral_type (^^int (cls::*)()));\n+static_assert (!is_integral_type (^^cls));\n+static_assert (!is_integral_type (^^empty));\n+static_assert (!is_integral_type (^^abstract_cls));\n+static_assert (!is_integral_type (^^final_cls));\n+static_assert (!is_integral_type (^^ctor_cls));\n+static_assert (!is_integral_type (^^trivial_cls));\n+static_assert (!is_integral_type (^^virtual_dtor_cls));\n+static_assert (!is_integral_type (^^onion));\n+static_assert (!is_integral_type (^^Enum));\n+static_assert (!is_integral_type (^^Enum_class));\n+static_assert (!is_integral_type (^^void ()));\n+\n+static_assert (!is_floating_point_type (^^void));\n+static_assert (!is_floating_point_type (^^int));\n+static_assert (!is_floating_point_type (^^const int));\n+static_assert (!is_floating_point_type (^^volatile int));\n+static_assert (!is_floating_point_type (^^unsigned));\n+static_assert (is_floating_point_type (^^float));\n+static_assert (is_floating_point_type (^^double));\n+static_assert (is_floating_point_type (^^const double));\n+static_assert (!is_floating_point_type (^^int&));\n+static_assert (!is_floating_point_type (^^int&&));\n+static_assert (!is_floating_point_type (^^int *));\n+static_assert (!is_floating_point_type (^^int[1]));\n+static_assert (!is_floating_point_type (^^int[]));\n+static_assert (!is_floating_point_type (^^nullptr_t));\n+static_assert (!is_floating_point_type (^^std::meta::info));\n+static_assert (!is_floating_point_type (^^int (cls::*)));\n+static_assert (!is_floating_point_type (^^int (cls::*)()));\n+static_assert (!is_floating_point_type (^^cls));\n+static_assert (!is_floating_point_type (^^empty));\n+static_assert (!is_floating_point_type (^^abstract_cls));\n+static_assert (!is_floating_point_type (^^final_cls));\n+static_assert (!is_floating_point_type (^^ctor_cls));\n+static_assert (!is_floating_point_type (^^trivial_cls));\n+static_assert (!is_floating_point_type (^^virtual_dtor_cls));\n+static_assert (!is_floating_point_type (^^onion));\n+static_assert (!is_floating_point_type (^^Enum));\n+static_assert (!is_floating_point_type (^^Enum_class));\n+static_assert (!is_floating_point_type (^^void ()));\n+\n+static_assert (!is_array_type (^^void));\n+static_assert (!is_array_type (^^int));\n+static_assert (!is_array_type (^^const int));\n+static_assert (!is_array_type (^^volatile int));\n+static_assert (!is_array_type (^^unsigned));\n+static_assert (!is_array_type (^^float));\n+static_assert (!is_array_type (^^int&));\n+static_assert (!is_array_type (^^int&&));\n+static_assert (!is_array_type (^^int *));\n+static_assert (is_array_type (^^int[1]));\n+static_assert (is_array_type (^^int[]));\n+static_assert (!is_array_type (^^nullptr_t));\n+static_assert (!is_array_type (^^std::meta::info));\n+static_assert (!is_array_type (^^int (cls::*)));\n+static_assert (!is_array_type (^^int (cls::*)()));\n+static_assert (!is_array_type (^^cls));\n+static_assert (!is_array_type (^^empty));\n+static_assert (!is_array_type (^^abstract_cls));\n+static_assert (!is_array_type (^^final_cls));\n+static_assert (!is_array_type (^^ctor_cls));\n+static_assert (!is_array_type (^^trivial_cls));\n+static_assert (!is_array_type (^^virtual_dtor_cls));\n+static_assert (!is_array_type (^^onion));\n+static_assert (!is_array_type (^^Enum));\n+static_assert (!is_array_type (^^Enum_class));\n+static_assert (!is_array_type (^^void ()));\n+\n+static_assert (!is_pointer_type (^^void));\n+static_assert (!is_pointer_type (^^int));\n+static_assert (!is_pointer_type (^^const int));\n+static_assert (!is_pointer_type (^^volatile int));\n+static_assert (!is_pointer_type (^^unsigned));\n+static_assert (!is_pointer_type (^^float));\n+static_assert (!is_pointer_type (^^int&));\n+static_assert (!is_pointer_type (^^int&&));\n+static_assert (is_pointer_type (^^int *));\n+static_assert (is_pointer_type (^^int **));\n+static_assert (is_pointer_type (^^int *const *const));\n+static_assert (!is_pointer_type (^^int[1]));\n+static_assert (!is_pointer_type (^^int[]));\n+static_assert (!is_pointer_type (^^nullptr_t));\n+static_assert (!is_pointer_type (^^std::meta::info));\n+static_assert (!is_pointer_type (^^int (cls::*)));\n+static_assert (!is_pointer_type (^^int (cls::*)()));\n+static_assert (!is_pointer_type (^^cls));\n+static_assert (!is_pointer_type (^^empty));\n+static_assert (!is_pointer_type (^^abstract_cls));\n+static_assert (!is_pointer_type (^^final_cls));\n+static_assert (!is_pointer_type (^^ctor_cls));\n+static_assert (!is_pointer_type (^^trivial_cls));\n+static_assert (!is_pointer_type (^^virtual_dtor_cls));\n+static_assert (!is_pointer_type (^^onion));\n+static_assert (!is_pointer_type (^^Enum));\n+static_assert (!is_pointer_type (^^Enum_class));\n+static_assert (!is_pointer_type (^^void ()));\n+\n+static_assert (!is_lvalue_reference_type (^^void));\n+static_assert (!is_lvalue_reference_type (^^int));\n+static_assert (!is_lvalue_reference_type (^^const int));\n+static_assert (!is_lvalue_reference_type (^^volatile int));\n+static_assert (!is_lvalue_reference_type (^^unsigned));\n+static_assert (!is_lvalue_reference_type (^^float));\n+static_assert (is_lvalue_reference_type (^^int&));\n+static_assert (!is_lvalue_reference_type (^^int&&));\n+static_assert (!is_lvalue_reference_type (^^int *));\n+static_assert (!is_lvalue_reference_type (^^int[1]));\n+static_assert (!is_lvalue_reference_type (^^int[]));\n+static_assert (!is_lvalue_reference_type (^^nullptr_t));\n+static_assert (!is_lvalue_reference_type (^^std::meta::info));\n+static_assert (!is_lvalue_reference_type (^^int (cls::*)));\n+static_assert (!is_lvalue_reference_type (^^int (cls::*)()));\n+static_assert (!is_lvalue_reference_type (^^cls));\n+static_assert (!is_lvalue_reference_type (^^empty));\n+static_assert (!is_lvalue_reference_type (^^abstract_cls));\n+static_assert (!is_lvalue_reference_type (^^final_cls));\n+static_assert (!is_lvalue_reference_type (^^ctor_cls));\n+static_assert (!is_lvalue_reference_type (^^trivial_cls));\n+static_assert (!is_lvalue_reference_type (^^virtual_dtor_cls));\n+static_assert (!is_lvalue_reference_type (^^onion));\n+static_assert (!is_lvalue_reference_type (^^Enum));\n+static_assert (!is_lvalue_reference_type (^^Enum_class));\n+static_assert (!is_lvalue_reference_type (^^void ()));\n+\n+static_assert (!is_rvalue_reference_type (^^void));\n+static_assert (!is_rvalue_reference_type (^^int));\n+static_assert (!is_rvalue_reference_type (^^const int));\n+static_assert (!is_rvalue_reference_type (^^volatile int));\n+static_assert (!is_rvalue_reference_type (^^unsigned));\n+static_assert (!is_rvalue_reference_type (^^float));\n+static_assert (!is_rvalue_reference_type (^^int&));\n+static_assert (is_rvalue_reference_type (^^int&&));\n+static_assert (!is_rvalue_reference_type (^^int *));\n+static_assert (!is_rvalue_reference_type (^^int[1]));\n+static_assert (!is_rvalue_reference_type (^^int[]));\n+static_assert (!is_rvalue_reference_type (^^nullptr_t));\n+static_assert (!is_rvalue_reference_type (^^std::meta::info));\n+static_assert (!is_rvalue_reference_type (^^int (cls::*)));\n+static_assert (!is_rvalue_reference_type (^^int (cls::*)()));\n+static_assert (!is_rvalue_reference_type (^^cls));\n+static_assert (!is_rvalue_reference_type (^^empty));\n+static_assert (!is_rvalue_reference_type (^^abstract_cls));\n+static_assert (!is_rvalue_reference_type (^^final_cls));\n+static_assert (!is_rvalue_reference_type (^^ctor_cls));\n+static_assert (!is_rvalue_reference_type (^^trivial_cls));\n+static_assert (!is_rvalue_reference_type (^^virtual_dtor_cls));\n+static_assert (!is_rvalue_reference_type (^^onion));\n+static_assert (!is_rvalue_reference_type (^^Enum));\n+static_assert (!is_rvalue_reference_type (^^Enum_class));\n+static_assert (!is_rvalue_reference_type (^^void ()));\n+\n+static_assert (!is_member_object_pointer_type (^^void));\n+static_assert (!is_member_object_pointer_type (^^int));\n+static_assert (!is_member_object_pointer_type (^^const int));\n+static_assert (!is_member_object_pointer_type (^^volatile int));\n+static_assert (!is_member_object_pointer_type (^^unsigned));\n+static_assert (!is_member_object_pointer_type (^^float));\n+static_assert (!is_member_object_pointer_type (^^int&));\n+static_assert (!is_member_object_pointer_type (^^int&&));\n+static_assert (!is_member_object_pointer_type (^^int *));\n+static_assert (!is_member_object_pointer_type (^^int[1]));\n+static_assert (!is_member_object_pointer_type (^^int[]));\n+static_assert (!is_member_object_pointer_type (^^nullptr_t));\n+static_assert (!is_member_object_pointer_type (^^std::meta::info));\n+static_assert (is_member_object_pointer_type (^^int (cls::*)));\n+static_assert (!is_member_object_pointer_type (^^int (cls::*)()));\n+static_assert (!is_member_object_pointer_type (^^cls));\n+static_assert (!is_member_object_pointer_type (^^empty));\n+static_assert (!is_member_object_pointer_type (^^abstract_cls));\n+static_assert (!is_member_object_pointer_type (^^final_cls));\n+static_assert (!is_member_object_pointer_type (^^ctor_cls));\n+static_assert (!is_member_object_pointer_type (^^trivial_cls));\n+static_assert (!is_member_object_pointer_type (^^virtual_dtor_cls));\n+static_assert (!is_member_object_pointer_type (^^onion));\n+static_assert (!is_member_object_pointer_type (^^Enum));\n+static_assert (!is_member_object_pointer_type (^^Enum_class));\n+static_assert (!is_member_object_pointer_type (^^void ()));\n+\n+static_assert (!is_member_function_pointer_type (^^void));\n+static_assert (!is_member_function_pointer_type (^^int));\n+static_assert (!is_member_function_pointer_type (^^const int));\n+static_assert (!is_member_function_pointer_type (^^volatile int));\n+static_assert (!is_member_function_pointer_type (^^unsigned));\n+static_assert (!is_member_function_pointer_type (^^float));\n+static_assert (!is_member_function_pointer_type (^^int&));\n+static_assert (!is_member_function_pointer_type (^^int&&));\n+static_assert (!is_member_function_pointer_type (^^int *));\n+static_assert (!is_member_function_pointer_type (^^int[1]));\n+static_assert (!is_member_function_pointer_type (^^int[]));\n+static_assert (!is_member_function_pointer_type (^^nullptr_t));\n+static_assert (!is_member_function_pointer_type (^^std::meta::info));\n+static_assert (!is_member_function_pointer_type (^^int (cls::*)));\n+static_assert (is_member_function_pointer_type (^^int (cls::*)()));\n+static_assert (!is_member_function_pointer_type (^^cls));\n+static_assert (!is_member_function_pointer_type (^^empty));\n+static_assert (!is_member_function_pointer_type (^^abstract_cls));\n+static_assert (!is_member_function_pointer_type (^^final_cls));\n+static_assert (!is_member_function_pointer_type (^^ctor_cls));\n+static_assert (!is_member_function_pointer_type (^^trivial_cls));\n+static_assert (!is_member_function_pointer_type (^^virtual_dtor_cls));\n+static_assert (!is_member_function_pointer_type (^^onion));\n+static_assert (!is_member_function_pointer_type (^^Enum));\n+static_assert (!is_member_function_pointer_type (^^Enum_class));\n+static_assert (!is_member_function_pointer_type (^^void ()));\n+\n+static_assert (!is_enum_type (^^void));\n+static_assert (!is_enum_type (^^int));\n+static_assert (!is_enum_type (^^const int));\n+static_assert (!is_enum_type (^^volatile int));\n+static_assert (!is_enum_type (^^unsigned));\n+static_assert (!is_enum_type (^^float));\n+static_assert (!is_enum_type (^^int&));\n+static_assert (!is_enum_type (^^int&&));\n+static_assert (!is_enum_type (^^int *));\n+static_assert (!is_enum_type (^^int[1]));\n+static_assert (!is_enum_type (^^int[]));\n+static_assert (!is_enum_type (^^nullptr_t));\n+static_assert (!is_enum_type (^^std::meta::info));\n+static_assert (!is_enum_type (^^int (cls::*)));\n+static_assert (!is_enum_type (^^int (cls::*)()));\n+static_assert (!is_enum_type (^^cls));\n+static_assert (!is_enum_type (^^empty));\n+static_assert (!is_enum_type (^^abstract_cls));\n+static_assert (!is_enum_type (^^final_cls));\n+static_assert (!is_enum_type (^^ctor_cls));\n+static_assert (!is_enum_type (^^trivial_cls));\n+static_assert (!is_enum_type (^^virtual_dtor_cls));\n+static_assert (!is_enum_type (^^onion));\n+static_assert (is_enum_type (^^Enum));\n+static_assert (is_enum_type (^^Enum_class));\n+static_assert (!is_enum_type (^^void ()));\n+\n+static_assert (!is_union_type (^^void));\n+static_assert (!is_union_type (^^int));\n+static_assert (!is_union_type (^^const int));\n+static_assert (!is_union_type (^^volatile int));\n+static_assert (!is_union_type (^^unsigned));\n+static_assert (!is_union_type (^^float));\n+static_assert (!is_union_type (^^int&));\n+static_assert (!is_union_type (^^int&&));\n+static_assert (!is_union_type (^^int *));\n+static_assert (!is_union_type (^^int[1]));\n+static_assert (!is_union_type (^^int[]));\n+static_assert (!is_union_type (^^nullptr_t));\n+static_assert (!is_union_type (^^std::meta::info));\n+static_assert (!is_union_type (^^int (cls::*)));\n+static_assert (!is_union_type (^^int (cls::*)()));\n+static_assert (!is_union_type (^^cls));\n+static_assert (!is_union_type (^^empty));\n+static_assert (!is_union_type (^^abstract_cls));\n+static_assert (!is_union_type (^^final_cls));\n+static_assert (!is_union_type (^^ctor_cls));\n+static_assert (!is_union_type (^^trivial_cls));\n+static_assert (!is_union_type (^^virtual_dtor_cls));\n+static_assert (is_union_type (^^onion));\n+static_assert (!is_union_type (^^Enum));\n+static_assert (!is_union_type (^^Enum_class));\n+static_assert (!is_union_type (^^void ()));\n+\n+static_assert (!is_class_type (^^void));\n+static_assert (!is_class_type (^^int));\n+static_assert (!is_class_type (^^const int));\n+static_assert (!is_class_type (^^volatile int));\n+static_assert (!is_class_type (^^unsigned));\n+static_assert (!is_class_type (^^float));\n+static_assert (!is_class_type (^^int&));\n+static_assert (!is_class_type (^^int&&));\n+static_assert (!is_class_type (^^int *));\n+static_assert (!is_class_type (^^int[1]));\n+static_assert (!is_class_type (^^int[]));\n+static_assert (!is_class_type (^^nullptr_t));\n+static_assert (!is_class_type (^^std::meta::info));\n+static_assert (!is_class_type (^^int (cls::*)));\n+static_assert (!is_class_type (^^int (cls::*)()));\n+static_assert (is_class_type (^^cls));\n+static_assert (is_class_type (^^empty));\n+static_assert (is_class_type (^^abstract_cls));\n+static_assert (is_class_type (^^final_cls));\n+static_assert (is_class_type (^^ctor_cls));\n+static_assert (is_class_type (^^trivial_cls));\n+static_assert (is_class_type (^^virtual_dtor_cls));\n+static_assert (!is_class_type (^^onion));\n+static_assert (!is_class_type (^^Enum));\n+static_assert (!is_class_type (^^Enum_class));\n+static_assert (!is_class_type (^^void ()));\n+\n+static_assert (!is_reflection_type (^^void));\n+static_assert (!is_reflection_type (^^int));\n+static_assert (!is_reflection_type (^^const int));\n+static_assert (!is_reflection_type (^^volatile int));\n+static_assert (!is_reflection_type (^^unsigned));\n+static_assert (!is_reflection_type (^^float));\n+static_assert (!is_reflection_type (^^int&));\n+static_assert (!is_reflection_type (^^int&&));\n+static_assert (!is_reflection_type (^^int *));\n+static_assert (!is_reflection_type (^^int[1]));\n+static_assert (!is_reflection_type (^^int[]));\n+static_assert (!is_reflection_type (^^nullptr_t));\n+static_assert (is_reflection_type (^^std::meta::info));\n+static_assert (!is_reflection_type (^^int (cls::*)));\n+static_assert (!is_reflection_type (^^int (cls::*)()));\n+static_assert (!is_reflection_type (^^cls));\n+static_assert (!is_reflection_type (^^empty));\n+static_assert (!is_reflection_type (^^abstract_cls));\n+static_assert (!is_reflection_type (^^final_cls));\n+static_assert (!is_reflection_type (^^ctor_cls));\n+static_assert (!is_reflection_type (^^trivial_cls));\n+static_assert (!is_reflection_type (^^virtual_dtor_cls));\n+static_assert (!is_reflection_type (^^onion));\n+static_assert (!is_reflection_type (^^Enum));\n+static_assert (!is_reflection_type (^^Enum_class));\n+static_assert (!is_reflection_type (^^void ()));\n+\n+static_assert (!is_reference_type (^^void));\n+static_assert (!is_reference_type (^^int));\n+static_assert (!is_reference_type (^^const int));\n+static_assert (!is_reference_type (^^volatile int));\n+static_assert (!is_reference_type (^^unsigned));\n+static_assert (!is_reference_type (^^float));\n+static_assert (is_reference_type (^^int&));\n+static_assert (is_reference_type (^^int&&));\n+static_assert (!is_reference_type (^^int *));\n+static_assert (!is_reference_type (^^int[1]));\n+static_assert (!is_reference_type (^^int[]));\n+static_assert (!is_reference_type (^^nullptr_t));\n+static_assert (!is_reference_type (^^std::meta::info));\n+static_assert (!is_reference_type (^^int (cls::*)));\n+static_assert (!is_reference_type (^^int (cls::*)()));\n+static_assert (!is_reference_type (^^cls));\n+static_assert (!is_reference_type (^^empty));\n+static_assert (!is_reference_type (^^abstract_cls));\n+static_assert (!is_reference_type (^^final_cls));\n+static_assert (!is_reference_type (^^ctor_cls));\n+static_assert (!is_reference_type (^^trivial_cls));\n+static_assert (!is_reference_type (^^virtual_dtor_cls));\n+static_assert (!is_reference_type (^^onion));\n+static_assert (!is_reference_type (^^Enum));\n+static_assert (!is_reference_type (^^Enum_class));\n+static_assert (!is_reference_type (^^void ()));\n+\n+static_assert (!is_arithmetic_type (^^void));\n+static_assert (is_arithmetic_type (^^bool));\n+static_assert (is_arithmetic_type (^^char));\n+static_assert (is_arithmetic_type (^^int));\n+static_assert (is_arithmetic_type (^^const int));\n+static_assert (is_arithmetic_type (^^volatile int));\n+static_assert (is_arithmetic_type (^^float));\n+static_assert (!is_arithmetic_type (^^cls));\n+static_assert (!is_arithmetic_type (^^int&));\n+static_assert (!is_arithmetic_type (^^int&&));\n+static_assert (!is_arithmetic_type (^^int *));\n+static_assert (!is_arithmetic_type (^^int [1]));\n+static_assert (!is_arithmetic_type (^^int []));\n+static_assert (!is_arithmetic_type (^^nullptr_t));\n+static_assert (!is_arithmetic_type (^^std::meta::info));\n+static_assert (!is_arithmetic_type (^^int (cls::*)));\n+static_assert (!is_arithmetic_type (^^int (cls::*)()));\n+static_assert (!is_arithmetic_type (^^cls));\n+static_assert (!is_arithmetic_type (^^empty));\n+static_assert (!is_arithmetic_type (^^abstract_cls));\n+static_assert (!is_arithmetic_type (^^final_cls));\n+static_assert (!is_arithmetic_type (^^ctor_cls));\n+static_assert (!is_arithmetic_type (^^trivial_cls));\n+static_assert (!is_arithmetic_type (^^virtual_dtor_cls));\n+static_assert (!is_arithmetic_type (^^onion));\n+static_assert (!is_arithmetic_type (^^Enum));\n+static_assert (!is_arithmetic_type (^^Enum_class));\n+static_assert (!is_arithmetic_type (^^void ()));\n+\n+static_assert (!is_object_type (^^void));\n+static_assert (is_object_type (^^bool));\n+static_assert (is_object_type (^^char));\n+static_assert (is_object_type (^^int));\n+static_assert (is_object_type (^^const int));\n+static_assert (is_object_type (^^volatile int));\n+static_assert (is_object_type (^^float));\n+static_assert (is_object_type (^^cls));\n+static_assert (!is_object_type (^^int&));\n+static_assert (!is_object_type (^^int&&));\n+static_assert (is_object_type (^^int *));\n+static_assert (is_object_type (^^int [1]));\n+static_assert (is_object_type (^^int []));\n+static_assert (is_object_type (^^nullptr_t));\n+static_assert (is_object_type (^^std::meta::info));\n+static_assert (is_object_type (^^int (cls::*)));\n+static_assert (is_object_type (^^int (cls::*)()));\n+static_assert (is_object_type (^^cls));\n+static_assert (is_object_type (^^empty));\n+static_assert (is_object_type (^^abstract_cls));\n+static_assert (is_object_type (^^final_cls));\n+static_assert (is_object_type (^^ctor_cls));\n+static_assert (is_object_type (^^trivial_cls));\n+static_assert (is_object_type (^^virtual_dtor_cls));\n+static_assert (is_object_type (^^onion));\n+static_assert (is_object_type (^^Enum));\n+static_assert (is_object_type (^^Enum_class));\n+static_assert (!is_object_type (^^void ()));\n+\n+static_assert (!is_member_pointer_type (^^void));\n+static_assert (!is_member_pointer_type (^^bool));\n+static_assert (!is_member_pointer_type (^^char));\n+static_assert (!is_member_pointer_type (^^int));\n+static_assert (!is_member_pointer_type (^^const int));\n+static_assert (!is_member_pointer_type (^^volatile int));\n+static_assert (!is_member_pointer_type (^^float));\n+static_assert (!is_member_pointer_type (^^cls));\n+static_assert (!is_member_pointer_type (^^int&));\n+static_assert (!is_member_pointer_type (^^int&&));\n+static_assert (!is_member_pointer_type (^^int *));\n+static_assert (!is_member_pointer_type (^^int [1]));\n+static_assert (!is_member_pointer_type (^^int []));\n+static_assert (!is_member_pointer_type (^^nullptr_t));\n+static_assert (!is_member_pointer_type (^^std::meta::info));\n+static_assert (is_member_pointer_type (^^int (cls::*)));\n+static_assert (is_member_pointer_type (^^int (cls::*)()));\n+static_assert (!is_member_pointer_type (^^cls));\n+static_assert (!is_member_pointer_type (^^empty));\n+static_assert (!is_member_pointer_type (^^abstract_cls));\n+static_assert (!is_member_pointer_type (^^final_cls));\n+static_assert (!is_member_pointer_type (^^ctor_cls));\n+static_assert (!is_member_pointer_type (^^trivial_cls));\n+static_assert (!is_member_pointer_type (^^virtual_dtor_cls));\n+static_assert (!is_member_pointer_type (^^onion));\n+static_assert (!is_member_pointer_type (^^Enum));\n+static_assert (!is_member_pointer_type (^^Enum_class));\n+static_assert (!is_member_pointer_type (^^void ()));\n+\n+static_assert (!is_scalar_type (^^void));\n+static_assert (is_scalar_type (^^bool));\n+static_assert (is_scalar_type (^^char));\n+static_assert (is_scalar_type (^^int));\n+static_assert (is_scalar_type (^^const int));\n+static_assert (is_scalar_type (^^volatile int));\n+static_assert (is_scalar_type (^^float));\n+static_assert (!is_scalar_type (^^cls));\n+static_assert (!is_scalar_type (^^int&));\n+static_assert (!is_scalar_type (^^int&&));\n+static_assert (is_scalar_type (^^int *));\n+static_assert (!is_scalar_type (^^int [1]));\n+static_assert (!is_scalar_type (^^int []));\n+static_assert (is_scalar_type (^^nullptr_t));\n+static_assert (is_scalar_type (^^std::meta::info));\n+static_assert (is_scalar_type (^^int (cls::*)));\n+static_assert (is_scalar_type (^^int (cls::*)()));\n+static_assert (!is_scalar_type (^^cls));\n+static_assert (!is_scalar_type (^^empty));\n+static_assert (!is_scalar_type (^^abstract_cls));\n+static_assert (!is_scalar_type (^^final_cls));\n+static_assert (!is_scalar_type (^^ctor_cls));\n+static_assert (!is_scalar_type (^^trivial_cls));\n+static_assert (!is_scalar_type (^^virtual_dtor_cls));\n+static_assert (!is_scalar_type (^^onion));\n+static_assert (is_scalar_type (^^Enum));\n+static_assert (is_scalar_type (^^Enum_class));\n+static_assert (!is_scalar_type (^^void ()));\n+\n+static_assert (is_fundamental_type (^^void));\n+static_assert (is_fundamental_type (^^bool));\n+static_assert (is_fundamental_type (^^char));\n+static_assert (is_fundamental_type (^^int));\n+static_assert (is_fundamental_type (^^const int));\n+static_assert (is_fundamental_type (^^volatile int));\n+static_assert (is_fundamental_type (^^float));\n+static_assert (!is_fundamental_type (^^cls));\n+static_assert (!is_fundamental_type (^^int&));\n+static_assert (!is_fundamental_type (^^int&&));\n+static_assert (!is_fundamental_type (^^int *));\n+static_assert (!is_fundamental_type (^^int [1]));\n+static_assert (!is_fundamental_type (^^int []));\n+static_assert (is_fundamental_type (^^nullptr_t));\n+static_assert (is_fundamental_type (^^std::meta::info));\n+static_assert (!is_fundamental_type (^^int (cls::*)));\n+static_assert (!is_fundamental_type (^^int (cls::*)()));\n+static_assert (!is_fundamental_type (^^cls));\n+static_assert (!is_fundamental_type (^^empty));\n+static_assert (!is_fundamental_type (^^abstract_cls));\n+static_assert (!is_fundamental_type (^^final_cls));\n+static_assert (!is_fundamental_type (^^ctor_cls));\n+static_assert (!is_fundamental_type (^^trivial_cls));\n+static_assert (!is_fundamental_type (^^virtual_dtor_cls));\n+static_assert (!is_fundamental_type (^^onion));\n+static_assert (!is_fundamental_type (^^Enum));\n+static_assert (!is_fundamental_type (^^Enum_class));\n+static_assert (!is_fundamental_type (^^void ()));\n+\n+static_assert (!is_compound_type (^^void));\n+static_assert (!is_compound_type (^^bool));\n+static_assert (!is_compound_type (^^char));\n+static_assert (!is_compound_type (^^int));\n+static_assert (!is_compound_type (^^const int));\n+static_assert (!is_compound_type (^^volatile int));\n+static_assert (!is_compound_type (^^float));\n+static_assert (is_compound_type (^^cls));\n+static_assert (is_compound_type (^^int&));\n+static_assert (is_compound_type (^^int&&));\n+static_assert (is_compound_type (^^int *));\n+static_assert (is_compound_type (^^int [1]));\n+static_assert (is_compound_type (^^int []));\n+static_assert (!is_compound_type (^^nullptr_t));\n+static_assert (!is_compound_type (^^std::meta::info));\n+static_assert (is_compound_type (^^int (cls::*)));\n+static_assert (is_compound_type (^^int (cls::*)()));\n+static_assert (is_compound_type (^^cls));\n+static_assert (is_compound_type (^^empty));\n+static_assert (is_compound_type (^^abstract_cls));\n+static_assert (is_compound_type (^^final_cls));\n+static_assert (is_compound_type (^^ctor_cls));\n+static_assert (is_compound_type (^^trivial_cls));\n+static_assert (is_compound_type (^^virtual_dtor_cls));\n+static_assert (is_compound_type (^^onion));\n+static_assert (is_compound_type (^^Enum));\n+static_assert (is_compound_type (^^Enum_class));\n+static_assert (is_compound_type (^^void ()));\ndiff --git a/gcc/testsuite/g++.dg/reflect/type_trait10.C b/gcc/testsuite/g++.dg/reflect/type_trait10.C\nnew file mode 100644\nindex 00000000000..896f9b0d0df\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/type_trait10.C\n@@ -0,0 +1,116 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflection type traits [meta.reflection.traits], other\n+// transformations.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+class ClassType { };\n+using CT = ClassType;\n+\n+static_assert (remove_cvref (^^const volatile int) == ^^int);\n+static_assert (remove_cvref (^^const volatile int *) == ^^const volatile int *);\n+static_assert (remove_cvref (^^const volatile int &) == ^^int);\n+static_assert (remove_cvref (^^const volatile int &&) == ^^int);\n+static_assert (remove_cvref (^^const volatile ClassType) == ^^ClassType);\n+static_assert (remove_cvref (^^const volatile ClassType *) == ^^const volatile ClassType *);\n+static_assert (remove_cvref (^^const volatile ClassType &) == ^^ClassType);\n+static_assert (remove_cvref (^^const volatile ClassType &&) == ^^ClassType);\n+static_assert (remove_cvref (^^CT) == ^^ClassType);\n+static_assert (remove_cvref (^^CT &) == ^^ClassType);\n+static_assert (remove_cvref (^^const CT &) == ^^ClassType);\n+static_assert (remove_cvref (^^const int (&) [3]) == ^^int [3]);\n+static_assert (remove_cvref (^^const int (&) ()) == ^^const int ());\n+\n+static_assert (decay (^^bool) == ^^bool);\n+static_assert (decay (^^int) == ^^int);\n+static_assert (decay (^^ClassType) == ^^ClassType);\n+static_assert (decay (^^CT) == ^^ClassType);\n+static_assert (decay (^^const int) == ^^int);\n+static_assert (decay (^^volatile const long) == ^^long);\n+static_assert (decay (^^int &) == ^^int);\n+static_assert (decay (^^int &&) == ^^int);\n+static_assert (decay (^^CT &) == ^^ClassType);\n+static_assert (decay (^^volatile const int &) == ^^int);\n+static_assert (decay (^^const int &&) == ^^int);\n+static_assert (decay (^^int [4]) == ^^int *);\n+static_assert (decay (^^const int []) == ^^const int *);\n+static_assert (decay (^^int [5][2][1]) == ^^int (*)[2][1]);\n+static_assert (decay (^^const int [][5][1]) == ^^const int (*)[5][1]);\n+static_assert (decay (^^int (int)) == ^^int (*) (int));\n+\n+enum E1 : unsigned { };\n+enum E2 : char { };\n+enum class E3 { };\n+enum class E4 : unsigned char { c = 1 };\n+enum class E5 : int { a = -1, b = 1 };\n+enum class E6 : long { c = __LONG_MAX__ };\n+enum E7 { E70 = 0 };\n+enum E8 { E80 = ~0UL };\n+\n+static_assert (underlying_type (^^E1) == ^^unsigned);\n+static_assert (underlying_type (^^E2) == ^^char);\n+static_assert (underlying_type (^^E3) == ^^int);\n+static_assert (underlying_type (^^E4) == ^^unsigned char);\n+static_assert (underlying_type (^^E5) == ^^int);\n+static_assert (underlying_type (^^E6) == ^^long);\n+static_assert (is_integral_type (underlying_type (^^E7)));\n+static_assert (is_integral_type (underlying_type (^^E8)));\n+\n+struct S;\n+struct T;\n+template <typename T>\n+struct U\n+{\n+};\n+typedef int int2;\n+struct V {};\n+namespace\n+{\n+ struct W {};\n+}\n+\n+template <typename T, typename U>\n+struct eq\n+{\n+ constexpr eq ()\n+ {\n+ static_assert (type_order (^^T, ^^U) == std::strong_ordering::equal);\n+ static_assert (type_order (^^U, ^^T) == std::strong_ordering::equal);\n+ }\n+};\n+template <typename T, typename U>\n+struct ne\n+{\n+ constexpr ne ()\n+ {\n+ static_assert (type_order (^^T, ^^U) != std::strong_ordering::equal);\n+ static_assert (type_order (^^U, ^^T) != std::strong_ordering::equal);\n+ static_assert (type_order (^^T, ^^U) == std::strong_ordering::greater\n+ ? type_order (^^U, ^^T) == std::strong_ordering::less\n+ : type_order (^^U, ^^T) == std::strong_ordering::greater);\n+ }\n+};\n+\n+constexpr eq <void, void> a;\n+constexpr eq <const void, const void> b;\n+constexpr eq <int, int> c;\n+constexpr eq <long int, long int> d;\n+constexpr eq <const volatile unsigned, const volatile unsigned> e;\n+constexpr eq <S, S> f;\n+constexpr eq <U <int>, U <int>> g;\n+constexpr eq <unsigned[2], unsigned[2]> h;\n+constexpr eq <int, int2> i;\n+constexpr eq <int (*) (int, long), int (*) (int, long)> j;\n+constexpr ne <int, long> k;\n+constexpr ne <const int, int> l;\n+constexpr ne <S, T> m;\n+constexpr ne <int &, int &&> n;\n+constexpr ne <U <S>, U <T>> o;\n+constexpr ne <U <short>, U <char>> p;\n+constexpr ne <int (*) (int, long), int (*) (int, int)> q;\n+constexpr eq <W, W> r;\n+constexpr ne <V, W> s;\n+constexpr eq <U <W>, U <W>> t;\n+constexpr ne <U <V>, U <W>> u;\n", "prefixes": [ "8/9", "v2" ] }