get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.0/patches/2175272/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2175272,
    "url": "http://patchwork.ozlabs.org/api/1.0/patches/2175272/?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": "<aULeqPSSHcZO6wmU@redhat.com>",
    "date": "2025-12-17T16:47:36",
    "name": "[5/9,v2] c++: C++26 Reflection [PR120775]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "d389e1286bcdee1916b5ec5971afdac12993b27f",
    "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/aULeqPSSHcZO6wmU@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/2175272/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=cSrm8wGD;\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=cSrm8wGD",
            "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.129.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 4dWfxK4xHgz1xpw\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 03:52:53 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id A09834BA2E20\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 17 Dec 2025 16:52:51 +0000 (GMT)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id A1AF34BA2E3E\n for <gcc-patches@gcc.gnu.org>; Wed, 17 Dec 2025 16:47:47 +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-363-oYC8ENIvMcCXpscgWKFpIQ-1; Wed, 17 Dec 2025 11:47:45 -0500",
            "by mail-qk1-f199.google.com with SMTP id\n af79cd13be357-8b2e19c8558so1409030885a.2\n for <gcc-patches@gcc.gnu.org>; Wed, 17 Dec 2025 08:47:45 -0800 (PST)",
            "from redhat.com ([2603:7000:9500:10::1db4])\n by smtp.gmail.com with ESMTPSA id\n af79cd13be357-8be31b53dbasm442076785a.34.2025.12.17.08.47.37\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 17 Dec 2025 08:47:39 -0800 (PST)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org A09834BA2E20",
            "OpenDKIM Filter v2.11.0 sourceware.org A1AF34BA2E3E"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org A1AF34BA2E3E",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org A1AF34BA2E3E",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1765990072; cv=none;\n b=liKcVBAz0/TEIr2tc2/5JEtV9ZNqvHLZVVEV+G1tJPwoLXvxxKIs+GtQpxMdMqFEn+qpAVWOyKMcGPckU6AoBEdH93v7jVXnvVoH24rXAfaja6ZbGTFjmm7TCbOmL5Ff+cDfPrDpOnHhtyr+nUON/0wy50lvmAghrLtEe4ZmMgA=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1765990072; c=relaxed/simple;\n bh=NILS0X5RbSWNYd+F4hfPMPxyF+x14GoQ5mMDpQ+0MqY=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=uwc+S0u0WGOAOJxErM4MPxq90H5vEAuFogsvKbgL9n83jUFS/NOMc3gaC6Sy4CiZCXddl7zr7MAFeAHUs56y0G4m6Ur0S3XumE6Nx/eH8pXSW8EHIC+vd9YBLVNq7l4ZdAvaxptFoOdjUZ0IqkNLhcy3Tcx5yBXTqBpzdQa3lDk=",
        "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=1765990067;\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 content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=0NBJA9MJ/6bMQD0t0RTvvTm6vXsGsozqGfHbqamJZnk=;\n b=cSrm8wGDKMga2ztR3eSqABJdTD5b42X4FazMfuJPmE8V9SsDvpgW8kwVo/odfC68kMvtBR\n 3LskBgJHnTJBaW0Ef22KG1Tm+wQe/wUuOR4xjb1Lsd0yCDSGPvJhlEkAhV7RbzwYZcO1xr\n w4OFhoVD6S9114le7IW5HkJo17jcTow=",
        "X-MC-Unique": "oYC8ENIvMcCXpscgWKFpIQ-1",
        "X-Mimecast-MFC-AGG-ID": "oYC8ENIvMcCXpscgWKFpIQ_1765990064",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1765990064; x=1766594864;\n h=user-agent:in-reply-to:content-transfer-encoding\n :content-disposition:mime-version:references:message-id:subject:to\n :from:date:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=0NBJA9MJ/6bMQD0t0RTvvTm6vXsGsozqGfHbqamJZnk=;\n b=qnSuGOf1zotqCAIP4ivXu/+BTjciRVStyXuXbtgcIDJZAMRMattfvxgqrPYPX869ze\n tlYA1pnYVUwKh5Xvph2vN0SS9GwSyPm+feFu5ZJl0TGfoxrv9YEGedCLkXUKw3FU+5/+\n THXTSR3Mm5mqmnd1SEmsmTWNc+uKKQz7XSx70XpULVoqmZZj6HHIi0ZEgnExRMqW6ZmK\n /EFtg0JHr4a2RkOSZl0ufplMjFePONHmCzN/lq9PifOQgDj1OD2hovySPnan7orpC1kW\n 1B9IVF2hbJmQhRhX1ZtKps9/cel5Ww15aricmF0+gk7Y5kdynFc+3E/qfkKsA0copwFm\n MiYg==",
        "X-Gm-Message-State": "AOJu0YxhnN/xcV/ZoWBh0BU8IcuqICgOc0qbHvMxV+ld7emxpvjU9rOF\n 1Ww7EK+5zh/Nh0fnfT8CjzPpI9V41nw8/VNy5XGyYL+D3RxzHDBnuevAR2wCJy8Dp69Z4h41j57\n llMypy2LfLH4mbvL0D2l5SZdE2xVNg2HGUOa6avBp6t/G3pS6F3o6sdZJYqcaYOA0e/SVdVX/50\n 2ewty27Je3j4bpeWV7qv7WAVKMIegS+Lx2d/0+26Mlrw==",
        "X-Gm-Gg": "AY/fxX5F9xHBcgOipbgNLvzgSorcQ6lVkM3wF9W2Wtd1Y6r8p2Lw757B1uE03GVJbb4\n GgjYr6027yx/DpXvGf+mcxGEKNwCUJ3Aic7kGg5CjP71XvZmu96yqUXqR26oKj3IXvEY8mvvAkL\n VCx9vdGjoXp0REtJr89HoJvFeiI40NAhWuTCpFZyMljIIc/5pJ1OA+H0c4WnFiT+B/N2Aq3y8Zr\n NW98/JUArHsqIpEUDBu19njgzeu/b8mfXQiCQxWoqdb9feDwyrapXqIGye5ehoM+B6VrAYjwgrd\n ayrh/5Rvpy8/1tLa9fDu6ZjMke7OIgiv2BYQ4fEStbi84dJNbJAOPzFkoVkBb2U5ag==",
        "X-Received": [
            "by 2002:a05:620a:7108:b0:8b2:dabe:de32 with SMTP id\n af79cd13be357-8bb3a253d57mr2509800585a.42.1765990062132;\n Wed, 17 Dec 2025 08:47:42 -0800 (PST)",
            "by 2002:a05:620a:7108:b0:8b2:dabe:de32 with SMTP id\n af79cd13be357-8bb3a253d57mr2509784285a.42.1765990060232;\n Wed, 17 Dec 2025 08:47:40 -0800 (PST)"
        ],
        "X-Google-Smtp-Source": "\n AGHT+IEg5N/3mgkIZxco0fxXzf7cetcoaU8w+7aR2yaD7wTohoDi9QbZEO7jqBjtNfbL7qSrEXn32g==",
        "Date": "Wed, 17 Dec 2025 11:47:36 -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 5/9 v2] c++: C++26 Reflection [PR120775]",
        "Message-ID": "<aULeqPSSHcZO6wmU@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": "4zQ_w3jvGwAD5nrSa-dzVoeAxaBXLj1T5mevZNX49uk_1765990064",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Type": "text/plain; charset=utf-8",
        "Content-Disposition": "inline",
        "Content-Transfer-Encoding": "8bit",
        "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 #1.\n\n-- >8 --",
    "diff": "diff --git a/gcc/testsuite/g++.dg/DRs/dr2581-1.C b/gcc/testsuite/g++.dg/DRs/dr2581-1.C\nindex 855c0d8f117..cb761b7378e 100644\n--- a/gcc/testsuite/g++.dg/DRs/dr2581-1.C\n+++ b/gcc/testsuite/g++.dg/DRs/dr2581-1.C\n@@ -1,6 +1,6 @@\n // DR 2581 - Undefined behavior for predefined macros\n // { dg-do preprocess }\n-// { dg-additional-options \"-fcontracts\" { target c++26 } }\n+// { dg-additional-options \"-fcontracts -freflection\" { target c++26 } }\n // { dg-additional-options \"-fmodules -fcoroutines\" { target c++20 } }\n \n #undef defined\t\t\t\t// { dg-error \"'defined' cannot be used as a macro name\" }\n@@ -63,7 +63,7 @@\n #undef __cpp_impl_coroutine\t\t// { dg-warning \"undefining '__cpp_impl_coroutine'\" \"\" { target c++20 } }\n #undef __cpp_impl_destroying_delete\t// { dg-warning \"undefining '__cpp_impl_destroying_delete'\" \"\" { target c++20 } }\n #undef __cpp_impl_three_way_comparison\t// { dg-warning \"undefining '__cpp_impl_three_way_comparison'\" \"\" { target c++20 } }\n-#undef __cpp_impl_reflection\n+#undef __cpp_impl_reflection\t\t// { dg-warning \"undefining '__cpp_impl_reflection'\" \"\" { target c++26 } }\n #undef __cpp_implicit_move\t\t// { dg-warning \"undefining '__cpp_implicit_move'\" \"\" { target c++23 } }\n #undef __cpp_inheriting_constructors\t// { dg-warning \"undefining '__cpp_inheriting_constructors'\" \"\" { target c++20 } }\n #undef __cpp_init_captures\t\t// { dg-warning \"undefining '__cpp_init_captures'\" \"\" { target c++20 } }\ndiff --git a/gcc/testsuite/g++.dg/DRs/dr2581-2.C b/gcc/testsuite/g++.dg/DRs/dr2581-2.C\nindex f09c672608f..77bf93b2741 100644\n--- a/gcc/testsuite/g++.dg/DRs/dr2581-2.C\n+++ b/gcc/testsuite/g++.dg/DRs/dr2581-2.C\n@@ -1,6 +1,6 @@\n // DR 2581 - Undefined behavior for predefined macros\n // { dg-do preprocess }\n-// { dg-additional-options \"-fcontracts\" { target c++26 } }\n+// { dg-additional-options \"-fcontracts -freflection\" { target c++26 } }\n // { dg-additional-options \"-fmodules -fcoroutines\" { target c++20 } }\n \n #define defined defined\t\t\t\t// { dg-error \"'defined' cannot be used as a macro name\" }\n@@ -64,7 +64,7 @@\n #define __cpp_impl_coroutine 201902L\t\t// { dg-error \"'__cpp_impl_coroutine' redefined\" \"\" { target c++20 } }\n #define __cpp_impl_destroying_delete 201806L\t// { dg-error \"'__cpp_impl_destroying_delete' redefined\" \"\" { target c++20 } }\n #define __cpp_impl_three_way_comparison 201907L\t// { dg-error \"'__cpp_impl_three_way_comparison' redefined\" \"\" { target c++20 } }\n-#define __cpp_impl_reflection 202506L\n+#define __cpp_impl_reflection 202506L\t\t// { dg-error \"'__cpp_impl_reflection' redefined\" \"\" { target c++26 } }\n #define __cpp_implicit_move 202207L\t\t// { dg-error \"'__cpp_implicit_move' redefined\" \"\" { target c++23 } }\n #define __cpp_inheriting_constructors 201511L\t// { dg-error \"'__cpp_inheriting_constructors' redefined\" \"\" { target c++20 } }\n #define __cpp_init_captures 201803L\t\t// { dg-error \"'__cpp_init_captures' redefined\" \"\" { target c++14 } }\ndiff --git a/gcc/testsuite/g++.dg/reflect/access_context1.C b/gcc/testsuite/g++.dg/reflect/access_context1.C\nnew file mode 100644\nindex 00000000000..c0ec0d3fa80\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/access_context1.C\n@@ -0,0 +1,175 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::access_context.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr info null_reflection;\n+struct S {};\n+\n+constexpr access_context a = access_context::unprivileged ();\n+static_assert (a.scope () == ^^:: && a.designating_class () == null_reflection);\n+constexpr access_context b = access_context::unchecked ();\n+static_assert (b.scope () == null_reflection && b.designating_class () == null_reflection);\n+constexpr access_context c = access_context::current ();\n+static_assert (c.scope () == ^^:: && c.designating_class () == null_reflection);\n+constexpr access_context d = access_context::unprivileged ().via (^^S);\n+static_assert (d.scope () == ^^:: && d.designating_class () == ^^S);\n+constexpr access_context e = access_context::unchecked ().via (^^const S);\n+static_assert (e.scope () == null_reflection && e.designating_class () == ^^const S);\n+constexpr access_context f = access_context::current ().via (^^volatile S);\n+static_assert (f.scope () == ^^:: && f.designating_class () == ^^volatile S);\n+\n+consteval info\n+foo (info x = access_context::current ().scope ())\n+{\n+  static_assert (access_context::current ().scope () == ^^foo);\n+  return x;\n+}\n+\n+static_assert (foo (^^std) == ^^std);\n+static_assert (foo () == ^^::);\n+\n+namespace N\n+{\n+  struct S {};\n+  constexpr access_context a = access_context::current ().via (^^::S).via (^^S);\n+  static_assert (a.scope () == ^^N && a.designating_class () == ^^S);\n+  static_assert (access_context::unprivileged ().scope () == ^^::);\n+  static_assert (access_context::unchecked ().scope () == null_reflection);\n+  namespace M\n+  {\n+    constexpr access_context a = access_context::current ().via (^^S).via (^^::S);\n+    static_assert (a.scope () == ^^M && a.designating_class () == ^^::S);\n+    static_assert (foo () == ^^M);\n+    consteval {\n+      static_assert (access_context::current ().scope () == ^^M);\n+      consteval {\n+        static_assert (access_context::current ().scope () == ^^M);\n+      }\n+    }\n+  }\n+}\n+\n+struct T\n+{\n+  static_assert (access_context::unprivileged ().scope () == ^^::);\n+  static_assert (access_context::unchecked ().scope () == null_reflection);\n+  static_assert (access_context::current ().scope () == ^^T);\n+  static_assert (access_context::unprivileged ().designating_class () == null_reflection);\n+  static_assert (access_context::unchecked ().designating_class () == null_reflection);\n+  static_assert (access_context::current ().designating_class () == null_reflection);\n+  static_assert (foo () == ^^T);\n+  info t = access_context::current ().scope ();\n+};\n+\n+struct U\n+{\n+  consteval U () {}\n+  info u = access_context::current ().scope ();\n+};\n+\n+struct V : U\n+{\n+  using U::U;\n+  info v = access_context::current ().scope ();\n+  consteval {\n+    static_assert (access_context::current ().scope () == ^^V);\n+    consteval {\n+      static_assert (access_context::current ().scope () == ^^V);\n+    }\n+  }\n+};\n+\n+void\n+bar ()\n+{\n+  static constexpr access_context a = access_context::current ();\n+  static_assert (a.scope () == ^^bar && a.designating_class () == null_reflection);\n+  static_assert (foo (^^foo) == ^^foo);\n+  static_assert (foo () == ^^bar);\n+  static_assert (T {}.t == ^^bar);\n+  consteval {\n+    static_assert (access_context::current ().scope () == ^^bar);\n+    consteval {\n+      static_assert (access_context::current ().scope () == ^^bar);\n+    }\n+  }\n+  auto l = [] () {\n+    int v = 0;\n+    static_assert (access_context::current ().scope () == parent_of (^^v));\n+    static_assert (parent_of (parent_of (access_context::current ().scope ())) == ^^bar);\n+  };\n+  auto l2 = [] () -> int (&) [access_context::current ().scope () == ^^bar ? 2 : 3] {\n+    static int a[2];\n+    return a;\n+  };\n+}\n+\n+consteval {\n+  static_assert (access_context::current ().scope () == ^^::);\n+  consteval {\n+    static_assert (access_context::current ().scope () == ^^::);\n+  }\n+  static_assert (access_context::current ().via (^^S).via (null_reflection).designating_class () == null_reflection);\n+}\n+\n+consteval bool\n+baz ()\n+{\n+  constexpr U u;\n+  static_assert (is_constructor (u.u) && parent_of (u.u) == ^^U);\n+  constexpr V v;\n+  static_assert (is_constructor (v.u) && parent_of (v.u) == ^^U);\n+  static_assert (is_constructor (v.v) && parent_of (v.v) == ^^V);\n+  return true;\n+}\n+\n+static_assert (baz ());\n+\n+consteval info\n+qux ()\n+{\n+  return ^^qux;\n+}\n+\n+constexpr info q = qux ();\n+static_assert (q == ^^qux);\n+\n+namespace O\n+{\n+  int a[2];\n+  auto\n+  foo () -> int (&) [access_context::current ().scope () == ^^O ? 2 : 3]\n+  {\n+    return a;\n+  }\n+}\n+\n+consteval bool\n+can_do_via (info r)\n+{\n+  try { access_context::current ().via (r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+struct W;\n+\n+static_assert (can_do_via (^^S));\n+static_assert (can_do_via (^^T));\n+static_assert (can_do_via (^^U));\n+static_assert (can_do_via (^^V));\n+static_assert (can_do_via (^^N::S));\n+static_assert (can_do_via (null_reflection));\n+static_assert (!can_do_via (^^W));\n+static_assert (!can_do_via (^^::));\n+static_assert (!can_do_via (^^O));\n+static_assert (!can_do_via (^^bar));\n+static_assert (!can_do_via (^^int));\n+enum E { E0, E1 };\n+static_assert (!can_do_via (^^E));\n+static_assert (!can_do_via (^^E0));\n+static_assert (!can_do_via (reflect_constant (42)));\ndiff --git a/gcc/testsuite/g++.dg/reflect/access_context2.C b/gcc/testsuite/g++.dg/reflect/access_context2.C\nnew file mode 100644\nindex 00000000000..ddcb5b821d8\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/access_context2.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::access_context.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template <typename T>\n+struct S\n+{\n+  static constexpr auto ctx = access_context::current ();\n+};\n+\n+static_assert (S <int>::ctx.designating_class () == info {} && S <int>::ctx.scope () == ^^S <int>);\ndiff --git a/gcc/testsuite/g++.dg/reflect/access_context3.C b/gcc/testsuite/g++.dg/reflect/access_context3.C\nnew file mode 100644\nindex 00000000000..9f4983e8bac\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/access_context3.C\n@@ -0,0 +1,50 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::access_context.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct Ctor\n+{\n+  consteval Ctor()\n+  { }\n+\n+  access_context ctx = access_context::current ();\n+};\n+\n+constexpr Ctor ctor;\n+static_assert (is_constructor (ctor.ctx.scope ()) && parent_of(ctor.ctx.scope()) == ^^Ctor);\n+\n+struct Dfltd\n+{\n+  Dfltd() = default;\n+\n+  access_context ctx = access_context::current ();\n+};\n+\n+constexpr Dfltd dfltd;\n+static_assert (is_constructor (dfltd.ctx.scope ()) && parent_of(dfltd.ctx.scope()) == ^^Dfltd);\n+\n+struct Aggr {\n+  access_context ctx = access_context::current ();\n+};\n+\n+constexpr Aggr aggrCtor;\n+static_assert (is_constructor (aggrCtor.ctx.scope ()) && parent_of(aggrCtor.ctx.scope()) == ^^Aggr);\n+\n+constexpr Aggr aggrInit{};\n+static_assert (aggrInit.ctx.scope () == ^^::);\n+\n+consteval Aggr\n+func(Aggr aggr = {})\n+{ return aggr; }\n+\n+static_assert (func().ctx.scope () == ^^::);\n+\n+constexpr void\n+bar()\n+{\n+  static_assert (func().ctx.scope () == ^^bar);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/adl1.C b/gcc/testsuite/g++.dg/reflect/adl1.C\nnew file mode 100644\nindex 00000000000..8e23b7cdcb5\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/adl1.C\n@@ -0,0 +1,16 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// ADL.  The namespace std::meta is an associated namespace of\n+// std::meta::info, which allows standard library meta functions\n+// to be invoked without explicit qualification.\n+\n+#include <meta>\n+\n+struct S {};\n+\n+bool b1 = std::meta::has_identifier (^^S);\n+bool b2 = has_identifier (^^S);\n+\n+\n+//std::string name2 = std::meta::identifier_of(^^S);  // Okay.\n+//std::string name1 = identifier_of(^^S);             // Also okay.\ndiff --git a/gcc/testsuite/g++.dg/reflect/alignment_of1.C b/gcc/testsuite/g++.dg/reflect/alignment_of1.C\nnew file mode 100644\nindex 00000000000..cee44c8ea01\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/alignment_of1.C\n@@ -0,0 +1,165 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::alignment_of.\n+\n+#include <meta>\n+#include <cstddef>\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+alignas (32) int arr4[] = {1, 2, 3};\n+alignas (64) extern int arr5[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+} s;\n+struct S2 {\n+  char p;\n+  int mem;\n+};\n+struct T {\n+  T ();\n+  T (const T &);\n+  ~T ();\n+  static int ta;\n+  alignas (128) static constexpr int tb = 42;\n+};\n+int T::ta;\n+struct U {\n+  int u;\n+};\n+static short v1;\n+alignas (64) static long long v2;\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_alignment_of (info r)\n+{\n+  try { alignment_of (r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+static_assert (!has_alignment_of (std::meta::reflect_constant (42)));\n+static_assert (has_alignment_of (std::meta::reflect_object (arr)));\n+static_assert (has_alignment_of (std::meta::reflect_object (arr[1])));\n+static_assert (has_alignment_of (std::meta::reflect_object (s.mem)));\n+static_assert (has_alignment_of (^^arr));\n+static_assert (!has_alignment_of (^^a3));\n+static_assert (!has_alignment_of (^^fn));\n+static_assert (!has_alignment_of (^^fn2));\n+static_assert (!has_alignment_of (^^Enum::A));\n+static_assert (has_alignment_of (^^Alias));\n+static_assert (has_alignment_of (^^S));\n+static_assert (has_alignment_of (^^S::mem));\n+static_assert (!has_alignment_of (members_of (^^S, access_context::current ())[1]));\n+static_assert (!has_alignment_of (^^TCls));\n+static_assert (!has_alignment_of (^^TFn));\n+static_assert (!has_alignment_of (^^TVar));\n+static_assert (!has_alignment_of (^^Concept));\n+static_assert (!has_alignment_of (^^NSAlias));\n+static_assert (!has_alignment_of (^^NS));\n+static_assert (has_alignment_of (std::meta::bases_of (^^S, ctx)[0]));\n+static_assert (has_alignment_of (std::meta::data_member_spec (^^int, { .name = \"member\" })));\n+static_assert (!has_alignment_of (std::meta::data_member_spec (^^int, { .name = \"member\", .bit_width = 6 })));\n+static_assert (!has_alignment_of (std::meta::data_member_spec (^^int, { .bit_width = 15 })));\n+static_assert (has_alignment_of (^^arr2));\n+static_assert (has_alignment_of (^^arr3));\n+static_assert (!has_alignment_of (^^ref));\n+static_assert (alignment_of (std::meta::reflect_object (arr)) == alignment_of (^^arr));\n+static_assert (alignment_of (std::meta::reflect_object (arr[1])) == alignof (int));\n+static_assert (alignment_of (std::meta::reflect_object (s.mem)) == alignment_of (^^S::mem));\n+static_assert (alignment_of (^^arr) >= alignof (int));\n+static_assert (alignment_of (^^arr4) == 32);\n+static_assert (alignment_of (^^Alias) == alignof (int));\n+static_assert (alignment_of (^^S) == alignof (S));\n+static_assert (alignment_of (^^S::mem) == offsetof (S2, mem));\n+static_assert (alignment_of (std::meta::bases_of (^^S, ctx)[0]) == alignof (B));\n+static_assert (alignment_of (std::meta::data_member_spec (^^int, { .name = \"member\" })) == alignof (int));\n+static_assert (alignment_of (^^arr3) >= alignof (int));\n+static_assert (alignment_of (^^arr5) == 64);\n+static_assert (alignment_of (^^T::ta) >= alignof (int));\n+static_assert (alignment_of (^^T::tb) == 128);\n+static_assert (alignment_of (^^v1) >= alignof (short));\n+static_assert (alignment_of (^^v2) == 64);\n+using fnt = int (int, int);\n+static_assert (!has_alignment_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_alignment_of (^^a));\n+  static_assert (has_alignment_of (^^b));\n+  static_assert (has_alignment_of (^^c));\n+  static_assert (has_alignment_of (^^d));\n+  static_assert (!has_alignment_of (^^e));\n+  static_assert (!has_alignment_of (parameters_of (^^foo)[0]));\n+  static_assert (!has_alignment_of (parameters_of (^^foo)[5]));\n+  static_assert (!has_alignment_of (parameters_of (^^bar)[0]));\n+  static_assert (alignment_of (^^a) >= alignof (int));\n+  static_assert (alignment_of (^^b) >= alignof (long));\n+  static_assert (alignment_of (^^c) >= alignof (T));\n+  static_assert (alignment_of (^^d) >= alignof (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+  alignas (32) int i;\n+  alignas (64) long long j;\n+};\n+struct V2\n+{\n+  char p;\n+  char a;\n+};\n+struct V3\n+{\n+  char p;\n+  long long f;\n+};\n+struct V4\n+{\n+  char p;\n+  int *h;\n+};\n+using CV = const V;\n+\n+static_assert (alignment_of (^^int) == alignof (int));\n+static_assert (alignment_of (^^char) == alignof (char));\n+static_assert (alignment_of (^^V) == alignof (V));\n+static_assert (alignment_of (^^CV) == alignof (V));\n+static_assert (alignment_of (^^char *) == alignof (char *));\n+static_assert (alignment_of (^^char &) == alignof (char *));\n+static_assert (alignment_of (^^char &&) == alignof (char *));\n+static_assert (alignof (char) == alignof (char *) || alignment_of (^^char &) != alignof (char &));\n+static_assert (alignof (char) == alignof (char *) || alignment_of (^^char &&) != alignof (char &&));\n+static_assert (alignment_of (^^V::a) == offsetof (V2, a));\n+static_assert (alignment_of (^^V::f) == offsetof (V3, f));\n+static_assert (!has_alignment_of (^^V::g));\n+static_assert (alignment_of (^^V::h) == offsetof (V4, h));\n+static_assert (alignment_of (^^V::i) == 32);\n+static_assert (alignment_of (^^V::j) == 64);\ndiff --git a/gcc/testsuite/g++.dg/reflect/alignment_of2.C b/gcc/testsuite/g++.dg/reflect/alignment_of2.C\nnew file mode 100644\nindex 00000000000..b0ff90da319\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/alignment_of2.C\n@@ -0,0 +1,27 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-options \"-freflection\" }\n+// Test std::meta::alignment_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S\n+{\n+  char a;\n+  int b;\n+};\n+struct [[gnu::packed]] V\n+{\n+  char a;\n+  long long f;\n+  int *h;\n+  S i;\n+} v;\n+\n+static_assert (alignment_of (^^v) == 1);\n+static_assert (alignment_of (^^V) == alignof (V));\n+static_assert (alignment_of (^^V::a) == 1);\n+static_assert (alignment_of (^^V::f) == 1);\n+static_assert (alignment_of (^^V::h) == 1);\n+static_assert (alignment_of (^^V::i) == 1);\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations1.C b/gcc/testsuite/g++.dg/reflect/annotations1.C\nnew file mode 100644\nindex 00000000000..561407f059e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations1.C\n@@ -0,0 +1,139 @@\n+// C++ 26 P3394R4 - Annotations for Reflection\n+// { dg-do compile { target c++26 } }\n+\n+int arr[2];\n+struct S { int a, b; };\n+S arr2[2];\n+\n+void\n+foo (int n)\n+{\n+  [[=1]] int x1;\n+  auto a = [] [[=1]] () {};\n+  auto b = [] constexpr [[=1]] {};\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+  auto c = [] noexcept [[=1]] {};\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+  auto d = [] () [[=1]] {};\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+  auto e = new int [n] [[=1]];\t\t// { dg-warning \"attributes ignored on outermost array type in new expression\" }\n+  auto e2 = new int [n] [[=1]] [42];\t// { dg-warning \"attributes ignored on outermost array type in new expression\" }\n+  auto f = new int [n][42] [[=1]];\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+  [[=1]];\t\t\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+  [[=1]] {}\t\t\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+  [[=1]] if (true) {}\t\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+  [[=1]] while (false) {}\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+  [[=1]] goto lab;\t\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+  [[=1]] lab:;\t\t\t\t// { dg-error \"annotation applied to a label\" }\n+  [[=1]] try {} catch (int) {}\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+  if ([[=1]] int x = 0) {}\n+  switch (n)\n+    {\n+    [[=1]] case 1:\t\t\t// { dg-error \"annotation applied to a label\" }\n+    [[=1]] break;\t\t\t// { dg-warning \"attributes at the beginning of statement are ignored\" }\n+    [[=1]] default:\t\t\t// { dg-error \"annotation applied to a label\" }\n+\t   break;\n+    }\n+  for ([[=1]] auto a : arr) {}\n+  for ([[=1]] auto [a, b] : arr2) {}\n+  [[=1]] asm (\"\");\t\t\t// { dg-warning \"attributes ignored on 'asm' declaration\" }\n+  try {} catch ([[=1]] int x) {}\n+  try {} catch ([[=1]] int) {}\n+  try {} catch (int [[=1]] x) {}\t// { dg-warning \"attribute ignored\" }\n+  try {} catch (int [[=1]]) {}\t\t// { dg-warning \"attribute ignored\" }\n+  try {} catch (int x [[=1]]) {}\n+}\n+\n+[[=1]] int bar ();\n+using foobar [[=1]] = int;\n+[[=1]] int a;\n+[[=1]] auto [b, c] = arr;\n+auto [b3 [[=1]], c3 [[=1]]] = arr;\t// { dg-error \"annotation on structured binding\" }\n+[[=1]];\t\t\t\t\t// { dg-warning \"attribute ignored\" }\n+inline [[=1]] void baz () {}\t\t// { dg-warning \"attribute ignored\" }\n+\t\t\t\t\t\t// { dg-error \"standard attributes in middle of decl-specifiers\" \"\" { target *-*-* } .-1 }\n+constexpr [[=1]] int qux () { return 0; }\t// { dg-warning \"attribute ignored\" }\n+\t\t\t\t\t\t// { dg-error \"standard attributes in middle of decl-specifiers\" \"\" { target *-*-* } .-1 }\n+int [[=1]] d;\t\t\t\t// { dg-warning \"attribute ignored\" }\n+int const [[=1]] e = 1;\t\t\t// { dg-warning \"attribute ignored\" }\n+struct A {} [[=1]];\t\t\t// { dg-warning \"attribute ignored in declaration of 'struct A'\" }\n+struct A [[=1]];\t\t\t// { dg-warning \"attribute ignored\" }\n+struct A [[=1]] a1;\t\t\t// { dg-warning \"attribute ignored\" }\n+A [[=1]] a2;\t\t\t\t// { dg-warning \"attribute ignored\" }\n+enum B { B0 } [[=1]];\t\t\t// { dg-warning \"attribute ignored in declaration of 'enum B'\" }\n+enum B [[=1]];\t\t\t\t// { dg-warning \"attribute ignored\" }\n+enum B [[=1]] b1;\t\t\t// { dg-warning \"attribute ignored\" }\n+B [[=1]] b2;\t\t\t\t// { dg-warning \"attribute ignored\" }\n+struct [[=1]] C {};\n+int f [[=1]];\n+int g[2] [[=1]];\t\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+int g2 [[=1]] [2];\n+int corge () [[=1]];\t\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+int *[[=1]] h;\t\t\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+int & [[=1]] i = f;\t\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+int && [[=1]] j = 0;\t\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+int S::* [[=1]] k;\t\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+auto l = sizeof (int [2] [[=1]]);\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+int freddy ([[=1]] int a,\n+\t    [[=1]] int,\n+\t    [[=1]] int c = 0,\n+\t    [[=1]] int = 0);\n+void\n+corge ([[=1]] int a,\n+       [[=1]] int,\n+       [[=1]] int c = 0,\n+       [[=1]] int = 0)\n+{\n+}\n+[[=1]] void\n+garply ()\n+{\n+}\n+int grault (int [[=1]] a,\t\t// { dg-warning \"attribute ignored\" }\n+\t    int [[=1]],\t\t\t// { dg-warning \"attribute ignored\" }\n+\t    int [[=1]] c = 0,\t\t// { dg-warning \"attribute ignored\" }\n+\t    int [[=1]] = 0);\t\t// { dg-warning \"attribute ignored\" }\n+void\n+waldo (int [[=1]] a,\t\t\t// { dg-warning \"attribute ignored\" }\n+       int [[=1]],\t\t\t// { dg-warning \"attribute ignored\" }\n+       int [[=1]] c = 0,\t\t// { dg-warning \"attribute ignored\" }\n+       int [[=1]] = 0)\t\t\t// { dg-warning \"attribute ignored\" }\n+{\n+}\n+int plugh (int a [[=1]],\n+\t    int b [[=1]] = 0);\n+void\n+thud (int a [[=1]],\n+      int b [[=1]] = 0)\n+{\n+}\n+enum [[=1]] D { D0 };\n+enum class [[=1]] E { E0 };\n+enum F {};\n+enum [[=1]] F;\t\t\t\t// { dg-warning \"type attributes ignored after type is already defined\" }\n+enum G {\n+  G0 [[=1]],\n+  G1 [[=1]] = 2\n+};\n+namespace [[=1]] H { using H0 = int; }\n+namespace [[=1]] {}\n+[[=1]] using namespace H;\t\t// { dg-error \"annotation on using directive\" }\n+struct [[=1]] I\n+{\n+  [[=1]];\t\t\t\t// { dg-error \"declaration does not declare anything\" }\n+  [[=1]] int i;\n+  [[=1]] int foo ();\n+  [[=1]] int bar () { return 1; }\n+  [[=1]] int : 0;\t\t\t// { dg-error \"annotation on unnamed bit-field\" }\n+  [[=1]] int i2 : 5;\n+  [[=1]] static int i3;\n+  static int i4;\n+};\n+[[=1]] int I::i4 = 0;\n+struct J : [[=1]] C {};\n+template <typename T>\n+concept K [[=1]] = requires { true; };\n+typedef int L [[=1]];\n+template <typename T>\n+struct M {};\n+template <>\n+struct [[=1]] M<int> { int m; };\n+typedef int N[2] [[=1]];\t\t// { dg-error \"annotation on a type other than class or enumeration definition\" }\n+typedef int O [[=1]] [2];\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations2.C b/gcc/testsuite/g++.dg/reflect/annotations2.C\nnew file mode 100644\nindex 00000000000..77b581165f1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations2.C\n@@ -0,0 +1,44 @@\n+// C++ 26 P3394R4 - Annotations for Reflection\n+// { dg-do compile { target c++26 } }\n+\n+struct [[=0]] A;\n+struct [[=1, =2]] A {\n+  [[=1]] [[=1]] [[=2]] int a;\n+  [[=3, =4, =5]] static int b; \n+};\n+namespace [[=6, =6]] [[=6]] N\n+{\n+};\n+namespace [[=7]] [[= 7 + 1]] [[= 7 + 2]] N\n+{\n+};\n+[[=9.5L]] int c;\n+struct B { constexpr B () : b (42) {} int b; };\n+[[=B ()]] int d;\n+struct C { constexpr C () : c (42) {} int c; ~C () {} };\n+[[=C ()]] int e;\t\t\t\t\t\t// { dg-error \"temporary of non-literal type 'C' in a constant expression\" }\n+\t\t\t\t\t\t\t\t// { dg-error \"annotation does not have structural type\" \"\" { target *-*-* } .-1 }\n+struct D { constexpr D () : d (42) {} volatile int d; };\n+[[=D ()]] int f;\t\t\t\t\t\t// { dg-error \"temporary of non-literal type 'D' in a constant expression\" }\n+\t\t\t\t\t\t\t\t// { dg-error \"annotation does not have structural type\" \"\" { target *-*-* } .-1 }\n+struct E { constexpr E () : e (42) {} private: int e; };\n+[[=E ()]] int g;\t\t\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+struct F { constexpr F () : f (42) {} protected: int f; };\n+[[=F ()]] int h;\t\t\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+struct G { constexpr G () : g (42) {} mutable int g; };\n+[[=G ()]] int i;\t\t\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+struct H { constexpr H () : h (42) {} int h; G g; };\n+[[=H ()]] int j;\t\t\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+[[=c]] int k;\t\t\t\t\t\t\t// { dg-error \"the value of 'c' is not usable in a constant expression\" }\n+[[=(throw 1, 0)]] int l;\t\t\t\t\t// { dg-error \"uncaught exception '1'\" }\n+struct I { int a, b; long c; };\n+constexpr B m = B ();\n+constexpr I n = { 1, 2, 3 };\n+template <auto ...A>\n+[[=1, =A...]] int o;\n+int p = o<1, m, n> + o<2, 42>;\n+[[maybe_unused]] [[=3]] [[gnu::unused]] int q;\n+[[=3, gnu::unused, gnu::aligned(16), =4]] int r;\t\t// { dg-error \"mixing annotations and attributes in the same list\" }\n+[[gnu::unused, =5, gnu::aligned(16), =6]] int s;\t\t// { dg-error \"mixing annotations and attributes in the same list\" }\n+[[using gnu:unused, =7, aligned(16), =8]] int t;\t\t// { dg-error \"mixing annotations and attributes in the same list\" }\n+[[using gnu:=9]] int u;\t\t\t\t\t\t// { dg-error \"mixing annotations and attributes in the same list\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations3.C b/gcc/testsuite/g++.dg/reflect/annotations3.C\nnew file mode 100644\nindex 00000000000..1f80d7a1851\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations3.C\n@@ -0,0 +1,174 @@\n+// C++ 26 P3394R4 - Annotations for Reflection\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::annotations_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template<class, class> inline constexpr bool same_type_v = false;\n+template<class T> inline constexpr bool same_type_v<T, T> = true;\n+\n+[[=42, =42]] int x;\n+static_assert (annotations_of (^^x).size () == 2);\n+static_assert (same_type_v<decltype (annotations_of (^^x)), std::vector<info>>);\n+static_assert (type_of (annotations_of (^^x)[0]) == ^^int);\n+static_assert (type_of (annotations_of (^^x)[1]) == ^^int);\n+\n+[[=42]] int foo ();\n+[[=24L]] int foo ();\n+static_assert (annotations_of (^^foo).size () == 2);\n+static_assert (type_of (annotations_of (^^foo)[0]) == ^^int);\n+static_assert (type_of (annotations_of (^^foo)[1]) == ^^long);\n+\n+[[=1]] void bar ();\n+[[=2U, =3UL]] void baz ();\n+void baz [[=4ULL]] ();\n+\n+static_assert (annotations_of (^^bar).size () == 1);\n+static_assert (type_of (annotations_of (^^bar)[0]) == ^^int);\n+static_assert (annotations_of (^^baz).size () == 3);\n+static_assert (type_of (annotations_of (^^baz)[0]) == ^^unsigned);\n+static_assert (type_of (annotations_of (^^baz)[1]) == ^^unsigned long);\n+static_assert (type_of (annotations_of (^^baz)[2]) == ^^unsigned long long);\n+\n+struct [[=42]] C {};\n+constexpr std::meta::info a0 = annotations_of (^^C)[0];\n+static_assert (is_annotation (a0));\n+static_assert (type_of (a0) == ^^int);\n+\n+template <class T>\n+struct [[=42]] D {};\n+\n+//constexpr std::meta::info a1 = annotations_of (^^D<int>)[0];\n+//constexpr std::meta::info a2 = annotations_of (^^D<char>)[0];\n+//static_assert (is_annotation (a1) && is_annotation (a2));\n+\n+[[=1, =2L, =3.0, =4U, =5U, =6L, =7U]] int y;\n+static_assert (annotations_of (^^y).size () == 7);\n+static_assert (type_of (annotations_of (^^y)[0]) == ^^int);\n+static_assert (type_of (annotations_of (^^y)[1]) == ^^long);\n+static_assert (type_of (annotations_of (^^y)[2]) == ^^double);\n+static_assert (type_of (annotations_of (^^y)[3]) == ^^unsigned);\n+static_assert (type_of (annotations_of (^^y)[4]) == ^^unsigned);\n+static_assert (type_of (annotations_of (^^y)[5]) == ^^long);\n+static_assert (type_of (annotations_of (^^y)[6]) == ^^unsigned);\n+static_assert (annotations_of_with_type (^^y, ^^int).size () == 1);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^int)[0]) == ^^int);\n+static_assert (annotations_of_with_type (^^y, ^^long).size () == 2);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^long)[0]) == ^^long);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^long)[1]) == ^^long);\n+static_assert (annotations_of_with_type (^^y, ^^unsigned).size () == 3);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^unsigned)[0]) == ^^unsigned);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^unsigned)[1]) == ^^unsigned);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^unsigned)[2]) == ^^unsigned);\n+static_assert (annotations_of_with_type (^^y, ^^const double).size () == 1);\n+static_assert (type_of (annotations_of_with_type (^^y, ^^double)[0]) == ^^double);\n+static_assert (annotations_of_with_type (^^y, ^^volatile double).size () == 0);\n+static_assert (annotations_of_with_type (^^y, ^^float).size () == 0);\n+\n+int z;\n+static_assert (annotations_of (^^z).size () == 0);\n+\n+struct V { int a, b, c; };\n+[[=1, =V { 2, 3, 4 }, =1.0]] int an;\n+static_assert (type_of (annotations_of (^^an)[0]) == ^^int);\n+static_assert (type_of (annotations_of (^^an)[1]) == ^^const V);\n+static_assert (type_of (annotations_of (^^an)[2]) == ^^double);\n+\n+struct W { [[=1, =2L, =3U, =4UL]] int a; [[=V { 2, 3, 4 }, =1.0f]] int b; };\n+static_assert (type_of (annotations_of (^^W::a)[0]) == ^^int);\n+static_assert (type_of (annotations_of (^^W::a)[1]) == ^^long);\n+static_assert (type_of (annotations_of (^^W::a)[2]) == ^^unsigned);\n+static_assert (type_of (annotations_of (^^W::a)[3]) == ^^long unsigned);\n+static_assert (type_of (annotations_of (^^W::b)[0]) == ^^const V);\n+static_assert (type_of (annotations_of (^^W::b)[1]) == ^^float);\n+\n+[[=1, =1.0f]] [[=2U]] extern int an2;\n+[[=3L, =4.0]] [[=5UL, =5UL]] extern int an2;\n+[[=6LL, =V { 7, 8, 9 }]] [[=6ULL, =6ULL]] int an2;\n+static_assert (annotations_of (^^an2).size () == 11);\n+static_assert (type_of (annotations_of (^^an2)[0]) == ^^int);\n+static_assert (type_of (annotations_of (^^an2)[1]) == ^^float);\n+static_assert (type_of (annotations_of (^^an2)[2]) == ^^unsigned);\n+static_assert (type_of (annotations_of (^^an2)[3]) == ^^long);\n+static_assert (type_of (annotations_of (^^an2)[4]) == ^^double);\n+static_assert (type_of (annotations_of (^^an2)[5]) == ^^unsigned long);\n+static_assert (type_of (annotations_of (^^an2)[6]) == ^^unsigned long);\n+static_assert (type_of (annotations_of (^^an2)[7]) == ^^long long);\n+static_assert (type_of (annotations_of (^^an2)[8]) == ^^const V);\n+static_assert (type_of (annotations_of (^^an2)[9]) == ^^unsigned long long);\n+static_assert (type_of (annotations_of (^^an2)[10]) == ^^unsigned long long);\n+\n+namespace [[=1, =2U]] [[=3L, =4.0]] N\n+{\n+  static_assert (annotations_of (^^N).size () == 4);\n+  static_assert (type_of (annotations_of (^^N)[0]) == ^^int);\n+  static_assert (type_of (annotations_of (^^N)[1]) == ^^unsigned);\n+  static_assert (type_of (annotations_of (^^N)[2]) == ^^long);\n+  static_assert (type_of (annotations_of (^^N)[3]) == ^^double);\n+}\n+\n+namespace [[=5.0f]] [[=6LL]] N\n+{\n+  static_assert (annotations_of (^^N).size () == 6);\n+  static_assert (type_of (annotations_of (^^N)[0]) == ^^int);\n+  static_assert (type_of (annotations_of (^^N)[1]) == ^^unsigned);\n+  static_assert (type_of (annotations_of (^^N)[2]) == ^^long);\n+  static_assert (type_of (annotations_of (^^N)[3]) == ^^double);\n+  static_assert (type_of (annotations_of (^^N)[4]) == ^^float);\n+  static_assert (type_of (annotations_of (^^N)[5]) == ^^long long);\n+}\n+\n+struct F { int f; };\n+struct G { int g; };\n+struct H { int h; };\n+struct I : [[=1U, =2L]] [[=3]] F, [[=4ULL]] G, H { int i; };\n+\n+constexpr auto ctx = access_context::unchecked ();\n+static_assert (annotations_of (bases_of (^^I, ctx)[0]).size () == 3);\n+static_assert (type_of (annotations_of (bases_of (^^I, ctx)[0])[0]) == ^^unsigned);\n+static_assert (type_of (annotations_of (bases_of (^^I, ctx)[0])[1]) == ^^long);\n+static_assert (type_of (annotations_of (bases_of (^^I, ctx)[0])[2]) == ^^int);\n+static_assert (annotations_of (bases_of (^^I, ctx)[1]).size () == 1);\n+static_assert (type_of (annotations_of (bases_of (^^I, ctx)[1])[0]) == ^^unsigned long long);\n+static_assert (annotations_of (bases_of (^^I, ctx)[2]).size () == 0);\n+\n+struct J { int j; };\n+struct K { int k; };\n+struct L { int l; };\n+template <typename ...T>\n+struct M : [[=1]] F, G, [[=2U, =V { 1, 2, 3 }]] [[=3LL]] T... { int m; };\n+static_assert (bases_of (^^M <>, ctx).size () == 2);\n+static_assert (annotations_of (bases_of (^^M <>, ctx)[0]).size () == 1);\n+static_assert (type_of (annotations_of (bases_of (^^M <>, ctx)[0])[0]) == ^^int);\n+static_assert (annotations_of (bases_of (^^M <>, ctx)[1]).size () == 0);\n+static_assert (bases_of (^^M <J, K, L>, ctx).size () == 5);\n+static_assert (annotations_of (bases_of (^^M <J, K, L>, ctx)[0]).size () == 1);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[0])[0]) == ^^int);\n+static_assert (annotations_of (bases_of (^^M <J, K, L>, ctx)[1]).size () == 0);\n+static_assert (annotations_of (bases_of (^^M <J, K, L>, ctx)[2]).size () == 3);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[2])[0]) == ^^unsigned);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[2])[1]) == ^^const V);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[2])[2]) == ^^long long);\n+static_assert (annotations_of (bases_of (^^M <J, K, L>, ctx)[3]).size () == 3);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[3])[0]) == ^^unsigned);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[3])[1]) == ^^const V);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[3])[2]) == ^^long long);\n+static_assert (annotations_of (bases_of (^^M <J, K, L>, ctx)[4]).size () == 3);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[4])[0]) == ^^unsigned);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[4])[1]) == ^^const V);\n+static_assert (type_of (annotations_of (bases_of (^^M <J, K, L>, ctx)[4])[2]) == ^^long long);\n+\n+template <auto ...V>\n+consteval auto\n+qux ()\n+{\n+  [[=1, =V..., =2]] int an;\n+  return ^^an;\n+}\n+\n+static_assert (annotations_of (qux <> ()).size () == 2);\n+static_assert (annotations_of (qux <3, 4, 5> ()).size () == 5);\n+static_assert (annotations_of (qux <V { 1, 2, 3 }, V { 2, 3, 4 }> ()).size () == 4);\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations4.C b/gcc/testsuite/g++.dg/reflect/annotations4.C\nnew file mode 100644\nindex 00000000000..ef1c4168308\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations4.C\n@@ -0,0 +1,79 @@\n+// C++ 26 P3394R4 - Annotations for Reflection\n+// { dg-do compile { target c++26 } }\n+\n+struct E { constexpr E () : e (42) {} private: int e; };\n+int arr[2];\n+struct S { int a, b; };\n+S arr2[2];\n+\n+void\n+foo (int n)\n+{\n+  [[=E ()]] int x1;\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  auto a = [] [[=E ()]] () {};\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  if ([[=E ()]] int x = 0) {}\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  for ([[=E ()]] auto a : arr) {}\t\t// { dg-error \"annotation does not have structural type\" }\n+  for ([[=E ()]] auto [a, b] : arr2) {}\t\t// { dg-error \"annotation does not have structural type\" }\n+  try {} catch ([[=E ()]] int x) {}\t\t// { dg-error \"annotation does not have structural type\" }\n+  try {} catch ([[=E ()]] int) {}\t\t// { dg-error \"annotation does not have structural type\" }\n+  try {} catch (int x [[=E ()]]) {}\t\t// { dg-error \"annotation does not have structural type\" }\n+}\n+\n+[[=E ()]] int bar ();\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+using foobar [[=E ()]] = int;\t\t\t// { dg-error \"annotation does not have structural type\" }\n+[[=E ()]] int a;\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+[[=E ()]] auto [b, c] = arr;\t\t\t// { dg-error \"annotation does not have structural type\" }\n+struct [[=E ()]] C {};\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+int f [[=E ()]];\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+int g2 [[=E ()]] [2];\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+int freddy ([[=E ()]] int a,\t\t\t// { dg-error \"annotation does not have structural type\" }\n+\t    [[=E ()]] int,\t\t\t// { dg-error \"annotation does not have structural type\" }\n+\t    [[=E ()]] int c = 0,\t\t// { dg-error \"annotation does not have structural type\" }\n+\t    [[=E ()]] int = 0);\t\t\t// { dg-error \"annotation does not have structural type\" }\n+void\n+corge ([[=E ()]] int a,\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+       [[=E ()]] int,\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+       [[=E ()]] int c = 0,\t\t\t// { dg-error \"annotation does not have structural type\" }\n+       [[=E ()]] int = 0)\t\t\t// { dg-error \"annotation does not have structural type\" }\n+{\n+}\n+[[=E ()]] void\n+garply ()\t\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+{\n+}\n+int plugh (int a [[=E ()]],\t\t\t// { dg-error \"annotation does not have structural type\" }\n+\t   int b [[=E ()]] = 0);\t\t// { dg-error \"annotation does not have structural type\" }\n+void\n+thud (int a [[=E ()]],\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+      int b [[=E ()]] = 0)\t\t\t// { dg-error \"annotation does not have structural type\" }\n+{\n+}\n+enum [[=E ()]] D { D0 };\t\t\t// { dg-error \"annotation does not have structural type\" }\n+enum class [[=E ()]] Z { Z0 };\t\t\t// { dg-error \"annotation does not have structural type\" }\n+enum F {};\n+enum G {\n+  G0 [[=E ()]],\t\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  G1 [[=E ()]] = 2\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+};\n+namespace [[=E ()]] H { using H0 = int; }\t// { dg-error \"annotation does not have structural type\" }\n+namespace [[=E ()]] {}\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+struct [[=E ()]] I\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+{\n+  [[=E ()]] int i;\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  [[=E ()]] int foo ();\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  [[=E ()]] int bar () { return 1; }\t\t// { dg-error \"annotation does not have structural type\" }\n+  [[=E ()]] int i2 : 5;\t\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  [[=E ()]] static int i3;\t\t\t// { dg-error \"annotation does not have structural type\" }\n+  static int i4;\n+};\n+[[=E ()]] int I::i4 = 0;\t\t\t// { dg-error \"annotation does not have structural type\" }\n+struct J : [[=E ()]] C {};\t\t\t// { dg-error \"annotation does not have structural type\" }\n+template <typename T>\n+concept K [[=E ()]] = requires { true; };\t// { dg-error \"annotation does not have structural type\" \"\" { xfail *-*-* } }\n+constexpr bool k = K <int>;\n+typedef int L [[=E ()]];\t\t\t// { dg-error \"annotation does not have structural type\" }\n+template <typename T>\n+struct M {};\n+template <>\n+struct [[=E ()]] M<int> { int m; };\t\t// { dg-error \"annotation does not have structural type\" }\n+typedef int O [[=E ()]] [2];\t\t\t// { dg-error \"annotation does not have structural type\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations5.C b/gcc/testsuite/g++.dg/reflect/annotations5.C\nnew file mode 100644\nindex 00000000000..df4e909ffa0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations5.C\n@@ -0,0 +1,30 @@\n+// C++ 26 P3394R4 - Annotations for Reflection\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::annotations_of.\n+\n+#include <meta>\n+#include <ranges>\n+#include <vector>\n+\n+[[=1, =1, =2, =1.0f]] void foo ();\n+static_assert ((std::meta::annotations_of (^^foo)\n+\t\t| std::views::transform (std::meta::constant_of)\n+\t\t| std::ranges::to<std::vector> ())\n+\t       == std::vector { std::meta::reflect_constant (1),\n+\t\t\t\tstd::meta::reflect_constant (1),\n+\t\t\t\tstd::meta::reflect_constant (2),\n+\t\t\t\tstd::meta::reflect_constant (1.0f) });\n+\n+[[=1]] [[=2]] void bar ();\n+[[=3]] [[=3]] void bar ();\n+[[=4L, =42]] void bar ();\n+static_assert ((std::meta::annotations_of (^^bar)\n+\t\t| std::views::transform (std::meta::constant_of)\n+\t\t| std::ranges::to<std::vector> ())\n+\t       == std::vector { std::meta::reflect_constant (1),\n+\t\t\t\tstd::meta::reflect_constant (2),\n+\t\t\t\tstd::meta::reflect_constant (3),\n+\t\t\t\tstd::meta::reflect_constant (3),\n+\t\t\t\tstd::meta::reflect_constant (4L),\n+\t\t\t\tstd::meta::reflect_constant (42) });\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations6.C b/gcc/testsuite/g++.dg/reflect/annotations6.C\nnew file mode 100644\nindex 00000000000..98db4cc82ca\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations6.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::annotations_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+extern int v;\n+\n+consteval std::size_t\n+foo ()\n+{\n+  return annotations_of (^^v).size ();\n+}\n+\n+static_assert (foo () == 0);\n+[[=1]] [[=2]] extern int v;\n+static_assert (foo () == 2);\n+[[=3, =4, =5]] extern int v;\n+static_assert (foo () == 5);\n+[[=6]] extern int v;\n+static_assert (foo () == 6);\n+[[=6]] int v;\n+static_assert (foo () == 7);\ndiff --git a/gcc/testsuite/g++.dg/reflect/annotations7.C b/gcc/testsuite/g++.dg/reflect/annotations7.C\nnew file mode 100644\nindex 00000000000..c4a5a96e023\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/annotations7.C\n@@ -0,0 +1,12 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct U {\n+  constexpr U() = default;\n+  U(const U&) = delete;\n+};\n+constexpr U u;\n+struct [[ =u ]] deletedCopy{};\t\t// { dg-error \"annotation does not have copy constructible type\" }\n+\t\t\t\t\t// { dg-error \"use of deleted function 'U::U\\\\\\(const U\\\\\\&\\\\\\)'\" \"\" { target *-*-* } .-1 }\n+struct [[ =U{} ]] deletedCopy2{};\t// { dg-error \"annotation does not have copy constructible type\" }\n+\t\t\t\t\t// { dg-error \"use of deleted function 'U::U\\\\\\(const U\\\\\\&\\\\\\)'\" \"\" { target *-*-* } .-1 }\ndiff --git a/gcc/testsuite/g++.dg/reflect/anon1.C b/gcc/testsuite/g++.dg/reflect/anon1.C\nnew file mode 100644\nindex 00000000000..52307a9d458\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/anon1.C\n@@ -0,0 +1,50 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// https://github.com/cplusplus/CWG/issues/705\n+\n+auto foo() {\n+  union { int what; };\n+  return &[:^^what:];  // { dg-error \"not a direct member of a named class\" }\n+}\n+\n+static union { int m; };\n+constexpr auto r = ^^m;\n+auto p = &[:r:]; // { dg-error \"not a direct member of a named class\" }\n+\n+namespace N {\n+  static union { int mn; };\n+  constexpr auto rn = ^^mn;\n+  auto pn = &[:rn:];  // { dg-error \"not a direct member of a named class\" }\n+}\n+\n+struct S {\n+  union {\n+    int m;\n+  };\n+};\n+\n+constexpr auto r2 = ^^S::m;\n+constexpr auto p2 = &[: ^^r2 :];\n+\n+void\n+f ()\n+{\n+  static union {\n+    int x;\n+  };\n+  auto rx = &[: ^^x :]; // { dg-error \"not a direct member of a named class\" }\n+\n+  union {\n+    union {\n+      int u;\n+    };\n+  };\n+  auto ru = &[: ^^u :]; // { dg-error \"not a direct member of a named class\" }\n+\n+  struct L {\n+    union {\n+      int z;\n+    };\n+  };\n+  auto rz = &[: ^^L::z :];\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/anon2.C b/gcc/testsuite/g++.dg/reflect/anon2.C\nnew file mode 100644\nindex 00000000000..5a55ace2d07\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/anon2.C\n@@ -0,0 +1,43 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+static union { int m; };\n+constexpr auto r = ^^m;\n+auto p = [:r:]; // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+\n+namespace N {\n+  static union { int mn; };\n+  constexpr auto rn = ^^mn;\n+  auto pn = [:rn:];  // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+}\n+\n+struct S {\n+  union {\n+    int m;\n+  };\n+};\n+\n+constexpr auto p2 = [: ^^S::m :]; // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+\n+void\n+f ()\n+{\n+  static union {\n+    int x;\n+  };\n+  auto rx = [: ^^x :]; // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+\n+  union {\n+    union {\n+      int u;\n+    };\n+  };\n+  auto ru = [: ^^u :]; // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+\n+  struct L {\n+    union {\n+      int z;\n+    };\n+  };\n+  auto rz = [: ^^L::z :]; // { dg-error \"cannot implicitly reference a class member through a splice\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/anon3.C b/gcc/testsuite/g++.dg/reflect/anon3.C\nnew file mode 100644\nindex 00000000000..0a735cfe754\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/anon3.C\n@@ -0,0 +1,49 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+auto foo() {\n+  union U { int what; };\n+  return &[:^^U::what:];\n+}\n+\n+union U { int m; };\n+constexpr auto r = ^^U::m;\n+auto p = &[:r:];\n+\n+namespace N {\n+  union V { int mn; };\n+  constexpr auto rn = ^^V::mn;\n+  auto pn = &[:rn:];\n+}\n+\n+struct S {\n+  union W {\n+    int m;\n+  };\n+};\n+\n+constexpr auto r2 = ^^S::W::m;\n+constexpr auto p2 = &[: ^^r2 :];\n+\n+void\n+f ()\n+{\n+  union U1 {\n+    int x;\n+  };\n+  auto rx = &[: ^^U1::x :];\n+\n+  union UU {\n+    union U2 {\n+      int u;\n+    };\n+  };\n+  auto ru = &[: ^^UU::U2::u :];\n+\n+  struct L {\n+    union U3 {\n+      int z;\n+    };\n+  };\n+  auto rz = &[: ^^L::U3::z :];\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/bases_of1.C b/gcc/testsuite/g++.dg/reflect/bases_of1.C\nnew file mode 100644\nindex 00000000000..76cb51c36cc\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/bases_of1.C\n@@ -0,0 +1,188 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::bases_of and has_inaccessible_bases.\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+static_assert (bases_of (^^A, uctx).size () == 0);\n+static_assert (bases_of (^^B, uctx).size () == 0);\n+static_assert (bases_of (^^C, uctx).size () == 0);\n+static_assert (!has_inaccessible_bases (^^C, uctx));\n+static_assert (bases_of (^^D, uctx).size () == 0);\n+static_assert (bases_of (^^E, uctx).size () == 0);\n+static_assert (bases_of (^^F, uctx).size () == 0);\n+static_assert (bases_of (^^G, uctx).size () == 0);\n+static_assert (bases_of (^^H, uctx).size () == 0);\n+static_assert (bases_of (^^I, uctx).size () == 3);\n+static_assert (is_base (bases_of (^^I, uctx)[0]));\n+static_assert (parent_of (bases_of (^^I, uctx)[0]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[0]) == ^^A);\n+static_assert (identifier_of (bases_of (^^I, uctx)[0]) == \"A\");\n+static_assert (is_accessible (bases_of (^^I, uctx)[0], gctx));\n+static_assert (size_of (bases_of (^^I, uctx)[0]) == sizeof (A));\n+static_assert (offset_of (bases_of (^^I, uctx)[0]).total_bits () == 0);\n+static_assert (is_base (bases_of (^^I, uctx)[1]));\n+static_assert (parent_of (bases_of (^^I, uctx)[1]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[1]) == ^^B);\n+static_assert (identifier_of (bases_of (^^I, uctx)[1]) == \"B\");\n+static_assert (!is_accessible (bases_of (^^I, uctx)[1], gctx));\n+static_assert (size_of (bases_of (^^I, uctx)[1]) == sizeof (B));\n+static_assert (offset_of (bases_of (^^I, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (A));\n+static_assert (is_base (bases_of (^^I, uctx)[2]));\n+static_assert (parent_of (bases_of (^^I, uctx)[2]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[2]) == ^^C);\n+static_assert (identifier_of (bases_of (^^I, uctx)[2]) == \"C\");\n+static_assert (!is_accessible (bases_of (^^I, uctx)[2], gctx));\n+static_assert (size_of (bases_of (^^I, uctx)[2]) == sizeof (C));\n+static_assert (offset_of (bases_of (^^I, uctx)[2]).total_bits () == __CHAR_BIT__ * (sizeof (A) + sizeof (B)));\n+static_assert (!has_inaccessible_bases (^^I, uctx));\n+static_assert (bases_of (^^J, uctx).size () == 3);\n+static_assert (is_base (bases_of (^^J, uctx)[0]));\n+static_assert (parent_of (bases_of (^^J, uctx)[0]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[0]) == ^^D);\n+static_assert (identifier_of (bases_of (^^J, uctx)[0]) == \"D\");\n+static_assert (!is_accessible (bases_of (^^J, uctx)[0], gctx));\n+static_assert (size_of (bases_of (^^J, uctx)[0]) == sizeof (D));\n+static_assert (offset_of (bases_of (^^J, uctx)[0]).total_bits () == 0);\n+static_assert (is_base (bases_of (^^J, uctx)[1]));\n+static_assert (parent_of (bases_of (^^J, uctx)[1]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[1]) == ^^E);\n+static_assert (identifier_of (bases_of (^^J, uctx)[1]) == \"E\");\n+static_assert (!is_accessible (bases_of (^^J, uctx)[1], gctx));\n+static_assert (size_of (bases_of (^^J, uctx)[1]) == sizeof (E));\n+static_assert (offset_of (bases_of (^^J, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (D));\n+static_assert (is_base (bases_of (^^J, uctx)[2]));\n+static_assert (parent_of (bases_of (^^J, uctx)[2]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[2]) == ^^F);\n+static_assert (identifier_of (bases_of (^^J, uctx)[2]) == \"F\");\n+static_assert (is_accessible (bases_of (^^J, uctx)[2], gctx));\n+static_assert (size_of (bases_of (^^J, uctx)[2]) == sizeof (F));\n+static_assert (offset_of (bases_of (^^J, uctx)[2]).total_bits () == __CHAR_BIT__ * (sizeof (D) + sizeof (E)));\n+static_assert (!has_inaccessible_bases (^^J, uctx));\n+static_assert (bases_of (^^K, uctx).size () == 4);\n+static_assert (is_base (bases_of (^^K, uctx)[0]));\n+static_assert (parent_of (bases_of (^^K, uctx)[0]) == ^^K);\n+static_assert (type_of (bases_of (^^K, uctx)[0]) == ^^G);\n+static_assert (identifier_of (bases_of (^^K, uctx)[0]) == \"G\");\n+static_assert (is_accessible (bases_of (^^K, uctx)[0], gctx));\n+static_assert (size_of (bases_of (^^K, uctx)[0]) == sizeof (G));\n+static_assert (offset_of (bases_of (^^K, uctx)[0]).total_bits () == 0);\n+static_assert (is_base (bases_of (^^K, uctx)[1]));\n+static_assert (parent_of (bases_of (^^K, uctx)[1]) == ^^K);\n+static_assert (type_of (bases_of (^^K, uctx)[1]) == ^^I);\n+static_assert (identifier_of (bases_of (^^K, uctx)[1]) == \"I\");\n+static_assert (!is_accessible (bases_of (^^K, uctx)[1], gctx));\n+static_assert (size_of (bases_of (^^K, uctx)[1]) == sizeof (I));\n+static_assert (offset_of (bases_of (^^K, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (G));\n+static_assert (is_base (bases_of (^^K, uctx)[2]));\n+static_assert (parent_of (bases_of (^^K, uctx)[2]) == ^^K);\n+static_assert (type_of (bases_of (^^K, uctx)[2]) == ^^H);\n+static_assert (identifier_of (bases_of (^^K, uctx)[2]) == \"H\");\n+static_assert (!is_accessible (bases_of (^^K, uctx)[2], gctx));\n+static_assert (size_of (bases_of (^^K, uctx)[2]) == sizeof (H));\n+static_assert (offset_of (bases_of (^^K, uctx)[2]).total_bits () == __CHAR_BIT__ * (sizeof (G) + sizeof (I)));\n+static_assert (is_base (bases_of (^^K, uctx)[3]));\n+static_assert (parent_of (bases_of (^^K, uctx)[3]) == ^^K);\n+static_assert (type_of (bases_of (^^K, uctx)[3]) == ^^J);\n+static_assert (identifier_of (bases_of (^^K, uctx)[3]) == \"J\");\n+static_assert (is_accessible (bases_of (^^K, uctx)[3], gctx));\n+static_assert (size_of (bases_of (^^K, uctx)[3]) == sizeof (J));\n+static_assert (offset_of (bases_of (^^K, uctx)[3]).total_bits () == __CHAR_BIT__ * (sizeof (G) + sizeof (I) + sizeof (H)));\n+static_assert (!has_inaccessible_bases (^^K, uctx));\n+static_assert (bases_of (^^L, uctx).size () == 1);\n+static_assert (is_base (bases_of (^^L, uctx)[0]));\n+static_assert (parent_of (bases_of (^^L, uctx)[0]) == ^^L);\n+static_assert (type_of (bases_of (^^L, uctx)[0]) == ^^A);\n+static_assert (identifier_of (bases_of (^^L, uctx)[0]) == \"A\");\n+static_assert (is_accessible (bases_of (^^L, uctx)[0], gctx));\n+static_assert (size_of (bases_of (^^L, uctx)[0]) == sizeof (A));\n+static_assert (offset_of (bases_of (^^L, uctx)[0]).total_bits () == __CHAR_BIT__ * (sizeof (void *) + sizeof (int)));\n+static_assert (bases_of (^^M, uctx).size () == 1);\n+static_assert (is_base (bases_of (^^M, uctx)[0]));\n+static_assert (parent_of (bases_of (^^M, uctx)[0]) == ^^M);\n+static_assert (type_of (bases_of (^^M, uctx)[0]) == ^^A);\n+static_assert (identifier_of (bases_of (^^M, uctx)[0]) == \"A\");\n+static_assert (is_accessible (bases_of (^^M, uctx)[0], gctx));\n+static_assert (size_of (bases_of (^^M, uctx)[0]) == sizeof (A));\n+static_assert (offset_of (bases_of (^^M, uctx)[0]).total_bits () == __CHAR_BIT__ * (sizeof (void *) + sizeof (int)));\n+static_assert (bases_of (^^N, uctx).size () == 3);\n+static_assert (is_base (bases_of (^^N, uctx)[0]));\n+static_assert (parent_of (bases_of (^^N, uctx)[0]) == ^^N);\n+static_assert (type_of (bases_of (^^N, uctx)[0]) == ^^L);\n+static_assert (identifier_of (bases_of (^^N, uctx)[0]) == \"L\");\n+static_assert (is_accessible (bases_of (^^N, uctx)[0], gctx));\n+static_assert (size_of (bases_of (^^N, uctx)[0]) == sizeof (L));\n+static_assert (offset_of (bases_of (^^N, uctx)[0]).total_bits () == 0);\n+static_assert (is_base (bases_of (^^N, uctx)[1]));\n+static_assert (parent_of (bases_of (^^N, uctx)[1]) == ^^N);\n+static_assert (type_of (bases_of (^^N, uctx)[1]) == ^^M);\n+static_assert (identifier_of (bases_of (^^N, uctx)[1]) == \"M\");\n+static_assert (!is_accessible (bases_of (^^N, uctx)[1], gctx));\n+static_assert (size_of (bases_of (^^N, uctx)[1]) == sizeof (M));\n+#if (__SIZEOF_POINTER__ == 4 || __SIZEOF_POINTER__ == 8) && __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8\n+// For LP64, L and M bases have vptr and the int field + 32 bits of padding,\n+// for ILP32 they have no padding.\n+static_assert (offset_of (bases_of (^^N, uctx)[1]).total_bits () == __CHAR_BIT__ * 2 * sizeof (void *));\n+#endif\n+static_assert (is_base (bases_of (^^N, uctx)[2]));\n+static_assert (parent_of (bases_of (^^N, uctx)[2]) == ^^N);\n+static_assert (type_of (bases_of (^^N, uctx)[2]) == ^^A);\n+static_assert (identifier_of (bases_of (^^N, uctx)[2]) == \"A\");\n+static_assert (is_accessible (bases_of (^^N, uctx)[2], gctx));\n+static_assert (size_of (bases_of (^^N, uctx)[2]) == sizeof (A));\n+#if (__SIZEOF_POINTER__ == 4 || __SIZEOF_POINTER__ == 8) && __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8\n+// For LP64, N::n is in the of M and then comes the A base.\n+// For ILP32 N::n is after the M base.\n+static_assert (offset_of (bases_of (^^N, uctx)[2]).total_bits () == __CHAR_BIT__ * (4 * sizeof (void *) + (sizeof (void *) == 8 ? 0 : sizeof (int))));\n+static_assert (offset_of (^^N::n).total_bits () == __CHAR_BIT__  * (4 * sizeof (void *) - ((sizeof (void *) == 8 ? sizeof (int) : 0))));\n+#endif\n+\n+static_assert (bases_of (^^A, gctx).size () == 0);\n+static_assert (bases_of (^^B, gctx).size () == 0);\n+static_assert (bases_of (^^C, gctx).size () == 0);\n+static_assert (!has_inaccessible_bases (^^C, gctx));\n+static_assert (bases_of (^^D, gctx).size () == 0);\n+static_assert (bases_of (^^E, gctx).size () == 0);\n+static_assert (bases_of (^^F, gctx).size () == 0);\n+static_assert (bases_of (^^G, gctx).size () == 0);\n+static_assert (bases_of (^^H, gctx).size () == 0);\n+static_assert (bases_of (^^I, gctx).size () == 1);\n+static_assert (bases_of (^^I, gctx)[0] == bases_of (^^I, uctx)[0]);\n+static_assert (has_inaccessible_bases (^^I, gctx));\n+static_assert (bases_of (^^J, gctx).size () == 1);\n+static_assert (bases_of (^^J, gctx)[0] == bases_of (^^J, uctx)[2]);\n+static_assert (has_inaccessible_bases (^^J, gctx));\n+static_assert (bases_of (^^K, gctx).size () == 2);\n+static_assert (bases_of (^^K, gctx)[0] == bases_of (^^K, uctx)[0]);\n+static_assert (bases_of (^^K, gctx)[1] == bases_of (^^K, uctx)[3]);\n+static_assert (has_inaccessible_bases (^^K, gctx));\n+static_assert (bases_of (^^L, gctx).size () == 1);\n+static_assert (bases_of (^^L, gctx)[0] == bases_of (^^L, uctx)[0]);\n+static_assert (!has_inaccessible_bases (^^L, gctx));\n+static_assert (bases_of (^^M, gctx).size () == 1);\n+static_assert (bases_of (^^M, gctx)[0] == bases_of (^^M, uctx)[0]);\n+static_assert (!has_inaccessible_bases (^^L, gctx));\n+static_assert (bases_of (^^N, gctx).size () == 2);\n+static_assert (bases_of (^^N, gctx)[0] == bases_of (^^N, uctx)[0]);\n+static_assert (bases_of (^^N, gctx)[1] == bases_of (^^N, uctx)[2]);\n+static_assert (has_inaccessible_bases (^^N, gctx));\ndiff --git a/gcc/testsuite/g++.dg/reflect/bases_of2.C b/gcc/testsuite/g++.dg/reflect/bases_of2.C\nnew file mode 100644\nindex 00000000000..85020535a49\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/bases_of2.C\n@@ -0,0 +1,73 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::bases_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A {};\n+struct B : virtual A {};\n+struct C : virtual A {};\n+struct D : virtual B, virtual C {};\n+struct E : virtual D {};\n+struct F : virtual D, virtual E {};\n+struct G : virtual E, virtual F {};\n+struct H : virtual A {};\n+struct I : virtual F, virtual H {};\n+struct J : virtual G, virtual I {};\n+\n+constexpr access_context uctx = access_context::unchecked ();\n+\n+static_assert (bases_of (^^A, uctx).size () == 0);\n+static_assert (bases_of (^^B, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^B, uctx)[0]) == ^^B);\n+static_assert (type_of (bases_of (^^B, uctx)[0]) == ^^A);\n+static_assert (offset_of (bases_of (^^B, uctx)[0]).total_bits () == 0);\n+static_assert (bases_of (^^C, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^C, uctx)[0]) == ^^C);\n+static_assert (type_of (bases_of (^^C, uctx)[0]) == ^^A);\n+static_assert (offset_of (bases_of (^^C, uctx)[0]).total_bits () == 0);\n+static_assert (bases_of (^^D, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^D, uctx)[0]) == ^^D);\n+static_assert (type_of (bases_of (^^D, uctx)[0]) == ^^B);\n+static_assert (offset_of (bases_of (^^D, uctx)[0]).total_bits () == 0);\n+static_assert (parent_of (bases_of (^^D, uctx)[1]) == ^^D);\n+static_assert (type_of (bases_of (^^D, uctx)[1]) == ^^C);\n+static_assert (offset_of (bases_of (^^D, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (bases_of (^^E, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^E, uctx)[0]) == ^^E);\n+static_assert (type_of (bases_of (^^E, uctx)[0]) == ^^D);\n+static_assert (offset_of (bases_of (^^E, uctx)[0]).total_bits () == 0);\n+static_assert (bases_of (^^F, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^F, uctx)[0]) == ^^F);\n+static_assert (type_of (bases_of (^^F, uctx)[0]) == ^^D);\n+static_assert (offset_of (bases_of (^^F, uctx)[0]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (parent_of (bases_of (^^F, uctx)[1]) == ^^F);\n+static_assert (type_of (bases_of (^^F, uctx)[1]) == ^^E);\n+static_assert (offset_of (bases_of (^^F, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (bases_of (^^G, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^G, uctx)[0]) == ^^G);\n+static_assert (type_of (bases_of (^^G, uctx)[0]) == ^^E);\n+static_assert (offset_of (bases_of (^^G, uctx)[0]).total_bits () == 0);\n+static_assert (parent_of (bases_of (^^G, uctx)[1]) == ^^G);\n+static_assert (type_of (bases_of (^^G, uctx)[1]) == ^^F);\n+static_assert (offset_of (bases_of (^^G, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (bases_of (^^H, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^H, uctx)[0]) == ^^H);\n+static_assert (type_of (bases_of (^^H, uctx)[0]) == ^^A);\n+static_assert (offset_of (bases_of (^^H, uctx)[0]).total_bits () == 0);\n+static_assert (bases_of (^^I, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^I, uctx)[0]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[0]) == ^^F);\n+static_assert (offset_of (bases_of (^^I, uctx)[0]).total_bits () == 0);\n+static_assert (parent_of (bases_of (^^I, uctx)[1]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[1]) == ^^H);\n+static_assert (offset_of (bases_of (^^I, uctx)[1]).total_bits () == __CHAR_BIT__ * 2 * sizeof (void *));\n+static_assert (bases_of (^^J, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^J, uctx)[0]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[0]) == ^^G);\n+static_assert (offset_of (bases_of (^^J, uctx)[0]).total_bits () == 0);\n+static_assert (parent_of (bases_of (^^J, uctx)[1]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[1]) == ^^I);\n+static_assert (offset_of (bases_of (^^J, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\ndiff --git a/gcc/testsuite/g++.dg/reflect/bases_of3.C b/gcc/testsuite/g++.dg/reflect/bases_of3.C\nnew file mode 100644\nindex 00000000000..1648cb39843\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/bases_of3.C\n@@ -0,0 +1,88 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::bases_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct A {};\n+struct B : private virtual A {};\n+struct C : protected virtual A {};\n+struct D : public virtual B, protected virtual C {};\n+struct E : private virtual D {};\n+struct F : public virtual D, public virtual E {};\n+struct G : protected virtual E, private virtual F {};\n+struct H : protected virtual A {};\n+struct I : public virtual F, private virtual H {};\n+struct J : virtual G, virtual I {};\n+\n+constexpr access_context gctx = access_context::current ();\n+constexpr access_context uctx = access_context::unchecked ();\n+\n+static_assert (bases_of (^^A, uctx).size () == 0);\n+static_assert (bases_of (^^B, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^B, uctx)[0]) == ^^B);\n+static_assert (type_of (bases_of (^^B, uctx)[0]) == ^^A);\n+static_assert (offset_of (bases_of (^^B, uctx)[0]).total_bits () == 0);\n+static_assert (!is_accessible (bases_of (^^B, uctx)[0], gctx));\n+static_assert (bases_of (^^C, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^C, uctx)[0]) == ^^C);\n+static_assert (type_of (bases_of (^^C, uctx)[0]) == ^^A);\n+static_assert (offset_of (bases_of (^^C, uctx)[0]).total_bits () == 0);\n+static_assert (!is_accessible (bases_of (^^C, uctx)[0], gctx));\n+static_assert (bases_of (^^D, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^D, uctx)[0]) == ^^D);\n+static_assert (type_of (bases_of (^^D, uctx)[0]) == ^^B);\n+static_assert (offset_of (bases_of (^^D, uctx)[0]).total_bits () == 0);\n+static_assert (is_accessible (bases_of (^^D, uctx)[0], gctx));\n+static_assert (parent_of (bases_of (^^D, uctx)[1]) == ^^D);\n+static_assert (type_of (bases_of (^^D, uctx)[1]) == ^^C);\n+static_assert (offset_of (bases_of (^^D, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (!is_accessible (bases_of (^^D, uctx)[1], gctx));\n+static_assert (bases_of (^^E, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^E, uctx)[0]) == ^^E);\n+static_assert (type_of (bases_of (^^E, uctx)[0]) == ^^D);\n+static_assert (offset_of (bases_of (^^E, uctx)[0]).total_bits () == 0);\n+static_assert (!is_accessible (bases_of (^^E, uctx)[0], gctx));\n+static_assert (bases_of (^^F, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^F, uctx)[0]) == ^^F);\n+static_assert (type_of (bases_of (^^F, uctx)[0]) == ^^D);\n+static_assert (offset_of (bases_of (^^F, uctx)[0]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (is_accessible (bases_of (^^F, uctx)[0], gctx));\n+static_assert (parent_of (bases_of (^^F, uctx)[1]) == ^^F);\n+static_assert (type_of (bases_of (^^F, uctx)[1]) == ^^E);\n+static_assert (offset_of (bases_of (^^F, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (is_accessible (bases_of (^^F, uctx)[1], gctx));\n+static_assert (bases_of (^^G, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^G, uctx)[0]) == ^^G);\n+static_assert (type_of (bases_of (^^G, uctx)[0]) == ^^E);\n+static_assert (offset_of (bases_of (^^G, uctx)[0]).total_bits () == 0);\n+static_assert (!is_accessible (bases_of (^^G, uctx)[0], gctx));\n+static_assert (parent_of (bases_of (^^G, uctx)[1]) == ^^G);\n+static_assert (type_of (bases_of (^^G, uctx)[1]) == ^^F);\n+static_assert (offset_of (bases_of (^^G, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (!is_accessible (bases_of (^^G, uctx)[1], gctx));\n+static_assert (bases_of (^^H, uctx).size () == 1);\n+static_assert (parent_of (bases_of (^^H, uctx)[0]) == ^^H);\n+static_assert (type_of (bases_of (^^H, uctx)[0]) == ^^A);\n+static_assert (offset_of (bases_of (^^H, uctx)[0]).total_bits () == 0);\n+static_assert (!is_accessible (bases_of (^^H, uctx)[0], gctx));\n+static_assert (bases_of (^^I, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^I, uctx)[0]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[0]) == ^^F);\n+static_assert (offset_of (bases_of (^^I, uctx)[0]).total_bits () == 0);\n+static_assert (is_accessible (bases_of (^^I, uctx)[0], gctx));\n+static_assert (parent_of (bases_of (^^I, uctx)[1]) == ^^I);\n+static_assert (type_of (bases_of (^^I, uctx)[1]) == ^^H);\n+static_assert (offset_of (bases_of (^^I, uctx)[1]).total_bits () == __CHAR_BIT__ * 2 * sizeof (void *));\n+static_assert (!is_accessible (bases_of (^^I, uctx)[1], gctx));\n+static_assert (bases_of (^^J, uctx).size () == 2);\n+static_assert (parent_of (bases_of (^^J, uctx)[0]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[0]) == ^^G);\n+static_assert (offset_of (bases_of (^^J, uctx)[0]).total_bits () == 0);\n+static_assert (is_accessible (bases_of (^^J, uctx)[0], gctx));\n+static_assert (parent_of (bases_of (^^J, uctx)[1]) == ^^J);\n+static_assert (type_of (bases_of (^^J, uctx)[1]) == ^^I);\n+static_assert (offset_of (bases_of (^^J, uctx)[1]).total_bits () == __CHAR_BIT__ * sizeof (void *));\n+static_assert (is_accessible (bases_of (^^J, uctx)[1], gctx));\ndiff --git a/gcc/testsuite/g++.dg/reflect/bit_size_of1.C b/gcc/testsuite/g++.dg/reflect/bit_size_of1.C\nnew file mode 100644\nindex 00000000000..4ba4028f395\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/bit_size_of1.C\n@@ -0,0 +1,125 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::bit_size_of.\n+\n+#include <meta>\n+#include <climits>\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_bit_size_of (info r)\n+{\n+  try { bit_size_of (r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+static_assert (has_bit_size_of (std::meta::reflect_constant (42)));\n+static_assert (has_bit_size_of (std::meta::reflect_object (arr[1])));\n+static_assert (has_bit_size_of (^^arr));\n+static_assert (!has_bit_size_of (^^a3));\n+static_assert (!has_bit_size_of (^^fn));\n+static_assert (!has_bit_size_of (^^fn2));\n+static_assert (!has_bit_size_of (^^Enum::A));\n+static_assert (has_bit_size_of (^^Alias));\n+static_assert (has_bit_size_of (^^S));\n+static_assert (has_bit_size_of (^^S::mem));\n+static_assert (has_bit_size_of (std::meta::members_of (^^S, ctx)[1]));\n+static_assert (!has_bit_size_of (^^TCls));\n+static_assert (!has_bit_size_of (^^TFn));\n+static_assert (!has_bit_size_of (^^TVar));\n+static_assert (!has_bit_size_of (^^Concept));\n+static_assert (!has_bit_size_of (^^NSAlias));\n+static_assert (!has_bit_size_of (^^NS));\n+static_assert (has_bit_size_of (std::meta::bases_of (^^S, ctx)[0]));\n+static_assert (has_bit_size_of (std::meta::data_member_spec (^^int, { .name = \"member\" })));\n+static_assert (has_bit_size_of (std::meta::data_member_spec (^^int, { .name = \"member2\", .bit_width = 6 })));\n+static_assert (!has_bit_size_of (^^arr2));\n+static_assert (has_bit_size_of (^^arr3));\n+static_assert (!has_bit_size_of (^^ref));\n+static_assert (bit_size_of (^^arr) == CHAR_BIT * sizeof (arr));\n+static_assert (bit_size_of (std::meta::reflect_constant (42)) == CHAR_BIT * sizeof (int));\n+static_assert (bit_size_of (^^Alias) == CHAR_BIT * sizeof (int));\n+static_assert (bit_size_of (^^S) == CHAR_BIT * sizeof (S));\n+static_assert (bit_size_of (^^S::mem) == CHAR_BIT * sizeof (S::mem));\n+static_assert (bit_size_of (^^arr3) == CHAR_BIT * sizeof (arr3));\n+using fnt = int (int, int);\n+static_assert (!has_bit_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_bit_size_of (^^a));\n+  static_assert (has_bit_size_of (^^b));\n+  static_assert (has_bit_size_of (^^c));\n+  static_assert (has_bit_size_of (^^d));\n+  static_assert (!has_bit_size_of (^^e));\n+  static_assert (!has_bit_size_of (parameters_of (^^foo)[0]));\n+  static_assert (!has_bit_size_of (parameters_of (^^foo)[5]));\n+  static_assert (!has_bit_size_of (parameters_of (^^bar)[0]));\n+  static_assert (bit_size_of (^^a) == CHAR_BIT * sizeof (int));\n+  static_assert (bit_size_of (^^b) == CHAR_BIT * sizeof (long));\n+  static_assert (bit_size_of (^^c) == CHAR_BIT * sizeof (T));\n+  static_assert (bit_size_of (^^d) == CHAR_BIT * 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+  long long i : sizeof (long long) * CHAR_BIT - 3;\n+};\n+using CV = const V;\n+\n+static_assert (bit_size_of (^^int) == CHAR_BIT * sizeof (int));\n+static_assert (bit_size_of (^^char) == CHAR_BIT * sizeof (char));\n+static_assert (bit_size_of (^^V) == CHAR_BIT * sizeof (V));\n+static_assert (bit_size_of (^^CV) == CHAR_BIT * sizeof (V));\n+static_assert (bit_size_of (^^char *) == CHAR_BIT * sizeof (char *));\n+static_assert (bit_size_of (^^char &) == CHAR_BIT * sizeof (char *));\n+static_assert (sizeof (char) == sizeof (char *) || bit_size_of (^^char &) != CHAR_BIT * sizeof (char &));\n+static_assert (bit_size_of (^^V::a) == CHAR_BIT * sizeof (char));\n+static_assert (bit_size_of (^^V::f) == CHAR_BIT * sizeof (long long));\n+static_assert (bit_size_of (^^V::g) == 3);\n+static_assert (bit_size_of (^^V::h) == CHAR_BIT * sizeof (int *));\n+static_assert (bit_size_of (^^V::i) == CHAR_BIT * sizeof (long long) - 3);\n+static_assert (bit_size_of (std::meta::bases_of (^^S, ctx)[0]) == CHAR_BIT * sizeof (B));\n+static_assert (bit_size_of (std::meta::data_member_spec (^^int, { .name = \"member\" })) == CHAR_BIT * sizeof (int));\n+static_assert (bit_size_of (std::meta::data_member_spec (^^int, { .name = \"member2\", .bit_width = 6 })) == 6);\ndiff --git a/gcc/testsuite/g++.dg/reflect/bitfield1.C b/gcc/testsuite/g++.dg/reflect/bitfield1.C\nnew file mode 100644\nindex 00000000000..c6dc0104bda\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/bitfield1.C\n@@ -0,0 +1,12 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct A {\n+  int x : 4, y : 4;\n+};\n+\n+constexpr auto f() {\n+  return &[:^^A::y:];  // { dg-error \"invalid pointer to bit-field .A::y.\" }\n+}\n+\n+static_assert(2 == A{1, 2}.*(f()));\ndiff --git a/gcc/testsuite/g++.dg/reflect/can_substitute1.C b/gcc/testsuite/g++.dg/reflect/can_substitute1.C\nnew file mode 100644\nindex 00000000000..a0dd75073aa\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/can_substitute1.C\n@@ -0,0 +1,200 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::can_substitute.\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+template <reflection_range R = std::initializer_list <info>>\n+consteval bool\n+could_substitute (info r, R &&args)\n+{\n+  try { can_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 = \"a\" });\n+static_assert (!could_substitute (dms, {}));\n+\n+struct Base {};\n+struct Derived : Base {};\n+static_assert (!could_substitute (bases_of (^^Derived, access_context::unchecked ())[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 (!can_substitute (^^S, {}));\n+static_assert (can_substitute (^^S, { ^^int }));\n+static_assert (can_substitute (^^S, { ^^V }));\n+static_assert (can_substitute (^^S, { ^^NS }));\n+static_assert (!can_substitute (^^S, { ^^int, ^^long }));\n+static_assert (!can_substitute (^^S, { reflect_constant (42) }));\n+static_assert (!can_substitute (^^S, { ^^n }));\n+static_assert (!can_substitute (^^S, { ^^nsv }));\n+static_assert (!can_substitute (^^T, {}));\n+static_assert (!can_substitute (^^T, { ^^float, ^^int }));\n+constexpr float fv = 42.0f;\n+static_assert (can_substitute (^^T, { ^^fv, reflect_constant (42) }));\n+static_assert (can_substitute (^^T, { ^^fv, reflect_constant (0) }));\n+static_assert (can_substitute (^^T, { ^^fv, ^^n }));\n+static_assert (!can_substitute (^^T, { ^^n, ^^fv }));\n+static_assert (!can_substitute (^^T, { ^^fv, ^^n, ^^fv }));\n+\n+static_assert (can_substitute (^^U, {}));\n+static_assert (can_substitute (^^U, { ^^int }));\n+static_assert (can_substitute (^^U, { ^^int, ^^long, ^^const int &, ^^float, ^^double }));\n+static_assert (!can_substitute (^^U, { ^^int, ^^long, ^^const int &, ^^n, ^^float }));\n+\n+static_assert (!can_substitute (^^v, {}));\n+static_assert (can_substitute (^^v, { reflect_constant (15) }));\n+static_assert (can_substitute (^^v, { ^^n }));\n+static_assert (!can_substitute (^^v, { ^^n, ^^n }));\n+static_assert (!can_substitute (^^v, { ^^int }));\n+\n+static_assert (!can_substitute (^^C, {}));\n+static_assert (can_substitute (^^C, { ^^int }));\n+static_assert (can_substitute (^^C, { ^^V }));\n+static_assert (!can_substitute (^^C, { ^^int, ^^int }));\n+static_assert (!can_substitute (^^C, { reflect_constant (42) }));\n+static_assert (!can_substitute (^^C, { ^^n }));\n+\n+static_assert (!can_substitute (^^foo, {}));\n+static_assert (can_substitute (^^foo, { ^^int }));\n+static_assert (can_substitute (^^foo, { ^^V }));\n+static_assert (can_substitute (^^foo, { ^^NS }));\n+static_assert (!can_substitute (^^foo, { ^^int, ^^long }));\n+static_assert (!can_substitute (^^foo, { reflect_constant (42) }));\n+static_assert (!can_substitute (^^foo, { ^^n }));\ndiff --git a/gcc/testsuite/g++.dg/reflect/class1.C b/gcc/testsuite/g++.dg/reflect/class1.C\nnew file mode 100644\nindex 00000000000..8c9a06a1a0f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/class1.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on classes.\n+\n+struct S {\n+  using T = int;\n+};\n+\n+void\n+f1 ()\n+{\n+  constexpr auto s = ^^S;\n+  [: s :]::T i = 42;\n+  typename [: s :]::T j = 42;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/class2.C b/gcc/testsuite/g++.dg/reflect/class2.C\nnew file mode 100644\nindex 00000000000..b717521d2eb\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/class2.C\n@@ -0,0 +1,27 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test using a splice expression in an explicit destructor call.\n+\n+struct S { };\n+struct X { };\n+\n+void\n+ok (S s)\n+{\n+  /* [class.dtor]/16:\n+     In an explicit destructor call, the destructor is specified by\n+     a ~ followed by a type-name or computed-type-specifier that\n+     denotes the destructor's class type.  */\n+  s.~typename [:^^S:]();\n+}\n+\n+void\n+bad (S s)\n+{\n+  /* [expr.prim.splice]/2.1.2\n+     For a splice-expression of the form splice-specifier, let S be\n+     the construct designated by splice-specifier. The expression is\n+     ill-formed if S is [...] a destructor  */\n+  s.~[:^^S:](); // { dg-error \"expected\" }\n+  s.~typename [:^^X:](); // { dg-error \"the destructor refers to .X.\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/common_reference1.C b/gcc/testsuite/g++.dg/reflect/common_reference1.C\nnew file mode 100644\nindex 00000000000..2dff16562c2\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/common_reference1.C\n@@ -0,0 +1,61 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::common_reference.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+template <reflection_range R = std::initializer_list <info>>\n+consteval bool\n+has_common_reference (R &&args)\n+{\n+  try { common_reference (args); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+struct A { };\n+struct B { };\n+struct C { };\n+struct D { };\n+struct E { };\n+struct F { };\n+\n+template<template<typename> class AQual, template<typename> class BQual>\n+struct std::basic_common_reference<A, B, AQual, BQual>\n+{\n+  using type = BQual<AQual<C>>;\n+};\n+\n+template<> struct std::common_type<D, E> { using type = F; };\n+\n+static_assert (common_reference ({ ^^int }) == ^^int);\n+static_assert (common_reference ({ ^^int & }) == ^^int &);\n+static_assert (common_reference ({ ^^void }) == ^^void);\n+static_assert (common_reference ({ ^^const void }) == ^^const void);\n+static_assert (common_reference ({ ^^const void, ^^void }) == ^^void);\n+static_assert (common_reference ({ ^^void (*const) (), ^^void (*) () }) == ^^void (*) ());\n+static_assert (common_reference ({ ^^int, ^^int }) == ^^int);\n+static_assert (common_reference ({ ^^int &, ^^int }) == ^^int);\n+static_assert (common_reference ({ ^^int, ^^int & }) == ^^int);\n+static_assert (common_reference ({ ^^int &&, ^^int }) == ^^int);\n+static_assert (common_reference ({ ^^int &, ^^int & }) == ^^int &);\n+static_assert (common_reference ({ ^^int &, ^^int && }) == ^^const int &);\n+static_assert (common_reference ({ ^^int &&, ^^int & }) == ^^const int &);\n+static_assert (common_reference ({ ^^int &&, ^^int && }) == ^^int &&);\n+static_assert (common_reference ({ ^^int &&, ^^const int && }) == ^^const int &&);\n+static_assert (common_reference ({ ^^int &, ^^int &, ^^int && }) == ^^const int &);\n+static_assert (common_reference ({ ^^int &&, ^^int &, ^^int & }) == ^^const int &);\n+static_assert (common_reference ({ ^^char &, ^^int & }) == ^^int);\n+static_assert (common_reference ({ ^^long &, ^^int & }) == ^^long);\n+static_assert (common_reference ({ ^^A, ^^B }) == ^^C);\n+static_assert (common_reference ({ ^^A &, ^^B }) == ^^C &);\n+static_assert (common_reference ({ ^^A &, ^^const B }) == ^^C &);\n+static_assert (common_reference ({ ^^const A, ^^B & }) == ^^const C &);\n+static_assert (common_reference ({ ^^const A &, ^^B && }) == ^^const C &);\n+static_assert (common_reference ({ ^^const A, ^^B && }) == ^^const C &&);\n+static_assert (common_reference ({ ^^D, ^^E }) == ^^F);\n+static_assert (common_reference ({ ^^D &, ^^E }) == ^^F);\n+static_assert (common_reference ({ ^^D &, ^^E && }) == ^^F);\n+static_assert (!has_common_reference ({ ^^::, ^^int }));\n+static_assert (!has_common_reference ({ ^^int, ^^int, ^^std }));\ndiff --git a/gcc/testsuite/g++.dg/reflect/common_type1.C b/gcc/testsuite/g++.dg/reflect/common_type1.C\nnew file mode 100644\nindex 00000000000..996531a0969\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/common_type1.C\n@@ -0,0 +1,151 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::common_type.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+template <reflection_range R = std::initializer_list <info>>\n+consteval bool\n+has_common_type (R &&args)\n+{\n+  try { common_type (args); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+struct S {};\n+struct B {};\n+struct D : B {};\n+struct F1 { operator void * (); };\n+struct F2 { operator void * (); };\n+struct G1 { operator const void * (); };\n+struct G2 { operator volatile void * (); };\n+template <typename T>\n+struct ImplicitTo { operator T (); };\n+template <typename T>\n+struct ExplicitTo { explicit operator T (); };\n+template <typename T>\n+struct PrivateImplicitTo { private: operator T (); };\n+auto lmd1 = [] (int, double) {};\n+auto lmd2 = [] (int, double) {};\n+struct Abstract { virtual ~Abstract () = 0; };\n+enum class ScEn;\n+enum UnscEn : int;\n+struct Ukn;\n+union U { int i; };\n+union U2 { long i; };\n+union UConv1 { operator Abstract * (); };\n+union UConv2 { operator Abstract * (); };\n+struct X1 {};\n+struct X2 {};\n+struct RX12 {};\n+struct RX21 {};\n+struct Y1 {};\n+struct Y2 {};\n+struct Y3 {};\n+struct Y4 {};\n+\n+namespace std {\n+  template <>\n+  struct common_type <X1, X2> { typedef RX12 type; };\n+  template <>\n+  struct common_type <X2, X1> { typedef RX21 type; };\n+  template <>\n+  struct common_type <RX12, X1> { typedef Y1 type; };\n+  template <>\n+  struct common_type <X1, RX12> { typedef Y2 type; };\n+  template <>\n+  struct common_type <RX21, X1> { typedef Y3 type; };\n+  template <>\n+  struct common_type <X1, RX21> { typedef Y4 type; };\n+}\n+\n+using A = int;\n+static_assert (common_type ({ ^^int }) == ^^int);\n+static_assert (common_type ({ ^^A }) == ^^int);\n+static_assert (common_type ({ ^^const int }) == ^^int);\n+static_assert (common_type ({ ^^int, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^A, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^A, ^^A }) == ^^int);\n+static_assert (common_type ({ ^^const int, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^ScEn, ^^ScEn }) == ^^ScEn);\n+static_assert (common_type ({ ^^UnscEn, ^^UnscEn }) == ^^UnscEn);\n+static_assert (common_type ({ ^^UnscEn, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^int, ^^int, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^int, ^^int, ^^int, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^int, ^^int, ^^int, ^^int, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^S, ^^S }) == ^^S);\n+static_assert (common_type ({ ^^const S, ^^const S }) == ^^S);\n+static_assert (common_type ({ ^^std::initializer_list<int>, ^^std::initializer_list<int> }) == ^^std::initializer_list<int>);\n+static_assert (common_type ({ ^^B, ^^D }) == ^^B);\n+static_assert (common_type ({ ^^D, ^^B }) == ^^B);\n+static_assert (common_type ({ ^^F1, ^^F2 }) == ^^void *);\n+static_assert (common_type ({ ^^F2, ^^F1 }) == ^^void *);\n+static_assert (common_type ({ ^^G1, ^^G2 }) == ^^const volatile void *);\n+static_assert (common_type ({ ^^G2, ^^G1 }) == ^^const volatile void *);\n+static_assert (common_type ({ ^^int *, ^^const volatile int * }) == ^^const volatile int *);\n+static_assert (common_type ({ ^^void *, ^^const volatile int * }) == ^^const volatile void *);\n+static_assert (common_type ({ ^^void }) == ^^void);\n+static_assert (common_type ({ ^^const void }) == ^^void);\n+static_assert (common_type ({ ^^void, ^^void }) == ^^void);\n+static_assert (common_type ({ ^^const void, ^^const void }) == ^^void);\n+static_assert (common_type ({ ^^int &, ^^int && }) == ^^int);\n+static_assert (common_type ({ ^^int &, ^^int & }) == ^^int);\n+static_assert (common_type ({ ^^int &&, ^^int && }) == ^^int);\n+static_assert (common_type ({ ^^int &&, ^^const int && }) == ^^int);\n+static_assert (common_type ({ ^^U &, ^^const U && }) == ^^U);\n+static_assert (common_type ({ ^^U &, ^^U & }) == ^^U);\n+static_assert (common_type ({ ^^U &&, ^^U && }) == ^^U);\n+static_assert (common_type ({ ^^int B::*, ^^int D::* }) == ^^int D::*);\n+static_assert (common_type ({ ^^int D::*, ^^int B::* }) == ^^int D::*);\n+static_assert (common_type ({ ^^const int B::*, ^^volatile int D::* }) == ^^const volatile int D::*);\n+static_assert (common_type ({ ^^int (B::*) (), ^^int (D::*) () }) == ^^int (D::*) ());\n+static_assert (common_type ({ ^^int (B::*) () const, ^^int (D::*) () const }) == ^^int (D::*) () const);\n+static_assert (common_type ({ ^^int [3], ^^int [3] }) == ^^int *);\n+static_assert (common_type ({ ^^int [1], ^^const int [3] }) == ^^const int *);\n+static_assert (common_type ({ ^^void (), ^^void () }) == ^^void (*) ());\n+static_assert (common_type ({ ^^void (&) (), ^^void (&) () }) == ^^void (*) ());\n+static_assert (common_type ({ ^^void (&) (), ^^void (&&) () }) == ^^void (*) ());\n+static_assert (common_type ({ ^^void (&&) (), ^^void (&) () }) == ^^void (*) ());\n+static_assert (common_type ({ ^^void (&&) (), ^^void (&&) () }) == ^^void (*) ());\n+static_assert (common_type ({ ^^ImplicitTo<int>, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^const ImplicitTo<int>, ^^int }) == ^^int);\n+static_assert (common_type ({ ^^ImplicitTo<int>, ^^ImplicitTo<int> }) == ^^ImplicitTo<int>);\n+static_assert (common_type ({ ^^ImplicitTo<int>, ^^int, ^^ImplicitTo<int> }) == ^^int);\n+static_assert (common_type ({ ^^ExplicitTo<int>, ^^ExplicitTo<int> }) == ^^ExplicitTo<int>);\n+static_assert (common_type ({ ^^decltype (lmd1), ^^decltype (lmd1) }) == ^^decltype (lmd1));\n+static_assert (common_type ({ ^^decltype (lmd1) &, ^^decltype (lmd1) & }) == ^^decltype (lmd1));\n+static_assert (common_type ({ ^^decltype (lmd1) &, ^^decltype (lmd2) & }) == ^^void (*) (int, double));\n+static_assert (common_type ({ ^^decltype (nullptr), ^^void * }) == ^^void *);\n+static_assert (common_type ({ ^^decltype (nullptr), ^^int * }) == ^^int *);\n+static_assert (common_type ({ ^^const decltype (nullptr) &, ^^int * }) == ^^int *);\n+static_assert (common_type ({ ^^decltype (nullptr), ^^const volatile int * }) == ^^const volatile int *);\n+static_assert (common_type ({ ^^decltype (nullptr), ^^int (B::*) () }) == ^^int (B::*) ());\n+static_assert (common_type ({ ^^decltype (nullptr), ^^int (B::*) () const }) == ^^int (B::*) () const);\n+static_assert (common_type ({ ^^decltype (nullptr), ^^const int B::* }) == ^^const int B::*);\n+static_assert (common_type ({ ^^Abstract &, ^^Abstract & }) == ^^Abstract);\n+static_assert (common_type ({ ^^Ukn &, ^^Ukn & }) == ^^Ukn);\n+static_assert (common_type ({ ^^ImplicitTo<B &>, ^^B & }) == ^^B);\n+static_assert (common_type ({ ^^ImplicitTo<B &> &, ^^B && }) == ^^B);\n+static_assert (common_type ({ ^^UConv1, ^^const Abstract * & }) == ^^const Abstract *);\n+static_assert (common_type ({ ^^UConv1, ^^UConv2 }) == ^^Abstract *);\n+static_assert (common_type ({ ^^UConv1 &, ^^UConv2 & }) == ^^Abstract *);\n+static_assert (common_type ({ ^^Abstract &&, ^^Abstract && }) == ^^Abstract);\n+static_assert (common_type ({ ^^const Abstract &&, ^^const Abstract && }) == ^^Abstract);\n+static_assert (common_type ({ ^^volatile Abstract &&, ^^volatile Abstract && }) == ^^Abstract);\n+static_assert (common_type ({ ^^Ukn &&, ^^Ukn && }) == ^^Ukn);\n+static_assert (common_type ({ ^^const Ukn &&, ^^const Ukn && }) == ^^Ukn);\n+static_assert (common_type ({ ^^volatile Ukn &&, ^^volatile Ukn && }) == ^^Ukn);\n+static_assert (common_type ({ ^^X1, ^^X2 }) == ^^RX12);\n+static_assert (common_type ({ ^^const X1, ^^X2 }) == ^^RX12);\n+static_assert (common_type ({ ^^X1 &, ^^const X2 }) == ^^RX12);\n+static_assert (common_type ({ ^^const X1 &, ^^const X2 & }) == ^^RX12);\n+static_assert (common_type ({ ^^X2, ^^X1 }) == ^^RX21);\n+static_assert (common_type ({ ^^X1, ^^X2, ^^X1 }) == ^^Y1);\n+static_assert (common_type ({ ^^X2, ^^X1, ^^X1 }) == ^^Y3);\n+static_assert (common_type ({ ^^X1, ^^X1, ^^X2 }) == ^^RX12);\n+static_assert (common_type ({ ^^X1 &, ^^const X1, ^^const X2 && }) == ^^RX12);\n+static_assert (common_type ({ ^^X1, ^^X1, ^^X2, ^^X1 }) == ^^Y1);\n+static_assert (!has_common_type ({ ^^::, ^^int }));\n+static_assert (!has_common_type ({ ^^int, ^^int, ^^std }));\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare1.C b/gcc/testsuite/g++.dg/reflect/compare1.C\nnew file mode 100644\nindex 00000000000..e54902baed6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare1.C\n@@ -0,0 +1,38 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test comparison of reflections.  Valid uses.\n+\n+#include <meta>\n+\n+namespace N {\n+  namespace M {\n+  }\n+}\n+\n+namespace NN = N;\n+namespace NM = N::M;\n+\n+static_assert(^^int == ^^int);\n+static_assert(^^int != ^^const int);\n+static_assert(^^int != ^^int &);\n+static_assert(^^int const == ^^const int);\n+\n+static_assert(^^char == ^^char);\n+static_assert(^^char != ^^unsigned char);\n+static_assert(^^char != ^^signed char);\n+\n+static_assert(^^:: == ^^::);\n+static_assert(^^:: != ^^N);\n+static_assert(^^N == ^^N);\n+static_assert(^^N != ^^N::M);\n+static_assert(^^N != ^^NN);\n+static_assert(^^N::M == ^^N::M);\n+static_assert(^^N::M != ^^NM);\n+\n+using Alias = int;\n+static_assert(^^int != ^^Alias);\n+static_assert(^^int == std::meta::dealias (^^Alias));\n+\n+namespace AliasNS = ::std;\n+static_assert(^^::std != ^^AliasNS);\n+static_assert(^^:: == parent_of(^^::std));\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare10.C b/gcc/testsuite/g++.dg/reflect/compare10.C\nnew file mode 100644\nindex 00000000000..7f63b79a28f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare10.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test comparing COMPONENT_REFs.\n+\n+#include <meta>\n+\n+struct S { int x, y; };\n+\n+consteval auto f(S &s) {\n+  return std::meta::reflect_object(s.x);\n+}\n+\n+S s;\n+int& x = s.x;\n+static_assert(object_of(^^x) == f(s));\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare2.C b/gcc/testsuite/g++.dg/reflect/compare2.C\nnew file mode 100644\nindex 00000000000..1b509bc8cd3\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare2.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test comparison of reflections.  Invalid uses.\n+\n+consteval void\n+f ()\n+{\n+  bool b = ^^int > ^^int;   // { dg-error \"invalid operands of types .std::meta::info. and .std::meta::info. to binary\" }\n+//  b = ^^int < ^^int;\n+  b = ^^int >= ^^int;\t    // { dg-error \"invalid operands of types .std::meta::info. and .std::meta::info. to binary\" }\n+  b = ^^int <= ^^int;\t    // { dg-error \"invalid operands of types .std::meta::info. and .std::meta::info. to binary\" }\n+  +^^int;\t\t    // { dg-error \"wrong type argument to unary plus\" }\n+  !^^int;\t\t    // { dg-error \"could not convert .\\\\^\\\\^int. from .std::meta::info. to .bool.\" }\n+\t\t\t    // { dg-error \"in argument to unary\" \"\" { target *-*-* } .-1 }\n+  ~^^int;\t\t    // { dg-error \"wrong type argument to bit-complement\" }\n+  *^^int;\t\t    // { dg-error \"invalid type argument of unary\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare3.C b/gcc/testsuite/g++.dg/reflect/compare3.C\nnew file mode 100644\nindex 00000000000..2a49773a0ac\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare3.C\n@@ -0,0 +1,24 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test comparison of reflections.\n+\n+namespace N {\n+namespace foo {\n+struct foo {\n+  static_assert(^^foo == ^^::N::foo::foo);\n+};\n+static_assert(^^foo == ^^::N::foo::foo);\n+}\n+\n+namespace tfoo {\n+template <typename T> struct tfoo {\n+  static_assert(^^tfoo == ^^tfoo<T>);\n+};\n+static_assert(^^tfoo == ^^::N::tfoo::tfoo);\n+\n+tfoo<int> instantiation;\n+}\n+\n+static_assert(^^foo == ^^::N::foo);\n+static_assert(^^tfoo == ^^::N::tfoo);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare4.C b/gcc/testsuite/g++.dg/reflect/compare4.C\nnew file mode 100644\nindex 00000000000..f3b41c5e3c9\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare4.C\n@@ -0,0 +1,27 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test comparison of reflections.\n+\n+using info = decltype(^^void);\n+\n+int x;\n+void fn();\n+struct S {\n+  int x;\n+  static constexpr int s_x = 11;\n+  void fn();\n+  static void s_fn();\n+};\n+enum Enum { A, B, C };\n+enum class EnumCls { A, B, C };\n+\n+static_assert(&[:^^x:] == &x);\n+static_assert([:^^fn:] == fn);\n+\n+static_assert(&[:^^S::x:] == &S::x);\n+static_assert(&[:^^S::s_x:] == &S::s_x);\n+static_assert(&[:^^S::fn:] == &S::fn);\n+static_assert([:^^S::s_fn:] == S::s_fn);\n+\n+static_assert([:^^Enum::B:] == Enum::B);\n+static_assert([:^^EnumCls::B:] == EnumCls::B);\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare5.C b/gcc/testsuite/g++.dg/reflect/compare5.C\nnew file mode 100644\nindex 00000000000..f8aa7bb6194\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare5.C\n@@ -0,0 +1,8 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test splicing of explicit object member functions.\n+\n+struct Y {\n+    int g(this Y const&, int, int);\n+};\n+static_assert(&Y::g == &[:^^Y::g:]);\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare6.C b/gcc/testsuite/g++.dg/reflect/compare6.C\nnew file mode 100644\nindex 00000000000..4dd10eb97f6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare6.C\n@@ -0,0 +1,12 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+enum Enum { A, B, C };\n+enum class EnumCls { A, B, C };\n+\n+constexpr info rB = ^^B, rClsB = ^^EnumCls::B;\n+static_assert(rB != rClsB);\n+static_assert(int([:rB:]) == int([:rClsB:]));\n+static_assert(static_cast<Enum>([:rClsB:]) == B);\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare7.C b/gcc/testsuite/g++.dg/reflect/compare7.C\nnew file mode 100644\nindex 00000000000..5c67c57feb5\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare7.C\n@@ -0,0 +1,20 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Reflection of a reflection.\n+\n+using info = decltype(^^void);\n+constexpr info r1 = ^^int;\n+constexpr info r2 = ^^int;\n+constexpr info rr1 = ^^r1;\n+constexpr info rr2 = ^^r2;\n+static_assert (r1 == ^^int);\n+static_assert (r1 == r2);\n+static_assert (r1 != rr1);\n+static_assert (r1 != rr2);\n+static_assert (^^r1 != ^^r2);\n+static_assert (^^int != rr1);\n+static_assert (^^r1 == rr1);\n+static_assert (rr2 != rr1);\n+static_assert (rr2 != ^^r1);\n+static_assert (rr2 == ^^r2);\n+static_assert (rr1 != ^^r2);\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare8.C b/gcc/testsuite/g++.dg/reflect/compare8.C\nnew file mode 100644\nindex 00000000000..6ea6c83c72b\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare8.C\n@@ -0,0 +1,67 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Reflection of a reflection.\n+\n+template <int N>\n+void\n+foo ()\n+{\n+}\n+\n+template <typename ... T>\n+void\n+bar ()\n+{\n+}\n+\n+template <int N>\n+struct R {};\n+\n+template <typename ... T>\n+struct S {};\n+\n+using info = decltype (^^int);\n+constexpr info r1 = ^^foo;\n+constexpr info r2 = ^^foo <42>;\n+constexpr info r3 = ^^foo <43>;\n+constexpr info r4 = ^^R;\n+constexpr info r5 = ^^R <42>;\n+constexpr info r6 = ^^R <43>;\n+constexpr info r7 = ^^bar;\n+constexpr info r8 = ^^bar <>;\n+constexpr info r9 = ^^bar <int>;\n+constexpr info r10 = ^^bar <int, int>;\n+constexpr info r11 = ^^bar <int, int, long>;\n+constexpr info r12 = ^^S;\n+constexpr info r13 = ^^S <>;\n+constexpr info r14 = ^^S <int>;\n+constexpr info r15 = ^^S <int, int>;\n+constexpr info r16 = ^^S <int, int, long>;\n+static_assert (r1 == ^^foo);\n+static_assert (r2 == ^^foo <42>);\n+static_assert (r3 == ^^foo <43>);\n+static_assert (r4 == ^^R);\n+static_assert (r5 == ^^R <42>);\n+static_assert (r6 == ^^R <43>);\n+static_assert (r7 == ^^bar);\n+static_assert (r8 == ^^bar <>);\n+static_assert (r9 == ^^bar <int>);\n+static_assert (r10 == ^^bar <int, int>);\n+static_assert (r11 == ^^bar <int, int, long>);\n+static_assert (r12 == ^^S);\n+static_assert (r13 == ^^S <>);\n+static_assert (r14 == ^^S <int>);\n+static_assert (r15 == ^^S <int, int>);\n+static_assert (r16 == ^^S <int, int, long>);\n+static_assert (r1 != r2);\n+static_assert (r2 != r3);\n+static_assert (r4 != r5);\n+static_assert (r5 != r6);\n+static_assert (r7 != r8);\n+static_assert (r8 != r9);\n+static_assert (r9 != r10);\n+static_assert (r10 != r11);\n+static_assert (r12 != r13);\n+static_assert (r13 != r14);\n+static_assert (r14 != r15);\n+static_assert (r15 != r16);\ndiff --git a/gcc/testsuite/g++.dg/reflect/compare9.C b/gcc/testsuite/g++.dg/reflect/compare9.C\nnew file mode 100644\nindex 00000000000..74815869400\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compare9.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test comparison of reflections.\n+\n+#include <meta>\n+#include <ranges>\n+\n+static union { int a; };\n+struct S { void foo () {} };\n+template <typename T>\n+consteval auto bar () { int v = 42; return parent_of (^^v); }\n+template <typename T>\n+consteval std::meta::info baz () { int v = 42; return parent_of (^^v); }\n+\n+constexpr auto ctx = std::meta::access_context::unchecked ();\n+// TODO: These should work\n+//static_assert (^^a == members_of (parent_of (^^a), ctx)[0]);\n+//static_assert (^^S::~S == (members_of (^^S, ctx) | std::views::filter (std::meta::is_destructor) | std::ranges::to <std::vector> ())[0]);\n+static_assert (^^S::foo == members_of (^^S, ctx)[0]);\n+static_assert (^^bar <int> == bar <int> ());\n+constexpr auto b = ^^bar <long>;\n+static_assert (b == bar <long> ());\n+static_assert (^^baz <int> == baz <int> ());\n+constexpr auto c = ^^baz <long>;\n+static_assert (c == baz <long> ());\ndiff --git a/gcc/testsuite/g++.dg/reflect/compat1.C b/gcc/testsuite/g++.dg/reflect/compat1.C\nnew file mode 100644\nindex 00000000000..8cb9f9ab5c9\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/compat1.C\n@@ -0,0 +1,13 @@\n+// C++26 P2996R13 - Reflection for C++26\n+// [diff.cpp23.dcl.dcl] tests\n+// { dg-do compile { target c++11 } }\n+// { dg-options \"\" }\n+\n+struct C { int operator ^ (int); };\n+int operator ^ (int (C::*p) (int), C);\n+int i = &C::operator ^^ C {};\t// { dg-error \"expected type-specifier before '\\\\\\^\\\\\\^' token\" \"\" { target c++26 } }\n+\n+struct [[using CC:]] C;\t\t// { dg-warning \"attribute using prefix only available with\" \"\" { target c++14_down } }\n+\t\t\t\t// { dg-error \"expected '\\\\\\]' before 'CC'\" \"\" { target c++26 } .-1 }\n+\t\t\t\t// { dg-error \"expected identifier before ';' token\" \"\" { target c++26 } .-2 }\n+struct [[using DD: ]] D;\t// { dg-warning \"attribute using prefix only available with\" \"\" { target c++14_down } }\ndiff --git a/gcc/testsuite/g++.dg/reflect/complete1.C b/gcc/testsuite/g++.dg/reflect/complete1.C\nnew file mode 100644\nindex 00000000000..269a20970cb\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/complete1.C\n@@ -0,0 +1,54 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test which constructs or metafunctions implicitly instantiate.\n+\n+#include <meta>\n+\n+template <int N>\n+struct S {\n+  static_assert (N < 42);\t// { dg-line static_assert }\n+};\n+// { dg-error \"static assertion failed\" \"\" { target *-*-* } static_assert }\n+// { dg-bogus \"the comparison reduces to '\\\\\\(42 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(43 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(44 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-bogus \"the comparison reduces to '\\\\\\(45 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-bogus \"the comparison reduces to '\\\\\\(46 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(47 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(48 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(49 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(50 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(51 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(52 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(53 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(54 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(55 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(56 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(57 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-bogus \"the comparison reduces to '\\\\\\(58 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+// { dg-message \"the comparison reduces to '\\\\\\(59 < 42\\\\\\)'\" \"\" { target *-*-* } static_assert }\n+\n+S<0> s1;\n+constexpr auto a = ^^S<42>;\n+bool b = is_complete_type (^^S<43>);\n+bool c = is_enumerable_type (^^S<44>);\n+constexpr auto d = data_member_spec (^^S<45>, { .name = \"_\" });\n+consteval {\n+  define_aggregate (^^S<46>, { data_member_spec (^^int, { .name = \"_\" }) });\n+}\n+auto e = size_of (^^S<47>);\n+auto f = bit_size_of (^^S<48>);\n+int g;\n+constexpr auto h = annotations_of_with_type (^^g, ^^S<49>);\n+constexpr auto ctx = std::meta::access_context::current ();\n+auto i = members_of (^^S<50>, ctx).size ();\n+auto j = bases_of (^^S<51>, ctx).size ();\n+auto k = static_data_members_of (^^S<52>, ctx).size ();\n+auto l = nonstatic_data_members_of (^^S<53>, ctx).size ();\n+auto m = subobjects_of (^^S<54>, ctx).size ();\n+bool n = has_inaccessible_nonstatic_data_members (^^S<55>, ctx);\n+bool o = has_inaccessible_bases (^^S<56>, ctx);\n+bool p = has_inaccessible_subobjects (^^S<57>, ctx);\n+consteval {\n+  define_aggregate (^^S<58>, { data_member_spec (^^S<59>, { .name = \"_\" }) });\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of1.C b/gcc/testsuite/g++.dg/reflect/constant_of1.C\nnew file mode 100644\nindex 00000000000..f467e60f86a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of1.C\n@@ -0,0 +1,40 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr int x = 0;\n+constexpr int y = 0;\n+\n+// OK, x and y are different variables, so their reflections compare different\n+static_assert (^^x != ^^y);\n+\n+// OK, both constant_of(^^x) and constant_of(^^y) represent the value 0\n+static_assert (constant_of (^^x) == constant_of (^^y));\n+\n+// OK, likewise\n+static_assert (constant_of (^^x) == reflect_constant (0));\n+\n+struct S { int m; };\n+constexpr S s {42};\n+static_assert (is_object (constant_of (^^s)) && is_object (reflect_object (s)));\n+// OK, template parameter object that is template-argument-equivalent to s is\n+// a different object than s\n+static_assert (constant_of (^^s) != reflect_object (s));\n+static_assert (constant_of (^^s) == constant_of (reflect_object (s)));\n+constexpr auto r1 = reflect_constant (s);\n+constexpr auto r2 = reflect_object (s);\n+static_assert (is_object (r1) && is_object (r2));\n+static_assert (r1 != r2);\n+static_assert (r1 == constant_of (r2));\n+\n+consteval info fn() {\n+  constexpr int x = 42;\n+  return ^^x;\n+}\n+\n+// error: x is outside its lifetime\n+constexpr info r = constant_of (fn ());\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of2.C b/gcc/testsuite/g++.dg/reflect/constant_of2.C\nnew file mode 100644\nindex 00000000000..dae41c930b2\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of2.C\n@@ -0,0 +1,87 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr int i = 1;\n+static_assert (constant_of (^^i) == constant_of (object_of (^^i)));\n+const int &r = i;\n+static_assert (constant_of (^^i) == reflect_constant (1));\n+static_assert (object_of (^^r) == object_of (^^i));\n+\n+const int constGlobal = 11;\n+constexpr auto rref = reflect_object (constGlobal);\n+\n+static_assert (constant_of (^^constGlobal) != ^^constGlobal);\n+static_assert ([:constant_of (^^constGlobal):] == 11);\n+static_assert ([:constant_of (rref):] == 11);\n+static_assert (constant_of (^^constGlobal) == constant_of (rref));\n+static_assert (constant_of (^^constGlobal) == reflect_constant (11));\n+\n+enum Enum { A };\n+static constexpr Enum e = A;\n+\n+enum EnumCls { CA };\n+static constexpr EnumCls ce = CA;\n+\n+static_assert (constant_of (^^A) != constant_of (^^CA));\n+static_assert (constant_of (^^A) != reflect_constant (0));\n+static_assert (constant_of (^^A) == reflect_constant (Enum (0)));\n+\n+static_assert (constant_of (^^A) != reflect_constant (EnumCls (0)));\n+static_assert (constant_of (^^e) != reflect_constant (0));\n+static_assert (constant_of (^^e) == reflect_constant (Enum (0)));\n+static_assert (constant_of (^^e) != reflect_constant (EnumCls (0)));\n+static_assert (constant_of (^^ce) != reflect_constant (0));\n+static_assert (constant_of (^^ce) != reflect_constant (Enum (0)));\n+static_assert (constant_of (^^ce) == reflect_constant (EnumCls (0)));\n+\n+using Alias1 = int;\n+constexpr Alias1 a1 = 3;\n+// ??? In clang++, type_of here produces \"^^const int\".  But\n+// <https://eel.is/c++draft/meta.reflection#queries-2> doesn't say anything\n+// about dealias.  On the other side it in all cases talks about\n+// reflection of types and type aliases aren't types, just entities\n+// with underlying entity thereof.\n+static_assert (type_of (^^a1) == ^^const int);\n+static_assert (type_of (constant_of (^^a1)) == ^^int);\n+\n+struct S{};\n+using Alias2 = S;\n+constexpr Alias2 a2 {};\n+// And here maybe it should be ^^S instead of ^^Alias2.\n+static_assert (type_of (^^a2) == ^^const Alias2);\n+// constant_of produces _ZTAXtl1SEE whose type is \"const S\".\n+static_assert (type_of (constant_of (^^a2)) == ^^const S);\n+\n+constexpr const int &ref = a1;\n+static_assert (type_of (constant_of (^^ref)) == ^^int);\n+\n+constexpr std::pair<std::pair<int, bool>, int> p = {{1, true}, 2};\n+static_assert (type_of (constant_of (reflect_object (p.first))) == ^^const std::pair<int, bool>);\n+constexpr info rfirst = reflect_object (p.first);\n+static_assert (is_object (rfirst) && !is_value (rfirst));\n+static_assert (type_of (rfirst) == ^^const std::pair<int, bool>);\n+static_assert (rfirst != reflect_constant (std::make_pair (1, true)));\n+\n+constexpr info rvfirst = constant_of (rfirst);\n+static_assert (is_object (rvfirst) && !is_value (rvfirst));\n+static_assert (type_of (rvfirst) == ^^const std::pair<int, bool>);\n+static_assert (rvfirst == reflect_constant (std::make_pair (1, true)));\n+static_assert ([:rvfirst:].first == 1);\n+\n+constexpr int g = 3;\n+consteval info\n+fn ()\n+{\n+  const int &rg = g;\n+  static_assert ([:constant_of(^^rg):] == 3);\n+  return constant_of (^^rg);\n+}\n+static_assert ([:fn ():] == 3);\n+\n+constexpr int foo () { return 42; }\n+static_assert (constant_of (^^foo) == reflect_function (foo));\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of3.C b/gcc/testsuite/g++.dg/reflect/constant_of3.C\nnew file mode 100644\nindex 00000000000..e386d26678a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of3.C\n@@ -0,0 +1,60 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+const int K = 0;\n+consteval const int &fn() { return K; }\n+\n+constexpr auto v = constant_of (reflect_constant (fn ()));\n+static_assert (is_value (v) && !is_object (v));\n+static_assert (type_of (v) == ^^int);\n+static_assert (!is_variable (v));\n+static_assert (v == reflect_constant (0));\n+\n+template<int N>\n+constexpr int V = N;\n+\n+struct W {\n+  static constexpr int I = 42;\n+};\n+\n+// clang++ doesn't accept this.  That seems wrong.\n+constexpr auto v2 = constant_of (^^V<3>);\n+static_assert (is_value (v2) && !is_object (v2));\n+static_assert (type_of (v2) == ^^int);\n+static_assert (!is_variable (v2));\n+static_assert (v2 == reflect_constant (3));\n+\n+constexpr auto v3 = constant_of (^^W::I);\n+static_assert (is_value (v3) && !is_object (v3));\n+static_assert (type_of (v3) == ^^int);\n+static_assert (!is_variable (v3));\n+static_assert (v3 == reflect_constant (42));\n+\n+constexpr auto v4 = constant_of (reflect_constant (42));\n+static_assert (is_value (v4) && !is_object (v4));\n+static_assert (type_of (v4) == ^^int);\n+static_assert (!is_variable (v4));\n+static_assert (v4 == reflect_constant (42));\n+\n+template<info R>\n+void\n+f ()\n+{\n+  constexpr auto v = constant_of (R);\n+  static_assert (is_value (v) && !is_object (v));\n+  static_assert (type_of (v) == ^^int);\n+  static_assert (!is_variable (v));\n+  static_assert (v == reflect_constant (42));\n+}\n+\n+void\n+g ()\n+{\n+  constexpr int b = 42;\n+  f<^^b>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of4.C b/gcc/testsuite/g++.dg/reflect/constant_of4.C\nnew file mode 100644\nindex 00000000000..d08d4a3f171\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of4.C\n@@ -0,0 +1,50 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S {\n+  int k;\n+  int bf:32;\n+};\n+\n+constexpr info null_reflection;\n+static union { int m; };\n+namespace NS { }\n+using T = int;\n+\n+consteval bool\n+constant_of_ok (info r)\n+{\n+  try { constant_of (r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+static_assert (!constant_of_ok (^^S::k));\n+static_assert (!constant_of_ok (^^m));\n+static_assert (!constant_of_ok (^^int));\n+static_assert (!constant_of_ok (^^NS));\n+static_assert (!constant_of_ok (^^S::bf));\n+static_assert (!constant_of_ok (null_reflection));\n+static_assert (!constant_of_ok (^^T));\n+\n+template<typename>\n+struct X { };\n+static_assert (!constant_of_ok (^^X));\n+static_assert (!constant_of_ok (^^X<int>));\n+\n+template<int N>\n+constexpr int bar () { return N; }\n+static_assert (!constant_of_ok (^^bar));\n+\n+template<int N>\n+constexpr int V = N;\n+\n+static_assert (!constant_of_ok (^^V));\n+\n+int x = 10;\n+constexpr auto rx = constant_of (^^x); // { dg-error \"not usable in a constant expression\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of5.C b/gcc/testsuite/g++.dg/reflect/constant_of5.C\nnew file mode 100644\nindex 00000000000..07187e915b0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of5.C\n@@ -0,0 +1,86 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+[[=1, =1, =2, =1.0f]] int i;\n+static_assert (type_of (constant_of (annotations_of (^^i)[0])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^i)[1])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^i)[2])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^i)[3])) == ^^float);\n+\n+[[=1, =1, =2, =1.0f]] void fn();\n+static_assert (type_of (constant_of (annotations_of (^^fn)[0])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^fn)[1])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^fn)[2])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^fn)[3])) == ^^float);\n+\n+struct [[=3, =3, =4, =2.0f]] S;\n+static_assert (type_of (constant_of (annotations_of (^^S)[0])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^S)[1])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^S)[2])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^S)[3])) == ^^float);\n+#if 0\n+template <typename> struct [[=5, =5, =6, =3.0f]] TCls {};\n+// TODO Should work but we don't propagate the annotations correctly to the\n+// instantiation.  See also the TODO in annotations3.C.\n+static_assert (type_of (constant_of (annotations_of (^^TCls<int>)[0])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^TCls<int>)[1])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^TCls<int>)[2])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^TCls<int>)[3])) == ^^float);\n+#endif\n+template <typename> [[=5, =5, =6, =3.0f]] void TFn();\n+static_assert (type_of (constant_of (annotations_of (^^TFn<int>)[0])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^TFn<int>)[1])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^TFn<int>)[2])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^TFn<int>)[3])) == ^^float);\n+namespace [[=7, =7, =8, =4.0f]] NS {}\n+static_assert (type_of (constant_of (annotations_of (^^NS)[0])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^NS)[1])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^NS)[2])) == ^^int);\n+static_assert (type_of (constant_of (annotations_of (^^NS)[3])) == ^^float);\n+\n+constexpr struct X {} x;\n+[[=x]] void foo ();\n+\n+// TODO clang++ says ^^X, we say ^^const X.\n+static_assert (type_of (annotations_of (^^foo)[0]) == ^^const X);\n+static_assert (type_of (constant_of (annotations_of (^^foo)[0])) == ^^const X);\n+\n+template<info R>\n+[[=[:constant_of (annotations_of (R)[0]):]]] void bar();\n+\n+template<info R>\n+struct [[=[:constant_of (annotations_of (R)[0]):]]] Y {};\n+\n+static_assert (extract<int>(annotations_of (^^bar<^^::fn>)[0]) == 1);\n+//static_assert (extract<int>(annotations_of (^^Y<^^::S>)[0]) == 3);\n+\n+struct [[=42, =42.0f]] S1;\n+struct [[=42, =40]] S2;\n+\n+static_assert (annotations_of (^^S1)[0] == annotations_of (^^S1)[0]);\n+static_assert (annotations_of (^^S1)[0] != annotations_of (^^S2)[0]);\n+static_assert (annotations_of (^^S1)[0] != annotations_of (^^S1)[1]);\n+\n+static_assert (constant_of (annotations_of (^^S1)[0]) == reflect_constant (42));\n+static_assert (constant_of (annotations_of (^^S1)[0]) == constant_of (annotations_of (^^S2)[0]));\n+\n+// A test from clang.\n+struct test_struct {};\n+constexpr test_struct test;\n+\n+[[=test]] void func() {}\n+[[=1]] void func2() {}\n+\n+constexpr auto func_first = constant_of (annotations_of (^^func)[0]);\n+constexpr auto func2_first = constant_of (annotations_of (^^func2)[0]);\n+\n+static_assert (constant_of (^^test) == reflect_constant (test));\n+// TODO We evaluate the decltype to test_struct.\n+//static_assert (std::same_as<decltype([:func_first:]), const test_struct &>);\n+static_assert (func2_first == reflect_constant (1));\n+static_assert (func_first == reflect_constant (test));\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of6.C b/gcc/testsuite/g++.dg/reflect/constant_of6.C\nnew file mode 100644\nindex 00000000000..21bd6a412b0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of6.C\n@@ -0,0 +1,26 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+[[=1, =1, =2, =1.0f]] void fn();\n+struct [[=3, =3, =4, =2.0f]] S;\n+\n+template<info R>\n+[[=[:constant_of (annotations_of (R)[0]):]]] void bar();\n+\n+template<info R>\n+struct [[=[:constant_of (annotations_of (R)[0]):]]] Y {};\n+\n+// TODO Fix this ugly crash.\n+/* This ICEs because we get:\n+   <<< Unknown tree: splice_expr\n+  std::meta::constant_of (*std::meta::annotations_of (<<< Unknown tree: template_parm_index >>>).<<< Unknown tree: baselink >>> (0)) >>>\n+  which needs to be substituted before we can do anything about it.\n+  constant_of5.C has the same problem (with extract).  */\n+\n+constexpr auto y = constant_of (annotations_of (^^bar<^^::fn>)[0]);\n+//constexpr auto z = constant_of (annotations_of (^^Y<^^::S>)[0]);\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of7.C b/gcc/testsuite/g++.dg/reflect/constant_of7.C\nnew file mode 100644\nindex 00000000000..1958fdcff6a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of7.C\n@@ -0,0 +1,54 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr int arr[] = { 1, 2, 3, 4 };\n+constexpr auto r = constant_of (^^arr);\n+static_assert (!is_value (r) && !is_object (r));\n+static_assert (*[:r:] == 1);\n+static_assert ([:r:][0] == 1);\n+static_assert ([:r:][1] == 2);\n+static_assert ([:r:][2] == 3);\n+static_assert ([:r:][3] == 4);\n+static_assert (type_of (r) == ^^const int [4]);\n+constexpr auto q = reflect_constant ([: ^^arr :]);\n+static_assert (type_of (q) == ^^const int *);\n+static_assert ([:q:][0] == 1);\n+static_assert ([:q:][1] == 2);\n+static_assert ([:q:][2] == 3);\n+static_assert ([:q:][3] == 4);\n+\n+using U = int;\n+constexpr U arr2[] = { 5, 6, 7, 8 };\n+constexpr auto r2 = constant_of (^^arr2);\n+static_assert (!is_value (r2) && !is_object (r2));\n+static_assert ([:r2:][0] == 5);\n+static_assert ([:r2:][1] == 6);\n+static_assert ([:r2:][2] == 7);\n+static_assert ([:r2:][3] == 8);\n+// ??? Probably should be const int *.\n+static_assert (type_of (r2) == ^^const U [4]);\n+constexpr auto q2 = reflect_constant ([: ^^arr2 :]);\n+static_assert (type_of (q2) == ^^const U *);\n+static_assert ([:q2:][0] == 5);\n+static_assert ([:q2:][1] == 6);\n+static_assert ([:q2:][2] == 7);\n+static_assert ([:q2:][3] == 8);\n+\n+struct S { int m; };\n+constexpr S arr3[] = { S{1}, S{2}, S{3} };\n+constexpr auto r3 = constant_of (^^arr3);\n+static_assert (!is_value (r3) && !is_object (r3));\n+static_assert ([:r3:][0].m == 1);\n+static_assert ([:r3:][1].m == 2);\n+static_assert ([:r3:][2].m == 3);\n+static_assert (type_of (r3) == ^^const S [3]);\n+constexpr auto q3 = reflect_constant ([: ^^arr3 :]);\n+static_assert (type_of (q3) == ^^const S *);\n+static_assert ([:q3:][0].m == 1);\n+static_assert ([:q3:][1].m == 2);\n+static_assert ([:q3:][2].m == 3);\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of8.C b/gcc/testsuite/g++.dg/reflect/constant_of8.C\nnew file mode 100644\nindex 00000000000..bd2e4cec389\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of8.C\n@@ -0,0 +1,16 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of, CWG 3111.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+constexpr int is[] = {1, 2, 3};\n+constexpr info r = reflect_constant_array (is);\n+static_assert (constant_of (^^is) == r);\n+\n+constexpr int mis[2][2] = {{1, 2}, {3, 4}};\n+// LWG4483 Multidimensional arrays\n+// constexpr info mr = reflect_constant_array (mis);\n+// static_assert (constant_of (^^mis) == mr);\n+\ndiff --git a/gcc/testsuite/g++.dg/reflect/constant_of9.C b/gcc/testsuite/g++.dg/reflect/constant_of9.C\nnew file mode 100644\nindex 00000000000..5cbc4095f16\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/constant_of9.C\n@@ -0,0 +1,9 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::constant_of, CWG 3111.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+void f() {}\n+static_assert (constant_of (^^f) == reflect_function (f));\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash1.C b/gcc/testsuite/g++.dg/reflect/crash1.C\nnew file mode 100644\nindex 00000000000..c93b6e190e9\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash1.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct free_entry {\n+  free_entry *next;\n+} first_free_entry;\n+\n+struct A;\n+struct B {\n+  A *a;\n+} BT;\n+\n+struct A {\n+  B b;\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash10.C b/gcc/testsuite/g++.dg/reflect/crash10.C\nnew file mode 100644\nindex 00000000000..05845846e23\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash10.C\n@@ -0,0 +1,11 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct S { };\n+using X = S;\n+\n+template <auto V> constexpr int e = [:V:];  // { dg-error \"expected a reflection of an expression instead of type .X.\" }\n+template <auto V> constexpr int e2 = [:V:]; // { dg-error \"expected a reflection of an expression instead of type .X.\" }\n+constexpr auto h = ^^X;\n+constexpr auto i = e<([:^^h:])>;\n+constexpr auto j = e2<^^X>;\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash11.C b/gcc/testsuite/g++.dg/reflect/crash11.C\nnew file mode 100644\nindex 00000000000..3aef5d0b2fe\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash11.C\n@@ -0,0 +1,23 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+template<typename T>\n+struct Z {};\n+\n+struct S {\n+  static constexpr auto r = ^^Z;\n+};\n+\n+template<typename T, auto R>\n+void\n+g ()\n+{\n+  template [: R :]<int> c0; // { dg-error \"not a function template|expected\" }\n+  template [: T::r :]<int> c1;  // { dg-error \"not a function template|expected\" }\n+}\n+\n+void\n+f ()\n+{\n+  g<S, ^^Z>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash12.C b/gcc/testsuite/g++.dg/reflect/crash12.C\nnew file mode 100644\nindex 00000000000..a234c95be55\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash12.C\n@@ -0,0 +1,8 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+struct X { constexpr operator std::meta::info(); }; // { dg-error \"function of consteval-only type\" }\n+// { dg-warning \"used but never defined\" \"\" { target *-*-* } .-1 }\n+constexpr auto r = std::meta::type_of (X{}); // { dg-error \"used before its definition\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash13.C b/gcc/testsuite/g++.dg/reflect/crash13.C\nnew file mode 100644\nindex 00000000000..50779e88cf0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash13.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^int);\n+\n+struct S {\n+  int j;\n+};\n+\n+template <info R>\n+consteval int fn() {\n+  auto x = [:R:]; // { dg-error \"cannot implicitly reference a class member\" }\n+  return true;\n+}\n+static_assert (fn<^^S::j>());\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash14.C b/gcc/testsuite/g++.dg/reflect/crash14.C\nnew file mode 100644\nindex 00000000000..e9654131fd7\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash14.C\n@@ -0,0 +1,7 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+constexpr int i = 0;\n+const int p = ++std::meta::extract<const int &>(^^i); // { dg-error \"\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash15.C b/gcc/testsuite/g++.dg/reflect/crash15.C\nnew file mode 100644\nindex 00000000000..74f3df90726\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash15.C\n@@ -0,0 +1,8 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection -g\" }\n+\n+void\n+foo ()\n+{\n+  constexpr auto r = ^^int;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash16.C b/gcc/testsuite/g++.dg/reflect/crash16.C\nnew file mode 100644\nindex 00000000000..9d3b367f297\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash16.C\n@@ -0,0 +1,43 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype (^^int);\n+\n+struct A { int x, y; };\n+struct B { info x, y; };\n+struct C { int x; info y; };\n+\n+void\n+foo ()\n+{\n+  constexpr A a { 3, 4 };\n+  constexpr auto [ax, ay] = a;\n+  static_assert (ax == 3);\n+  static_assert (ay == 4);\n+\n+  constexpr B b { ^^::, ^^int };\n+  constexpr auto [bx, by] = b;\n+  static_assert (b.x == ^^::);\n+  static_assert (b.y == ^^int);\n+  static_assert (bx == ^^::);\n+  static_assert (by == ^^int);\n+\n+  constexpr C c { 4, ^^:: };\n+  constexpr auto [cx, cy] = c;\n+  static_assert (c.x == 4);\n+  static_assert (c.y == ^^::);\n+  static_assert (cx == 4);\n+  static_assert (cy == ^^::);\n+\n+  constexpr int d[] { 6, 7 };\n+  constexpr auto [dx, dy] = d;\n+  static_assert (dx == 6);\n+  static_assert (dy == 7);\n+\n+  constexpr info e[] { ^^::, ^^int };\n+  constexpr auto [ex, ey] = e;\n+  static_assert (e[0] == ^^::);\n+  static_assert (e[1] == ^^int);\n+  static_assert (ex == ^^::);\n+  static_assert (ey == ^^int);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash17.C b/gcc/testsuite/g++.dg/reflect/crash17.C\nnew file mode 100644\nindex 00000000000..c6344ceda98\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash17.C\n@@ -0,0 +1,29 @@\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 <typename>\n+void\n+foo ()\n+{\n+  constexpr int i = [: reflect_constant (5) :];\n+  constexpr info f = reflect_constant_array (std::vector { 1, 2, 3 });\n+  constexpr auto &arr = [: f :];\n+  constexpr auto &arr2 = [: reflect_constant_array (std::vector { 1, 2, 3 }) :];\n+}\n+\n+void\n+bar ()\n+{\n+  constexpr auto &arr = [: reflect_constant_array (std::vector { 1, 2, 3 }) :];   \n+}\n+\n+int\n+main ()\n+{\n+  foo <int> ();\n+  bar ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash18.C b/gcc/testsuite/g++.dg/reflect/crash18.C\nnew file mode 100644\nindex 00000000000..3fe08734f56\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash18.C\n@@ -0,0 +1,6 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+// We also test this elsewhere but we only crashed when there were no other\n+// errors.\n+void fn (decltype(^^::)) {} // { dg-error \"function of consteval-only type must be declared .consteval.\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash2.C b/gcc/testsuite/g++.dg/reflect/crash2.C\nnew file mode 100644\nindex 00000000000..83927fbdc7c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash2.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct S {\n+  template<typename T>\n+  static void tfn () { }\n+  template<typename T>\n+  static constexpr int var = 1;\n+};\n+\n+template<typename T>\n+void\n+f ()\n+{\n+  // Parsed as \"S::tfn < S\".\n+  [: ^^T :]::tfn<[: ^^T :]>();\t// { dg-error \"expected primary-expression|expected a reflection of an expression instead of type .S.\" }\n+// { dg-warning \"expected .template. keyword\" \"\" { target *-*-* } .-1 }\n+  int i = [: ^^T :]::var<int>;\t// { dg-error \"missing|expected\" }\n+}\n+\n+void\n+g ()\n+{\n+  f<S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash3.C b/gcc/testsuite/g++.dg/reflect/crash3.C\nnew file mode 100644\nindex 00000000000..51cf3d8b727\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash3.C\n@@ -0,0 +1,8 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+template <auto V> constexpr int e = [:V:];  // { dg-error \"expected a reflection of an expression instead of type .int.\" }\n+template <auto V> constexpr int e2 = [:V:]; // { dg-error \"expected a reflection of an expression instead of type .int.\" }\n+constexpr auto h = ^^int;\n+constexpr auto i = e<([:^^h:])>;\n+constexpr auto j = e2<^^int>;\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash4.C b/gcc/testsuite/g++.dg/reflect/crash4.C\nnew file mode 100644\nindex 00000000000..acbdbe7ede1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash4.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct S {\n+  int j;\n+  static int i;\n+} s;\n+\n+int X;\n+\n+// Typo: should have been ^^s.\n+decltype([: ^^S :].j) x;  // { dg-error \"expected a reflection of an expression\" }\n+decltype([: ^^S :].i) z;  // { dg-error \"expected a reflection of an expression\" }\n+decltype([: ^^X :].x) y;  // { dg-error \"request for member|expected\" }\n+decltype([: ^^:: :].x w;  // { dg-error \"expected a reflection of an expression\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash5.C b/gcc/testsuite/g++.dg/reflect/crash5.C\nnew file mode 100644\nindex 00000000000..a2479d675ba\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash5.C\n@@ -0,0 +1,14 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct S {\n+  int j;\n+  int k;\n+};\n+\n+// Forgot to define info and we crashed :-(\n+template <info R>   // { dg-error \".info. has not been declared\" }\n+consteval int fn() {\n+  S s = {11, 13};\n+  return s.[:R:];   // { dg-error \".R. was not declared\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash6.C b/gcc/testsuite/g++.dg/reflect/crash6.C\nnew file mode 100644\nindex 00000000000..13ce48afcba\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash6.C\n@@ -0,0 +1,21 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+template<typename T>\n+constexpr T magic = 1234;\n+\n+template<info R>\n+void\n+f ()\n+{\n+  [:R:] r; // { dg-error \"expected\" }\n+  [:R:]<int> r; // { dg-error \"reflection .\\\\\\[: R :\\\\\\]<int>. not usable in a splice expression\" }\n+}\n+\n+void\n+g ()\n+{\n+  f<^^magic>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash7.C b/gcc/testsuite/g++.dg/reflect/crash7.C\nnew file mode 100644\nindex 00000000000..50905acc7a0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash7.C\n@@ -0,0 +1,22 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+struct S {\n+  template<typename T>\n+  static T t{};\n+} s;\n+\n+template<info R>\n+void\n+f ()\n+{\n+  int j = s.template [:R:]<int>; // { dg-error \"expected a reflection of an expression instead of type .S.\" }\n+}\n+\n+void\n+g ()\n+{\n+  f<^^S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash8.C b/gcc/testsuite/g++.dg/reflect/crash8.C\nnew file mode 100644\nindex 00000000000..451a1b6833e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash8.C\n@@ -0,0 +1,11 @@\n+// { dg-do compile { target c++26 } }\n+// Test using a splice expression in an explicit destructor call\n+// but without reflection enabled, which ICEd.\n+\n+struct S { };\n+\n+void\n+oy (S s)\n+{\n+  s.~typename [:^^S:](); // { dg-error \"reflection\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/crash9.C b/gcc/testsuite/g++.dg/reflect/crash9.C\nnew file mode 100644\nindex 00000000000..1f8aff6a715\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/crash9.C\n@@ -0,0 +1,10 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+namespace N { }\n+\n+template <auto V> constexpr int e = [:V:];  // { dg-error \"expected a reflection of an expression instead of .N.\" }\n+template <auto V> constexpr int e2 = [:V:]; // { dg-error \"expected a reflection of an expression instead of .N.\" }\n+constexpr auto h = ^^N;\n+constexpr auto i = e<([:^^h:])>;\n+constexpr auto j = e2<^^N>;\ndiff --git a/gcc/testsuite/g++.dg/reflect/data_member_spec1.C b/gcc/testsuite/g++.dg/reflect/data_member_spec1.C\nnew file mode 100644\nindex 00000000000..c213992ab62\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/data_member_spec1.C\n@@ -0,0 +1,119 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::data_member_spec.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+enum E { E0, E1 };\n+struct S {};\n+\n+consteval bool\n+valid_data_member_spec (info r, data_member_options opts)\n+{\n+  try { data_member_spec (r, opts); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+consteval bool\n+foo ()\n+{\n+  std::string n1 = \"bar\";\n+  data_member_options a = { .name = n1 };\n+  auto dmsa = data_member_spec (^^S, a);\n+  if (!is_data_member_spec (dmsa))\n+    throw 1;\n+  std::u8string_view n2 = u8\"baz\";\n+  data_member_options b = { .name = n2, .alignment = 2 * alignof (long), .no_unique_address = true };\n+  auto dmsb = data_member_spec (^^long, b);\n+  if (!is_data_member_spec (dmsb))\n+    throw 2;\n+  data_member_options c = { .bit_width = 7 };\n+  auto dmsc = data_member_spec (^^int, c);\n+  if (!is_data_member_spec (dmsc))\n+    throw 3;\n+  data_member_options d = { .name = \"extremely_long_identifier1\", .bit_width = 6 };\n+  auto dmsd = data_member_spec (^^E, d);\n+  if (!is_data_member_spec (dmsd))\n+    throw 4;\n+  data_member_options e = { .bit_width = 0 };\n+  auto dmse = data_member_spec (^^int, e);\n+  if (!is_data_member_spec (dmse))\n+    throw 5;\n+  data_member_options f = { .name = u8\"extremely_long_identifier2\", .alignment = 2 * alignof (E) };\n+  auto dmsf = data_member_spec (^^E &, f);\n+  if (!is_data_member_spec (dmsf))\n+    throw 6;\n+  if (dmsa != data_member_spec (^^S, { .name = \"bar\" }))\n+    throw 7;\n+  if (dmsb != data_member_spec (^^long, { .name = u8\"baz\", .alignment = 2 * alignof (long), .no_unique_address = true }))\n+    throw 8;\n+  if (dmsc != data_member_spec (^^int, { .bit_width = 7ULL }))\n+    throw 9;\n+  if (dmsd != data_member_spec (^^E, { .name = \"extremely_long_identifier1\", .bit_width = 6 }))\n+    throw 10;\n+  if (dmse != data_member_spec (^^int, { .bit_width = 0U }))\n+    throw 11;\n+  if (dmsf != data_member_spec (^^E &, { .name = u8\"extremely_long_identifier2\", .alignment = 2 * alignof (E) }))\n+    throw 12;\n+  if (dmsa == data_member_spec (^^const S, { .name = \"bar\" }))\n+    throw 13;\n+  if (dmsa == data_member_spec (^^S, { .name = \"foo\" }))\n+    throw 14;\n+  if (dmsb == data_member_spec (^^long, { .name = u8\"baz\", .alignment = 4 * alignof (long), .no_unique_address = true }))\n+    throw 15;\n+  if (dmsb == data_member_spec (^^long, { .name = u8\"baz\", .alignment = 2 * alignof (long), .no_unique_address = false }))\n+    throw 16;\n+  if (dmsc == data_member_spec (^^int, { .bit_width = 8 }))\n+    throw 17;\n+  if (dmsd == data_member_spec (^^E, { .name = \"extremely_long_identifier3\", .bit_width = 6 }))\n+    throw 18;\n+  if (dmsd == data_member_spec (^^E, { .name = \"extremely_long_identifier\", .bit_width = 5 }))\n+    throw 19;\n+  if (dmse == data_member_spec (^^int, { .name = \"a\" }))\n+    throw 20;\n+  if (data_member_spec (^^int, { .name = \"a\" }) == data_member_spec (^^int, { .name = \"a\", .no_unique_address = true }))\n+    throw 21;\n+  return true;\n+}\n+\n+static_assert (foo ());\n+\n+static_assert (!valid_data_member_spec (^^void, { .name = \"a\" }));\n+static_assert (!valid_data_member_spec (^^int (int), { .name = \"a\" }));\n+static_assert (!valid_data_member_spec (^^int, {}));\n+static_assert (!valid_data_member_spec (^^int, { .alignment = alignof (int) }));\n+static_assert (!valid_data_member_spec (^^int, { .no_unique_address = true }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"for\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"if\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"char8_t\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"virtual\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"static_assert\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"__is_convertible\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"__builtin_is_implicit_lifetime\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"007\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"operator++\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"operator ++\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"foo\\\\u00AA\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"+ -\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"\\u00AA\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"\\u00AB\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"\\u00B6\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"\\u00BA\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"\\u00C0\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"\\u00D6\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"\\u0384\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"\\u0669\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"A\\u0669\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"\\u0E59\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"A\\u0E59\" }));\n+static_assert (!valid_data_member_spec (^^S, { .name = \"a\", .bit_width = 4 }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"a\", .alignment = alignof (int), .bit_width = 4 }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"a\", .bit_width = 4, .no_unique_address = true }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"a\", .bit_width = 0 }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"a\", .bit_width = -42 }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"a\", .alignment = 41 }));\n+static_assert (!valid_data_member_spec (^^int, { .name = \"a\", .alignment = -__INT_MAX__ - 1 }));\n+static_assert (!valid_data_member_spec (^^long long, { .name = \"a\", .alignment = alignof (long long) / 2 }));\ndiff --git a/gcc/testsuite/g++.dg/reflect/data_member_spec2.C b/gcc/testsuite/g++.dg/reflect/data_member_spec2.C\nnew file mode 100644\nindex 00000000000..3c0043fe314\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/data_member_spec2.C\n@@ -0,0 +1,113 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::data_member_spec.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval bool\n+valid_data_member_spec (info r, data_member_options opts)\n+{\n+  try { data_member_spec (r, opts); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\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 (!valid_data_member_spec (null_reflection, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^::, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^ns, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^ns_alias, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (reflect_constant (3), { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^cls, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls::dm, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls::ref_dm, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls::static_dm, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls::mem_fun, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls::static_mem_fun, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^cls::type, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls_var, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^onion, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^anon, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^fun, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^alias, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^var, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^ref, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^rref, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^ptr, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls_tmpl, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^cls_tmpl<int>, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^incomplete_cls<int>, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^fun_tmpl, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^fun_tmpl<int>, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^conc, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (substitute (^^conc, { ^^int }), { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^var_tmpl, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^var_tmpl<int>, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^cls_tmpl_alias, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^cls_tmpl_alias<int>, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^Enum, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^Enum::A, { .name = \"dms\" }));\n+static_assert (valid_data_member_spec (^^Enum_class, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^Enum_class::A, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^decomp, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^decomp_ref, { .name = \"dms\" }));\n+static_assert (!valid_data_member_spec (^^arr, { .name = \"dms\" }));\n+\n+constexpr auto dms = data_member_spec (^^int, { .name = \"dms\" });\n+static_assert (!valid_data_member_spec (dms, { .name = \"dms\" }));\n+\n+struct Base {};\n+struct Derived : Base {};\n+static_assert (!valid_data_member_spec (bases_of (^^Derived, access_context::unchecked ())[0], { .name = \"dms\" }));\n+\n+template<typename T, info R, info R2, info R3>\n+void\n+f ()\n+{\n+  static_assert (valid_data_member_spec (^^T, { .name = \"dms\" }));\n+  static_assert (!valid_data_member_spec (R, { .name = \"dms\" }));\n+  static_assert (!valid_data_member_spec (R2, { .name = \"dms\" }));\n+  static_assert (valid_data_member_spec (R3, { .name = \"dms\" }));\n+}\n+\n+void\n+g (int p, cls c)\n+{\n+  f<int, ^^var, ^^ns, ^^cls>();\n+  static_assert (!valid_data_member_spec (^^p, { .name = \"dms\" }));\n+  static_assert (!valid_data_member_spec (^^c, { .name = \"dms\" }));\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/data_member_spec3.C b/gcc/testsuite/g++.dg/reflect/data_member_spec3.C\nnew file mode 100644\nindex 00000000000..e29013da32d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/data_member_spec3.C\n@@ -0,0 +1,29 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::data_member_spec.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval bool\n+valid_data_member_spec (info r, data_member_options opts)\n+{\n+  try { data_member_spec (r, opts); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"👷\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"👷.♀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"⏰\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"🕐\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"☠\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"💀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"✋\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"👊\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"✈\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"🚀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"☹\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"😀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"💩\" }));\ndiff --git a/gcc/testsuite/g++.dg/reflect/data_member_spec4.C b/gcc/testsuite/g++.dg/reflect/data_member_spec4.C\nnew file mode 100644\nindex 00000000000..49c6b9b2873\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/data_member_spec4.C\n@@ -0,0 +1,29 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-options \"-freflection\" }\n+// Test std::meta::data_member_spec.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval bool\n+valid_data_member_spec (info r, data_member_options opts)\n+{\n+  try { data_member_spec (r, opts); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"👷\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"👷.♀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"⏰\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"🕐\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"☠\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"💀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"✋\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"👊\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"✈\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"🚀\" }));\n+static_assert (!valid_data_member_spec (^^int, { .name = u8\"☹\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"😀\" }));\n+static_assert (valid_data_member_spec (^^int, { .name = u8\"💩\" }));\ndiff --git a/gcc/testsuite/g++.dg/reflect/dealias1.C b/gcc/testsuite/g++.dg/reflect/dealias1.C\nnew file mode 100644\nindex 00000000000..81fd469e39f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dealias1.C\n@@ -0,0 +1,36 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::dealias.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+namespace N { }\n+\n+using int_alias = int;\n+using int_alias_alias = int_alias;\n+template <typename T> using alias_templ = T;\n+\n+typedef int T1;\n+typedef T1 T2;\n+\n+namespace N_alias = N;\n+namespace N_alias_alias = N_alias;\n+\n+typename [: dealias (^^int) :] i1 = 42;\n+typename [: dealias (^^int_alias_alias) :] i2 = 42;\n+\n+static_assert (dealias (^^int) == ^^int);\n+static_assert (dealias (^^int_alias) == ^^int);\n+static_assert (dealias (^^int_alias_alias) == ^^int);\n+static_assert (dealias (^^alias_templ<int_alias_alias>) == ^^int);\n+static_assert (dealias (^^T1) == ^^int);\n+static_assert (dealias (^^T2) == ^^int);\n+\n+static_assert (dealias (^^::) == ^^::);\n+static_assert (dealias (^^N) == ^^N);\n+static_assert (dealias (^^N_alias) == ^^N);\n+static_assert (dealias (^^N_alias_alias) == ^^N);\n+\n+static_assert (dealias (std::meta::info{}) == std::meta::info{});\ndiff --git a/gcc/testsuite/g++.dg/reflect/dealias2.C b/gcc/testsuite/g++.dg/reflect/dealias2.C\nnew file mode 100644\nindex 00000000000..ecf3e3edb4e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dealias2.C\n@@ -0,0 +1,14 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::dealias.\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+constexpr int i = 42;\n+static_assert (dealias (reflect_object (i)) == reflect_object (i));\n+static_assert (dealias (constant_of (^^i)) == constant_of (^^i));\n+static_assert (dealias (reflect_constant (42)) == reflect_constant (42));\n+[[=1, =1, =2, =1.0f]] void fn ();\n+static_assert (dealias (annotations_of (^^fn)[0]) == annotations_of (^^fn)[0]);\n+static_assert (dealias (^^i) == ^^i);\ndiff --git a/gcc/testsuite/g++.dg/reflect/dealias3.C b/gcc/testsuite/g++.dg/reflect/dealias3.C\nnew file mode 100644\nindex 00000000000..21a52ca0861\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dealias3.C\n@@ -0,0 +1,32 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::dealias.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template<typename T>\n+struct S {};\n+static_assert (dealias (^^S) == ^^S);\n+\n+template <typename T> using A1 = T;\n+static_assert (dealias (^^A1) == ^^A1);\n+\n+template <typename T> using A2 = S<T>;\n+static_assert (dealias (^^A2) == ^^A2);\n+\n+template <typename T> using A3 = S<T*>;\n+static_assert (dealias (^^A3) == ^^A3);\n+\n+template <typename T>\n+int v = sizeof(T);\n+static_assert (dealias (^^v) == ^^v);\n+\n+template <typename T>\n+void fn();\n+static_assert (dealias (^^fn) == ^^fn);\n+\n+template<typename T>\n+concept C = true;\n+static_assert (dealias (^^C) == ^^C);\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_aggregate1.C b/gcc/testsuite/g++.dg/reflect/define_aggregate1.C\nnew file mode 100644\nindex 00000000000..0bf80435b3d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_aggregate1.C\n@@ -0,0 +1,108 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::define_aggregate.\n+\n+#include <cstddef>\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+enum E { E0, E1 };\n+struct S0 {};\n+struct S1;\n+struct S2;\n+struct S3;\n+struct S4;\n+struct S5;\n+union U1;\n+template <int N>\n+struct S6;\n+template <int N>\n+struct S7 { long e; short f; };\n+struct S8;\n+struct S9;\n+using A9 = S9;\n+\n+consteval {\n+  if (define_aggregate (^^S1, {}) != ^^S1)\n+    throw 1;\n+  if (define_aggregate (^^S2, { data_member_spec (^^S1, { .name = \"bar\" }),\n+\t\t\t\tdata_member_spec (^^long, { .name = u8\"baz\",\n+\t\t\t\t\t\t\t    .alignment = 2 * alignof (long),\n+\t\t\t\t\t\t\t    .no_unique_address = true }),\n+\t\t\t\tdata_member_spec (^^unsigned int, { .bit_width = 7 }),\n+\t\t\t\tdata_member_spec (^^E, { .name = \"extremely_long_identifier1\",\n+\t\t\t\t\t\t\t .bit_width = 6 }),\n+\t\t\t\tdata_member_spec (^^int, { .bit_width = 0 }),\n+\t\t\t\tdata_member_spec (^^const E *, { .name = u8\"extremely_long_identifier2\",\n+\t\t\t\t\t\t\t\t .alignment = 2 * alignof (E *) }) }) != ^^S2)\n+    throw 2;\n+  if (define_aggregate (^^S3, { data_member_spec (^^S0, { .name = \"a\",\n+\t\t\t\t\t\t\t  .no_unique_address = true }),\n+\t\t\t\tdata_member_spec (^^S1, { .name = \"b\",\n+\t\t\t\t\t\t\t  .no_unique_address = true }) }) != ^^S3)\n+    throw 3;\n+  if (define_aggregate (^^S4, { data_member_spec (^^S0, { .name = \"c\" }),\n+\t\t\t\tdata_member_spec (^^S1, { .name = \"d\" }) }) != ^^S4)\n+    throw 4;\n+  if (define_aggregate (^^S5, { data_member_spec (^^const E &, { .name = u8\"qu\\N{LATIN SMALL LETTER AE}\" }),\n+\t\t\t\tdata_member_spec (^^const E &, { .name = u8\"foo\" }) }) != ^^S5)\n+    throw 5;\n+  if (define_aggregate (^^U1, { data_member_spec (^^int, { .name = u8\"_\" }),\n+\t\t\t\tdata_member_spec (^^long long, { .name = \"abc\" }) }) != ^^U1)\n+    throw 6;\n+  if (define_aggregate (^^S6 <42>, { data_member_spec (^^int, { .name = \"a\" }),\n+\t\t\t\t     data_member_spec (^^long, { .name = \"b\" }) }) != ^^S6 <42>)\n+    throw 7;\n+  if (define_aggregate (substitute (^^S6, { reflect_constant (43) }),\n+\t\t\t{ data_member_spec (^^long, { .name = \"c\" }),\n+\t\t\t  data_member_spec (^^unsigned int, { .name = \"d\", .bit_width = 3 }) }) != ^^S6 <43>)\n+    throw 8;\n+  if (define_aggregate (^^S7 <42>, { data_member_spec (^^short, { .name = \"g\" }),\n+\t\t\t\t     data_member_spec (^^float, { .name = \"h\" }) }) != ^^S7 <42>)\n+    throw 9;\n+  if (define_aggregate (^^S8, { data_member_spec (^^U1, { .name = \"u\" }) }) != ^^S8)\n+    throw 10;\n+  if (define_aggregate (dealias (^^A9), { data_member_spec (^^U1, { .name = \"u\" }) }) != ^^S9)\n+    throw 10;\n+}\n+\n+constexpr E e0 = E0, e1 = E1;\n+S2 s2 = { .bar = {}, .baz = 42LL, .extremely_long_identifier1 = E1, .extremely_long_identifier2 = &e0 };\n+S3 s3 = { .a = {}, .b = {} };\n+S4 s4 = { .c = {}, .d = {} };\n+constexpr S5 s5 = { e0, e1 };\n+U1 u1 = { ._ = 5 }, u1a = { .abc = 42LL };\n+S6 <42> s642 = { .a = 1, .b = 2 };\n+S6 <43> s643 = { .c = 6, .d = 7 };\n+S7 <42> s742 = { .g = 5, .h = 6.0f };\n+S7 <43> s743 = { .e = 8, .f = 9 };\n+S8 s8 = { .u = { .abc = 2LL } };\n+S9 s9 = { .u = { ._ = 3 } };\n+consteval {\n+  S6 <43> x;\n+  x.c = -1;\n+  x.d = 7;\n+  ++x.d;\n+  if (x.d != 0)\n+    throw 11;\n+  --x.d;\n+  if (x.d != 7)\n+    throw 12;\n+}\n+static_assert (type_of (^^S2::bar) == ^^S1);\n+static_assert (type_of (^^S2::baz) == ^^long);\n+static_assert (type_of (^^S2::extremely_long_identifier1) == ^^E);\n+static_assert (type_of (^^S2::extremely_long_identifier2) == ^^const E *);\n+static_assert (offsetof (S2, bar) == 0);\n+static_assert (offsetof (S2, baz) >= 2 * alignof (long) && offsetof (S2, baz) % (2 * alignof (long)) == 0);\n+static_assert (offsetof (S2, extremely_long_identifier2) > offsetof (S2, baz));\n+static_assert (offsetof (S2, extremely_long_identifier2) % (2 * alignof (E)) == 0);\n+static_assert (type_of (^^S3::a) == ^^S0);\n+static_assert (type_of (^^S3::b) == ^^S1);\n+static_assert (sizeof (S3) == sizeof (S0) && sizeof (S4) == 2 * sizeof (S0));\n+static_assert (type_of (^^S4::c) == ^^S0);\n+static_assert (type_of (^^S4::d) == ^^S1);\n+static_assert (s5.qu\\u00E6 == E0 && s5.foo == E1);\n+static_assert (type_of (^^S5::qu\\u00E6) == ^^const E &);\n+static_assert (type_of (^^S5::foo) == ^^const E &);\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_aggregate2.C b/gcc/testsuite/g++.dg/reflect/define_aggregate2.C\nnew file mode 100644\nindex 00000000000..4f5868e82e6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_aggregate2.C\n@@ -0,0 +1,44 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::define_aggregate.\n+\n+#include <cstddef>\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+enum E { E0, E1 };\n+struct S0 {};\n+struct S1;\n+struct S2;\n+struct S3;\n+struct S4;\n+struct S5;\n+template <int N>\n+struct S7 { long e; short f; };\n+S7 <15> s715;\n+struct S8;\n+using A8 = S8;\n+struct S9;\n+struct S10;\n+struct S11;\n+struct S12;\n+consteval { define_aggregate (^^::, {}); }\t\t// { dg-error \"first 'define_aggregate' argument is not a class type reflection\" }\n+consteval { define_aggregate (^^int, {}); }\t\t// { dg-error \"first 'define_aggregate' argument is not a class type reflection\" }\n+consteval { define_aggregate (^^E, {}); }\t\t// { dg-error \"first 'define_aggregate' argument is not a class type reflection\" }\n+consteval { define_aggregate (^^S0, {}); }\t\t// { dg-error \"first 'define_aggregate' argument is a complete class type reflection\" }\n+consteval { define_aggregate (^^S7 <15>, {}); }\t\t// { dg-error \"first 'define_aggregate' argument is a complete class type reflection\" }\n+consteval { define_aggregate (^^A8, {}); }\t\t// { dg-error \"first 'define_aggregate' argument is a reflection of a type alias\" }\n+consteval { define_aggregate (^^const S9, {}); }\t// { dg-error \"first 'define_aggregate' argument is not a cv-unqualified class type reflection\" }\n+consteval { define_aggregate (^^volatile S10, {}); }\t// { dg-error \"first 'define_aggregate' argument is not a cv-unqualified class type reflection\" }\n+consteval { define_aggregate (^^S11 const volatile, {}); } // { dg-error \"first 'define_aggregate' argument is not a cv-unqualified class type reflection\" }\n+consteval { define_aggregate (^^S1, { ^^int }); }\t// { dg-error \"'define_aggregate' argument not a data member description\" }\n+consteval { define_aggregate (^^S2, { data_member_spec (^^S5, { .name = \"a\" }) }); }\t// { dg-error \"'define_aggregate' argument data member description without complete type\" }\n+consteval { define_aggregate (^^S3, { data_member_spec (^^int, { .name = \"a\" }),\t// { dg-error \"name 'a' used in multiple data member descriptions\" }\n+\t\t\t\t      data_member_spec (^^long, { .name = \"a\" }) }); }\n+consteval { define_aggregate (^^S4, { data_member_spec (^^int, { .name = u8\"_\" }),\n+\t\t\t\t      data_member_spec (^^long, { .name = u8\"_\" }) }); }\n+consteval { define_aggregate (^^S12, { data_member_spec (^^int, { .name = \"foobar\" }),\t// { dg-error \"name 'foobar' used in multiple data member descriptions\" }\n+\t\t\t\t       data_member_spec (^^long, { .name = u8\"foobar\" }) }); }\n+constexpr S4 s4 = { 1, 2 };\n+consteval { auto a = s4._; }\t\t\t\t// { dg-error \"request for member '_' is ambiguous\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_aggregate3.C b/gcc/testsuite/g++.dg/reflect/define_aggregate3.C\nnew file mode 100644\nindex 00000000000..db04a80bbe3\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_aggregate3.C\n@@ -0,0 +1,217 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::define_aggregate.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S1;\n+struct S2;\n+static_assert (define_aggregate (^^S1, {}) == ^^S1);\t// { dg-error \"non-constant condition for static assertion\" }\n+// { dg-error \"'define_aggregate' not evaluated from 'consteval' block\" \"\" { target *-*-* } .-1 }\n+consteval bool foo () { return define_aggregate (^^S2, {}) == ^^S2; }\n+// { dg-error \"'define_aggregate' not evaluated from 'consteval' block\" \"\" { target *-*-* } .-1 }\n+const bool a = foo ();\t\t\t\t\t// { dg-error \"call to consteval function 'foo\\\\\\(\\\\\\)' is not a constant expression\" }\n+\n+struct S3 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S3, {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S3' being defined\" }\n+  }\n+};\n+\n+template <typename T>\n+struct S4 {\n+  consteval {\n+    define_aggregate (^^S4 <T>, {});\n+  }\n+};\n+\n+consteval {\n+  define_aggregate (^^S4 <long>, {});\n+}\n+\n+template <typename T>\n+struct S5 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S5 <T>, {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S5<int>' being defined\" }\n+  }\n+};\n+\n+S5 <int> s5;\n+\n+consteval bool bar (info x) { return define_aggregate (x, {}) == x; }\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S6' being defined\" }\n+\n+struct S6 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    bar (^^S6);\n+  }\n+};\n+\n+consteval bool baz (info x) { return define_aggregate (x, {}) == x; }\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S7<char>' being defined\" }\n+\n+template <typename T>\n+struct S7 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    baz (^^S7 <T>);\n+  }\n+};\n+\n+S7 <char> s7;\n+\n+consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+  struct S8;\n+  define_aggregate (^^S8, {});\t\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block which encloses '<lambda\\\\\\(\\\\\\)> static::S8'\" }\n+};\n+\n+struct S9;\n+consteval {\n+  constexpr auto a = define_aggregate (^^S9, {});\t// { dg-error \"'define_aggregate' not evaluated from 'consteval' block\" }\n+}\n+\n+struct S10;\n+consteval {\n+  const auto a = define_aggregate (^^S10, {});\n+}\n+static_assert (is_complete_type (^^S10));\n+\n+consteval {\n+  struct S11 {\n+    struct S12;\n+  };\n+  define_aggregate (^^S11::S12, {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block which encloses '<lambda\\\\\\(\\\\\\)> static::S11::S12' being defined\" }\n+}\n+\n+consteval info\n+baz ()\n+{\n+  struct S13;\n+  return ^^S13;\n+}\n+\n+consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+  define_aggregate (baz (), {});\t\t\t// { dg-error \"'consteval std::meta::info baz\\\\\\(\\\\\\)' intervenes between 'baz\\\\\\(\\\\\\)::S13' scope and 'consteval' block 'define_aggregate' is evaluated from\" }\n+}\n+\n+struct S14 {\n+  struct S15;\n+};\n+\n+consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+  define_aggregate (^^S14::S15, {});\t\t\t// { dg-error \"'S14' intervenes between 'S14::S15' scope and 'consteval' block 'define_aggregate' is evaluated from\" }\n+}\n+\n+struct S16;\n+\n+void\n+qux ()\n+{\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S16, {});\t\t\t// { dg-error \"'void qux\\\\\\(\\\\\\)' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'S16' scope\" }\n+  }\n+}\n+\n+struct S17;\n+\n+struct S18 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S17, {});\t\t\t// { dg-error \"'S18' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'S17' scope\" }\n+  }\n+};\n+\n+void\n+garply ()\n+{\n+  struct S19;\n+  consteval {\n+    define_aggregate (^^S19, {});\n+  }\n+}\n+\n+void\n+fred ()\n+{\n+  struct S20;\n+  [] () {\n+    consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+      define_aggregate (^^S20, {});\t\t\t// { dg-error \"'fred\\\\\\(\\\\\\)::<lambda\\\\\\(\\\\\\)>' intervenes between 'consteval' block 'define_aggregate' is evaluated from and 'fred\\\\\\(\\\\\\)::S20' scope\" }\n+    }\n+  } ();\n+}\n+\n+consteval info\n+corge ()\n+{\n+  struct S21;\n+  return ^^S21;\n+}\n+\n+void\n+plugh ()\n+{\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (corge (), {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'void plugh\\\\\\(\\\\\\)' while 'corge\\\\\\(\\\\\\)::S21' type being defined is enclosed by 'consteval std::meta::info corge\\\\\\(\\\\\\)'\" }\n+  }\n+}\n+\n+struct S22 {\n+  struct S23;\n+};\n+\n+struct S24 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S22::S23, {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S24' while 'S22::S23' type being defined is enclosed by 'S22'\" }\n+  }\n+};\n+\n+consteval info\n+waldo ()\n+{\n+  struct S25;\n+  return ^^S25;\n+}\n+\n+struct S26 {\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (waldo (), {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'S26' while 'waldo\\\\\\(\\\\\\)::S25' type being defined is enclosed by 'consteval std::meta::info waldo\\\\\\(\\\\\\)'\" }\n+  }\n+};\n+\n+struct S27 {\n+  struct S28;\n+};\n+\n+void\n+grault ()\n+{\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S27::S28, {});\t\t\t// { dg-error \"'define_aggregate' evaluated from 'consteval' block enclosed by 'void grault\\\\\\(\\\\\\)' while 'S27::S28' type being defined is enclosed by 'S27'\" }\n+  }\n+}\n+\n+void\n+xyzzy ()\n+{\n+  struct S29 {\n+    struct S30;\n+  };\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S29::S30, {});\t\t\t// { dg-error \"'xyzzy\\\\\\(\\\\\\)::S29' intervenes between 'xyzzy\\\\\\(\\\\\\)::S29::S30' scope and 'consteval' block 'define_aggregate' is evaluated from\" }\n+  }\n+  static constexpr auto a = [] () consteval {\n+    struct S31;\n+    return ^^S31;\n+  } ();\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (a, {});\t\t\t\t// { dg-error \"'xyzzy\\\\\\(\\\\\\)::<lambda\\\\\\(\\\\\\)>' intervenes between 'xyzzy\\\\\\(\\\\\\)::<lambda\\\\\\(\\\\\\)>::S31' scope and 'consteval' block 'define_aggregate' is evaluated from\" }\n+  }\n+}\n+\n+struct S32 {\n+  struct S33 {\n+    struct S34;\n+  };\n+  consteval {\t\t\t\t\t\t// { dg-message \"'consteval' block defined here\" }\n+    define_aggregate (^^S33::S34, {});\t\t\t// { dg-error \"'S32::S33' intervenes between 'S32::S33::S34' scope and 'consteval' block 'define_aggregate' is evaluated from\" }\n+  }\n+};\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_aggregate4.C b/gcc/testsuite/g++.dg/reflect/define_aggregate4.C\nnew file mode 100644\nindex 00000000000..c620c5b18b6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_aggregate4.C\n@@ -0,0 +1,225 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::define_aggregate.\n+\n+#include <meta>\n+#include <ranges>\n+\n+using namespace std::meta;\n+\n+constexpr auto uctx = access_context::unchecked ();\n+constexpr auto ctx = access_context::unprivileged ();\n+\n+void\n+foo ()\n+{\n+  struct S;\n+  class C;\n+  union U;\n+  static_assert (!is_complete_type (^^S));\n+  static_assert (!is_complete_type (^^C));\n+  static_assert (!is_complete_type (^^U));\n+  consteval {\n+    if (is_complete_type (^^S))\n+      throw 1;\n+    if (is_complete_type (^^C))\n+      throw 2;\n+    if (is_complete_type (^^U))\n+      throw 3;\n+    define_aggregate (^^S, {});\n+    define_aggregate (^^C, {});\n+    define_aggregate (^^U, {});\n+    if (!is_complete_type (^^S))\n+      throw 4;\n+    if (!is_complete_type (^^C))\n+      throw 5;\n+    if (!is_complete_type (^^U))\n+      throw 6;\n+    if (!nonstatic_data_members_of (^^S, uctx).empty ())\n+      throw 7;\n+    if (!nonstatic_data_members_of (^^C, uctx).empty ())\n+      throw 8;\n+    if (!nonstatic_data_members_of (^^U, uctx).empty ())\n+      throw 9;\n+  }\n+  static_assert (is_complete_type (^^S));\n+  static_assert (is_complete_type (^^C));\n+  static_assert (is_complete_type (^^U));\n+  static_assert (nonstatic_data_members_of (^^S, uctx).empty ());\n+  static_assert (nonstatic_data_members_of (^^C, uctx).empty ());\n+  static_assert (nonstatic_data_members_of (^^U, uctx).empty ());\n+}\n+\n+void\n+bar ()\n+{\n+  struct S;\n+  class C;\n+  union U;\n+  union U2;\n+  static_assert (!is_complete_type (^^S));\n+  static_assert (!is_complete_type (^^C));\n+  static_assert (!is_complete_type (^^U));\n+  consteval {\n+    if (is_complete_type (^^S))\n+      throw 1;\n+    if (is_complete_type (^^C))\n+      throw 2;\n+    if (is_complete_type (^^U))\n+      throw 3;\n+    define_aggregate (^^S, { data_member_spec (^^int, { .name = \"a\", .alignment = 32 }),\n+\t\t\t     data_member_spec (^^bool, { .name = \"b\" }),\n+\t\t\t     data_member_spec (^^int, { .bit_width = 0 }),\n+\t\t\t     data_member_spec (^^int, { .name = \"_\", .bit_width = 3 }),});\n+    define_aggregate (^^C, { data_member_spec (^^int, { .name = \"a\", .alignment = 32 }),\n+\t\t\t     data_member_spec (^^bool, { .name = \"b\" }),\n+\t\t\t     data_member_spec (^^int, { .bit_width = 0 }),\n+\t\t\t     data_member_spec (^^int, { .name = \"_\", .bit_width = 3 }),});\n+    define_aggregate (^^U, { data_member_spec (^^int, { .name = \"a\", .alignment = 32 }),\n+\t\t\t     data_member_spec (^^bool, { .name = \"b\" }),\n+\t\t\t     data_member_spec (^^int, { .bit_width = 0 }),\n+\t\t\t     data_member_spec (^^int, { .name = \"_\", .bit_width = 3 }),});\n+    define_aggregate (^^U2, { data_member_spec (^^int, { .name = \"a\" }),\n+\t\t\t      data_member_spec (^^bool, { .name = \"b\" }),\n+\t\t\t      data_member_spec (^^int, { .bit_width = 0 }),\n+\t\t\t      data_member_spec (^^int, { .name = \"_\", .bit_width = 3 }),});\n+    if (!is_complete_type (^^S))\n+      throw 4;\n+    if (!is_complete_type (^^C))\n+      throw 5;\n+    if (!is_complete_type (^^U))\n+      throw 6;\n+    if (!nonstatic_data_members_of (^^S, uctx).size () == 3)\n+      throw 7;\n+    if (!nonstatic_data_members_of (^^C, uctx).size () == 3)\n+      throw 8;\n+    if (!nonstatic_data_members_of (^^U, uctx).size () == 3)\n+      throw 9;\n+    if (!nonstatic_data_members_of (^^S, ctx).size () == 3)\n+      throw 10;\n+    if (!nonstatic_data_members_of (^^C, ctx).size () == 3)\n+      throw 11;\n+    if (!nonstatic_data_members_of (^^U, ctx).size () == 3)\n+      throw 12;\n+    if (!alignment_of (nonstatic_data_members_of (^^S, uctx)[0]) == 32)\n+      throw 13;\n+    if (!bit_size_of (members_of (^^S, uctx)[2]) == 0)\n+      throw 14;\n+    if (!is_bit_field (members_of (^^S, ctx)[2]))\n+      throw 15;\n+    if (!bit_size_of (members_of (^^S, uctx)[3]) == 3)\n+      throw 16;\n+    if (!is_bit_field (members_of (^^S, ctx)[3]))\n+      throw 17;\n+    if (!alignment_of (nonstatic_data_members_of (^^C, uctx)[0]) == 32)\n+      throw 18;\n+    if (!bit_size_of (members_of (^^C, uctx)[2]) == 0)\n+      throw 19;\n+    if (!is_bit_field (members_of (^^C, ctx)[2]))\n+      throw 20;\n+    if (!bit_size_of (members_of (^^C, uctx)[3]) == 3)\n+      throw 21;\n+    if (!is_bit_field (members_of (^^C, ctx)[3]))\n+      throw 22;\n+    if (!alignment_of (nonstatic_data_members_of (^^U, uctx)[0]) == 32)\n+      throw 23;\n+    if (!bit_size_of (members_of (^^U, uctx)[2]) == 0)\n+      throw 24;\n+    if (!is_bit_field (members_of (^^U, ctx)[2]))\n+      throw 25;\n+    if (!bit_size_of (members_of (^^U, uctx)[3]) == 3)\n+      throw 26;\n+    if (!is_bit_field (members_of (^^U, ctx)[3]))\n+      throw 27;\n+    if (!is_public (members_of (^^S, uctx)[0]))\n+      throw 28;\n+    if (!is_public (members_of (^^S, uctx)[1]))\n+      throw 29;\n+    if (!is_public (members_of (^^S, uctx)[2]))\n+      throw 30;\n+    if (!is_public (members_of (^^S, uctx)[3]))\n+      throw 31;\n+    if (!is_public (members_of (^^C, uctx)[0]))\n+      throw 32;\n+    if (!is_public (members_of (^^C, uctx)[1]))\n+      throw 33;\n+    if (!is_public (members_of (^^C, uctx)[2]))\n+      throw 34;\n+    if (!is_public (members_of (^^C, uctx)[3]))\n+      throw 35;\n+    if (!is_public (members_of (^^U, uctx)[0]))\n+      throw 36;\n+    if (!is_public (members_of (^^U, uctx)[1]))\n+      throw 37;\n+    if (!is_public (members_of (^^U, uctx)[2]))\n+      throw 38;\n+    if (!is_public (members_of (^^U, uctx)[3]))\n+      throw 39;\n+    if (!is_class_type (^^S))\n+      throw 40;\n+    if (!is_class_type (^^C))\n+      throw 41;\n+    if (!is_union_type (^^U))\n+      throw 42;\n+  }\n+  static_assert (is_complete_type (^^S));\n+  static_assert (is_complete_type (^^C));\n+  static_assert (is_complete_type (^^U));\n+  static_assert (nonstatic_data_members_of (^^S, uctx).size () == 3);\n+  static_assert (nonstatic_data_members_of (^^C, uctx).size () == 3);\n+  static_assert (nonstatic_data_members_of (^^U, uctx).size () == 3);\n+  static_assert (nonstatic_data_members_of (^^S, ctx).size () == 3);\n+  static_assert (nonstatic_data_members_of (^^C, ctx).size () == 3);\n+  static_assert (nonstatic_data_members_of (^^U, ctx).size () == 3);\n+  static_assert (alignment_of (nonstatic_data_members_of (^^S, uctx)[0]) == 32);\n+  static_assert (bit_size_of (members_of (^^S, uctx)[2]) == 0);\n+  static_assert (is_bit_field (members_of (^^S, ctx)[2]));\n+  static_assert (bit_size_of (members_of (^^S, uctx)[3]) == 3);\n+  static_assert (is_bit_field (members_of (^^S, ctx)[3]));\n+  static_assert (alignment_of (nonstatic_data_members_of (^^C, uctx)[0]) == 32);\n+  static_assert (bit_size_of (members_of (^^C, uctx)[2]) == 0);\n+  static_assert (is_bit_field (members_of (^^C, ctx)[2]));\n+  static_assert (bit_size_of (members_of (^^C, uctx)[3]) == 3);\n+  static_assert (is_bit_field (members_of (^^C, ctx)[3]));\n+  static_assert (alignment_of (nonstatic_data_members_of (^^U, uctx)[0]) == 32);\n+  static_assert (bit_size_of (members_of (^^U, uctx)[2]) == 0);\n+  static_assert (is_bit_field (members_of (^^U, ctx)[2]));\n+  static_assert (bit_size_of (members_of (^^U, uctx)[3]) == 3);\n+  static_assert (is_bit_field (members_of (^^U, ctx)[3]));\n+  static_assert (is_public (members_of (^^S, uctx)[0]));\n+  static_assert (is_public (members_of (^^S, uctx)[1]));\n+  static_assert (is_public (members_of (^^S, uctx)[2]));\n+  static_assert (is_public (members_of (^^S, uctx)[3]));\n+  static_assert (is_public (members_of (^^C, uctx)[0]));\n+  static_assert (is_public (members_of (^^C, uctx)[1]));\n+  static_assert (is_public (members_of (^^C, uctx)[2]));\n+  static_assert (is_public (members_of (^^C, uctx)[3]));\n+  static_assert (is_public (members_of (^^U, uctx)[0]));\n+  static_assert (is_public (members_of (^^U, uctx)[1]));\n+  static_assert (is_public (members_of (^^U, uctx)[2]));\n+  static_assert (is_public (members_of (^^U, uctx)[3]));\n+  static_assert (is_class_type (^^S));\n+  static_assert (is_class_type (^^C));\n+  static_assert (is_union_type (^^U));\n+  static_assert (sizeof (U2) == sizeof (int));\n+  constexpr S s = { 1, true, 2 };\n+  static_assert (s.a == 1 && s.b == true && s._ == 2);\n+  constexpr C c = { 3, false, -4 };\n+  static_assert (c.a == 3 && c.b == false && c._ == -4);\n+  union U u { .a = 42 };\n+  u.b = true;\n+  u._ = 3;\n+  u.[: nonstatic_data_members_of (^^U, ctx)[2] :] = 1;\n+}\n+\n+void\n+baz ()\n+{\n+  struct E {};\n+  struct S;\n+  consteval {\n+    define_aggregate (^^S, { data_member_spec (^^int, { .name = \"_\" }),\n+\t\t\t     data_member_spec (^^E, { .name = \"_\", .no_unique_address = true }) });\n+  }\n+  static_assert (sizeof (S) == sizeof (int));\n+}\n\\ No newline at end of file\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_aggregate5.C b/gcc/testsuite/g++.dg/reflect/define_aggregate5.C\nnew file mode 100644\nindex 00000000000..00501c5b3b4\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_aggregate5.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+#include <ranges>\n+\n+struct foo;\n+\n+consteval {\n+  using namespace std::meta;\n+  using namespace std::views;\n+  using std::make_pair;\n+  using std::vector;\n+  using std::pair;\n+  define_aggregate (^^foo, join (vector <vector <pair <bool, info>>> {\n+    { make_pair (true, data_member_spec (^^int, { .name = \"i\" })) },\n+    { make_pair (false, data_member_spec (^^std::string, { .name = \"s\" })),\n+      make_pair (true, data_member_spec (^^bool, { .name = \"b\" })) }})\n+\t| filter ([] (auto x) constexpr { return x.first; })\n+\t| transform ([] (auto x) constexpr { return x.second; }));\n+}\n+\n+static_assert (type_of (^^foo::i) == ^^int);\n+static_assert (type_of (^^foo::b) == ^^bool);\n+static_assert (nonstatic_data_members_of (^^foo, std::meta::access_context::current ()).size () == 2);\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_static_array1.C b/gcc/testsuite/g++.dg/reflect/define_static_array1.C\nnew file mode 100644\nindex 00000000000..61a6a53c908\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_array1.C\n@@ -0,0 +1,91 @@\n+// { dg-do run { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::define_static_array.\n+\n+#include <array>\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+struct V { int a, b, c; };\n+constexpr auto a = std::define_static_array (\"abcd\");\n+constexpr auto b = std::define_static_array (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\");\n+constexpr auto c = std::define_static_array (std::vector <char> {});\n+constexpr auto d = std::define_static_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 = std::define_static_array (ea);\n+constexpr int fb[] = { 1, 2, 3, 4, 5, 6 };\n+constexpr std::span <const int> fa (fb);\n+constexpr auto f = std::define_static_array (fa);\n+constexpr auto g = std::define_static_array (fa.subspan (1, 4));\n+constexpr auto h = std::define_static_array (fa.subspan (1, 4) | std::views::reverse);\n+constexpr auto i = std::define_static_array (std::vector <V> { V { 1, 2, 3 }, V { 2, 3, 4 }, V { 3, 4, 5 } });\n+constexpr auto j = std::define_static_array (std::vector <long long> {});\n+constexpr auto k = std::define_static_array (std::meta::nonstatic_data_members_of (^^V, std::meta::access_context::current ()));\n+static_assert (a.data () == std::define_static_string (\"abcd\") && a.size () == 5);\n+static_assert (b.data () == std::define_static_string (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\")\n+\t       && b.size () == sizeof (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\") / sizeof (char32_t));\n+static_assert (c.data () == nullptr && c.size () == 0);\n+static_assert (d.data () == std::define_static_array (std::vector <int> { 1, 2, 42, 3 }).data ()\n+\t       && d.size () == 4 && d[0] == 1 && d[1] == 2 && d[2] == 42 && d[3] == 3);\n+static_assert (e.data () == std::define_static_array (std::array { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f }).data ()\n+\t       && e.size () == 6 && e[0] == 1.0f && e[1] == 2.0f && e[2] == 3.0f && e[3] == 4.0f && e[4] == 5.0f && e[5] == 6.0f);\n+static_assert (f.data () == std::define_static_array (std::vector <int> { 1, 2, 3, 4, 5, 6 }).data ()\n+\t       && f.size () == 6);\n+static_assert (d.data () != f.data ());\n+static_assert (g.data () == std::define_static_array (std::array { 2, 3, 4, 5 }).data ()\n+\t       && g.size () == 4);\n+static_assert (h.data () == std::define_static_array (std::vector <int> { 5, 4, 3, 2 }).data ()\n+\t       && h.size () == 4 && h[0] == 5 && h[1] == 4 && h[2] == 3 && h[3] == 2);\n+static_assert (i.size () == 3);\n+static_assert (j.data () == nullptr && j.size () == 0);\n+static_assert (k.size () == 3 && k[0] == ^^V::a && k[1] == ^^V::b && k[2] == ^^V::c);\n+\n+int\n+main ()\n+{\n+  if (std::string_view (a) != std::string_view (\"abcd\", 5))\n+    __builtin_abort ();\n+  if (std::u32string_view (b) != std::u32string_view (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\", 9))\n+    __builtin_abort ();\n+  for (const char &x : c)\n+    __builtin_abort ();\n+  int i = 0;\n+  for (const int &x : d)\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 : e)\n+    if (x != ++i)\n+      __builtin_abort ();\n+  if (i != 6)\n+    __builtin_abort ();\n+  i = 0;\n+  for (const int &x : f)\n+    if (x != ++i)\n+      __builtin_abort ();\n+  if (i != 6)\n+    __builtin_abort ();\n+  i = 1;\n+  for (const int &x : g)\n+    if (x != ++i)\n+      __builtin_abort ();\n+  if (i != 5)\n+    __builtin_abort ();\n+  i = 6;\n+  for (const int &x : h)\n+    if (x != --i)\n+      __builtin_abort ();\n+  if (i != 2)\n+    __builtin_abort ();\n+  i = 0;\n+  for (const V &x : ::i)\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/define_static_array2.C b/gcc/testsuite/g++.dg/reflect/define_static_array2.C\nnew file mode 100644\nindex 00000000000..01c20c37145\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_array2.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::define_static_array.\n+\n+#include <meta>\n+\n+struct A {\n+  int a;\n+  consteval A (int x) : a(x) {}\n+  consteval A (const A &x) : a(x.a + 1) {}\n+};\n+static_assert (std::vector <A> { 1 }[0].a == 2);\n+constexpr auto a = std::define_static_array (std::vector <A> { 1, 11, 21 });\n+static_assert (a.size () == 3);\n+static_assert (a[0].a >= 2 && a[1].a >= 12 && a[2].a >= 22);\n+// TODO: I believe there should be at least 2 copy ctors per element rather\n+// than just one.  One is already in the vector construction.\n+// Then [meta.define.static]/10 models it as if reflect_constant was called\n+// on each element and reflect_constant takes the class by value rather than\n+// reference, so one needs to copy construct from a const reference to the\n+// range element into a TARGET_EXPR of the reflect_constant argument.\n+// And not sure if there shouldn't be further bumps inside of\n+// reflect_constant, libcxx bumps 3 times.\n+// static_assert (a[0].a == 3 && a[1].a == 13 && a[2].a == 23);\n+\n+// I believe the copy-constructor of this class breaks the rule for NTTP\n+// from [temp.arg.nontype] p4 (copies are not structurally equivalent),\n+// that we seem to not currently implement. It makes this test moot\n+// as reflect_constant should throw an exception.\n+// So language seems to say, that you should have no way to observe this copies.\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_static_array3.C b/gcc/testsuite/g++.dg/reflect/define_static_array3.C\nnew file mode 100644\nindex 00000000000..c196c043989\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_array3.C\n@@ -0,0 +1,16 @@\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+constexpr int arr[4]{1, 2, 3, 4};\n+constexpr std::span<const int> spn = std::define_static_array(std::span<const int, 4>(arr));\n+static_assert ([: std::meta::constant_of(^^arr) :] == spn.data());\n+\n+constexpr int marr[2][2]{1, 2, 3, 4};\n+// LWG4483 multidimensional arrays\n+// constexpr std::span<const int[2]> mspn = std::define_static_array(std::span<const int[2], 2>(marr));\n+// static_assert ([: std::meta::constant_of(^^marr) :] == mspn.data());\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_static_array4.C b/gcc/testsuite/g++.dg/reflect/define_static_array4.C\nnew file mode 100644\nindex 00000000000..1c70e73815c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_array4.C\n@@ -0,0 +1,17 @@\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+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 std::span spn = std::define_static_array(std::views::zip (x, y) | std::views::transform (as_pair));\n+// FIXME these should pass\n+// static_assert (^^decltype(spn) == ^^std::span<const std::pair<int, int>>);\n+// static_assert (spn[2].first == 3);\n+// static_assert (spn[2].second == 13);\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_static_object1.C b/gcc/testsuite/g++.dg/reflect/define_static_object1.C\nnew file mode 100644\nindex 00000000000..1e2be04a858\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_object1.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::define_static_object.\n+\n+#include <meta>\n+\n+struct V { int a, b, c; };\n+constexpr auto a = std::define_static_object (42);\n+constexpr auto b = std::define_static_object (U'\\N{LATIN CAPITAL LETTER AE}');\n+constexpr auto c = std::define_static_object (V { 1, 2, 42 });\n+static_assert (a == std::define_static_object (42) && *a == 42);\n+static_assert (is_same_type (type_of (^^a), ^^const int *const));\n+static_assert (b == std::define_static_object (U'\\N{LATIN CAPITAL LETTER AE}') && *b == U'\\N{LATIN CAPITAL LETTER AE}');\n+static_assert (is_same_type (type_of (^^b), ^^const char32_t *const));\n+static_assert (c == std::define_static_object (V { 1, 2, 42 }) && c->a == 1 && c->b == 2 && c->c == 42);\n+static_assert (is_same_type (type_of (^^c), ^^const V *const));\n+static_assert (a == std::define_static_array (std::vector <int> { 42 }).data ());\n+static_assert (b == std::define_static_array (std::vector <char32_t> { U'\\N{LATIN CAPITAL LETTER AE}' }).data ());\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_static_object2.C b/gcc/testsuite/g++.dg/reflect/define_static_object2.C\nnew file mode 100644\nindex 00000000000..f1a70d34840\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_object2.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::define_static_object.\n+\n+#include <meta>\n+\n+constexpr int arr[]{1, 2, 3};\n+// LWG4483 use extract(reflect_constant_array())\n+// constexpr const int(*ptr)[3] = std::define_static_object(arr);\n+// static_assert( *ptr == std::define_static_array(arr).data() );\n+// static_assert( ptr = &std::meta::constant_of(arr) );\n+\n+constexpr int marr[3][3]{1, 2, 3};\n+// LWG4483 array are not structural so this fail\n+// constexpr const int(*mptr)[3][3] = std::define_static_object(marr);\n+// static_assert( *mptr == std::define_static_array(marr).data() );\n+// static_assert( mptr = &std::meta::constant_of(marr) );\n+\ndiff --git a/gcc/testsuite/g++.dg/reflect/define_static_string1.C b/gcc/testsuite/g++.dg/reflect/define_static_string1.C\nnew file mode 100644\nindex 00000000000..b0a14c60254\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/define_static_string1.C\n@@ -0,0 +1,133 @@\n+// { dg-do run { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::define_static_string.\n+\n+#include <meta>\n+#include <ranges>\n+#include <span>\n+\n+constexpr const char *a = std::define_static_string (\"abcd\");\n+constexpr const char8_t *b = std::define_static_string (u8\"abcd\\N{LATIN SMALL LETTER AE}\");\n+constexpr const wchar_t *c = std::define_static_string (L\"abcd\");\n+constexpr const char16_t *d = std::define_static_string (u\"abcd\\0ef\");\n+constexpr const char32_t *e = std::define_static_string (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\");\n+constexpr auto f = std::define_static_string (std::string_view (\"abcd\", 5));\n+constexpr auto g = std::define_static_string (std::string_view (\"abcdefg\", 4));\n+constexpr auto h = std::define_static_string (std::u8string_view (u8\"ab\\0\\N{LATIN SMALL LETTER AE}\", 5));\n+constexpr auto i = std::define_static_string (std::string_view (\"abcdefgh\", 9).substr (0, 5));\n+constexpr auto j = std::define_static_string (std::string_view (\"abcdefgh\", 9).substr (4, 3));\n+constexpr auto k = std::define_static_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 = std::define_static_string (la);\n+constexpr std::span <const char8_t> ma (la);\n+constexpr auto m = std::define_static_string (ma);\n+constexpr auto n = std::define_static_string (ma.subspan (1, 4));\n+constexpr auto o = std::define_static_string (ma.subspan (1, 4) | std::views::reverse);\n+constexpr auto p = std::define_static_string (std::vector <wchar_t> { L'W', L'o', L'r', L'l', L'd' });\n+constexpr auto q = std::define_static_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+const char *r = std::define_static_string (\"some string\");\n+const char8_t *s = std::define_static_string (u8\"\\N{GRINNING FACE}\\N{GRINNING FACE WITH SMILING EYES}\");\n+static_assert (a == std::define_static_string (\"abcd\"));\n+static_assert (b == std::define_static_string (u8\"abcd\\N{LATIN SMALL LETTER AE}\"));\n+static_assert (c == std::define_static_string (L\"abcd\"));\n+static_assert (d == std::define_static_string (u\"abcd\\0ef\"));\n+static_assert (e == std::define_static_string (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\"));\n+static_assert (f == std::define_static_string (\"abcd\\0\"));\n+static_assert (g == a);\n+static_assert (h == std::define_static_string (u8\"ab\\0\\N{LATIN SMALL LETTER AE}\"));\n+static_assert (i == std::define_static_string (\"abcde\"));\n+static_assert (a != i);\n+static_assert (j == std::define_static_string (\"efg\"));\n+static_assert (a != j);\n+static_assert (k == std::define_static_string (U\"defg\"));\n+static_assert (l == std::define_static_string (u8\"hello\\0\"));\n+static_assert (m == l);\n+static_assert (n == std::define_static_string (u8\"ello\"));\n+static_assert (o == std::define_static_string (u8\"olle\"));\n+static_assert (p == std::define_static_string (L\"World\"));\n+static_assert (q == std::define_static_string (u\"extremely long string with non-ASCII characters \\N{LATIN SMALL LETTER A WITH ACUTE}\"));\n+static_assert (std::define_static_string (\"bar\") != std::define_static_string (\"baz\"));\n+\n+template <typename T, const T *P>\n+struct C { const T *p = P; };\n+\n+static_assert (std::is_same_v <C <char, std::define_static_string (\"foobar\")>,\n+\t\t\t       C <char, std::define_static_string (std::vector <char> { 'f', 'o', 'o', 'b', 'a', 'r' })>>);\n+static_assert (!std::is_same_v <C <char, std::define_static_string (\"foobar\")>,\n+\t\t\t\tC <char, std::define_static_string (std::vector <char> { 'f', 'o', 'O', 'b', 'a', 'r' })>>);\n+static_assert (std::is_same_v <C <wchar_t, std::define_static_string (L\"hello\")>,\n+\t\t\t       C <wchar_t, std::define_static_string (L\"hello\")>>);\n+static_assert (std::is_same_v <C <char8_t, std::define_static_string (u8\"hello\\0\")>,\n+\t\t\t       C <char8_t, std::define_static_string (ma)>>);\n+static_assert (std::is_same_v <C <char8_t, std::define_static_string (u8\"\\N{LATIN SMALL LETTER AE}\")>,\n+\t\t\t       C <char8_t, std::define_static_string (u8\"\\N{LATIN SMALL LETTER AE}\")>>);\n+static_assert (std::is_same_v <C <char16_t, std::define_static_string (u\"\\N{LATIN CAPITAL LETTER AE}\")>,\n+\t\t\t       C <char16_t, std::define_static_string (std::vector <char16_t> { u'\\N{LATIN CAPITAL LETTER AE}' })>>);\n+static_assert (std::is_same_v <C <char32_t, std::define_static_string (U\"\\N{GRINNING FACE}\\N{GRINNING FACE WITH SMILING EYES}\")>,\n+\t\t\t       C <char32_t, std::define_static_string (std::vector <char32_t> { U'\\N{GRINNING FACE}', U'\\N{GRINNING FACE WITH SMILING EYES}' })>>);\n+\n+template <auto V>\n+consteval auto\n+foo ()\n+{\n+  return V[0];\n+}\n+\n+static_assert (foo <std::define_static_string (\"foo\")> () == 'f');\n+static_assert (foo <std::define_static_string (L\"bar\")> () == L'b');\n+static_assert (foo <std::define_static_string (u8\"qux\")> () == u8'q');\n+static_assert (foo <std::define_static_string (u\"\\N{LATIN SMALL LETTER AE}\\N{LATIN CAPITAL LETTER AE}\")> () == u'\\N{LATIN SMALL LETTER AE}');\n+static_assert (foo <std::define_static_string (U\"\\N{GRINNING FACE WITH SMILING EYES}\\N{GRINNING FACE}\")> () == U'\\N{GRINNING FACE WITH SMILING EYES}');\n+\n+int\n+main ()\n+{\n+  if (std::string_view (a) != std::string_view (\"abcd\"))\n+    __builtin_abort ();\n+  if (std::u8string_view (b) != std::u8string_view (u8\"abcd\\N{LATIN SMALL LETTER AE}\"))\n+    __builtin_abort ();\n+  if (std::wstring_view (c) != std::wstring_view (L\"abcd\"))\n+    __builtin_abort ();\n+  if (std::u16string_view (d) != std::u16string_view (u\"abcd\\0ef\"))\n+    __builtin_abort ();\n+  if (std::u32string_view (e) != std::u32string_view (U\"abcd\\0ef\\N{LATIN CAPITAL LETTER AE}\"))\n+    __builtin_abort ();\n+  if (std::string_view (f) != std::string_view (\"abcd\\0\"))\n+    __builtin_abort ();\n+  if (g != a)\n+    __builtin_abort ();\n+  if (std::u8string_view (h) != std::u8string_view (u8\"ab\\0\\N{LATIN SMALL LETTER AE}\"))\n+    __builtin_abort ();\n+  if (std::string_view (i) != std::string_view (\"abcde\"))\n+    __builtin_abort ();\n+  if (a == i)\n+    __builtin_abort ();\n+  if (std::string_view (j) != std::string_view (\"efg\"))\n+    __builtin_abort ();\n+  if (a == j)\n+    __builtin_abort ();\n+  if (std::u32string_view (k) != std::u32string_view (U\"defg\"))\n+    __builtin_abort ();\n+  if (std::u8string_view (l) != std::u8string_view (u8\"hello\\0\"))\n+    __builtin_abort ();\n+  if (m != l)\n+    __builtin_abort ();\n+  if (std::u8string_view (n) != std::u8string_view (u8\"ello\"))\n+    __builtin_abort ();\n+  if (std::u8string_view (o) != std::u8string_view (u8\"olle\"))\n+    __builtin_abort ();\n+  if (std::wstring_view (p) != std::wstring_view (L\"World\"))\n+    __builtin_abort ();\n+  if (std::u16string_view (q) != std::u16string_view (u\"extremely long string with non-ASCII characters \\N{LATIN SMALL LETTER A WITH ACUTE}\"))\n+    __builtin_abort ();\n+  if (r != std::define_static_string (\"some string\"))\n+    __builtin_abort ();\n+  if (s != std::define_static_string (u8\"\\N{GRINNING FACE}\\N{GRINNING FACE WITH SMILING EYES}\"))\n+    __builtin_abort ();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep1.C b/gcc/testsuite/g++.dg/reflect/dep1.C\nnew file mode 100644\nindex 00000000000..4bfc995fa89\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep1.C\n@@ -0,0 +1,14 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test dependent splice specifiers.\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/dep10.C b/gcc/testsuite/g++.dg/reflect/dep10.C\nnew file mode 100644\nindex 00000000000..f942a2e9347\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep10.C\n@@ -0,0 +1,15 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Partial substitution of a SPLICE_SCOPE.\n+\n+template<typename>\n+void f()\n+{\n+   auto func = []<auto Mem>() static {\n+      return [: ^^[:Mem:] ::func :];\n+   };\n+}\n+\n+void g() {\n+   f<int>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep11.C b/gcc/testsuite/g++.dg/reflect/dep11.C\nnew file mode 100644\nindex 00000000000..ad9f58452ce\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep11.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Stolen from LLVM's splice-exprs.cpp.\n+\n+using info = decltype(^^::);\n+\n+template<info FN>\n+struct Cls {\n+    template <typename RESULT, typename... Args>\n+    struct Impl {\n+        Impl(decltype(&[:FN:]));\n+    };\n+    template <typename RESULT, typename... Args>\n+    Impl(RESULT (*)(Args...)) -> Impl<RESULT, Args...>;\n+};\n+\n+void fn(int);\n+static_assert(^^decltype(Cls<^^fn>::Impl(&fn)) == ^^Cls<^^fn>::Impl<void, int>);\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep2.C b/gcc/testsuite/g++.dg/reflect/dep2.C\nnew file mode 100644\nindex 00000000000..dfc27b2824c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep2.C\n@@ -0,0 +1,36 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+template<typename T>\n+constexpr int\n+fn (T t)\n+{\n+  return t;\n+}\n+\n+template<typename T>\n+constexpr T\n+foo ()\n+{\n+  constexpr auto r = ^^fn<T>;\n+  int n = [: r :](42);\n+  return n;\n+}\n+\n+void\n+g ()\n+{\n+  constexpr int r = foo<int>();\n+  static_assert (r == 42);\n+}\n+\n+template<typename T>\n+consteval info\n+h ()\n+{\n+  return ^^T;\n+}\n+\n+constexpr info i = h<int>();\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep3.C b/gcc/testsuite/g++.dg/reflect/dep3.C\nnew file mode 100644\nindex 00000000000..1b606ded23e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep3.C\n@@ -0,0 +1,33 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct S {\n+  template<typename T>\n+  struct NS { };\n+\n+  template<typename T>\n+  void foo ();\n+\n+  template<typename T>\n+  S &operator|(const T&);\n+\n+  template<typename T>\n+  static int V;\n+};\n+\n+template<typename T>\n+void\n+g ()\n+{\n+  // Looks like r1 and r4 should work.\n+  //constexpr auto r1 = ^^T::template NS;\n+  constexpr auto r2 = ^^T::template foo;\n+  constexpr auto r3 = ^^T::template operator|;\n+  //constexpr auto r4 = ^^T::template V;\n+}\n+\n+void\n+f ()\n+{\n+  g<S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep4.C b/gcc/testsuite/g++.dg/reflect/dep4.C\nnew file mode 100644\nindex 00000000000..a264ab12298\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep4.C\n@@ -0,0 +1,24 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^int);\n+\n+consteval int fn1 () { return 42; }\n+consteval int fn2 (int a = 5) { return a; }\n+\n+constexpr info r1 = ^^fn1;\n+constexpr info r2 = ^^fn2;\n+static_assert([: r1 :]() == 42);\n+static_assert([: r2 :]() == 5);\n+static_assert([: r2 :](11) == 11);\n+\n+// With a dependent reflection.\n+template <info R> consteval int fn() { return [:R:](); }\n+static_assert(fn<r1>() == 42);\n+static_assert(fn<r2>() == 5);\n+\n+void\n+runtime ()\n+{\n+  [:^^runtime:];\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep5.C b/gcc/testsuite/g++.dg/reflect/dep5.C\nnew file mode 100644\nindex 00000000000..4a118de1b70\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep5.C\n@@ -0,0 +1,29 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct S {\n+  static constexpr int x = 42;\n+  using type = int;\n+  static void fn (int) { }\n+  template<typename T>\n+  static void tfn () { }\n+  template<typename T>\n+  static T var;\n+};\n+\n+template<typename T>\n+void\n+f ()\n+{\n+  static_assert ([: ^^T :]::x == 42);\n+  typename [: ^^T :]::type a = 42;\n+  [: ^^T :]::fn (42);\n+  [: ^^T :]::template tfn<([: ^^T :])>();  // { dg-error \"expected a reflection of an expression instead of type .S.\" }\n+  auto x = [: ^^T :]::template var<([: ^^T :])>;  // { dg-error \"expected a reflection of an expression instead of type .S.\" }\n+}\n+\n+void\n+g ()\n+{\n+  f<S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep6.C b/gcc/testsuite/g++.dg/reflect/dep6.C\nnew file mode 100644\nindex 00000000000..55ebdb71230\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep6.C\n@@ -0,0 +1,20 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test that we give a nice error about a missing typename.\n+\n+struct S {\n+  using type = int;\n+};\n+\n+template<typename T>\n+void\n+f ()\n+{\n+  [: ^^T :]::type i = 42; // { dg-error \"need .typename. before .\\\\\\[: \\\\\\^\\\\\\^T :\\\\\\]::type. because .\\\\\\[: \\\\\\^\\\\\\^T :\\\\\\]. is a dependent scope\" }\n+}\n+\n+void\n+g ()\n+{\n+  f<S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep7.C b/gcc/testsuite/g++.dg/reflect/dep7.C\nnew file mode 100644\nindex 00000000000..3ed80fd1bdd\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep7.C\n@@ -0,0 +1,23 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+template<typename T>\n+struct Z {};\n+\n+struct S {\n+  static constexpr auto r = ^^Z;\n+};\n+\n+template<typename T, auto R>\n+void\n+g ()\n+{\n+ typename [: R :]<int> c1;\n+ typename [: T::r :]<int> c2;\n+}\n+\n+void\n+f ()\n+{\n+  g<S, ^^Z>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep8.C b/gcc/testsuite/g++.dg/reflect/dep8.C\nnew file mode 100644\nindex 00000000000..cc2c2d7ff0f\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep8.C\n@@ -0,0 +1,70 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+struct S {\n+  int i;\n+  static int si;\n+  static int mfn () { return 1; }\n+};\n+\n+int S::si;\n+\n+template<typename T>\n+struct C {\n+  int i;\n+  static T si;\n+  static T mfn() { return 1; }\n+};\n+\n+template<info R>\n+void\n+f ()\n+{\n+  typename [:R:] r{1};\n+  ++[:R:]::si;\n+  [:R:]::si += [:R:]::mfn ();\n+  using L = [:R:];\n+  L r2{2};\n+}\n+\n+template<info R>\n+struct A {\n+  typename [:R:] r;\n+  int i = [:R:]::mfn ();\n+  using L = [:R:];\n+  L r2;\n+  int mem () { return [:R:]::si; }\n+};\n+\n+template<info R>\n+void\n+f2 ()\n+{\n+  typename [:R:]<int> r{1};\n+  ++template [:R:]<int>::si;\n+  template [:R:]<int>::si += template [:R:]<int>::mfn ();\n+  using L = [:R:]<int>;\n+  L r2{2};\n+}\n+\n+template<info R>\n+struct A2 {\n+  typename [:R:]<int> r;\n+  int i = template [:R:]<int>::mfn ();\n+  using L = [:R:]<int>;\n+  L r2;\n+  int mem () { return template [:R:]<int>::si; }\n+};\n+\n+void\n+doit ()\n+{\n+  f<^^S>();\n+  f<^^C<int>>();\n+  A<^^S> a;\n+  A<^^C<int>> a2;\n+  f2<^^C>();\n+  A2<^^C> a3;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/dep9.C b/gcc/testsuite/g++.dg/reflect/dep9.C\nnew file mode 100644\nindex 00000000000..b8941522931\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/dep9.C\n@@ -0,0 +1,40 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Dependent variable templates.\n+\n+using info = decltype(^^void);\n+\n+template<typename T>\n+constexpr T magic = 1234;\n+\n+void foo (int);\n+\n+template<info R>\n+void\n+f ()\n+{\n+  int i = template [:R:]<int>;\n+  constexpr int ci = template [:R:]<int>;\n+  foo (template [:R:]<int>);\n+}\n+\n+template<auto R>\n+void\n+f2 ()\n+{\n+  int i = [:R:];\n+  constexpr int ic = [:R:];\n+  foo ([:R:]);\n+}\n+\n+constexpr info V = ^^magic;\n+constexpr info VT = ^^magic<int>;\n+\n+void\n+g ()\n+{\n+  f<^^magic>();\n+  f<V>();\n+  f2<^^magic<int>>();\n+  f2<VT>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/diag1.C b/gcc/testsuite/g++.dg/reflect/diag1.C\nnew file mode 100644\nindex 00000000000..2d34623a8ac\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/diag1.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test that we offer some helpful diagnostic.\n+\n+struct S {\n+  template<typename T>\n+  void tfn (T) { }\n+};\n+\n+template<typename T>\n+constexpr T fortytwo = 42;\n+\n+void\n+f ()\n+{\n+  S s;\n+  s.[: ^^S::tfn :](42); // { dg-error \"reflection .S::tfn. not usable in a splice expression\" }\n+// { dg-message \"add .template. to denote a template\" \"\" { target *-*-* } .-1 }\n+  s.template [: ^^S::tfn :](42);\n+\n+  constexpr auto r = ^^fortytwo;\n+  constexpr int i1 = [:r:]<int>; // { dg-error \"reflection .fortytwo<int>. not usable in a splice expression with template arguments\" }\n+// { dg-message \"add .template. to denote a template\" \"\" { target *-*-* } .-1 }\n+  constexpr int i2 = template [:r:]<int>;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/diag2.C b/gcc/testsuite/g++.dg/reflect/diag2.C\nnew file mode 100644\nindex 00000000000..7c2c8270dcf\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/diag2.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// This used to say ''splice_scope' not supported by\n+// dump_type_prefix<typeprefixerror>r'splice_scope' not supported\n+// by dump_type_suffix'.  Eeech.\n+\n+using info = decltype(^^void);\n+\n+struct S {\n+  int i;\n+};\n+\n+template<info R>\n+void\n+f ()\n+{\n+  typename [:R:] r{1};  // { dg-message \"previous declaration as .\\\\\\[: R :\\\\\\] r.\" }\n+  typename [:R:] r{2};  // { dg-error \"conflicting declaration .\\\\\\[: R :\\\\\\] r.\" }\n+}\n+\n+int\n+main ()\n+{\n+  f<^^S>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/diag3.C b/gcc/testsuite/g++.dg/reflect/diag3.C\nnew file mode 100644\nindex 00000000000..754a8b29b87\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/diag3.C\n@@ -0,0 +1,28 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test that we suggest adding \"constexpr\" or \"constinit\" (where allowed).\n+\n+auto foo = ^^int;  // { dg-error \"consteval-only variable .foo.\" }\n+// { dg-message \"add .constexpr. or .constinit.\" \"\" { target *-*-* } .-1 }\n+constinit auto foo_ = ^^int;\n+constexpr auto foo__ = ^^int;\n+thread_local auto tfoo = ^^int;  // { dg-error \"consteval-only variable .tfoo.\" }\n+// { dg-message \"add .constexpr. or .constinit.\" \"\" { target *-*-* } .-1 }\n+thread_local constinit auto tfoo_ = ^^int;\n+thread_local constexpr auto tfoo__ = ^^int;\n+\n+void\n+f ()\n+{\n+  auto ref = ^^int;  // { dg-error \"consteval-only variable .ref.\" }\n+// { dg-message \"add .constexpr.\" \"\" { target *-*-* } .-1 }\n+  constexpr auto ref_ = ^^int;\n+  static auto sref = ^^int;  // { dg-error \"consteval-only variable .sref.\" }\n+// { dg-message \"add .constexpr. or .constinit.\" \"\" { target *-*-* } .-1 }\n+  static auto constinit sref_ = ^^int;\n+  static auto constexpr sref__ = ^^int;\n+  thread_local auto tref = ^^int; // { dg-error \"consteval-only variable .tref.\" }\n+// { dg-message \"add .constexpr. or .constinit.\" \"\" { target *-*-* } .-1 }\n+  thread_local constinit auto tref_ = ^^int;\n+  thread_local constexpr auto tref__ = ^^int;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/diag4.C b/gcc/testsuite/g++.dg/reflect/diag4.C\nnew file mode 100644\nindex 00000000000..5aabeae8059\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/diag4.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test that we suggest adding \"typename\" (where allowed).\n+\n+constexpr auto r = ^^int;\n+\n+template<typename> struct S {};\n+\n+void\n+g ()\n+{\n+  [:r:] i = 42;  // { dg-error \"expected a reflection of an expression\" }\n+// { dg-message \"add .typename. to denote a type outside a type-only context\" \"\" { target *-*-* } .-1 }\n+\n+  S<([:r:])> s;  // { dg-error \"expected a reflection of an expression|template argument 1 is invalid\" }\n+// { dg-message \"add .typename. to denote a type outside a type-only context\" \"\" { target *-*-* } .-1 }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/display_string_of1.C b/gcc/testsuite/g++.dg/reflect/display_string_of1.C\nnew file mode 100644\nindex 00000000000..d3707608b91\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/display_string_of1.C\n@@ -0,0 +1,230 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::display_string_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr info null_reflection;\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+namespace {\n+  namespace NS2 {}\n+};\n+namespace NS3 {\n+  namespace {\n+    namespace {\n+      namespace NS4 {}\n+    }\n+  }\n+};\n+enum { Z };\n+\n+constexpr auto ctx = access_context::current ();\n+\n+struct AN { int a; long b; char c; };\n+\n+[[=1, =AN { 1, 42, ' ' }]] void bar (long, const T f, int g[2], T &);\n+\n+struct V1 {\n+  constexpr V1 (int) {}\n+};\n+struct V2 {\n+  V2 &operator = (const V2 &);\n+};\n+struct V3 {\n+  V3 &operator = (V3 &&);\n+};\n+struct V4 {\n+  V4 &operator += (const V4 &);\n+};\n+struct V5 {\n+  operator int ();\n+};\n+int operator \"\"_a (const char *);\n+\n+void\n+foo (int a, const long b, T c, int d[4], T &e)\n+{\n+  static_assert (display_string_of (^^a) == \"a\");\n+  static_assert (display_string_of (^^b) == \"b\");\n+  static_assert (display_string_of (^^c) == \"c\");\n+  static_assert (display_string_of (^^d) == \"d\");\n+  static_assert (display_string_of (^^e) == \"e\");\n+  static_assert (display_string_of (parameters_of (^^foo)[0]) == \"<parameter a of void foo(int, long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^foo)[1]) == \"<parameter b of void foo(int, long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^foo)[2]) == \"<parameter c of void foo(int, long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^foo)[3]) == \"<parameter d of void foo(int, long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^foo)[4]) == \"<parameter e of void foo(int, long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^bar)[0]) == \"<unnamed parameter 1 of void bar(long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^bar)[1]) == \"<parameter f of void bar(long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^bar)[2]) == \"<parameter g of void bar(long int, T, int*, T&)>\");\n+  static_assert (display_string_of (parameters_of (^^bar)[3]) == \"<unnamed parameter 4 of void bar(long int, T, int*, T&)>\");\n+  static_assert (display_string_of (null_reflection) == \"<null reflection>\");\n+  static_assert (display_string_of (^^::) == \"::\");\n+  static_assert (display_string_of (^^NS2) == \"{anonymous}::NS2\");\n+  static_assert (display_string_of (parent_of (^^NS2)) == \"{anonymous}\");\n+  static_assert (display_string_of (^^NS3::NS4) == \"NS3::{anonymous}::{anonymous}::NS4\");\n+  static_assert (display_string_of (parent_of (^^NS3::NS4)) == \"NS3::{anonymous}::{anonymous}\");\n+  static_assert (display_string_of (parent_of (parent_of (^^NS3::NS4))) == \"NS3::{anonymous}\");\n+  static_assert (display_string_of (parent_of (parent_of (parent_of   (^^NS3::NS4)))) == \"NS3\");\n+  static_assert (display_string_of (^^Z) == \"Z\");\n+  static_assert (display_string_of (parent_of (^^Z)) == \"<unnamed enum>\");\n+  static_assert (display_string_of (reflect_constant (42)) == \"42\");\n+  static_assert (display_string_of (reflect_object (arr[1])) == \"arr[1]\");\n+  static_assert (display_string_of (^^arr) == \"arr\");\n+  static_assert (display_string_of (^^a3) == \"a3\");\n+  static_assert (display_string_of (^^fn) == \"void fn()\");\n+  static_assert (display_string_of (^^fn2) == \"auto& fn2()\");\n+  static_assert (display_string_of (^^Enum::A) == \"A\");\n+  static_assert (display_string_of (^^Alias) == \"Alias {aka int}\");\n+  static_assert (display_string_of (^^S) == \"S\");\n+  static_assert (display_string_of (^^S::mem) == \"S::mem\");\n+  static_assert (display_string_of (members_of (^^S, ctx)[1]) == \"S::<unnamed bit-field>\");\n+  static_assert (display_string_of (^^TCls) == \"template<auto <anonymous> > struct TCls\");\n+  static_assert (display_string_of (^^TFn) == \"template<auto <anonymous> > void TFn()\");\n+  static_assert (display_string_of (^^TVar) == \"template<auto <anonymous> > int TVar<<anonymous> >\");\n+  static_assert (display_string_of (^^Concept) == \"template<auto <anonymous> > concept Concept\");\n+  static_assert (display_string_of (^^NSAlias) == \"NSAlias\");\n+  static_assert (display_string_of (^^NS) == \"NS\");\n+  static_assert (display_string_of (bases_of (^^S, ctx)[0]) == \"(S, B)\");\n+  static_assert (display_string_of (data_member_spec (^^int, { .name = \"member\", .alignment = 128, .no_unique_address = true })) == \"(int, member, 128, , true)\");\n+  static_assert (display_string_of (data_member_spec (^^const int, { .name = \"member\", .bit_width = 6 })) == \"(const int, member, , 6, false)\");\n+  static_assert (display_string_of (data_member_spec (^^int, { .bit_width = 0 })) == \"(int, , , 0, false)\");\n+  static_assert (display_string_of (data_member_spec (^^long, { .bit_width = 5 })) == \"(long int, , , 5, false)\");\n+  static_assert (display_string_of (annotations_of (^^bar)[0]) == \"[[=1]]\");\n+  static_assert (display_string_of (annotations_of (^^bar)[1]) == \"[[=AN{1, 42, ' '}]]\");\n+  static_assert (display_string_of (^^int) == \"int\");\n+  static_assert (display_string_of (^^unsigned) == \"unsigned int\");\n+  static_assert (display_string_of (^^unsigned long) == \"long unsigned int\");\n+  static_assert (display_string_of (^^const long long &) == \"const long long int&\");\n+  static_assert (display_string_of (^^const double **) == \"const double**\");\n+  static_assert (display_string_of (^^int (int)) == \"int(int)\");\n+  static_assert (display_string_of (^^int (&) (int, long, S &)) == \"int (&)(int, long int, S&)\");\n+  static_assert (display_string_of (^^int (*) (int, long, S &)) == \"int (*)(int, long int, S&)\");\n+  static_assert (display_string_of (members_of (^^V2, ctx)[0]) == \"V2& V2::operator=(const V2&)\");\n+  static_assert (display_string_of (members_of (^^V3, ctx)[0]) == \"V3& V3::operator=(V3&&)\");\n+  static_assert (display_string_of (members_of (^^V4, ctx)[0]) == \"V4& V4::operator+=(const V4&)\");\n+  static_assert (display_string_of (members_of (^^V5, ctx)[0]) == \"V5::operator int()\");\n+  static_assert (display_string_of (^^operator\"\"_a) == \"int operator\\\"\\\"_a(const char*)\");\n+}\n+\n+namespace NS5 {\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+  enum { Z };\n+\n+  struct AN { int a; long b; char c; };\n+\n+  [[=1, =AN { 1, 42, ' ' }]] void bar (long, const T f, int g[2], T &);\n+\n+  struct V1 {\n+    constexpr V1 (int) {}\n+  };\n+  struct V2 {\n+    V2 &operator = (const V2 &);\n+  };\n+  struct V3 {\n+    V3 &operator = (V3 &&);\n+  };\n+  struct V4 {\n+    V4 &operator += (const V4 &);\n+  };\n+  struct V5 {\n+    operator int ();\n+  };\n+  int operator \"\"_a (const char *);\n+\n+  void\n+  foo (int a, const long b, T c, int d[4], T &e)\n+  {\n+    static_assert (display_string_of (^^a) == \"a\");\n+    static_assert (display_string_of (^^b) == \"b\");\n+    static_assert (display_string_of (^^c) == \"c\");\n+    static_assert (display_string_of (^^d) == \"d\");\n+    static_assert (display_string_of (^^e) == \"e\");\n+    static_assert (display_string_of (parameters_of (^^foo)[0]) == \"<parameter a of void NS5::foo(int, long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^foo)[1]) == \"<parameter b of void NS5::foo(int, long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^foo)[2]) == \"<parameter c of void NS5::foo(int, long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^foo)[3]) == \"<parameter d of void NS5::foo(int, long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^foo)[4]) == \"<parameter e of void NS5::foo(int, long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^bar)[0]) == \"<unnamed parameter 1 of void NS5::bar(long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^bar)[1]) == \"<parameter f of void NS5::bar(long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^bar)[2]) == \"<parameter g of void NS5::bar(long int, T, int*, T&)>\");\n+    static_assert (display_string_of (parameters_of (^^bar)[3]) == \"<unnamed parameter 4 of void NS5::bar(long int, T, int*, T&)>\");\n+    static_assert (display_string_of (^^Z) == \"NS5::Z\");\n+    static_assert (display_string_of (parent_of (^^Z)) == \"NS5::<unnamed enum>\");\n+    static_assert (display_string_of (reflect_constant (42)) == \"42\");\n+    static_assert (display_string_of (reflect_object (arr[1])) == \"NS5::arr[1]\");\n+    static_assert (display_string_of (^^arr) == \"NS5::arr\");\n+    static_assert (display_string_of (^^a3) == \"NS5::a3\");\n+    static_assert (display_string_of (^^fn) == \"void NS5::fn()\");\n+    static_assert (display_string_of (^^fn2) == \"auto& NS5::fn2()\");\n+    static_assert (display_string_of (^^Enum::A) == \"NS5::A\");\n+    static_assert (display_string_of (^^Alias) == \"NS5::Alias {aka int}\");\n+    static_assert (display_string_of (^^S) == \"NS5::S\");\n+    static_assert (display_string_of (^^S::mem) == \"NS5::S::mem\");\n+    static_assert (display_string_of (members_of (^^S, ctx)[1]) == \"NS5::S::<unnamed bit-field>\");\n+    static_assert (display_string_of (^^TCls) == \"template<auto <anonymous> > struct NS5::TCls\");\n+    static_assert (display_string_of (^^TFn) == \"template<auto <anonymous> > void NS5::TFn()\");\n+    static_assert (display_string_of (^^TVar) == \"template<auto <anonymous> > int NS5::TVar<<anonymous> >\");\n+    static_assert (display_string_of (^^Concept) == \"template<auto <anonymous> > concept NS5::Concept\");\n+    static_assert (display_string_of (bases_of (^^S, ctx)[0]) == \"(NS5::S, NS5::B)\");\n+    static_assert (display_string_of (annotations_of (^^bar)[0]) == \"[[=1]]\");\n+    static_assert (display_string_of (annotations_of (^^bar)[1]) == \"[[=NS5::AN{1, 42, ' '}]]\");\n+    static_assert (display_string_of (^^int (&) (int, long, S &)) == \"int (&)(int, long int, NS5::S&)\");\n+    static_assert (display_string_of (^^int (*) (int, long, S &)) == \"int (*)(int, long int, NS5::S&)\");\n+    static_assert (display_string_of (members_of (^^V2, ctx)[0]) == \"NS5::V2& NS5::V2::operator=(const NS5::V2&)\");\n+    static_assert (display_string_of (members_of (^^V3, ctx)[0]) == \"NS5::V3& NS5::V3::operator=(NS5::V3&&)\");\n+    static_assert (display_string_of (members_of (^^V4, ctx)[0]) == \"NS5::V4& NS5::V4::operator+=(const NS5::V4&)\");\n+    static_assert (display_string_of (members_of (^^V5, ctx)[0]) == \"NS5::V5::operator int()\");\n+    static_assert (display_string_of (^^operator\"\"_a) == \"int NS5::operator\\\"\\\"_a(const char*)\");\n+  }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh1.C b/gcc/testsuite/g++.dg/reflect/eh1.C\nnew file mode 100644\nindex 00000000000..10eba7b2a8d\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh1.C\n@@ -0,0 +1,355 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test throwing std::meta::exception.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval void\n+eval (int n)\n+{\n+  switch (n)\n+    {\n+    case 0:\n+      is_reference_type (^^n);\n+      break;\n+    case 1:\n+      is_class_type (^^n);\n+      break;\n+    case 2:\n+      is_union_type (^^n);\n+      break;\n+    case 3:\n+      is_enum_type (^^n);\n+      break;\n+    case 4:\n+      is_member_function_pointer_type (^^n);\n+      break;\n+    case 5:\n+      is_member_object_pointer_type (^^n);\n+      break;\n+    case 6:\n+      is_array_type (^^n);\n+      break;\n+    case 7:\n+      is_pointer_type (^^n);\n+      break;\n+    case 8:\n+      is_void_type (^^n);\n+      break;\n+    case 9:\n+      is_null_pointer_type (^^n);\n+      break;\n+    case 10:\n+      is_integral_type (^^n);\n+      break;\n+    case 11:\n+      is_floating_point_type (^^n);\n+      break;\n+    case 12:\n+      is_lvalue_reference_type (^^n);\n+      break;\n+    case 13:\n+      is_rvalue_reference_type (^^n);\n+      break;\n+    case 14:\n+      is_reflection_type (^^n);\n+      break;\n+    case 15:\n+      remove_const (^^n);\n+      break;\n+    case 16:\n+      remove_volatile (^^n);\n+      break;\n+    case 17:\n+      remove_cv (^^n);\n+      break;\n+    case 18:\n+      add_const (^^n);\n+      break;\n+    case 19:\n+      add_volatile (^^n);\n+      break;\n+    case 20:\n+      add_cv (^^n);\n+      break;\n+    case 21:\n+      is_object_type (^^n);\n+      break;\n+    case 22:\n+      is_arithmetic_type (^^n);\n+      break;\n+    case 23:\n+      is_member_pointer_type (^^n);\n+      break;\n+    case 24:\n+      is_scalar_type (^^n);\n+      break;\n+    case 25:\n+      is_fundamental_type (^^n);\n+      break;\n+    case 26:\n+      is_compound_type (^^n);\n+      break;\n+    case 27:\n+      remove_reference (^^n);\n+      break;\n+    case 28:\n+      add_lvalue_reference (^^n);\n+      break;\n+    case 29:\n+      add_rvalue_reference (^^n);\n+      break;\n+    case 30:\n+      make_signed (^^n);\n+      break;\n+    case 31:\n+      make_unsigned (^^n);\n+      break;\n+    case 32:\n+      remove_extent (^^n);\n+      break;\n+    case 33:\n+      remove_all_extents (^^n);\n+      break;\n+    case 34:\n+      remove_pointer (^^n);\n+      break;\n+    case 35:\n+      add_pointer (^^n);\n+      break;\n+    case 36:\n+      is_const_type (^^n);\n+      break;\n+    case 37:\n+      is_volatile_type (^^n);\n+      break;\n+    case 38:\n+      is_trivially_copyable_type (^^n);\n+      break;\n+    case 41:\n+      is_standard_layout_type (^^n);\n+      break;\n+    case 42:\n+      is_empty_type (^^n);\n+      break;\n+    case 43:\n+      is_polymorphic_type (^^n);\n+      break;\n+    case 44:\n+      is_abstract_type (^^n);\n+      break;\n+    case 45:\n+      is_final_type (^^n);\n+      break;\n+    case 46:\n+      is_aggregate_type (^^n);\n+      break;\n+    case 47:\n+      is_consteval_only_type (^^n);\n+      break;\n+    case 48:\n+      is_signed_type (^^n);\n+      break;\n+    case 49:\n+      is_unsigned_type (^^n);\n+      break;\n+    case 50:\n+      is_bounded_array_type (^^n);\n+      break;\n+    case 51:\n+      is_unbounded_array_type (^^n);\n+      break;\n+    case 52:\n+      is_scoped_enum_type (^^n);\n+      break;\n+    case 53:\n+      is_default_constructible_type (^^n);\n+      break;\n+    case 54:\n+      is_copy_constructible_type (^^n);\n+      break;\n+    case 55:\n+      is_move_constructible_type (^^n);\n+      break;\n+    case 56:\n+      is_copy_assignable_type (^^n);\n+      break;\n+    case 57:\n+      is_move_assignable_type (^^n);\n+      break;\n+    case 58:\n+      is_destructible_type (^^n);\n+      break;\n+    case 59:\n+      is_trivially_default_constructible_type (^^n);\n+      break;\n+    case 60:\n+      is_trivially_copy_constructible_type (^^n);\n+      break;\n+    case 61:\n+      is_trivially_move_constructible_type (^^n);\n+      break;\n+    case 62:\n+      is_trivially_copy_assignable_type (^^n);\n+      break;\n+    case 63:\n+      is_trivially_move_assignable_type (^^n);\n+      break;\n+    case 64:\n+      is_trivially_destructible_type (^^n);\n+      break;\n+    case 65:\n+      is_nothrow_default_constructible_type (^^n);\n+      break;\n+    case 66:\n+      is_nothrow_copy_constructible_type (^^n);\n+      break;\n+    case 67:\n+      is_nothrow_move_constructible_type (^^n);\n+      break;\n+    case 68:\n+      is_nothrow_copy_assignable_type (^^n);\n+      break;\n+    case 69:\n+      is_nothrow_move_assignable_type (^^n);\n+      break;\n+    case 70:\n+      is_nothrow_destructible_type (^^n);\n+      break;\n+    case 72:\n+      has_virtual_destructor (^^n);\n+      break;\n+    case 73:\n+      has_unique_object_representations (^^n);\n+      break;\n+    case 74:\n+      rank (^^n);\n+      break;\n+    case 75:\n+      extent (^^n);\n+      break;\n+    case 76:\n+      extent (^^n, 2);\n+      break;\n+    case 77:\n+      remove_cvref (^^n);\n+      break;\n+    case 78:\n+      decay (^^n);\n+      break;\n+    case 79:\n+      underlying_type (^^n);\n+      break;\n+    case 80:\n+      is_implicit_lifetime_type (^^n);\n+      break;\n+    case 81:\n+      is_swappable_type (^^n);\n+      break;\n+    case 82:\n+      is_nothrow_swappable_type (^^n);\n+      break;\n+    case 83:\n+      unwrap_reference (^^n);\n+      break;\n+    case 84:\n+      unwrap_ref_decay (^^n);\n+      break;\n+   default:\n+      break;\n+    }\n+}\n+\n+consteval bool\n+test (int n)\n+{\n+  try { eval (n); }\n+  catch (std::meta::exception &) { return true; }\n+  catch (...) { return false; }\n+  return false;\n+}\n+\n+static_assert (test (0));\n+static_assert (test (1));\n+static_assert (test (2));\n+static_assert (test (3));\n+static_assert (test (4));\n+static_assert (test (5));\n+static_assert (test (6));\n+static_assert (test (7));\n+static_assert (test (8));\n+static_assert (test (9));\n+static_assert (test (10));\n+static_assert (test (11));\n+static_assert (test (12));\n+static_assert (test (13));\n+static_assert (test (14));\n+static_assert (test (15));\n+static_assert (test (16));\n+static_assert (test (17));\n+static_assert (test (18));\n+static_assert (test (19));\n+static_assert (test (20));\n+static_assert (test (21));\n+static_assert (test (22));\n+static_assert (test (23));\n+static_assert (test (24));\n+static_assert (test (25));\n+static_assert (test (26));\n+static_assert (test (27));\n+static_assert (test (28));\n+static_assert (test (29));\n+static_assert (test (30));\n+static_assert (test (31));\n+static_assert (test (32));\n+static_assert (test (33));\n+static_assert (test (34));\n+static_assert (test (35));\n+static_assert (test (36));\n+static_assert (test (37));\n+static_assert (test (38));\n+static_assert (test (41));\n+static_assert (test (42));\n+static_assert (test (43));\n+static_assert (test (44));\n+static_assert (test (45));\n+static_assert (test (46));\n+static_assert (test (47));\n+static_assert (test (48));\n+static_assert (test (49));\n+static_assert (test (50));\n+static_assert (test (51));\n+static_assert (test (52));\n+static_assert (test (53));\n+static_assert (test (54));\n+static_assert (test (55));\n+static_assert (test (56));\n+static_assert (test (57));\n+static_assert (test (58));\n+static_assert (test (59));\n+static_assert (test (60));\n+static_assert (test (61));\n+static_assert (test (62));\n+static_assert (test (63));\n+static_assert (test (64));\n+static_assert (test (65));\n+static_assert (test (66));\n+static_assert (test (67));\n+static_assert (test (68));\n+static_assert (test (69));\n+static_assert (test (70));\n+static_assert (test (72));\n+static_assert (test (73));\n+static_assert (test (74));\n+static_assert (test (75));\n+static_assert (test (76));\n+static_assert (test (77));\n+static_assert (test (78));\n+static_assert (test (79));\n+static_assert (test (80));\n+static_assert (test (81));\n+static_assert (test (82));\n+static_assert (test (83));\n+static_assert (test (84));\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh2.C b/gcc/testsuite/g++.dg/reflect/eh2.C\nnew file mode 100644\nindex 00000000000..21f98796dfe\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh2.C\n@@ -0,0 +1,91 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test throwing std::meta::exception.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+int i;\n+static_assert (is_reference_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_class_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_union_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_enum_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_member_function_pointer_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_member_object_pointer_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_pointer_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_array_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_void_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_null_pointer_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_integral_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_floating_point_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_lvalue_reference_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_rvalue_reference_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert (is_reflection_type (^^i)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_const (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_volatile (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_cv (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((add_const (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((add_volatile (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((add_cv (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_object_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_arithmetic_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_member_pointer_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_scalar_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_fundamental_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_compound_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_reference (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((add_lvalue_reference (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((add_rvalue_reference (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((make_signed (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((make_unsigned (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_extent (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_all_extents (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_pointer (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((add_pointer (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_const_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_volatile_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_copyable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_standard_layout_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_empty_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_polymorphic_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_abstract_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_final_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_aggregate_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_consteval_only_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_signed_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_unsigned_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_bounded_array_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_unbounded_array_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_scoped_enum_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_default_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_copy_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_move_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_copy_assignable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_move_assignable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_destructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_default_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_copy_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_move_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_copy_assignable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_move_assignable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_trivially_destructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_default_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_copy_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_move_constructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_copy_assignable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_move_assignable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_destructible_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((has_virtual_destructor (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((has_unique_object_representations (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((rank (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((extent (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((extent (^^i, 42), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((remove_cvref (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((decay (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((underlying_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_implicit_lifetime_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_swappable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((is_nothrow_swappable_type (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((unwrap_reference (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\n+static_assert ((unwrap_ref_decay (^^i), true)); // { dg-error \"non-constant|uncaught exception\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh3.C b/gcc/testsuite/g++.dg/reflect/eh3.C\nnew file mode 100644\nindex 00000000000..a08afec8a95\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh3.C\n@@ -0,0 +1,22 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test throwing std::meta::exception.\n+\n+#include <meta>\n+\n+consteval void\n+foo ()\n+{\n+  throw std::meta::exception{\"foo\", ^^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/eh4.C b/gcc/testsuite/g++.dg/reflect/eh4.C\nnew file mode 100644\nindex 00000000000..754ac90e2bc\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh4.C\n@@ -0,0 +1,221 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test throwing std::meta::exception.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S { };\n+\n+consteval void\n+eval (int n)\n+{\n+  switch (n)\n+    {\n+    case 0:\n+      is_same_type (^^S, ^^n);\n+      break;\n+    case 1:\n+      is_same_type (^^n, ^^S);\n+      break;\n+    case 2:\n+      is_base_of_type (^^S, ^^n);\n+      break;\n+    case 3:\n+      is_base_of_type (^^n, ^^S);\n+      break;\n+    case 4:\n+      is_virtual_base_of_type (^^S, ^^n);\n+      break;\n+    case 5:\n+      is_virtual_base_of_type (^^n, ^^S);\n+      break;\n+    case 6:\n+      is_convertible_type (^^S, ^^n);\n+      break;\n+    case 7:\n+      is_convertible_type (^^n, ^^S);\n+      break;\n+    case 8:\n+      is_nothrow_convertible_type (^^S, ^^n);\n+      break;\n+    case 9:\n+      is_nothrow_convertible_type (^^n, ^^S);\n+      break;\n+    case 10:\n+      is_layout_compatible_type (^^S, ^^n);\n+      break;\n+    case 11:\n+      is_layout_compatible_type (^^n, ^^S);\n+      break;\n+    case 12:\n+      is_pointer_interconvertible_base_of_type (^^S, ^^n);\n+      break;\n+    case 13:\n+      is_pointer_interconvertible_base_of_type (^^n, ^^S);\n+      break;\n+    case 14:\n+      is_assignable_type (^^S, ^^n);\n+      break;\n+    case 15:\n+      is_assignable_type (^^n, ^^S);\n+      break;\n+    case 16:\n+      is_trivially_assignable_type (^^S, ^^n);\n+      break;\n+    case 17:\n+      is_trivially_assignable_type (^^n, ^^S);\n+      break;\n+    case 18:\n+      is_nothrow_assignable_type (^^S, ^^n);\n+      break;\n+    case 19:\n+      is_nothrow_assignable_type (^^n, ^^S);\n+      break;\n+    case 20:\n+      reference_constructs_from_temporary (^^S, ^^n);\n+      break;\n+    case 21:\n+      reference_constructs_from_temporary (^^n, ^^S);\n+      break;\n+    case 22:\n+      reference_converts_from_temporary (^^S, ^^n);\n+      break;\n+    case 23:\n+      reference_converts_from_temporary (^^n, ^^S);\n+      break;\n+    case 24:\n+      type_order (^^S, ^^n);\n+      break;\n+    case 25:\n+      type_order (^^n, ^^S);\n+      break;\n+    case 26:\n+      is_constructible_type (^^n, {});\n+      break;\n+    case 27:\n+      is_constructible_type (^^S, { ^^S, ^^n, ^^S });\n+      break;\n+    case 28:\n+      is_trivially_constructible_type (^^n, {});\n+      break;\n+    case 29:\n+      is_trivially_constructible_type (^^S, { ^^n, ^^S, ^^S, ^^S });\n+      break;\n+    case 30:\n+      is_nothrow_constructible_type (^^n, {});\n+      break;\n+    case 31:\n+      is_nothrow_constructible_type (^^S, { ^^S, ^^S, ^^S, ^^S, ^^n });\n+      break;\n+    case 32:\n+      is_invocable_type (^^n, {});\n+      break;\n+    case 33:\n+      is_invocable_type (^^S, { ^^S, ^^S, ^^n, ^^S });\n+      break;\n+    case 34:\n+      is_nothrow_invocable_type (^^n, {});\n+      break;\n+    case 35:\n+      is_nothrow_invocable_type (^^S, { ^^S, ^^n, ^^S });\n+      break;\n+    case 36:\n+      is_invocable_r_type (^^n, ^^S, {});\n+      break;\n+    case 37:\n+      is_invocable_r_type (^^S, ^^n, {});\n+      break;\n+    case 38:\n+      is_invocable_r_type (^^S, ^^S, { ^^S, ^^n, ^^S });\n+      break;\n+    case 39:\n+      is_nothrow_invocable_r_type (^^n, ^^S, {});\n+      break;\n+    case 40:\n+      is_nothrow_invocable_r_type (^^S, ^^n, {});\n+      break;\n+    case 41:\n+      is_nothrow_invocable_r_type (^^S, ^^S, { ^^S, ^^n, ^^S });\n+      break;\n+    case 42:\n+      invoke_result (^^n, {});\n+      break;\n+    case 43:\n+      invoke_result (^^S, { ^^S, ^^n, ^^S });\n+      break;\n+    case 44:\n+      is_swappable_with_type (^^S, ^^n);\n+      break;\n+    case 45:\n+      is_swappable_with_type (^^n, ^^S);\n+      break;\n+    case 46:\n+      is_nothrow_swappable_with_type (^^S, ^^n);\n+      break;\n+    case 47:\n+      is_nothrow_swappable_with_type (^^n, ^^S);\n+      break;\n+    default:\n+      break;\n+    }\n+}\n+\n+consteval bool\n+test (int n)\n+{\n+  try { eval (n); }\n+  catch (std::meta::exception &) { return true; }\n+  catch (...) { return false; }\n+  return false;\n+}\n+\n+static_assert (test (0));\n+static_assert (test (1));\n+static_assert (test (2));\n+static_assert (test (3));\n+static_assert (test (4));\n+static_assert (test (5));\n+static_assert (test (6));\n+static_assert (test (7));\n+static_assert (test (8));\n+static_assert (test (9));\n+static_assert (test (10));\n+static_assert (test (11));\n+static_assert (test (12));\n+static_assert (test (13));\n+static_assert (test (14));\n+static_assert (test (15));\n+static_assert (test (16));\n+static_assert (test (17));\n+static_assert (test (18));\n+static_assert (test (19));\n+static_assert (test (20));\n+static_assert (test (21));\n+static_assert (test (22));\n+static_assert (test (23));\n+static_assert (test (24));\n+static_assert (test (25));\n+static_assert (test (26));\n+static_assert (test (27));\n+static_assert (test (28));\n+static_assert (test (29));\n+static_assert (test (30));\n+static_assert (test (31));\n+static_assert (test (32));\n+static_assert (test (33));\n+static_assert (test (34));\n+static_assert (test (35));\n+static_assert (test (36));\n+static_assert (test (37));\n+static_assert (test (38));\n+static_assert (test (39));\n+static_assert (test (40));\n+static_assert (test (41));\n+static_assert (test (42));\n+static_assert (test (43));\n+static_assert (test (44));\n+static_assert (test (45));\n+static_assert (test (46));\n+static_assert (test (47));\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh5.C b/gcc/testsuite/g++.dg/reflect/eh5.C\nnew file mode 100644\nindex 00000000000..9e6c78169f6\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh5.C\n@@ -0,0 +1,103 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test throwing std::meta::exception.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template <int N>\n+struct S {};\n+\n+consteval bool\n+foo (info x)\n+{\n+  try\n+    {\n+      is_class_type (x);\n+    }\n+  catch (std::meta::exception &ex)\n+    {\n+      std::string_view what = ex.what ();\n+      info from = ex.from ();\n+      std::source_location loc = ex.where ();\n+      if (loc.line () != std::source_location::current ().line () - 7\n+\t  || from != ^^std::meta::is_class_type\n+\t  || what != \"reflection does not represent a type\"\n+\t  || ex.u8what () != u8\"reflection does not represent a type\")\n+\treturn false;\n+      return true;\n+    }\n+  return false;\n+}\n+\n+consteval bool\n+bar (info x)\n+{\n+  try\n+    {\n+      parameters_of (x);\n+    }\n+  catch (std::meta::exception &ex)\n+    {\n+      std::string_view what = ex.what ();\n+      info from = ex.from ();\n+      std::source_location loc = ex.where ();\n+      if (loc.line () != std::source_location::current ().line () - 7\n+\t  || from != ^^std::meta::parameters_of\n+\t  || what != \"reflection does not represent a function or function type\"\n+\t  || ex.u8what () != u8\"reflection does not represent a function or function type\")\n+\treturn false;\n+      return true;\n+    }\n+  return false;\n+}\n+\n+consteval bool\n+baz (info x)\n+{\n+  try\n+    {\n+      data_member_spec (x, { .name = \"consteval\" });\n+    }\n+  catch (std::meta::exception &ex)\n+    {\n+      std::string_view what = ex.what ();\n+      info from = ex.from ();\n+      std::source_location loc = ex.where ();\n+      if (loc.line () != std::source_location::current ().line () - 7\n+\t  || from != ^^std::meta::data_member_spec\n+\t  || what != \"name is a keyword\"\n+\t  || ex.u8what () != u8\"name is a keyword\")\n+\treturn false;\n+      return true;\n+    }\n+  return false;\n+}\n+\n+consteval bool\n+qux (info x)\n+{\n+  try\n+    {\n+      can_substitute (^^S, { x });\n+    }\n+  catch (std::meta::exception &ex)\n+    {\n+      std::string_view what = ex.what ();\n+      info from = ex.from ();\n+      std::source_location loc = ex.where ();\n+      if (loc.line () != std::source_location::current ().line () - 7\n+\t  || from != ^^std::meta::can_substitute\n+\t  || what != \"invalid argument to can_substitute\"\n+\t  || ex.u8what () != u8\"invalid argument to can_substitute\")\n+\treturn false;\n+      return true;\n+    }\n+  return false;\n+}\n+\n+static_assert (foo (^^::));\n+static_assert (bar (^^::));\n+static_assert (baz (^^int));\n+static_assert (qux (^^::));\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh6.C b/gcc/testsuite/g++.dg/reflect/eh6.C\nnew file mode 100644\nindex 00000000000..b33cf319085\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh6.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 throwing std::meta::exception.\n+\n+#include \"eh5.C\"\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh7.C b/gcc/testsuite/g++.dg/reflect/eh7.C\nnew file mode 100644\nindex 00000000000..2a065241e1a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh7.C\n@@ -0,0 +1,22 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-require-iconv \"IBM1047\" }\n+// { dg-additional-options \"-freflection -fexec-charset=IBM1047\" }\n+// Test std::meta::exception.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval bool\n+foo ()\n+{\n+  exception a (u8\"This is a string\", ^^foo);\n+  if (std::string_view (a.what ()) != std::string_view (\"This is a string\"))\n+    return false;\n+  exception b (\"This is a string\", ^^foo);\n+  if (b.u8what () != std::u8string_view (u8\"This is a string\"))\n+    return false;\n+  return true;\n+}\n+\n+static_assert (foo ());\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh8.C b/gcc/testsuite/g++.dg/reflect/eh8.C\nnew file mode 100644\nindex 00000000000..ac4afa4b053\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh8.C\n@@ -0,0 +1,31 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-require-iconv \"ISO-8859-2\" }\n+// { dg-options \"-freflection -fexec-charset=ISO-8859-2\" }\n+// Test std::meta::exception.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+consteval bool\n+foo ()\n+{\n+  exception a (u8\"h\\u00e1\\U0000010Dky a \\u010d\\u00E1rky\", ^^foo);\n+  if (std::string_view (a.what ()) != std::string_view (\"h\\u00e1\\U0000010Dky a \\u010d\\u00E1rky\"))\n+    return false;\n+  exception b (\"h\\u00e1\\U0000010Dky a \\u010d\\u00E1rky\", ^^foo);\n+  if (b.u8what () != std::u8string_view (u8\"h\\u00e1\\U0000010Dky a \\u010d\\u00E1rky\"))\n+    return false;\n+  return true;\n+}\n+\n+consteval bool\n+bar ()\n+{\n+  exception a (u8\"\\N{GRINNING FACE}\\N{GRINNING FACE WITH SMILING EYES}\\N{LEFT SPEECH BUBBLE}\", ^^foo);\n+  const char *b = a.what ();\t// { dg-message \"in 'constexpr' expansion of 'a.std::meta::exception::what\\\\\\(\\\\\\)\" }\n+  return true;\t\t\t// { dg-error \"inline assembly is not a constant expression\" \"\" { target *-*-* } 0 }\n+}\n+\n+static_assert (foo ());\n+constexpr auto c = bar ();\ndiff --git a/gcc/testsuite/g++.dg/reflect/eh9.C b/gcc/testsuite/g++.dg/reflect/eh9.C\nnew file mode 100644\nindex 00000000000..3051d41b1cd\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/eh9.C\n@@ -0,0 +1,11 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test throwing an exception in a template.\n+\n+#include <meta>\n+\n+enum E : int;\n+template <int K>\n+constexpr auto R = enumerators_of(^^E)[0];\n+enum E : int { A, B, C };\n+static_assert(R<0> == ^^A);\ndiff --git a/gcc/testsuite/g++.dg/reflect/enumerators_of1.C b/gcc/testsuite/g++.dg/reflect/enumerators_of1.C\nnew file mode 100644\nindex 00000000000..17141185afa\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/enumerators_of1.C\n@@ -0,0 +1,189 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::enumerators_of.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr info null_reflection;\n+void foo ();\n+\n+consteval bool\n+has_enumerators_of (info r)\n+{\n+  try { enumerators_of (r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+static_assert (!has_enumerators_of (null_reflection));\n+static_assert (!has_enumerators_of (^^int));\n+static_assert (!has_enumerators_of (^^::));\n+static_assert (!has_enumerators_of (^^foo));\n+\n+class S;\n+enum class E;\n+typedef E TE;\n+static_assert (!has_enumerators_of (^^S));\n+static_assert (!has_enumerators_of (^^E));\n+static_assert (!has_enumerators_of (^^TE));\n+\n+template<typename> struct cls_tmpl {};\n+template<typename T> using cls_tmpl_alias = cls_tmpl<T>;\n+static_assert (!has_enumerators_of (^^cls_tmpl));\n+static_assert (!has_enumerators_of (^^cls_tmpl<int>));\n+static_assert (!has_enumerators_of (^^cls_tmpl_alias));\n+static_assert (!has_enumerators_of (^^cls_tmpl_alias<int>));\n+\n+class S {\n+  void foo ()\n+  {\n+    static_assert (!has_enumerators_of (^^S));\n+  }\n+  static_assert (!has_enumerators_of (^^S));\n+};\n+static_assert (!has_enumerators_of (^^S));\n+\n+enum class E {\n+//  A1 = (has_enumerators_of (^^E) || has_enumerators_of (^^TE)) ? 1 : 2,\n+  A2 = has_enumerators_of (^^E) ? 10 : 20,\n+  A3 = has_enumerators_of (^^TE) ? 20 : 30\n+};\n+static_assert (has_enumerators_of (^^E));\n+//static_assert (static_cast <int> (E::A1) == 2);\n+static_assert (static_cast <int> (E::A2) == 20);\n+static_assert (static_cast <int> (E::A3) == 30);\n+static_assert (has_enumerators_of (^^TE));\n+\n+enum F : int;\n+using TF = F;\n+static_assert (!has_enumerators_of (^^F));\n+static_assert (!has_enumerators_of (^^TF));\n+enum F : int {\n+//  B1 = (has_enumerators_of (^^F) || has_enumerators_of (^^TF)) ? 3 : 4,\n+  B2 = has_enumerators_of (^^F) ? 30 : 40,\n+  B3 = has_enumerators_of (^^TF) ? 40 : 42\n+};\n+static_assert (has_enumerators_of (^^F));\n+//static_assert (B1 == 4);\n+static_assert (B2 == 40);\n+static_assert (B3 == 42);\n+static_assert (has_enumerators_of (^^TF));\n+\n+enum G {\n+  C = has_enumerators_of (^^G) ? 5 : 6\n+};\n+static_assert (has_enumerators_of (^^G));\n+static_assert (C == 6);\n+\n+enum H : int;\n+typedef H TH;\n+static_assert (!has_enumerators_of (^^H));\n+static_assert (!has_enumerators_of (^^TH));\n+\n+enum H : int {};\n+static_assert (has_enumerators_of (^^H));\n+static_assert (has_enumerators_of (^^TH));\n+\n+enum I : short;\n+using TI = I;\n+static_assert (!has_enumerators_of (^^I));\n+static_assert (!has_enumerators_of (^^TI));\n+enum I : short {};\n+static_assert (has_enumerators_of (^^I));\n+static_assert (has_enumerators_of (^^TI));\n+\n+template <typename T>\n+void\n+qux ()\n+{\n+  enum J : T;\n+  using K = J;\n+  // FIXME: No idea if this is supposed to be false or true.\n+  // We certainly during instantiation don't differentiate between\n+  // forward enum declarations and later definitions.\n+  //  static_assert (!has_enumerators_of (^^J));\n+  //  static_assert (!has_enumerators_of (dealias(^^K)));\n+  enum J : T {\n+    D = (has_enumerators_of (^^J) || has_enumerators_of (^^K))\n+\t? sizeof (T) * 2 : sizeof (T)\n+  };\n+  static_assert (has_enumerators_of (^^J));\n+  static_assert (D == sizeof (T));\n+  static_assert (has_enumerators_of (^^K));\n+}\n+\n+void\n+corge ()\n+{\n+  qux <int> ();\n+  qux <unsigned char> ();\n+}\n+\n+enum L : int;\n+using TL = L;\n+static_assert (!has_enumerators_of (^^L));\n+static_assert (!has_enumerators_of (^^TL));\n+enum L : int {\n+  L0, L1 = 42, L2, L3 = 14, L4 = 16, L6 = 18, L5 = 24\n+};\n+static_assert (enumerators_of (^^L).size () == 7);\n+static_assert (enumerators_of (^^L)[0] == ^^L0);\n+static_assert (enumerators_of (^^L)[1] == ^^L1);\n+static_assert (enumerators_of (^^L)[2] == ^^L2);\n+static_assert (enumerators_of (^^L)[3] == ^^L3);\n+static_assert (enumerators_of (^^L)[4] == ^^L4);\n+static_assert (enumerators_of (^^L)[5] == ^^L6);\n+static_assert (enumerators_of (^^L)[6] == ^^L5);\n+static_assert (enumerators_of (^^TL).size () == 7);\n+static_assert (enumerators_of (^^TL)[0] == ^^L0);\n+static_assert (enumerators_of (^^TL)[1] == ^^L1);\n+static_assert (enumerators_of (^^TL)[2] == ^^L2);\n+static_assert (enumerators_of (^^TL)[3] == ^^L3);\n+static_assert (enumerators_of (^^TL)[4] == ^^L4);\n+static_assert (enumerators_of (^^TL)[5] == ^^L6);\n+static_assert (enumerators_of (^^TL)[6] == ^^L5);\n+\n+enum M {\n+  M5, M13, M2 = 8, M0, M17\n+};\n+static_assert (enumerators_of (^^M).size () == 5);\n+static_assert (enumerators_of (^^M)[0] == ^^M5);\n+static_assert (enumerators_of (^^M)[1] == ^^M13);\n+static_assert (enumerators_of (^^M)[2] == ^^M2);\n+static_assert (enumerators_of (^^M)[3] == ^^M0);\n+static_assert (enumerators_of (^^M)[4] == ^^M17);\n+static_assert (enumerators_of (parent_of (^^M5)).size () == 5);\n+\n+enum N : int;\n+typedef N TN;\n+static_assert (!has_enumerators_of (^^N));\n+static_assert (!has_enumerators_of (^^TN));\n+\n+enum N : int { N1 = 5 };\n+static_assert (enumerators_of (^^N).size () == 1);\n+static_assert (enumerators_of (^^N)[0] == ^^N1);\n+static_assert (enumerators_of (^^TN).size () == 1);\n+static_assert (enumerators_of (^^TN)[0] == ^^N1);\n+\n+enum O : short;\n+using TO = O;\n+static_assert (!has_enumerators_of (^^O));\n+static_assert (!has_enumerators_of (^^TO));\n+enum O : short { O1 = 2, O2 = 3, O3 = 4};\n+static_assert (enumerators_of (^^O).size () == 3);\n+static_assert (enumerators_of (^^O)[0] == ^^O1);\n+static_assert (enumerators_of (^^O)[1] == ^^O2);\n+static_assert (enumerators_of (^^O)[2] == ^^O3);\n+static_assert (enumerators_of (^^TO).size () == 3);\n+static_assert (enumerators_of (^^TO)[0] == ^^O1);\n+static_assert (enumerators_of (^^TO)[1] == ^^O2);\n+static_assert (enumerators_of (^^TO)[2] == ^^O3);\n+\n+enum { P1, P2, P3 };\n+static_assert (enumerators_of (parent_of (^^P1)).size() == 3);\n+static_assert (enumerators_of (parent_of (^^P1))[0] == ^^P1);\n+static_assert (enumerators_of (parent_of (^^P1))[1] == ^^P2);\n+static_assert (enumerators_of (parent_of (^^P1))[2] == ^^P3);\n+\ndiff --git a/gcc/testsuite/g++.dg/reflect/error1.C b/gcc/testsuite/g++.dg/reflect/error1.C\nnew file mode 100644\nindex 00000000000..ad308625e97\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error1.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct X { };\n+\n+void\n+f1 ()\n+{\n+  constexpr auto r = ^^int;\n+  [: r ] i = 42;  // { dg-error \"expected .:].|expected unqualified-id\" }\n+  [: :] x1;\t  // { dg-error \"expected primary-expression|forbids|reflection not usable\" }\n+  [: int :] x2;\t  // { dg-error \"expected|reflection not usable\" }\n+  [: X :] x3;\t  // { dg-error \"expected|reflection not usable\" }\n+  constexpr X x;\n+  [: x :] x4;\t  // { dg-error \"could not convert .x. from .const X. to .std::meta::info.|reflection not usable\" }\n+\n+  constexpr auto e1 = ^^42;  // { dg-error \"cannot be applied\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/error10.C b/gcc/testsuite/g++.dg/reflect/error10.C\nnew file mode 100644\nindex 00000000000..2ca2b18a1fa\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error10.C\n@@ -0,0 +1,39 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+int g;\n+\n+void\n+fn0 (int, typename [: ^^:: :] i) // { dg-error \"reflection .::. not usable in a splice type|declared\" }\n+{\n+}\n+\n+void\n+fn1 (int, typename [: ^^g :] i) // { dg-error \"reflection .g. not usable in a splice type|declared\" }\n+{\n+}\n+\n+void\n+fn2 (int, typename [: ^^fn1 :] i) // { dg-error \"reflection .fn1. not usable in a splice type|declared\" }\n+{\n+}\n+\n+void\n+fn3 (int p, typename [: ^^p :] i) // { dg-error \"reflection .p. not usable in a splice type|declared\" }\n+{\n+}\n+\n+enum Harold { Budd };\n+\n+void\n+fn4 (int, typename [: ^^Budd :] i) // { dg-error \"reflection .Budd. not usable in a splice type|declared\" }\n+{\n+}\n+\n+template<int>\n+struct S {};\n+\n+void\n+fn5 (int, typename [: ^^S :] i) // { dg-error \"reflection .S. not usable in a splice type|declared\" }\n+{\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/error2.C b/gcc/testsuite/g++.dg/reflect/error2.C\nnew file mode 100644\nindex 00000000000..27fd3fdfb66\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error2.C\n@@ -0,0 +1,19 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct A {\n+  A();\n+  ~A();\n+};\n+\n+void\n+g ()\n+{\n+  // clang accepts these, but EDG rejects too.\n+  constexpr auto r1 = ^^A::A;\t  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r2 = ^^A::A();\t  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r3 = ^^A::A::A;  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r4 = ^^A::~A;\n+  [: r4 :];\t  // { dg-error \"cannot use constructor or destructor in a splice expression\" }\n+  [: ^^A::~A :];  // { dg-error \"cannot use constructor or destructor in a splice expression\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/error3.C b/gcc/testsuite/g++.dg/reflect/error3.C\nnew file mode 100644\nindex 00000000000..1f3ed4f00cb\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error3.C\n@@ -0,0 +1,5 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+typename[: ^^:: :] x = 0;  // { dg-error \"expected\" }\n+[: ^^:: :] x2 = 0;  // { dg-error \"expected\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/error4.C b/gcc/testsuite/g++.dg/reflect/error4.C\nnew file mode 100644\nindex 00000000000..cb3dd80ff6e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error4.C\n@@ -0,0 +1,11 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+namespace A {}\n+constexpr auto NS_A = ^^A;\n+\n+namespace B {\n+  namespace [:NS_A:] {\t// { dg-error \"expected\" }\n+    void fn();  // Is this '::A::fn' or '::B::A::fn' ?\n+  }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/error5.C b/gcc/testsuite/g++.dg/reflect/error5.C\nnew file mode 100644\nindex 00000000000..2b125fffc1a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error5.C\n@@ -0,0 +1,19 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+namespace N { }\n+\n+template<info R>\n+void\n+f ()\n+{\n+  int i = [:R:]; // { dg-error \"expected a reflection of an expression instead of .N.\" }\n+}\n+\n+void\n+g ()\n+{\n+  f<^^N>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/error6.C b/gcc/testsuite/g++.dg/reflect/error6.C\nnew file mode 100644\nindex 00000000000..35ffd66f7ea\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error6.C\n@@ -0,0 +1,24 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Detect taking the reflection of a using-declarator as per [expr.reflect]/5.\n+\n+namespace NS {\n+  namespace Inner {\n+    consteval int fn() { return 42; }\n+    template <auto V> consteval int tfn() { return V; }\n+  }  // namespace Inner\n+\n+  using Inner::fn;\n+  using Inner::tfn;\n+}  // namespace NS\n+\n+// splice-expressions\n+static_assert([:^^NS::fn:]() == 42);  // { dg-error \"cannot be applied to a using-declarator\" }\n+static_assert(template [:^^NS::tfn:]<4>() == 4);  // { dg-error \"cannot be applied to a using-declarator|expected\" }\n+\n+// nested proxies\n+struct A { int m; };\n+struct B : A { using A::m; };\n+struct C : B { using B::m; };\n+\n+static_assert(&[:^^C::m:] == &A::m); // { dg-error \"cannot be applied to a using-declarator\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/error8.C b/gcc/testsuite/g++.dg/reflect/error8.C\nnew file mode 100644\nindex 00000000000..8f35b09b2f1\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error8.C\n@@ -0,0 +1,37 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test static consteval-only vars in a consteval function.\n+\n+consteval void\n+f1 ()\n+{\n+  static auto i = ^^int;  // { dg-error \".i. defined .static. in .constexpr. context\" }\n+}\n+\n+consteval void\n+f2 ()\n+{\n+  static const auto i = ^^int;  // { dg-error \".i. defined .static. in .constexpr. context\" }\n+}\n+\n+consteval void\n+f3 ()\n+{\n+  static constexpr auto i = ^^int;\n+}\n+\n+consteval\n+void\n+f4 ()\n+{\n+  static constinit auto i = ^^int;  // { dg-error \".i. defined .static. in .constexpr. context\" }\n+}\n+\n+void\n+z ()\n+{\n+  f1();  // { dg-error \"call to consteval function|in a constant expression\" }\n+  f2();  // { dg-error \"call to consteval function|in a constant expression\" }\n+  f3();\n+  f4();  // { dg-error \"call to consteval function|in a constant expression\" }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/error9.C b/gcc/testsuite/g++.dg/reflect/error9.C\nnew file mode 100644\nindex 00000000000..fe0829a972b\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/error9.C\n@@ -0,0 +1,6 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+template<typename> concept conc = requires { true; };\n+constexpr auto r = ^^conc;\n+constexpr auto x = ^^conc<int>;  // { dg-error \"cannot be applied to a concept check\" }\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr1.C b/gcc/testsuite/g++.dg/reflect/expr1.C\nnew file mode 100644\nindex 00000000000..8f893584153\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr1.C\n@@ -0,0 +1,68 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on id-expression.\n+\n+int arr[2] = { 1, 2 };\n+\n+template<typename T>\n+void foo (T) { }\n+\n+struct S {\n+  int i;\n+  operator int() { return this->i; }\n+  ~S();\n+};\n+\n+static int operator+(S a, S b) { return a.i + b.i; }\n+\n+void operator \"\"_km(long double);\n+template <char...> double operator \"\"_fm();\n+\n+void\n+f (S a, S b)\n+{\n+  // unqualified-id\n+  constexpr auto r1 = ^^foo<int>;\n+  [: r1 :](1);\n+\n+  constexpr auto r2 = ^^operator+;\n+  [: r2 :](a, b);\n+\n+  constexpr auto r3 = ^^operator \"\"_km;\n+  constexpr auto r4 = ^^operator \"\"_fm;\n+  constexpr auto r5 = ^^operator \"\"_fm<'a'>;\n+\n+  auto & [ c, d ] = arr;\n+  constexpr auto r6 = ^^c;\n+  constexpr auto r7 = ^^d;\n+  [: r6 :] = 1;\n+  [: r7 :] = 1;\n+}\n+\n+void\n+g (S a, S b)\n+{\n+  // qualified-id\n+  constexpr auto r1 = ^^::foo<int>;\n+  [: r1 :](1);\n+\n+  constexpr auto r2 = ^^::operator+;\n+  [: r2 :](a, b);\n+\n+  constexpr auto r3 = ^^S::operator int;\n+  constexpr auto r4 = ^^::operator \"\"_km;\n+  constexpr auto r5 = ^^S::~S;\n+  constexpr auto r6 = ^^::operator \"\"_fm;\n+  constexpr auto r7 = ^^::operator \"\"_fm<'a'>;\n+}\n+\n+consteval int\n+h ()\n+{\n+  int x = 41;\n+  constexpr auto rx = ^^x;\n+  ++[: rx :];\n+  return x;\n+}\n+\n+static_assert(h () == 42);\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr10.C b/gcc/testsuite/g++.dg/reflect/expr10.C\nnew file mode 100644\nindex 00000000000..7b195e781cd\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr10.C\n@@ -0,0 +1,39 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections in consteval blocks.\n+\n+using info = decltype(^^void);\n+\n+consteval info foo (info i) { return i; }\n+\n+constexpr info u = ^^int;\n+\n+consteval {\n+  auto z = ^^int;\n+  u;\n+  ^^double;\n+  static constexpr auto gl = ^^double;\n+  foo (^^int);\n+}\n+\n+struct S {\n+  consteval {\n+    auto z = ^^int;\n+    ^^double;\n+    static constexpr auto gl = ^^double;\n+    foo (^^int);\n+  }\n+};\n+\n+void\n+g ()\n+{\n+  constexpr info r = ^^int;\n+  consteval {\n+    r;\n+    ^^double;\n+    auto l = ^^double;\n+    static constexpr auto gl = ^^double;\n+    foo (^^int);\n+  }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr11.C b/gcc/testsuite/g++.dg/reflect/expr11.C\nnew file mode 100644\nindex 00000000000..20af4bc07ae\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr11.C\n@@ -0,0 +1,32 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections in if and while.\n+\n+using info = decltype(^^void);\n+consteval info foo (info i) { return i; }\n+\n+void\n+f ()\n+{\n+  constexpr auto q = ^^float;\n+  if constexpr (foo (^^::) == ^^::)\n+    {\n+      auto r = ^^int; // { dg-error \"consteval-only variable .r.\" }\n+      constexpr auto cr = ^^int;\n+    }\n+  if constexpr (auto r = ^^int;  // { dg-error \"consteval-only variable .r.\" }\n+\t\tr == ^^int);\t // { dg-error \"the value of .r. is not usable\" }\n+  if constexpr (constexpr auto r = ^^int; r == ^^int);\n+  if constexpr (q != ^^char);\n+  if constexpr (^^int != ^^char);\n+  if (q != ^^char);  // { dg-error \"consteval-only expressions\" }\n+  if (^^char == ^^char);  // { dg-error \"consteval-only expressions\" }\n+  while (^^char == ^^char);  // { dg-error \"consteval-only expressions\" }\n+  do {} while (^^char == ^^char);  // { dg-error \"consteval-only expressions\" }\n+  consteval {\n+    if (q != ^^char);\n+    if (^^char == ^^char);\n+    while (^^char != ^^char);\n+    do {} while (^^char != ^^char);\n+  }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr12.C b/gcc/testsuite/g++.dg/reflect/expr12.C\nnew file mode 100644\nindex 00000000000..a59a60f03a3\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr12.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections in consteval if.\n+\n+void\n+f ()\n+{\n+  constexpr auto q = ^^float;\n+  if consteval\n+    {\n+      ^^void;\n+      q;\n+      auto r = ^^int;\n+      if (q != ^^char);\n+      if (^^char == ^^char);\n+      while (^^char != ^^char);\n+      do {} while (^^char != ^^char);\n+    }\n+\n+  if not consteval\n+    {\n+      ^^void;  // { dg-error \"consteval-only expressions\" }\n+      q;  // { dg-error \"consteval-only expressions\" }\n+      auto r = ^^int;  // { dg-error \"consteval-only variable\" }\n+      if (q != ^^char);  // { dg-error \"consteval-only expressions\" }\n+      if (^^char == ^^char);  // { dg-error \"consteval-only expressions\" }\n+      while (^^char != ^^char);  // { dg-error \"consteval-only expressions\" }\n+      do {} while (^^char != ^^char);  // { dg-error \"consteval-only expressions\" }\n+    }\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr13.C b/gcc/testsuite/g++.dg/reflect/expr13.C\nnew file mode 100644\nindex 00000000000..6be27640ed7\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr13.C\n@@ -0,0 +1,20 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <type_traits>\n+\n+template <auto I>\n+struct X {};\n+\n+struct Y {\n+  int name;\n+};\n+\n+template <typename S>\n+constexpr auto foo (S s) {\n+  return X<^^S::name> {};\n+}\n+\n+constexpr auto a = foo (Y { 42 });\n+// TODO: This doesn't work: 'const struct X<^^Y::name>' is not the same as 'const struct X<^^Y::name>'\n+//static_assert (std::is_same_v <decltype (a), const X <^^Y::name>>);\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr14.C b/gcc/testsuite/g++.dg/reflect/expr14.C\nnew file mode 100644\nindex 00000000000..cec7e66593b\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr14.C\n@@ -0,0 +1,16 @@\n+// PR c++/123081\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+template<typename T>\n+constexpr auto refl = ^^T;\n+\n+struct {\n+\ttemplate<typename T>\n+\trequires(requires { typename[:refl<T>:]; })\n+\tvoid f(T) {}\n+} a;\n+\n+int main() {\n+\ta.f([] {});\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr2.C b/gcc/testsuite/g++.dg/reflect/expr2.C\nnew file mode 100644\nindex 00000000000..1cca88672eb\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr2.C\n@@ -0,0 +1,60 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test reflections on id-expression.\n+\n+template<typename T>\n+void foo (T) { }\n+\n+template<typename T>\n+void foo (T, T) { }\n+\n+void\n+f (int p)\n+{\n+  constexpr auto r1 = ^^foo<int>;   // { dg-error \"insufficient contextual information\" }\n+  constexpr auto r2 = ^^::foo<int>; // { dg-error \"insufficient contextual information\" }\n+\n+  constexpr auto r3 = ^^__func__;   // { dg-error \"cannot be applied\" }\n+  constexpr auto r4 = ^^__FUNCTION__; // { dg-error \"cannot be applied\" }\n+  constexpr auto r5 = ^^__PRETTY_FUNCTION__;  // { dg-error \"cannot be applied\" }\n+\n+  requires(int a) { ^^p; };\n+  requires(int a) { ^^a; }; // { dg-error \"cannot be applied to a local parameter of a requires-expression .a.\" }\n+}\n+\n+// NTTPs and pack-index-expressions cannot appear as operands\n+// of the reflection operator.\n+\n+struct S { int i; };\n+enum E { EE };\n+static constexpr int glob = 0;\n+\n+template<S s, int n, E e, double d, const int& r>\n+void\n+g ()\n+{\n+  constexpr auto r1 = ^^s;  // { dg-error \"cannot be applied to a non-type template parameter .s.\" }\n+  constexpr auto r2 = ^^n;  // { dg-error \"cannot be applied to a non-type template parameter .n.\" }\n+  constexpr auto r3 = ^^e;  // { dg-error \"cannot be applied to a non-type template parameter .e.\" }\n+  constexpr auto r4 = ^^d;  // { dg-error \"cannot be applied to a non-type template parameter .d.\" }\n+  constexpr auto r5 = ^^r;  // { dg-error \"cannot be applied to a non-type template parameter .r.\" }\n+}\n+\n+template<typename T, T t>\n+void\n+g2 ()\n+{\n+  constexpr auto r = ^^t; // { dg-error \"cannot be applied to a non-type template parameter .t.\" }\n+}\n+\n+void\n+h ()\n+{\n+  constexpr S s{};\n+  constexpr int n = 42;\n+  constexpr E e{};\n+  constexpr double d = 0.0;\n+  g<s, n, e, d, glob>();\n+\n+  g2<int, 42>();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr3.C b/gcc/testsuite/g++.dg/reflect/expr3.C\nnew file mode 100644\nindex 00000000000..27295f1875a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr3.C\n@@ -0,0 +1,47 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+int x = 42;\n+template<typename T>\n+constexpr T two = 2;\n+\n+template<typename T>\n+constexpr T foo (T t) { return t; }\n+\n+void bar () { }\n+\n+struct S { };\n+\n+template<typename>\n+struct ST { };\n+\n+template <int P1, const int &P2> void fn() {}\n+\n+static constexpr int p[2] = {1, 2};\n+constexpr auto spec = ^^fn<p[0], p[1]>;\n+\n+void\n+g ()\n+{\n+  int i1 = [: ^^x :];\n+  int i2 = template [: ^^x :];    // { dg-error \"reflection .x. not usable in a template splice\" }\n+  int i3 = [: ^^two<int> :];\n+  int i4 = template [: ^^two<int> :]; // { dg-error \"reflection .two<int>. not usable in a template splice\" }\n+  int i5 = [: ^^foo :](42);\t      // { dg-error \"reflection .foo. not usable in a splice expression\" }\n+  int i6 = template [: ^^foo :](42);\n+  int i7 = [: ^^foo<int> :](42);\n+  int i8 = template [: ^^foo<int> :](42);   // { dg-error \"reflection .foo<int>. not usable in a template splice\" }\n+  int i9 = [: ^^foo :]<int>(42);\t    // { dg-error \"reflection .foo<int>. not usable in a splice expression with template arguments\" }\n+  int i10 = template [: ^^foo :]<int>(42);\n+  int i11 = template [: ^^bar :]<int>(42);  // { dg-error \"no matching function for call\" }\n+  int i12 = [: ^^two :]<int>;\t\t    // { dg-error \"reflection .two<int>. not usable in a splice expression with template arguments\" }\n+  int i13 = template [: ^^two :]<int>;\n+\n+  [: ^^ST :]<int> c1;  // { dg-error \"reflection .ST<int>. not usable in a splice expression with template arguments\" }\n+  [: ^^S :]<int> c2;   // { dg-error \"not a template|reflection not usable in a splice expression with template arguments\" }\n+  [: ^^bar :]<int>();\t// { dg-error \"reflection .bar<int>. not usable in a splice expression with template arguments\" }\n+\n+  auto x1 = [: ^^ST :]<int>{};\t  // { dg-error \"reflection .ST<int>. not usable in a splice expression with template arguments\" }\n+  auto x2 = template [: ^^ST :]<int>{};\t// { dg-error \"expected a reflection of an expression\" }\n+  auto x3 = typename [: ^^ST :]<int>{};\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr4.C b/gcc/testsuite/g++.dg/reflect/expr4.C\nnew file mode 100644\nindex 00000000000..b43812b9bf8\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr4.C\n@@ -0,0 +1,61 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+void oy (int);\n+template<typename T>\n+void oy (T);\n+\n+struct S {\n+  void foo (int);\n+  void foo (int, int);\n+  void bar (int);\n+\n+  template<typename T>\n+  void baz (T);\n+  template<typename T>\n+  void baz (T, T);\n+\n+  template<typename T>\n+  void qux (T);\n+\n+  void sfoo (int);\n+  void sfoo (int, int);\n+  void sbar (int);\n+\n+  template<typename T>\n+  void sbaz (T);\n+  template<typename T>\n+  void sbaz (T, T);\n+\n+  template<typename T>\n+  void squx (T);\n+\n+  void lox (int);\n+  template<typename T>\n+  void lox (T);\n+\n+  template<typename T>\n+  S &operator+(const T&);\n+\n+  template<typename T>\n+  static bool B;\n+};\n+\n+void\n+g ()\n+{\n+  constexpr auto r1 = ^^S::foo;\t  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r2 = ^^S::bar;\n+  constexpr auto r3 = ^^S::baz;\t  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r4 = ^^S::qux;\n+  constexpr auto r5 = ^^S::sfoo;  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r6 = ^^S::sbar;\n+  constexpr auto r7 = ^^S::sbaz;  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r8 = ^^S::squx;\n+  constexpr auto r9 = ^^oy;\t  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r10 = ^^S::lox;  // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r11 = ^^S::operator+;\n+  constexpr auto r12 = ^^S::template operator+;\n+  constexpr auto r13 = ^^S::B;\n+  constexpr auto r14 = ^^S::template B;\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr5.C b/gcc/testsuite/g++.dg/reflect/expr5.C\nnew file mode 100644\nindex 00000000000..d3a0513438e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr5.C\n@@ -0,0 +1,22 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+struct A {\n+  static void g();\n+  static void g(int);\n+  void h();\n+  void h(int);\n+  static void i();\n+  void j();\n+};\n+\n+void\n+f ()\n+{\n+  constexpr auto r1 = ^^A::g; // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r2 = ^^A::h; // { dg-error \"cannot take the reflection of an overload set\" }\n+  constexpr auto r3 = ^^A::i;\n+  constexpr auto r4 = ^^A::j;\n+\n+  [: r3 :]();\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr6.C b/gcc/testsuite/g++.dg/reflect/expr6.C\nnew file mode 100644\nindex 00000000000..bd9624bc084\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr6.C\n@@ -0,0 +1,49 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Otherwise, if the id-expression denotes a local entity E for which\n+// there is a lambda scope that intervenes between R and the point at\n+// which E was introduced, R is ill-formed.\n+\n+static int s1;\n+\n+void\n+f ()\n+{\n+  int l1;\n+  static int s2;\n+  constexpr auto rl1 = ^^l1;\n+  [] -> decltype(^^l1) { return {}; }; // { dg-error \"intervening lambda expression\" }\n+  [] -> decltype(^^s1, s2) {\n+    int l2;\n+\n+    constexpr auto rl1_2 = ^^l1;  // { dg-error \"intervening lambda expression\" }\n+    constexpr auto rl2 = ^^l2;\n+\n+    return s1;\n+  };\n+}\n+\n+void\n+g ()\n+{\n+  int x;\n+  [=]<auto r> {\n+    static_assert(^^x == r);  // { dg-error \"intervening lambda expression\" }\n+  }.operator()<^^x>();\n+}\n+\n+void\n+h ()\n+{\n+  int x = 42;\n+  int y = 42;\n+  [x_=x, y]() {\n+    constexpr auto r1 = ^^x;  // { dg-error \"intervening lambda expression\" }\n+    constexpr auto r2 = ^^x_; // { dg-error \"local entity declared by init-capture\" }\n+    constexpr auto r3 = ^^y;  // { dg-error \"intervening lambda expression\" }\n+\n+    [x_]() {\n+      constexpr auto r4 = ^^x_;\t// { dg-error \"intervening lambda expression\" }\n+    };\n+  };\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr7.C b/gcc/testsuite/g++.dg/reflect/expr7.C\nnew file mode 100644\nindex 00000000000..1764668e950\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr7.C\n@@ -0,0 +1,11 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test using enum.\n+\n+// TODO cannot take the reflection of a using-declarator\n+enum class Color { R, G, B };\n+struct S { using enum Color; };\n+\n+static_assert(^^S::R != ^^S::G);\n+static_assert(^^S::R != ^^Color::R);\n+static_assert([:^^S::R:] == Color::R);\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr8.C b/gcc/testsuite/g++.dg/reflect/expr8.C\nnew file mode 100644\nindex 00000000000..c507637d473\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr8.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+using info = decltype(^^void);\n+\n+template<info R>\n+void\n+g ()\n+{\n+  int i0 = typename [:^^int:](42);\n+  int i1 = (typename [:^^int:])(42);\n+  int i2 = typename [:R:](42);\n+  int i3 = (typename [:R:]) 42;\n+}\n+\n+template void g<^^int>();\n+\n+struct X { X(int); operator int(); };\n+\n+template<info R>\n+void\n+f ()\n+{\n+  X x1 = typename [:R:](42);\n+  X x2 = (typename [:R:]) 42;\n+  int i1 = (typename [:R:]) x1;\n+  int i2 = typename [:R:](x1);\n+}\n+\n+template void f<^^X>();\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr9.C b/gcc/testsuite/g++.dg/reflect/expr9.C\nnew file mode 100644\nindex 00000000000..e27a23dbd6c\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr9.C\n@@ -0,0 +1,73 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+void\n+fn1 ()\n+{\n+  int x = 1;\t    // { dg-message \".x. declared here\" }\n+  constexpr auto r = ^^x;\n+\n+  [] -> decltype([:r:]) {\n+    return {};\n+  };\n+\n+  [] -> decltype(x) {\n+    return [:r:];   // { dg-error \"use of local variable\" }\n+  };\n+}\n+\n+void\n+fn2 ()\n+{\n+  static int x = 1;\n+  constexpr auto r = ^^x;\n+\n+  [] -> decltype([:r:]) {\n+    return [:r:];\n+  };\n+}\n+\n+void\n+fn3 ()\n+{\n+  int x = 1;\t// { dg-message \".x. declared here\" }\n+\n+  [] -> int {\n+    static constexpr auto r = ^^x;  // { dg-error \"cannot be applied a local entity\" }\n+    return [:r:];\n+  };\n+}\n+\n+void\n+fn4 ()\n+{\n+  static int x = 1;\n+\n+  [] -> int {\n+    static constexpr auto r = ^^x;\n+    return [:r:];\n+  };\n+}\n+\n+void\n+fn5 (int x)   // { dg-message \".x. declared here\" }\n+{\n+  constexpr auto r = ^^x;\n+\n+  [] -> decltype([:r:]) {\n+    return {};\n+  };\n+\n+  [] -> decltype(x) {\n+    return [:r:];   // { dg-error \"use of local variable\" }\n+  };\n+}\n+\n+void\n+fn6 (int x)   // { dg-message \".x. declared here\" }\n+{\n+  [] -> int {\n+    static constexpr auto r = ^^x;  // { dg-error \"cannot be applied a local entity\" }\n+    return [:r:];\n+  };\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract1.C b/gcc/testsuite/g++.dg/reflect/extract1.C\nnew file mode 100644\nindex 00000000000..108642af00a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract1.C\n@@ -0,0 +1,183 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+constexpr auto rnptr = reflect_constant (nullptr_t{});\n+static_assert (extract<nullptr_t>(rnptr) == nullptr_t{});\n+static_assert (extract<const nullptr_t>(rnptr) == nullptr_t{});\n+constexpr auto rt = reflect_constant (true);\n+static_assert (extract<bool>(rt));\n+static_assert (extract<const bool>(rt));\n+constexpr auto rf = reflect_constant (false);\n+static_assert (!extract<bool>(rf));\n+static_assert (!extract<const bool>(rf));\n+constexpr auto r1 = reflect_constant (1);\n+static_assert (extract<int>(r1) == 1);\n+static_assert (extract<const int>(r1) == 1);\n+constexpr auto r1u = reflect_constant (1u);\n+static_assert (extract<unsigned>(r1u) == 1u);\n+static_assert (extract<const unsigned>(r1u) == 1u);\n+constexpr auto rA = reflect_constant ('A');\n+static_assert (extract<char>(rA) == 'A');\n+static_assert (extract<const char>(rA) == 'A');\n+constexpr auto rPIf = reflect_constant (3.14f);\n+static_assert (extract<float>(rPIf) == 3.14f);\n+static_assert (extract<const float>(rPIf) == 3.14f);\n+constexpr auto rPI = reflect_constant (3.14);\n+static_assert (extract<double>(rPI) == 3.14);\n+static_assert (extract<const double>(rPI) == 3.14);\n+constexpr auto r666 = reflect_constant (666L);\n+static_assert (extract<long int>(r666) == 666L);\n+static_assert (extract<const long int>(r666) == 666L);\n+constexpr short int shrt = 42;\n+static_assert (extract<short int>(constant_of (^^shrt)) == 42);\n+static_assert (extract<const short int>(constant_of (^^shrt)) == 42);\n+constexpr signed char sc = -1;\n+static_assert (extract<signed char>(constant_of (^^sc)) == -1);\n+static_assert (extract<const signed char>(constant_of (^^sc)) == -1);\n+constexpr unsigned char uc = 255;\n+static_assert (extract<unsigned char>(constant_of (^^uc)) == 255);\n+static_assert (extract<const unsigned char>(constant_of (^^uc)) == 255);\n+constexpr int *p = nullptr;\n+constexpr info rp = ^^p;\n+static_assert (extract<int *>(rp) == nullptr);\n+static_assert (extract<int * const>(rp) == nullptr);\n+static_assert (extract<const int *>(rp) == nullptr);\n+static_assert (extract<const int *const>(rp) == nullptr);\n+constexpr const int *cp = nullptr;\n+constexpr info rcp = ^^cp;\n+static_assert (extract<const int *>(rcp) == nullptr);\n+static_assert (extract<const int *const>(rcp) == nullptr);\n+constexpr void (*pfn0)() = nullptr;\n+constexpr void (*pfn1)(int) = nullptr;\n+constexpr info rpfn0 = ^^pfn0;\n+constexpr info rpfn1 = ^^pfn1;\n+static_assert (extract<void (*const)()>(rpfn0) == nullptr);\n+static_assert (extract<void (*)()>(rpfn0) == nullptr);\n+static_assert (extract<void (*)(int)>(rpfn1) == nullptr);\n+static_assert (extract<void (*const)(int)>(rpfn1) == nullptr);\n+constexpr int arr[] = { 1, 2, 3, 4, 5 };\n+static_assert (extract<const int *>(^^arr) == [: reflect_constant_array (arr) :]);\n+static_assert (extract<const int *const>(^^arr) == [: reflect_constant_array (arr) :]);\n+static_assert (extract<const int *>(^^arr)[0] == 1);\n+static_assert (extract<const int *>(^^arr)[1] == 2);\n+static_assert (extract<const int *>(^^arr)[2] == 3);\n+static_assert (extract<const int *>(^^arr)[3] == 4);\n+static_assert (extract<const int *>(^^arr)[4] == 5);\n+static_assert (extract<int>(reflect_constant (arr[0])) == 1);\n+static_assert (extract<int>(reflect_constant (arr[1])) == 2);\n+static_assert (extract<int>(reflect_constant (arr[2])) == 3);\n+static_assert (extract<int>(reflect_constant (arr[3])) == 4);\n+static_assert (extract<int>(reflect_constant (arr[4])) == 5);\n+const auto lambda = []{};\n+static_assert (extract<void (*)()>(^^lambda) == lambda);\n+static_assert (extract<void (*const)()>(^^lambda) == lambda);\n+\n+enum E { A = 42 };\n+enum struct EC { A = 42 };\n+static_assert (extract<E>(reflect_constant (A)) == 42);\n+static_assert (extract<EC>(reflect_constant (EC::A)) == EC::A);\n+\n+struct S { int m; };\n+static_assert (extract<S>(reflect_constant (S{42})).m == 42);\n+\n+constexpr int foo () { return 42; }\n+static_assert (extract<int>(reflect_constant (foo ())) == 42);\n+\n+constexpr int cxi = 42;\n+static_assert (extract<const int *>(reflect_constant (&cxi)) == &cxi);\n+\n+const int ci = 42;\n+void fn () {}\n+struct C {\n+  int k;\n+  void fn ();\n+};\n+\n+template<auto E>\n+consteval bool\n+check_val (info R)\n+{\n+  return extract<decltype (E)>(R) == E;\n+}\n+static_assert (check_val<42>(reflect_constant (42)));\n+static_assert (check_val<EC::A>(^^EC::A));\n+static_assert (check_val<E::A>(^^E::A));\n+static_assert (check_val<42>(^^ci));\n+static_assert (check_val<42>(^^cxi));\n+static_assert (check_val<&fn>(^^fn));\n+static_assert (check_val<&C::k>(^^C::k));\n+static_assert (check_val<&C::fn>(^^C::fn));\n+static_assert (check_val<42>([]() {\n+  constexpr static int x = 42;\n+  return ^^x;\n+}()));\n+\n+template<int K> struct TC {\n+  static constexpr int value = K;\n+};\n+\n+TC<3> t;\n+static_assert (check_val<3>(static_data_members_of\n+\t\t\t    (substitute (^^TC, {reflect_constant (3)}),\n+\t\t\t     access_context::unchecked ())[0]));\n+\n+template<typename T>\n+consteval bool\n+roundtrip (T value)\n+{\n+  return extract<T>(reflect_constant (value)) == value;\n+}\n+static_assert (roundtrip (42));\n+static_assert (roundtrip (EC::A));\n+static_assert (roundtrip (E::A));\n+static_assert (roundtrip (ci));\n+static_assert (roundtrip (cxi));\n+static_assert (roundtrip (fn));\n+static_assert (roundtrip (&C::k));\n+static_assert (roundtrip (&C::fn));\n+static_assert (roundtrip ([] {}));\n+\n+struct B {\n+  static constexpr int k = 42;\n+  int m;\n+  int* p;\n+\n+  int fn ();\n+  int fn2 () noexcept;\n+  static int fn3 ();\n+  static int fn4 () noexcept;\n+  int fn5 (this B);\n+  int fn6 (int) &;\n+  int fn7 (int) &&;\n+};\n+static_assert (extract<const int>(^^B::k) == 42);\n+static_assert (extract<const int &>(^^B::k) == 42);\n+static_assert (extract<int (B::*)()>(^^B::fn) == &B::fn);\n+static_assert (extract<int (B::*)() noexcept>(^^B::fn2) == &B::fn2);\n+static_assert (extract<int (*)()>(^^B::fn3) == &B::fn3);\n+static_assert (extract<int (*)() noexcept>(^^B::fn4) == &B::fn4);\n+static_assert (extract<int (*)(B)>(^^B::fn5) == &B::fn5);\n+static_assert (extract<int (B::*)(int) &>(^^B::fn6) == &B::fn6);\n+static_assert (extract<int (B::*)(int) &&>(^^B::fn7) == &B::fn7);\n+constexpr auto a = extract<int (B::*)()>(^^B::fn);\n+constexpr auto a2 = extract<int (B::*)()noexcept>(^^B::fn2);\n+constexpr auto a3 = extract<int (*)()>(^^B::fn3);\n+constexpr auto a4 = extract<int (*)() noexcept>(^^B::fn4);\n+constexpr auto a5 = extract<int (*)(B)>(^^B::fn5);\n+constexpr auto a6 = extract<int (B::*)(int) &>(^^B::fn6);\n+constexpr auto a7 = extract<int (B::*)(int) &&>(^^B::fn7);\n+\n+constexpr auto a8 = extract<int B::*>(^^B::m);\n+constexpr auto a9 = extract<int const B::*>(^^B::m);\n+constexpr auto a10 = extract<int* B::*>(^^B::p);\n+constexpr auto a11 = extract<int* const B::*>(^^B::p);\n+constexpr auto a12 = extract<int const* const B::*>(^^B::p);\n+\n+// FIXME removing noexcept should be allowed\n+// constexpr auto a13 = extract<int (*)()>(^^B::fn4);\n+// constexpr auto a14 = extract<int (B::*)()>(^^B::fn2);\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract2.C b/gcc/testsuite/g++.dg/reflect/extract2.C\nnew file mode 100644\nindex 00000000000..edb5382ce39\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract2.C\n@@ -0,0 +1,140 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template<typename T>\n+consteval bool\n+can_extract (info r)\n+{\n+  try { extract<T>(r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+constexpr info null_reflection;\n+static_assert (!can_extract<int>(null_reflection));\n+\n+constexpr auto rt = reflect_constant (true);\n+static_assert (!can_extract<int>(rt));\n+static_assert (!can_extract<char>(rt));\n+static_assert (!can_extract<short>(rt));\n+static_assert (!can_extract<long>(rt));\n+static_assert (!can_extract<float>(rt));\n+static_assert (!can_extract<bool *>(rt));\n+constexpr auto rA = reflect_constant ('A');\n+static_assert (!can_extract<bool>(rA));\n+static_assert (!can_extract<int>(rA));\n+static_assert (!can_extract<unsigned short>(rA));\n+static_assert (!can_extract<long>(rA));\n+static_assert (!can_extract<double>(rA));\n+static_assert (!can_extract<int *>(rA));\n+constexpr short int shrt = 42;\n+constexpr info rshrt = constant_of (^^shrt);\n+static_assert (!can_extract<int *>(rshrt));\n+static_assert (!can_extract<bool>(rshrt));\n+static_assert (!can_extract<signed char>(rshrt));\n+static_assert (!can_extract<int>(rshrt));\n+static_assert (!can_extract<double>(rshrt));\n+static_assert (!can_extract<long>(rshrt));\n+constexpr signed char sc = -1;\n+constexpr info rsc = constant_of (^^sc);\n+static_assert (!can_extract<int *>(rsc));\n+static_assert (!can_extract<bool>(rsc));\n+static_assert (!can_extract<unsigned char>(rsc));\n+static_assert (!can_extract<int>(rsc));\n+static_assert (!can_extract<double>(rsc));\n+static_assert (!can_extract<long>(rsc));\n+constexpr unsigned char uc = 255;\n+constexpr info ruc = constant_of (^^uc);\n+static_assert (!can_extract<int *>(ruc));\n+static_assert (!can_extract<bool>(ruc));\n+static_assert (!can_extract<signed char>(ruc));\n+static_assert (!can_extract<int>(ruc));\n+static_assert (!can_extract<double>(ruc));\n+static_assert (!can_extract<long>(ruc));\n+\n+constexpr const int *p = nullptr;\n+constexpr auto rp = ^^p;\n+static_assert (!can_extract<int *>(rp));\n+static_assert (!can_extract<char *>(rp));\n+\n+constexpr void (*pfn0)() = nullptr;\n+constexpr void (*pfn1)(int) = nullptr;\n+constexpr info rpfn0 = ^^pfn0;\n+constexpr info rpfn1 = ^^pfn1;\n+static_assert (!can_extract<void (*)(int)>(rpfn0));\n+static_assert (!can_extract<void (*)()>(rpfn1));\n+\n+constexpr int arr[] = { 1, 2, 3, 4, 5 };\n+static_assert (!can_extract<int *>(^^arr));\n+static_assert (!can_extract<const double *>(^^arr));\n+\n+const auto lambda = []{};\n+static_assert (!can_extract<void (*)(int)>(^^lambda));\n+\n+enum E { X = 42 };\n+enum struct EC { Y = 42 };\n+static_assert (!can_extract<int *>(reflect_constant (X)));\n+static_assert (!can_extract<int>(reflect_constant (EC::Y)));\n+\n+struct S { int m; };\n+static_assert (!can_extract<int>(reflect_constant (S{42})));\n+\n+constexpr int foo () { return 42; }\n+static_assert (!can_extract<int *>(reflect_constant (foo ())));\n+\n+static constexpr int i = 0;\n+static_assert (!can_extract<const int>(reflect_constant (&i)));\n+static_assert (!can_extract<const int &>(reflect_constant (i)));\n+static_assert (!can_extract<int &>(^^i));\n+\n+int j;\n+static_assert (extract<int &>(^^j)); // { dg-error \"non-constant|not usable\" }\n+\n+consteval info\n+bar ()\n+{\n+   constexpr int x = 10;\n+   return ^^x;\n+};\n+\n+constexpr info rbar = bar ();\n+static_assert (!can_extract<int &>(rbar));\n+\n+struct B {\n+  int k;\n+  int bf : 16;\n+};\n+\n+static_assert (!can_extract<int>(^^B::bf));\n+static_assert (!can_extract<int &>(^^B::bf));\n+static_assert (!can_extract<const int &>(^^B::bf));\n+static_assert (!can_extract<int B::*>(^^B::bf));\n+\n+static union { int um; };\n+static_assert (!can_extract<int>(^^um));\n+static_assert (!can_extract<int&>(^^um));\n+\n+struct C {\n+  int fn ();\n+  int fn2 () noexcept;\n+  static int fn3 ();\n+  static int fn4 () noexcept;\n+  int fn5 (this B);\n+  int fn6 (int) &;\n+  int fn7 (int) &&;\n+};\n+static_assert (!can_extract<void (C::*)()>(^^C::fn));\n+static_assert (!can_extract<int (C::*)() noexcept>(^^C::fn));\n+static_assert (!can_extract<int (C::*)()>(^^C::fn2));\n+static_assert (!can_extract<int (C::*)()>(^^C::fn3));\n+static_assert (!can_extract<int (C::*)()>(^^C::fn4));\n+static_assert (!can_extract<int (*)() noexcept>(^^C::fn3));\n+static_assert (!can_extract<int (*)()>(^^C::fn4));\n+static_assert (!can_extract<int (*)()>(^^C::fn5));\n+static_assert (!can_extract<int (C::*)(int) &&>(^^C::fn6));\n+static_assert (!can_extract<int (C::*)(int) &>(^^C::fn7));\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract3.C b/gcc/testsuite/g++.dg/reflect/extract3.C\nnew file mode 100644\nindex 00000000000..f8c173c0208\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract3.C\n@@ -0,0 +1,90 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\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+static constexpr int i = 0;\n+constexpr const int &r = i;\n+static_assert (extract<const int &>(^^i) == i);\n+static_assert (extract<const int &>(^^i) == 0);\n+static_assert (&extract<const int &>(^^i) == &i);\n+same_type<decltype(extract<const int &>(^^i)), const int &> st1;\n+same_type<decltype(&extract<const int &>(^^i)), const int *> st2;\n+const int& p = extract<const int &>(^^i);\n+static_assert (extract<const int &>(^^r) == 0);\n+static_assert (extract<const int &>(^^r) == i);\n+\n+static const int j = 0;\n+const int &rj = j;\n+static_assert (extract<const int &>(^^j) == j);\n+static_assert (extract<const int &>(^^j) == 0);\n+static_assert (&extract<const int &>(^^j) == &j);\n+same_type<decltype(extract<const int &>(^^j)), const int &> st3;\n+same_type<decltype(&extract<const int &>(^^j)), const int *> st4;\n+const int &q = extract<const int &>(^^j);\n+static_assert (extract<const int &>(^^rj) == 0);\n+static_assert (extract<const int &>(^^rj) == j);\n+static_assert (&extract<const int &>(^^rj) == &j);\n+\n+int k = 1;\n+static_assert (&extract<int &>(^^k) == &k);\n+static_assert (&extract<const int &>(^^k) == &k);\n+\n+int arr[5] {};\n+static_assert (&extract<int (&)[5]>(^^arr) == &arr);\n+static_assert (&extract<const int (&)[5]>(^^arr) == &arr);\n+\n+struct S { int m; };\n+constexpr S s{42};\n+constexpr const S &rs = s;\n+static_assert (extract<const S &>(^^s).m == 42);\n+static_assert (&extract<const S &>(^^s) == &s);\n+same_type<decltype(extract<const S &>(^^s)), const S &> st5;\n+same_type<decltype(&extract<const S &>(^^s)), const S *> st6;\n+const S &ps = extract<const S &>(^^s);\n+static_assert (extract<const S &>(^^rs).m == 42);\n+static_assert (extract<const S &>(reflect_constant (S{42})).m == 42);\n+same_type<decltype(extract<const S &>(reflect_constant (S{42}))), const S &> st7;\n+same_type<decltype(&extract<const S &>(reflect_constant (S{42}))), const S *> st8;\n+\n+S sr{42};\n+static_assert (&extract<S&>(^^sr) == &sr);\n+static_assert (&extract<const S&>(^^sr) == &sr);\n+static_assert (&extract<S&>(^^sr).m == &sr.m);\n+int &srm = sr.m;\n+static_assert (&extract<int&>(^^srm) == &sr.m);\n+\n+consteval bool foo() {\n+   int i = 5;\n+   return &extract<int&>(^^i) == &i;\n+}\n+static_assert (foo ());\n+\n+consteval int\n+bar (int arg)\n+{\n+  int val = 3;\n+  int &ref = extract<int &>(^^val);\n+  ref = 4;\n+  return val + extract<int>(^^arg);\n+}\n+static_assert (bar (5) == 9);\n+\n+consteval const int &\n+baz ()\n+{\n+  return j;\n+}\n+\n+void\n+doit ()\n+{\n+  constexpr auto r = reflect_object (baz ());\n+  static_assert (extract<const int &>(r) == 0);\n+}\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract4.C b/gcc/testsuite/g++.dg/reflect/extract4.C\nnew file mode 100644\nindex 00000000000..890caaac34e\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract4.C\n@@ -0,0 +1,30 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+struct S {\n+  int k;\n+};\n+\n+// This one verifies that we called mark_used.\n+constexpr auto a = extract<int S::*>(^^S::k);\n+static_assert (extract<int S::*>(^^S::k) == &S::k);\n+\n+consteval int\n+fn1 ()\n+{\n+  return extract<int(*)(int)>(reflect_constant ([](int id) { return id; }))(42);\n+}\n+static_assert (fn1 () == 42);\n+\n+constexpr auto l = [](int id) { return id; };\n+static_assert (extract<int(*)(int)>(^^l)(42) == 42);\n+static_assert (extract<decltype(l)>(^^l)(42) == 42);\n+\n+constexpr auto gl = [](auto a) { return constant_of (a); };\n+constexpr int i = 42;\n+static_assert (extract<decltype(gl)>(^^gl)(^^i) == reflect_constant (42));\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract5.C b/gcc/testsuite/g++.dg/reflect/extract5.C\nnew file mode 100644\nindex 00000000000..1e5fbde2313\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract5.C\n@@ -0,0 +1,31 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+consteval int\n+foo ()\n+{\n+  int arg = 4;\n+  return std::meta::extract<int>(^^arg);\n+}\n+\n+static_assert (foo () == 4);\n+\n+consteval int\n+bar (int arg)\n+{\n+  return std::meta::extract<int>(^^arg);\n+}\n+\n+static_assert (bar (4) == 4);\n+\n+consteval int\n+baz ()\n+{\n+  constexpr int arg = 4;\n+  return std::meta::extract<int>(^^arg);\n+}\n+\n+static_assert (baz () == 4);\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract6.C b/gcc/testsuite/g++.dg/reflect/extract6.C\nnew file mode 100644\nindex 00000000000..e6e0986de4a\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract6.C\n@@ -0,0 +1,20 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+[[=1, =1, =2, =1.0f]] void fn ();\n+struct [[=3, =3, =4, =2.0f]] S;\n+\n+template<info R>\n+[[=[:constant_of (annotations_of (R)[0]):]]] void TFn();\n+template<info R>\n+struct [[=[:constant_of (annotations_of (R)[0]):]]] TCls {};\n+\n+static_assert (extract<int>(annotations_of (^^TFn<^^::fn>)[0]) == 1);\n+// TODO See constant_of6.C and constant_of5.C.\n+//static_assert (extract<int>(annotations_of (^^TCls<^^::S>)[0]) == 3);\n+static_assert (extract<int>(annotations_of (^^fn)[0]) == 1);\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract7.C b/gcc/testsuite/g++.dg/reflect/extract7.C\nnew file mode 100644\nindex 00000000000..ed4f4642ed0\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract7.C\n@@ -0,0 +1,27 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+void fn();\n+static_assert(annotations_of(^^fn).size() == 0);\n+[[=1, =2]] void fn();\n+static_assert(annotations_of(^^fn).size() == 2);\n+[[=3]] void fn();\n+static_assert(annotations_of(^^fn).size() == 3);\n+[[=4, =5]] void fn();\n+static_assert(annotations_of(^^fn).size() == 5);\n+[[=6]] void fn();\n+static_assert(annotations_of(^^fn).size() == 6);\n+void fn();\n+static_assert(annotations_of(^^fn).size() == 6);\n+\n+static_assert(extract<int>(annotations_of(^^fn)[0]) == 1);\n+static_assert(extract<int>(annotations_of(^^fn)[1]) == 2);\n+static_assert(extract<int>(annotations_of(^^fn)[2]) == 3);\n+static_assert(extract<int>(annotations_of(^^fn)[3]) == 4);\n+static_assert(extract<int>(annotations_of(^^fn)[4]) == 5);\n+static_assert(extract<int>(annotations_of(^^fn)[5]) == 6);\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract8.C b/gcc/testsuite/g++.dg/reflect/extract8.C\nnew file mode 100644\nindex 00000000000..2f9773b9d56\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract8.C\n@@ -0,0 +1,18 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test std::meta::extract.\n+\n+#include <meta>\n+\n+using namespace std::meta;\n+\n+template<auto E>\n+consteval bool\n+check_val (info R)\n+{\n+  return extract<decltype (E)>(R) == E; // { dg-error \"accessing .x. outside its lifetime\" }\n+}\n+constexpr auto r = (check_val<42>([]() {\n+  constexpr int x = 42;\n+  return ^^x;\n+}()));\ndiff --git a/gcc/testsuite/g++.dg/reflect/extract9.C b/gcc/testsuite/g++.dg/reflect/extract9.C\nnew file mode 100644\nindex 00000000000..1f509b0b2cd\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/extract9.C\n@@ -0,0 +1,25 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// US 112-172\n+\n+#include <meta>\n+using namespace std::meta;\n+\n+struct B { };\n+struct D : B { };\n+\n+template<typename T>\n+consteval bool\n+can_extract (info r)\n+{\n+  try { extract<T>(r); }\n+  catch (std::meta::exception &) { return false; }\n+  return true;\n+}\n+\n+constexpr B arrb[] = { {}, {}, {} };\n+constexpr D arrd[] = { {}, {}, {} };\n+static_assert (can_extract<const D *>(^^arrd));\n+static_assert (can_extract<const B *>(^^arrb));\n+static_assert (!can_extract<const B *>(^^arrd));\n+static_assert (!can_extract<const D *>(^^arrb));\ndiff --git a/gcc/testsuite/g++.dg/reflect/feat1.C b/gcc/testsuite/g++.dg/reflect/feat1.C\nnew file mode 100644\nindex 00000000000..a84946d6a80\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/feat1.C\n@@ -0,0 +1,17 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test feature test macros.\n+\n+#ifndef __cpp_impl_reflection\n+#  error \"__cpp_impl_reflection\"\n+#elif __cpp_impl_reflection != 202506\n+#  error \"__cpp_impl_reflection != 202506\"\n+#endif\n+\n+#include <meta>\n+\n+#ifndef __cpp_lib_reflection\n+#  error \"__cpp_lib_reflection\"\n+#elif __cpp_lib_reflection != 202506\n+#  error \"__cpp_lib_reflection != 202506\"\n+#endif\ndiff --git a/gcc/testsuite/g++.dg/reflect/feat2.C b/gcc/testsuite/g++.dg/reflect/feat2.C\nnew file mode 100644\nindex 00000000000..902732b0824\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/feat2.C\n@@ -0,0 +1,11 @@\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+// Test feature test macros.\n+\n+#include <version>\n+\n+#ifndef __cpp_lib_reflection\n+#  error \"__cpp_lib_reflection\"\n+#elif __cpp_lib_reflection != 202506\n+#  error \"__cpp_lib_reflection != 202506\"\n+#endif\n",
    "prefixes": [
        "5/9",
        "v2"
    ]
}