LCOV - code coverage report
Current view: top level - gcc/cp - reflect.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.9 % 4180 3843
Test Date: 2026-03-28 14:25:54 Functions: 100.0 % 290 290
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* C++ reflection code.
       2              :    Copyright (C) 2025-2026 Free Software Foundation, Inc.
       3              :    Written by Marek Polacek <polacek@redhat.com> and
       4              :    Jakub Jelinek <jakub@redhat.com>.
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful,
      14              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16              : GNU General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "target.h"
      26              : #include "tm.h"
      27              : #include "cp-tree.h"
      28              : #include "stringpool.h" // for get_identifier
      29              : #include "intl.h"
      30              : #include "attribs.h"
      31              : #include "c-family/c-pragma.h" // for parse_in
      32              : #include "gimplify.h" // for unshare_expr
      33              : #include "metafns.h"
      34              : 
      35              : static tree eval_is_function_type (tree);
      36              : static tree eval_is_object_type (location_t, tree);
      37              : static tree eval_reflect_constant (location_t, const constexpr_ctx *, tree,
      38              :                                    tree, bool *, tree *, tree);
      39              : static tree eval_is_array_type (location_t, tree);
      40              : static tree eval_reflect_constant_array (location_t, const constexpr_ctx *,
      41              :                                          tree, bool *, bool *, tree *, tree);
      42              : static tree eval_reflect_function (location_t, const constexpr_ctx *, tree,
      43              :                                    tree, bool *, tree *, tree);
      44              : struct constexpr_ctx;
      45              : 
      46              : /* Return the appropriate tsubst flags for processing a metafunction.  */
      47              : 
      48              : static tsubst_flags_t
      49          213 : complain_flags (const constexpr_ctx *ctx)
      50              : {
      51          213 :   return cxx_constexpr_quiet_p (ctx) ? tf_none : tf_warning_or_error;
      52              : }
      53              : 
      54              : /* Initialize state for reflection; e.g., initialize meta_info_type_node.  */
      55              : 
      56              : void
      57          539 : init_reflection ()
      58              : {
      59              :   /* The type std::meta::info is a scalar type for which equality and
      60              :      inequality are meaningful, but for which no ordering relation is
      61              :      defined.  */
      62          539 :   meta_info_type_node = make_node (META_TYPE);
      63              :   /* Make it a complete type.  */
      64         1078 :   TYPE_SIZE (meta_info_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
      65         1078 :   TYPE_SIZE_UNIT (meta_info_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
      66              :   /* Name it.  */
      67          539 :   record_builtin_type (RID_MAX, "decltype(^^int)", meta_info_type_node);
      68              : 
      69              :   /* Create the `std::meta' namespace.  */
      70          539 :   push_namespace (get_identifier ("std"));
      71          539 :   push_namespace (get_identifier ("meta"), /*inline*/false);
      72          539 :   std_meta_node = current_namespace;
      73          539 :   pop_namespace ();
      74          539 :   pop_namespace ();
      75          539 : }
      76              : 
      77              : /* Create a REFLECT_EXPR expression of kind KIND around T.  */
      78              : 
      79              : static tree
      80        67685 : get_reflection_raw (location_t loc, tree t, reflect_kind kind = REFLECT_UNDEF)
      81              : {
      82        67685 :   t = build1_loc (loc, REFLECT_EXPR, meta_info_type_node, t);
      83        67685 :   SET_REFLECT_EXPR_KIND (t, kind);
      84        67685 :   TREE_CONSTANT (t) = true;
      85        67685 :   TREE_READONLY (t) = true;
      86        67685 :   TREE_SIDE_EFFECTS (t) = false;
      87        67685 :   return t;
      88              : }
      89              : 
      90              : /* Return the reflection for T.
      91              : 
      92              :     [basic.fundamental]: A value of type std::meta::info is called a reflection.
      93              :     There exists a unique null reflection; every other reflection is
      94              :     a representation of
      95              : 
      96              :     -- a value of scalar type,
      97              :     -- an object with static storage duration,
      98              :     -- a variable,
      99              :     -- a structured binding,
     100              :     -- a function,
     101              :     -- a function parameter,
     102              :     -- an enumerator,
     103              :     -- an annotation,
     104              :     -- a type alias,
     105              :     -- a type,
     106              :     -- a class member,
     107              :     -- an unnamed bit-field,
     108              :     -- a class template,
     109              :     -- a function template,
     110              :     -- a variable template,
     111              :     -- an alias template,
     112              :     -- a concept,
     113              :     -- a namespace alias,
     114              :     -- a namespace,
     115              :     -- a direct base class relationship, or
     116              :     -- a data member description.
     117              : 
     118              :    KIND is used to distinguish between categories that are represented
     119              :    by the same handle.  */
     120              : 
     121              : tree
     122        23676 : get_reflection (location_t loc, tree t, reflect_kind kind/*=REFLECT_UNDEF*/)
     123              : {
     124        23676 :   STRIP_ANY_LOCATION_WRAPPER (t);
     125              : 
     126              :   /* [expr.reflect] If the type-id designates a placeholder type, R is
     127              :      ill-formed.  */
     128        23676 :   if (is_auto (t))
     129              :     {
     130            2 :       error_at (loc, "%<^^%> cannot be applied to a placeholder type");
     131            2 :       return error_mark_node;
     132              :     }
     133              :   /* Constant template parameters and pack-index-expressions cannot
     134              :      appear as operands of the reflection operator.  */
     135        23674 :   else if (PACK_INDEX_P (t))
     136              :     {
     137            1 :       error_at (loc, "%<^^%> cannot be applied to a pack index");
     138            1 :       return error_mark_node;
     139              :     }
     140        23673 :   else if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t))
     141              :     {
     142            6 :       error_at (loc, "%<^^%> cannot be applied to a non-type template "
     143              :                 "parameter %qD", t);
     144            6 :       return error_mark_node;
     145              :     }
     146              :   /* If the id-expression denotes a variable declared by an init-capture,
     147              :      R is ill-formed.  */
     148        23667 :   else if (is_capture_proxy (t))
     149              :     {
     150            2 :       error_at (loc, "%<^^%> cannot be applied to a capture %qD", t);
     151            2 :       return error_mark_node;
     152              :     }
     153              :   /* If the id-expression denotes a local parameter introduced by
     154              :      a requires-expression, R is ill-formed.  */
     155        23665 :   else if (TREE_CODE (t) == PARM_DECL && CONSTRAINT_VAR_P (t))
     156              :     {
     157            1 :       error_at (loc, "%<^^%> cannot be applied to a local parameter of "
     158              :                 "a requires-expression %qD", t);
     159            1 :       return error_mark_node;
     160              :     }
     161              :   /* If the id-expression denotes a local entity E for which there is
     162              :      a lambda scope that intervenes between R and the point at which E
     163              :      was introduced, R is ill-formed.  */
     164        23664 :   else if (outer_automatic_var_p (t)
     165              :            /* Since outer_automatic_var_p is also true when we are in
     166              :               a local class member function, additionally check that
     167              :               we are in a lambda.  */
     168        23664 :            && ((current_function_decl
     169           18 :                 && LAMBDA_FUNCTION_P (current_function_decl))
     170            6 :                || parsing_lambda_declarator ()))
     171              :     {
     172            7 :       auto_diagnostic_group d;
     173            7 :       error_at (loc, "%<^^%> cannot be applied a local entity for which "
     174              :                 "there is an intervening lambda expression");
     175            7 :       inform (DECL_SOURCE_LOCATION (t), "%qD declared here", t);
     176            7 :       return error_mark_node;
     177            7 :     }
     178              :   /* If lookup finds a declaration that replaced a using-declarator during
     179              :      a single search, R is ill-formed.  */
     180        23657 :   else if (TREE_CODE (t) == USING_DECL
     181        23657 :            || (TREE_CODE (t) == OVERLOAD && OVL_USING_P (t)))
     182              :     {
     183            4 :       error_at (loc, "%<^^%> cannot be applied to a using-declaration");
     184            4 :       return error_mark_node;
     185              :     }
     186              :   /* A concept is fine, but not Concept<arg>.  */
     187        23653 :   else if (concept_check_p (t))
     188              :     {
     189            1 :       error_at (loc, "%<^^%> cannot be applied to a concept check");
     190            1 :       return error_mark_node;
     191              :     }
     192              : 
     193              :   /* Otherwise, if the template-name names a function template F,
     194              :      then the template-name interpreted as an id-expression shall
     195              :      denote an overload set containing only F.  R represents F.
     196              : 
     197              :      When we have:
     198              :        template<typename T>
     199              :        void foo (T) {}
     200              :        constexpr auto a = ^^foo;
     201              :      we will get an OVERLOAD containing only one function.  */
     202        23652 :   tree r = MAYBE_BASELINK_FUNCTIONS (t);
     203        23652 :   if (OVL_P (r))
     204              :     {
     205         1781 :       if (!OVL_SINGLE_P (r))
     206              :         {
     207           16 :           error_at (loc, "cannot take the reflection of an overload set");
     208           16 :           return error_mark_node;
     209              :         }
     210              :     }
     211              :   /* [expr.reflect] If the id-expression denotes an overload set S,
     212              :      overload resolution for the expression &S with no target shall
     213              :      select a unique function; R represents that function.  */
     214        21871 :   else if (!processing_template_decl && t != unknown_type_node)
     215              :     {
     216              :       /* Resolve all TEMPLATE_ID_EXPRs here.  */
     217        20452 :       t = resolve_nondeduced_context_or_error (t, tf_warning_or_error);
     218              :       /* The argument could have a deduced return type, so we need to
     219              :          instantiate it now to find out its type.  */
     220        20452 :       if (!mark_used (t))
     221            8 :         return error_mark_node;
     222              :     }
     223              : 
     224              :   /* For injected-class-name, use the main variant so that comparing
     225              :      reflections works (cf. compare3.C).  */
     226        23628 :   if (RECORD_OR_UNION_TYPE_P (t)
     227         6397 :       && TYPE_NAME (t)
     228        29965 :       && DECL_SELF_REFERENCE_P (TYPE_NAME (t)))
     229           36 :     t = TYPE_MAIN_VARIANT (t);
     230              : 
     231              :   /* It's annoying to deal with BIT_NOT_EXPR in a reflection later, so
     232              :      look up the FUNCTION_DECL here.  */
     233        23628 :   if (TREE_CODE (t) == BIT_NOT_EXPR
     234           48 :       && CLASS_TYPE_P (TREE_OPERAND (t, 0))
     235        23676 :       && COMPLETE_TYPE_P (TREE_OPERAND (t, 0)))
     236              :     {
     237           48 :       r = TREE_OPERAND (t, 0);
     238           48 :       if (CLASSTYPE_LAZY_DESTRUCTOR (r))
     239            7 :         lazily_declare_fn (sfk_destructor, r);
     240           48 :       if (tree dtor = CLASSTYPE_DESTRUCTOR (r))
     241        23628 :         t = dtor;
     242              :     }
     243              : 
     244              :   /* Look through block scope externs.  */
     245        23628 :   if (VAR_OR_FUNCTION_DECL_P (t) && DECL_LOCAL_DECL_P (t))
     246           14 :     t = DECL_LOCAL_DECL_ALIAS (t);
     247              : 
     248        23628 :   if (t == error_mark_node)
     249              :     return error_mark_node;
     250              : 
     251        23628 :   return get_reflection_raw (loc, t, kind);
     252              : }
     253              : 
     254              : /* Null reflection shared tree.  */
     255              : 
     256              : static GTY(()) tree null_reflection;
     257              : 
     258              : /* Return a null reflection value.  */
     259              : 
     260              : tree
     261         6851 : get_null_reflection ()
     262              : {
     263         6851 :   if (!null_reflection)
     264          360 :     null_reflection = get_reflection_raw (UNKNOWN_LOCATION, unknown_type_node);
     265         6851 :   return null_reflection;
     266              : }
     267              : 
     268              : /* Do strip_typedefs on T, but only for types.  */
     269              : 
     270              : static tree
     271         3601 : maybe_strip_typedefs (tree t)
     272              : {
     273         3601 :   if (TYPE_P (t))
     274         3458 :     return strip_typedefs (t);
     275              :   return t;
     276              : }
     277              : 
     278              : /* If PARM_DECL comes from an earlier reflection of a function parameter
     279              :    and function definition is seen after that, DECL_ARGUMENTS is
     280              :    overwritten and so the old PARM_DECL is no longer present in the
     281              :    DECL_ARGUMENTS (DECL_CONTEXT (parm)) chain.  Return corresponding
     282              :    PARM_DECL which is in the chain.  */
     283              : 
     284              : static tree
     285          354 : maybe_update_function_parm (tree parm)
     286              : {
     287          354 :   if (!OLD_PARM_DECL_P (parm))
     288              :     return parm;
     289           89 :   tree fn = DECL_CONTEXT (parm);
     290           89 :   int oldlen = list_length (parm);
     291           89 :   int newlen = list_length (DECL_ARGUMENTS (fn));
     292           89 :   gcc_assert (newlen >= oldlen);
     293           89 :   tree ret = DECL_ARGUMENTS (fn);
     294           89 :   int n = newlen - oldlen;
     295          239 :   while (n)
     296              :     {
     297          150 :       ret = DECL_CHAIN (ret);
     298          150 :       --n;
     299              :     }
     300              :   return ret;
     301              : }
     302              : 
     303              : /* Return true if DECL comes from std::meta.  */
     304              : 
     305              : static bool
     306       574567 : decl_in_std_meta_p (tree decl)
     307              : {
     308            0 :   return decl_namespace_context (decl) == std_meta_node;
     309              : }
     310              : 
     311              : /* Returns true if FNDECL, a FUNCTION_DECL, is a call to a metafunction
     312              :    declared in namespace std::meta.  */
     313              : 
     314              : bool
     315    182944037 : metafunction_p (tree fndecl)
     316              : {
     317    182944037 :   if (!flag_reflection)
     318              :     return false;
     319              : 
     320              :   /* Metafunctions are expected to be marked consteval.  */
     321      4264828 :   if (!DECL_IMMEDIATE_FUNCTION_P (fndecl))
     322              :     return false;
     323              : 
     324       648583 :   if (special_function_p (fndecl))
     325              :     return false;
     326              : 
     327       574567 :   if (!decl_in_std_meta_p (fndecl))
     328              :     return false;
     329              : 
     330              :   /* They should be user provided and not defined.  */
     331        41376 :   if (!user_provided_p (fndecl)
     332        41376 :       || (DECL_NAMESPACE_SCOPE_P (fndecl) && DECL_DELETED_FN (fndecl)))
     333              :     return false;
     334        41376 :   if (DECL_INITIAL (fndecl))
     335              :     return false;
     336              : 
     337              :   return true;
     338              : }
     339              : 
     340              : /* Extract the N-th reflection argument from a metafunction call CALL.  */
     341              : 
     342              : static tree
     343        24026 : get_info (const constexpr_ctx *ctx, tree call, int n, bool *non_constant_p,
     344              :           bool *overflow_p, tree *jump_target)
     345              : {
     346        24026 :   gcc_checking_assert (call_expr_nargs (call) > n);
     347        24026 :   tree info = get_nth_callarg (call, n);
     348        24026 :   gcc_checking_assert (REFLECTION_TYPE_P (TREE_TYPE (info)));
     349        24026 :   info = cxx_eval_constant_expression (ctx, info, vc_prvalue,
     350              :                                        non_constant_p, overflow_p,
     351              :                                        jump_target);
     352        24026 :   if (*jump_target)
     353              :     return NULL_TREE;
     354        24020 :   if (!REFLECT_EXPR_P (info))
     355              :     {
     356           20 :       *non_constant_p = true;
     357           20 :       return NULL_TREE;
     358              :     }
     359              :   return info;
     360              : }
     361              : 
     362              : /* Helper function for get_range_elts, called through cp_walk_tree.  */
     363              : 
     364              : static tree
     365        77203 : replace_parm_r (tree *tp, int *walk_subtrees, void *data)
     366              : {
     367        77203 :   tree *p = (tree *) data;
     368        77203 :   if (*tp == p[0])
     369         6977 :     *tp = p[1];
     370        70226 :   else if (TYPE_P (*tp))
     371            0 :     *walk_subtrees = 0;
     372        77203 :   return NULL_TREE;
     373              : }
     374              : 
     375              : static tree throw_exception (location_t, const constexpr_ctx *, const char *,
     376              :                              tree, bool *, tree *);
     377              : 
     378              : /* Kinds for get_range_elts.  */
     379              : 
     380              : enum get_range_elts_kind {
     381              :   GET_INFO_VEC,
     382              :   REFLECT_CONSTANT_STRING,
     383              :   REFLECT_CONSTANT_ARRAY
     384              : };
     385              : 
     386              : /* Extract the N-th input_range argument from a metafunction call CALL
     387              :    and return it as TREE_VEC or STRING_CST or CONSTRUCTOR.  Helper function
     388              :    for get_info_vec, eval_reflect_constant_string and
     389              :    eval_reflect_constant_array.  For GET_INFO_VEC kind, <meta> ensures
     390              :    the argument is reference to reflection_range concept and so both
     391              :    range_value_t is info and range_refernce_t is cv info or cv info & or
     392              :    cv info &&.  */
     393              : 
     394              : static tree
     395         3523 : get_range_elts (location_t loc, const constexpr_ctx *ctx, tree call, int n,
     396              :                 bool *non_constant_p, bool *overflow_p, tree *jump_target,
     397              :                 get_range_elts_kind kind, tree fun)
     398              : {
     399         3523 :   gcc_checking_assert (call_expr_nargs (call) > n);
     400         3523 :   tree arg = get_nth_callarg (call, n);
     401         3523 :   tree parm = DECL_ARGUMENTS (cp_get_callee_fndecl_nofold (call));
     402         5109 :   for (int i = 0; i < n; ++i)
     403         1586 :     parm = DECL_CHAIN (parm);
     404         3523 :   tree type = TREE_TYPE (arg);
     405         3523 :   gcc_checking_assert (TYPE_REF_P (type));
     406         3523 :   arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, non_constant_p,
     407              :                                       overflow_p, jump_target);
     408         3523 :   if (*jump_target || *non_constant_p)
     409              :     return NULL_TREE;
     410         3522 :   tree map[2] = { parm, arg };
     411              :   /* To speed things up, check
     412              :      if constexpr (std::ranges::contiguous_range <_R>).  */
     413         3522 :   tree ranges_ns = lookup_qualified_name (std_node, "ranges");
     414         3522 :   if (TREE_CODE (ranges_ns) != NAMESPACE_DECL)
     415              :     {
     416            0 :       error_at (loc, "%<std::ranges%> is not a namespace");
     417            0 :       *non_constant_p = true;
     418            0 :       return NULL_TREE;
     419              :     }
     420         3522 :   tree contiguous_range
     421         3522 :     = lookup_qualified_name (ranges_ns, "contiguous_range");
     422         3522 :   if (TREE_CODE (contiguous_range) != TEMPLATE_DECL
     423         3522 :       || !concept_definition_p (contiguous_range))
     424              :     contiguous_range = NULL_TREE;
     425              :   else
     426              :     {
     427         3522 :       tree args = make_tree_vec (1);
     428         3522 :       TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
     429         3522 :       contiguous_range = build2_loc (loc, TEMPLATE_ID_EXPR, boolean_type_node,
     430              :                                      contiguous_range, args);
     431         3522 :       if (!integer_nonzerop (maybe_constant_value (contiguous_range)))
     432           73 :         contiguous_range = NULL_TREE;
     433              :     }
     434         3522 :   tree valuet = meta_info_type_node;
     435         3522 :   tree ret = NULL_TREE;
     436         3522 :   if (kind != GET_INFO_VEC)
     437              :     {
     438         1923 :       tree args = make_tree_vec (1);
     439         1923 :       TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
     440         1923 :       tree inst = lookup_template_class (get_identifier ("range_value_t"),
     441              :                                          args, /*in_decl*/NULL_TREE,
     442              :                                          /*context*/ranges_ns,
     443              :                                          tf_warning_or_error);
     444         1923 :       inst = complete_type (inst);
     445         1923 :       if (inst == error_mark_node)
     446              :         {
     447            0 :           *non_constant_p = true;
     448            0 :           return NULL_TREE;
     449              :         }
     450         1923 :       valuet = TYPE_MAIN_VARIANT (inst);
     451         1923 :       if (kind == REFLECT_CONSTANT_STRING
     452         1634 :           && valuet != char_type_node
     453          103 :           && valuet != wchar_type_node
     454           92 :           && valuet != char8_type_node
     455           35 :           && valuet != char16_type_node
     456           24 :           && valuet != char32_type_node)
     457              :         {
     458            9 :           if (!cxx_constexpr_quiet_p (ctx))
     459            3 :             error_at (loc, "%<reflect_constant_string%> called with %qT "
     460              :                            "rather than %<char%>, %<wchar_t%>, %<char8_t%>, "
     461              :                            "%<char16_t%> or %<char32_t%>", inst);
     462            9 :           *non_constant_p = true;
     463            9 :           return NULL_TREE;
     464              :         }
     465              :       /* Check for the reflect_object_string special-case, where r
     466              :          refers to a string literal.  In that case CharT() should not
     467              :          be appended.  */
     468         1625 :       if (kind == REFLECT_CONSTANT_STRING
     469         1625 :           && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE
     470           79 :           && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) == valuet
     471           79 :           && TYPE_DOMAIN (TREE_TYPE (type)))
     472              :         {
     473           79 :           tree a = arg;
     474           79 :           tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (type)));
     475           79 :           STRIP_NOPS (a);
     476           79 :           tree at;
     477           79 :           if (TREE_CODE (a) == ADDR_EXPR
     478           79 :               && TREE_CODE (TREE_OPERAND (a, 0)) == STRING_CST
     479           77 :               && tree_fits_uhwi_p (maxv)
     480           77 :               && ((unsigned) TREE_STRING_LENGTH (TREE_OPERAND (a, 0))
     481           77 :                   == ((tree_to_uhwi (maxv) + 1)
     482           77 :                        * tree_to_uhwi (TYPE_SIZE_UNIT (valuet))))
     483           77 :               && (at = TREE_TYPE (TREE_OPERAND (a, 0)))
     484          156 :               && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type),
     485              :                                                             at))
     486           77 :             return TREE_OPERAND (a, 0);
     487              :         }
     488         1837 :       if (kind == REFLECT_CONSTANT_ARRAY)
     489              :         {
     490          289 :           if (!structural_type_p (valuet))
     491              :             {
     492            3 :               if (!cxx_constexpr_quiet_p (ctx))
     493              :                 {
     494            1 :                   auto_diagnostic_group d;
     495            1 :                   error_at (loc, "%<reflect_constant_array%> argument with "
     496              :                                  "%qT which is not a structural type", inst);
     497            1 :                   structural_type_p (valuet, true);
     498            1 :                 }
     499            3 :               *non_constant_p = true;
     500            3 :               return NULL_TREE;
     501              :             }
     502          286 :           TREE_VEC_ELT (args, 0)
     503          286 :             = build_stub_type (valuet,
     504          286 :                                cp_type_quals (valuet) | TYPE_QUAL_CONST,
     505              :                                false);
     506          286 :           if (!is_xible (INIT_EXPR, valuet, args))
     507              :             {
     508            3 :               if (!cxx_constexpr_quiet_p (ctx))
     509            1 :                 error_at (loc, "%<reflect_constant_array%> argument with %qT "
     510              :                                "which is not copy constructible", inst);
     511            3 :               *non_constant_p = true;
     512            3 :               return NULL_TREE;
     513              :             }
     514          283 :           TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
     515          283 :           tree instr
     516          283 :             = lookup_template_class (get_identifier ("range_reference_t"),
     517              :                                      args, /*in_decl*/NULL_TREE,
     518              :                                      /*context*/ranges_ns,
     519              :                                      tf_warning_or_error);
     520          283 :           instr = complete_type (instr);
     521          283 :           if (instr == error_mark_node)
     522              :             {
     523            0 :               *non_constant_p = true;
     524            0 :               return NULL_TREE;
     525              :             }
     526          283 :           tree referencet = TYPE_MAIN_VARIANT (instr);
     527          283 :           TREE_VEC_ELT (args, 0) = referencet;
     528          283 :           if (!is_xible (INIT_EXPR, valuet, args))
     529              :             {
     530            0 :               if (!cxx_constexpr_quiet_p (ctx))
     531            0 :                 error_at (loc, "%<reflect_constant_array%> argument with %qT "
     532              :                                "which is not constructible from %qT "
     533              :                                "%<std::ranges::range_reference_t%>",
     534              :                           inst, referencet);
     535            0 :               *non_constant_p = true;
     536            0 :               return NULL_TREE;
     537              :             }
     538              :         }
     539              :     }
     540         3430 :   auto_vec<tree, 32> retvec;
     541         3430 :   tree p = convert_from_reference (parm);
     542        10424 :   auto obj_call = [=, &map] (tree obj, tsubst_flags_t complain) {
     543         6994 :     releasing_vec args;
     544         6994 :     vec_safe_push (args, p);
     545         6994 :     tree call = finish_call_expr (obj, &args, true, false, complain);
     546         6994 :     if (call == error_mark_node)
     547              :       return call;
     548         6977 :     cp_walk_tree (&call, replace_parm_r, map, NULL);
     549         6977 :     if (complain != tf_none)
     550          280 :       return call;
     551         6697 :     call = cxx_eval_constant_expression (ctx, call, vc_prvalue, non_constant_p,
     552              :                                          overflow_p, jump_target);
     553         6697 :     if (*jump_target || *non_constant_p)
     554            0 :       return NULL_TREE;
     555              :     return call;
     556        10424 :   };
     557         3639 :   auto ret_retvec = [=, &retvec] () {
     558          209 :     unsigned HOST_WIDE_INT sz = retvec.length ();
     559         1093 :     for (size_t i = 0; i < sz; ++i)
     560              :       {
     561          884 :         if (INTEGRAL_TYPE_P (valuet))
     562              :           {
     563          734 :             if (TREE_CODE (retvec[i]) != INTEGER_CST)
     564            0 :               return throw_exception (loc, ctx,
     565              :                                       "array element not a constant integer",
     566            0 :                                       fun, non_constant_p, jump_target);
     567              :           }
     568              :         else
     569              :           {
     570          150 :             gcc_assert (kind == REFLECT_CONSTANT_ARRAY);
     571          150 :             tree expr = convert_reflect_constant_arg (valuet, retvec[i]);
     572          150 :             if (expr == error_mark_node)
     573            0 :               return throw_exception (loc, ctx, "reflect_constant failed",
     574            0 :                                       fun, non_constant_p, jump_target);
     575          150 :             if (VAR_P (expr))
     576           71 :               expr = unshare_expr (DECL_INITIAL (expr));
     577          150 :             retvec[i] = expr;
     578              :           }
     579              :       }
     580          209 :     if (kind == REFLECT_CONSTANT_ARRAY && sz == 0)
     581              :       {
     582              :         /* Return std::array <valuet, 0> {}.  */
     583            4 :         tree args = make_tree_vec (2);
     584            4 :         TREE_VEC_ELT (args, 0) = valuet;
     585            4 :         TREE_VEC_ELT (args, 1) = size_zero_node;
     586            4 :         tree inst = lookup_template_class (get_identifier ("array"), args,
     587              :                                            /*in_decl*/NULL_TREE,
     588              :                                            /*context*/std_node,
     589              :                                            tf_warning_or_error);
     590            4 :         tree type = complete_type (inst);
     591            4 :         if (type == error_mark_node)
     592              :           {
     593            0 :             *non_constant_p = true;
     594            0 :             return NULL_TREE;
     595              :           }
     596            4 :         tree ctor = build_constructor (init_list_type_node, nullptr);
     597            4 :         CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
     598            4 :         TREE_CONSTANT (ctor) = true;
     599            4 :         TREE_STATIC (ctor) = true;
     600            4 :         tree r = finish_compound_literal (type, ctor, tf_warning_or_error,
     601              :                                           fcl_functional);
     602              :         /* Here, we're evaluating an AGGR_INIT_EXPR, which is already
     603              :            embedded in a TARGET_EXPR, so we don't want to add another
     604              :            TARGET_EXPR inside it.  Note that SIMPLE_TARGET_EXPR_P would
     605              :            always be false because the TARGET_EXPR_INITIAL is an
     606              :            AGGR_INIT_EXPR with void type.  */
     607            4 :         if (TREE_CODE (r) == TARGET_EXPR)
     608            4 :           r = TARGET_EXPR_INITIAL (r);
     609            4 :         return r;
     610              :       }
     611          205 :     unsigned esz = tree_to_uhwi (TYPE_SIZE_UNIT (valuet));
     612          205 :     unsigned last = kind == REFLECT_CONSTANT_STRING ? esz : 0;
     613          205 :     tree index = build_index_type (size_int (last ? sz : sz - 1));
     614          205 :     tree at = build_array_type (valuet, index);
     615          205 :     at = cp_build_qualified_type (at, TYPE_QUAL_CONST);
     616          205 :     if (kind == REFLECT_CONSTANT_STRING
     617          205 :         || ((valuet == char_type_node
     618          174 :              || valuet == wchar_type_node
     619          174 :              || valuet == char8_type_node
     620          174 :              || valuet == char16_type_node
     621          174 :              || valuet == char32_type_node)
     622           20 :             && integer_zerop (retvec.last ())))
     623              :       {
     624           27 :         unsigned HOST_WIDE_INT szt = sz * esz;
     625           27 :         char *p;
     626           27 :         if (szt < 4096)
     627           27 :           p = XALLOCAVEC (char, szt + last);
     628              :         else
     629            0 :           p = XNEWVEC (char, szt + last);
     630          276 :         for (size_t i = 0; i < sz; ++i)
     631          249 :           native_encode_expr (retvec[i], (unsigned char *) p + i * esz,
     632              :                               esz, 0);
     633           27 :         if (last)
     634           21 :           memset (p + szt, '\0', last);
     635           27 :         tree ret = build_string (szt + last, p);
     636           27 :         TREE_TYPE (ret) = at;
     637           27 :         TREE_CONSTANT (ret) = 1;
     638           27 :         TREE_READONLY (ret) = 1;
     639           27 :         TREE_STATIC (ret) = 1;
     640           27 :         if (szt >= 4096)
     641            0 :           XDELETEVEC (p);
     642           27 :         return ret;
     643              :       }
     644          178 :     vec<constructor_elt, va_gc> *elts = nullptr;
     645          813 :     for (unsigned i = 0; i < sz; ++i)
     646          635 :       CONSTRUCTOR_APPEND_ELT (elts, bitsize_int (i), retvec[i]);
     647          178 :     return build_constructor (at, elts);
     648         3430 :   };
     649              :   /* If true, call std::ranges::data (p) and std::ranges::size (p)
     650              :      and if that works out and what the former returns can be handled,
     651              :      grab the elements from the initializer of the decl pointed by the
     652              :      first expression.  p has to be convert_from_reference (PARM_DECL)
     653              :      rather than its value, otherwise it is not considered lvalue.  */
     654         3430 :   if (contiguous_range)
     655              :     {
     656         3357 :       tree data = lookup_qualified_name (ranges_ns, "data");
     657         3357 :       tree size = lookup_qualified_name (ranges_ns, "size");
     658         3357 :       if (TREE_CODE (data) != VAR_DECL || TREE_CODE (size) != VAR_DECL)
     659              :         {
     660            0 :           error_at (loc, "%<std::ranges::data%> or %<std::ranges::size%> "
     661              :                          "are not customization point objects");
     662            0 :           *non_constant_p = true;
     663            0 :           return NULL_TREE;
     664              :         }
     665         3357 :       data = obj_call (data, tf_none);
     666         3357 :       if (error_operand_p (data))
     667            0 :         goto non_contiguous;
     668         3357 :       if (data == NULL_TREE)
     669              :         return NULL_TREE;
     670         3357 :       size = obj_call (size, tf_none);
     671         3357 :       if (error_operand_p (size))
     672           17 :         goto non_contiguous;
     673         3340 :       if (size == NULL_TREE)
     674              :         return NULL_TREE;
     675         3340 :       if (!tree_fits_uhwi_p (size) || tree_to_uhwi (size) > INT_MAX)
     676            0 :         goto non_contiguous;
     677         3340 :       if (integer_zerop (size))
     678              :         {
     679          357 :           if (kind == GET_INFO_VEC)
     680          353 :             return make_tree_vec (0);
     681            4 :           return ret_retvec ();
     682              :         }
     683         2983 :       STRIP_NOPS (data);
     684         2983 :       unsigned HOST_WIDE_INT minidx = 0, pplus = 0;
     685         2983 :       if (TREE_CODE (data) == POINTER_PLUS_EXPR
     686           12 :           && tree_fits_uhwi_p (TREE_OPERAND (data, 1))
     687         2995 :           && !wi::neg_p (wi::to_wide (TREE_OPERAND (data, 1))))
     688              :         {
     689           12 :           pplus = tree_to_uhwi (TREE_OPERAND (data, 1));
     690           12 :           data = TREE_OPERAND (data, 0);
     691           12 :           STRIP_NOPS (data);
     692              :         }
     693         2983 :       if (TREE_CODE (data) != ADDR_EXPR)
     694            0 :         goto non_contiguous;
     695         2983 :       data = TREE_OPERAND (data, 0);
     696         2983 :       if (TREE_CODE (data) == ARRAY_REF
     697         2983 :           && tree_fits_uhwi_p (TREE_OPERAND (data, 1)))
     698              :         {
     699           13 :           minidx = tree_to_uhwi (TREE_OPERAND (data, 1));
     700           13 :           data = TREE_OPERAND (data, 0);
     701              :         }
     702         2983 :       data = cxx_eval_constant_expression (ctx, data, vc_prvalue,
     703              :                                            non_constant_p, overflow_p,
     704              :                                            jump_target);
     705         2983 :       if (*jump_target || *non_constant_p)
     706              :         return NULL_TREE;
     707         2983 :       if (TREE_CODE (TREE_TYPE (data)) != ARRAY_TYPE
     708         2983 :           || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (data))) != valuet)
     709            8 :         goto non_contiguous;
     710         2975 :       if (pplus
     711         2975 :           && (pplus % tree_to_uhwi (TYPE_SIZE_UNIT (valuet))) != 0)
     712            0 :         goto non_contiguous;
     713         2975 :       minidx += pplus / tree_to_uhwi (TYPE_SIZE_UNIT (valuet));
     714         2975 :       if (kind != GET_INFO_VEC && TREE_CODE (data) == STRING_CST)
     715              :         {
     716         1624 :           unsigned esz = tree_to_uhwi (TYPE_SIZE_UNIT (valuet));
     717         1624 :           unsigned HOST_WIDE_INT sz = tree_to_uhwi (size) * esz;
     718         1624 :           if (minidx > INT_MAX
     719         1624 :               || (unsigned) TREE_STRING_LENGTH (data) < sz + minidx * esz)
     720            0 :             goto non_contiguous;
     721         1624 :           if (kind == REFLECT_CONSTANT_ARRAY && sz == 0)
     722            0 :             return ret_retvec ();
     723         1624 :           tree index
     724         3151 :             = build_index_type (size_int ((kind == REFLECT_CONSTANT_ARRAY
     725              :                                            ? -1 : 0) + tree_to_uhwi (size)));
     726         1624 :           tree at = build_array_type (valuet, index);
     727         1624 :           at = cp_build_qualified_type (at, TYPE_QUAL_CONST);
     728         1624 :           const unsigned char *q
     729         1624 :             = (const unsigned char *) TREE_STRING_POINTER (data);
     730         1624 :           q += minidx * esz;
     731         1624 :           if (kind == REFLECT_CONSTANT_ARRAY)
     732              :             {
     733              :               unsigned HOST_WIDE_INT i;
     734          259 :               for (i = 0; i < esz; ++i)
     735          164 :                 if (q[sz - esz + i])
     736              :                   break;
     737           97 :               if (i != esz)
     738              :                 {
     739              :                   /* Not a NUL terminated string.  Build a CONSTRUCTOR
     740              :                      instead.  */
     741           10 :                   for (i = 0; i < sz; i += esz)
     742              :                     {
     743            8 :                       tree t = native_interpret_expr (valuet, q + i, sz);
     744            8 :                       retvec.safe_push (t);
     745              :                     }
     746            2 :                   return ret_retvec ();
     747              :                 }
     748              :             }
     749         1622 :           char *p;
     750         1622 :           if (sz < 4096)
     751         1622 :             p = XALLOCAVEC (char, sz + esz);
     752              :           else
     753            0 :             p = XNEWVEC (char, sz + esz);
     754         1622 :           memcpy (p, q, sz);
     755         1622 :           memset (p + sz, '\0', esz);
     756         1717 :           ret = build_string (sz + (kind == REFLECT_CONSTANT_ARRAY
     757              :                                     ? 0 : esz), p);
     758         1622 :           TREE_TYPE (ret) = at;
     759         1622 :           TREE_CONSTANT (ret) = 1;
     760         1622 :           TREE_READONLY (ret) = 1;
     761         1622 :           TREE_STATIC (ret) = 1;
     762         1622 :           if (sz >= 4096)
     763            0 :             XDELETEVEC (p);
     764         1622 :           return ret;
     765              :         }
     766         1351 :       if (TREE_CODE (data) != CONSTRUCTOR)
     767            0 :         goto non_contiguous;
     768         1351 :       unsigned sz = tree_to_uhwi (size), i;
     769         1351 :       unsigned HOST_WIDE_INT j = 0;
     770         1351 :       tree *r, null = NULL_TREE;
     771         1351 :       if (kind == GET_INFO_VEC)
     772              :         {
     773         1184 :           ret = make_tree_vec (sz);
     774         1184 :           r = TREE_VEC_BEGIN (ret);
     775         1184 :           null = get_null_reflection ();
     776              :         }
     777              :       else
     778              :         {
     779          167 :           retvec.safe_grow (sz, true);
     780          167 :           r = retvec.address ();
     781              :         }
     782         3803 :       for (i = 0; i < sz; ++i)
     783         2452 :         r[i] = null;
     784              :       tree field, value;
     785         3836 :       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (data), i, field, value)
     786         2485 :         if (field == NULL_TREE)
     787              :           {
     788            0 :             if (j >= minidx && j - minidx < sz)
     789            0 :               r[j - minidx] = value;
     790            0 :             ++j;
     791              :           }
     792         2485 :         else if (TREE_CODE (field) == RANGE_EXPR)
     793              :           {
     794            0 :             tree lo = TREE_OPERAND (field, 0);
     795            0 :             tree hi = TREE_OPERAND (field, 1);
     796            0 :             if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
     797            0 :               goto non_contiguous;
     798            0 :             unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
     799            0 :             for (j = tree_to_uhwi (lo); j <= m; ++j)
     800            0 :               if (j >= minidx && j - minidx < sz)
     801            0 :                 r[j - minidx] = value;
     802              :           }
     803         2485 :         else if (tree_fits_uhwi_p (field))
     804              :           {
     805         2485 :             j = tree_to_uhwi (field);
     806         2485 :             if (j >= minidx && j - minidx < sz)
     807         2434 :               r[j - minidx] = value;
     808         2485 :             ++j;
     809              :           }
     810              :         else
     811            0 :           goto non_contiguous;
     812         1351 :       if (kind == GET_INFO_VEC)
     813              :         return ret;
     814          738 :       for (i = 0; i < sz; ++i)
     815          613 :         if (r[i] == NULL_TREE || !tree_fits_shwi_p (r[i]))
     816           42 :           goto non_contiguous;
     817          125 :       return ret_retvec ();
     818              :     }
     819           73 :  non_contiguous:
     820              :   /* Otherwise, do it the slower way.  Initialize two temporaries,
     821              :      one to std::ranges::base (p) and another to std::ranges::end (p)
     822              :      and use a loop.  */
     823          140 :   tree begin = lookup_qualified_name (ranges_ns, "begin");
     824          140 :   tree end = lookup_qualified_name (ranges_ns, "end");
     825          140 :   if (TREE_CODE (begin) != VAR_DECL || TREE_CODE (end) != VAR_DECL)
     826              :     {
     827            0 :       error_at (loc, "missing %<std::ranges::begin%> or %<std::ranges::end%>");
     828            0 :       *non_constant_p = true;
     829            0 :       return NULL_TREE;
     830              :     }
     831          140 :   begin = obj_call (begin, tf_warning_or_error);
     832          140 :   if (error_operand_p (begin))
     833              :     {
     834            0 :       *non_constant_p = true;
     835            0 :       return NULL_TREE;
     836              :     }
     837          140 :   end = obj_call (end, tf_warning_or_error);
     838          140 :   if (error_operand_p (end))
     839              :     {
     840            0 :       *non_constant_p = true;
     841            0 :       return NULL_TREE;
     842              :     }
     843          140 :   if (!CLASS_TYPE_P (TREE_TYPE (begin)) && !POINTER_TYPE_P (TREE_TYPE (begin)))
     844              :     {
     845            0 :       error_at (loc, "incorrect type %qT of %<std::ranges::begin(arg)%>",
     846            0 :                 TREE_TYPE (begin));
     847            0 :       *non_constant_p = true;
     848            0 :       return NULL_TREE;
     849              :     }
     850          140 :   if (VOID_TYPE_P (TREE_TYPE (end)))
     851              :     {
     852            0 :       error_at (loc, "incorrect type %qT of %<std::ranges::end(arg)%>",
     853            0 :                 TREE_TYPE (end));
     854            0 :       *non_constant_p = true;
     855            0 :       return NULL_TREE;
     856              :     }
     857          140 :   begin = get_target_expr (begin);
     858          140 :   end = get_target_expr (end);
     859          140 :   begin = cxx_eval_constant_expression (ctx, begin, vc_glvalue, non_constant_p,
     860              :                                         overflow_p, jump_target);
     861          140 :   if (*jump_target || *non_constant_p)
     862              :     return NULL_TREE;
     863          140 :   end = cxx_eval_constant_expression (ctx, end, vc_glvalue, non_constant_p,
     864              :                                       overflow_p, jump_target);
     865          140 :   if (*jump_target || *non_constant_p)
     866              :     return NULL_TREE;
     867          140 :   tree cmp = build_new_op (loc, NE_EXPR, LOOKUP_NORMAL, begin, end,
     868              :                            tf_warning_or_error);
     869          140 :   tree deref = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, begin,
     870              :                              NULL_TREE, tf_warning_or_error);
     871          140 :   tree inc = build_new_op (loc, PREINCREMENT_EXPR, LOOKUP_NORMAL, begin,
     872              :                            NULL_TREE, tf_warning_or_error);
     873          140 :   cmp = condition_conversion (cmp);
     874          140 :   if (error_operand_p (cmp)
     875          140 :       || error_operand_p (deref)
     876          280 :       || error_operand_p (inc))
     877              :     {
     878            0 :       *non_constant_p = true;
     879            0 :       return NULL_TREE;
     880              :     }
     881          140 :   if (TYPE_MAIN_VARIANT (TREE_TYPE (deref)) != valuet)
     882              :     {
     883            3 :       deref = perform_implicit_conversion (valuet, deref, tf_warning_or_error);
     884            3 :       if (error_operand_p (deref))
     885              :         {
     886            0 :           *non_constant_p = true;
     887            0 :           return NULL_TREE;
     888              :         }
     889            3 :       if (CLASS_TYPE_P (valuet))
     890              :         {
     891            1 :           deref = force_target_expr (valuet, deref, tf_warning_or_error);
     892            1 :           if (error_operand_p (deref))
     893              :             {
     894            0 :               *non_constant_p = true;
     895            0 :               return NULL_TREE;
     896              :             }
     897              :         }
     898              :     }
     899          140 :   deref = fold_build_cleanup_point_expr (TREE_TYPE (deref), deref);
     900          140 :   inc = fold_build_cleanup_point_expr (void_type_node, inc);
     901          140 :   retvec.truncate (0);
     902              :   /* while (begin != end) { push (*begin); ++begin; }  */
     903         1262 :   do
     904              :     {
     905          701 :       tree t = cxx_eval_constant_expression (ctx, cmp, vc_prvalue,
     906              :                                              non_constant_p, overflow_p,
     907              :                                              jump_target);
     908          701 :       if (*jump_target || *non_constant_p)
     909            0 :         return NULL_TREE;
     910          701 :       if (integer_zerop (t))
     911              :         break;
     912          561 :       t = cxx_eval_constant_expression (ctx, deref, vc_prvalue, non_constant_p,
     913              :                                         overflow_p, jump_target);
     914          561 :       if (*jump_target || *non_constant_p)
     915              :         return NULL_TREE;
     916          561 :       retvec.safe_push (t);
     917          561 :       cxx_eval_constant_expression (ctx, inc, vc_discard, non_constant_p,
     918              :                                     overflow_p, jump_target);
     919          561 :       if (*jump_target || *non_constant_p)
     920              :         return NULL_TREE;
     921          561 :     }
     922              :   while (true);
     923          140 :   if (kind != GET_INFO_VEC)
     924           78 :     return ret_retvec ();
     925           62 :   ret = make_tree_vec (retvec.length ());
     926           62 :   tree v;
     927           62 :   unsigned int i;
     928         3810 :   FOR_EACH_VEC_ELT (retvec, i, v)
     929          256 :     TREE_VEC_ELT (ret, i) = v;
     930              :   return ret;
     931         3430 : }
     932              : 
     933              : /* Extract the N-th reflection_range argument from a metafunction call CALL
     934              :    and return it as TREE_VEC.  */
     935              : 
     936              : static tree
     937         1600 : get_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
     938              :               bool *non_constant_p, bool *overflow_p, tree *jump_target,
     939              :               tree fun)
     940              : {
     941            0 :   return get_range_elts (loc, ctx, call, n, non_constant_p, overflow_p,
     942            0 :                          jump_target, GET_INFO_VEC, fun);
     943              : }
     944              : 
     945              : /* Create std::meta::exception{ what, from }.  WHAT is the string for what(),
     946              :    and FROM is the info for from().  */
     947              : 
     948              : static tree
     949         1470 : get_meta_exception_object (location_t loc, const constexpr_ctx *ctx,
     950              :                            const char *what, tree from, bool *non_constant_p)
     951              : {
     952              :   /* Don't throw in a template.  */
     953         1470 :   if (processing_template_decl)
     954              :     {
     955            2 :       *non_constant_p = true;
     956            2 :       return NULL_TREE;
     957              :     }
     958              : 
     959              :   /* Don't try to throw exceptions with -fno-exceptions.  */
     960         1468 :   if (!flag_exceptions)
     961              :     {
     962            4 :       if (!cxx_constexpr_quiet_p (ctx))
     963              :         {
     964            1 :           auto_diagnostic_group d;
     965            1 :           error_at (loc, "%qD should throw %qs; %<what()%>: %qs",
     966              :                     from, "std::meta::exception", _(what));
     967            1 :           inform (loc, "exceptions are disabled, treating as non-constant");
     968            1 :         }
     969            4 :       *non_constant_p = true;
     970            4 :       return NULL_TREE;
     971              :     }
     972              : 
     973         1464 :   tree type = lookup_qualified_name (std_meta_node, "exception",
     974              :                                      LOOK_want::TYPE, /*complain*/true);
     975         1464 :   if (TREE_CODE (type) != TYPE_DECL || !CLASS_TYPE_P (TREE_TYPE (type)))
     976              :     {
     977            0 :       error_at (loc, "couldn%'t throw %qs", "std::meta::exception");
     978            0 :       return NULL_TREE;
     979              :     }
     980         1464 :   type = TREE_TYPE (type);
     981         1464 :   vec<constructor_elt, va_gc> *elts = nullptr;
     982         1464 :   what = _(what);
     983              :   /* Translate what from SOURCE_CHARSET to exec charset.  */
     984         1464 :   cpp_string istr, ostr;
     985         1464 :   istr.len = strlen (what) + 1;
     986         1464 :   istr.text = (const unsigned char *) what;
     987         1464 :   if (!cpp_translate_string (parse_in, &istr, &ostr, CPP_STRING, false))
     988              :     {
     989            0 :       what = "";
     990            0 :       ostr.text = NULL;
     991              :     }
     992              :   else
     993         1464 :     what = (const char *) ostr.text;
     994         1464 :   if (TREE_CODE (from) == FUNCTION_DECL && DECL_TEMPLATE_INFO (from))
     995          438 :     from = DECL_TI_TEMPLATE (from);
     996         1464 :   tree string_lit = build_string (strlen (what) + 1, what);
     997         1464 :   free (const_cast <unsigned char *> (ostr.text));
     998         1464 :   TREE_TYPE (string_lit) = char_array_type_node;
     999         1464 :   string_lit = fix_string_type (string_lit);
    1000         1464 :   CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, string_lit);
    1001         1464 :   CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, get_reflection_raw (loc, from));
    1002         1464 :   tree ctor = build_constructor (init_list_type_node, elts);
    1003         1464 :   CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
    1004         1464 :   TREE_CONSTANT (ctor) = true;
    1005         1464 :   TREE_STATIC (ctor) = true;
    1006         1464 :   return finish_compound_literal (type, ctor, tf_warning_or_error,
    1007         1464 :                                   fcl_functional);
    1008              : }
    1009              : 
    1010              : /* Perform 'throw std::meta::exception{...}'.  MSGID is the string for what(),
    1011              :    FROM is the reflection for from().  */
    1012              : 
    1013              : static tree
    1014         1470 : throw_exception (location_t loc, const constexpr_ctx *ctx, const char *msgid,
    1015              :                  tree from, bool *non_constant_p, tree *jump_target)
    1016              : {
    1017         1470 :   if (tree obj = get_meta_exception_object (loc, ctx, msgid, from,
    1018              :                                             non_constant_p))
    1019         1464 :     *jump_target = cxa_allocate_and_throw_exception (loc, ctx, obj);
    1020         1470 :   return NULL_TREE;
    1021              : }
    1022              : 
    1023              : /* Wrapper around throw_exception to complain that the reflection does not
    1024              :    represent a type.  */
    1025              : 
    1026              : static tree
    1027          387 : throw_exception_nontype (location_t loc, const constexpr_ctx *ctx,
    1028              :                          tree from, bool *non_constant_p, tree *jump_target)
    1029              : {
    1030            0 :   return throw_exception (loc, ctx,
    1031              :                           "reflection does not represent a type",
    1032            0 :                           from, non_constant_p, jump_target);
    1033              : }
    1034              : 
    1035              : /* Wrapper around throw_exception to complain that the reflection does not
    1036              :    represent something that satisfies has_template_arguments.  */
    1037              : 
    1038              : static tree
    1039            1 : throw_exception_notargs (location_t loc, const constexpr_ctx *ctx,
    1040              :                          tree from, bool *non_constant_p, tree *jump_target)
    1041              : {
    1042            0 :   return throw_exception (loc, ctx,
    1043              :                           "reflection does not have template arguments",
    1044            0 :                           from, non_constant_p, jump_target);
    1045              : }
    1046              : 
    1047              : /* Wrapper around throw_exception to complain that the reflection does not
    1048              :    represent a function or a function type.  */
    1049              : 
    1050              : static tree
    1051            6 : throw_exception_nofn (location_t loc, const constexpr_ctx *ctx,
    1052              :                       tree from, bool *non_constant_p, tree *jump_target)
    1053              : {
    1054            0 :   return throw_exception (loc, ctx, "reflection does not represent a "
    1055              :                                     "function or function type",
    1056            0 :                           from, non_constant_p, jump_target);
    1057              : }
    1058              : 
    1059              : /* The values of std::meta::operators enumerators corresponding to
    1060              :    the ovl_op_code and IDENTIFIER_ASSIGN_OP_P pair.  */
    1061              : 
    1062              : static unsigned char meta_operators[2][OVL_OP_MAX];
    1063              : 
    1064              : /* Init the meta_operators table if not yet initialized.  */
    1065              : 
    1066              : static void
    1067          288 : maybe_init_meta_operators (location_t loc)
    1068              : {
    1069          288 :   if (meta_operators[0][OVL_OP_ERROR_MARK])
    1070          281 :     return;
    1071            7 :   meta_operators[0][OVL_OP_ERROR_MARK] = 1;
    1072            7 :   tree operators = lookup_qualified_name (std_meta_node, "operators");
    1073            7 :   if (TREE_CODE (operators) != TYPE_DECL
    1074            7 :       || TREE_CODE (TREE_TYPE (operators)) != ENUMERAL_TYPE)
    1075              :     {
    1076            0 :     fail:
    1077            0 :       error_at (loc, "unexpected %<std::meta::operators%>");
    1078            0 :       return;
    1079              :     }
    1080            7 :   char buf[sizeof "op_greater_greater_equals"];
    1081            7 :   memcpy (buf, "op_", 3);
    1082           21 :   for (int i = 0; i < 2; ++i)
    1083          812 :     for (int j = OVL_OP_ERROR_MARK + 1; j < OVL_OP_MAX; ++j)
    1084          798 :       if (ovl_op_info[i][j].meta_name)
    1085              :         {
    1086          350 :           strcpy (buf + 3, ovl_op_info[i][j].meta_name);
    1087          350 :           tree id = get_identifier (buf);
    1088          350 :           tree t = lookup_enumerator (TREE_TYPE (operators), id);
    1089          350 :           if (t == NULL_TREE || TREE_CODE (t) != CONST_DECL)
    1090            0 :             goto fail;
    1091          350 :           tree v = DECL_INITIAL (t);
    1092          350 :           if (!tree_fits_uhwi_p (v) || tree_to_uhwi (v) > UCHAR_MAX)
    1093            0 :             goto fail;
    1094          350 :           meta_operators[i][j] = tree_to_uhwi (v);
    1095              :         }
    1096              : }
    1097              : 
    1098              : /* Process std::meta::is_variable.
    1099              :    Returns: true if r represents a variable.  Otherwise, false.  */
    1100              : 
    1101              : static tree
    1102         6719 : eval_is_variable (const_tree r, reflect_kind kind)
    1103              : {
    1104              :   /* ^^param is a variable but parameters_of(parent_of(^^param))[0] is not.  */
    1105          199 :   if ((TREE_CODE (r) == PARM_DECL && kind != REFLECT_PARM)
    1106         6598 :       || (VAR_P (r)
    1107         1936 :           && kind == REFLECT_UNDEF
    1108              :           /* A structured binding is not a variable.  */
    1109         1820 :           && !(DECL_DECOMPOSITION_P (r) && !DECL_DECOMP_IS_BASE (r)))
    1110        11548 :       || (VAR_P (r)
    1111              :           /* Underlying variable of tuple using structured binding is a
    1112              :              variable.  */
    1113          167 :           && kind == REFLECT_VAR
    1114           30 :           && DECL_DECOMPOSITION_P (r)
    1115           30 :           && !DECL_DECOMP_IS_BASE (r)))
    1116         1920 :     return boolean_true_node;
    1117              :   else
    1118         4799 :     return boolean_false_node;
    1119              : }
    1120              : 
    1121              : /* Process std::meta::is_type.
    1122              :    Returns: true if r represents an entity whose underlying entity is
    1123              :    a type.  Otherwise, false.  */
    1124              : 
    1125              : static tree
    1126         9958 : eval_is_type (const_tree r)
    1127              : {
    1128              :   /* Null reflection isn't a type.  */
    1129         9958 :   if (TYPE_P (r) && r != unknown_type_node)
    1130         7752 :     return boolean_true_node;
    1131              :   else
    1132         2206 :     return boolean_false_node;
    1133              : }
    1134              : 
    1135              : /* Process std::meta::is_type_alias.
    1136              :    Returns: true if r represents a type alias.  Otherwise, false.  */
    1137              : 
    1138              : static tree
    1139         1582 : eval_is_type_alias (const_tree r)
    1140              : {
    1141         1582 :   if (TYPE_P (r) && typedef_variant_p (r))
    1142           56 :     return boolean_true_node;
    1143              :   else
    1144         1526 :     return boolean_false_node;
    1145              : }
    1146              : 
    1147              : /* Process std::meta::is_namespace.
    1148              :    Returns: true if r represents an entity whose underlying entity is
    1149              :    a namespace.  Otherwise, false.  */
    1150              : 
    1151              : static tree
    1152          721 : eval_is_namespace (const_tree r)
    1153              : {
    1154          471 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    1155           67 :     return boolean_true_node;
    1156              :   else
    1157          519 :     return boolean_false_node;
    1158              : }
    1159              : 
    1160              : /* Process std::meta::is_namespace_alias.
    1161              :    Returns: true if r represents a namespace alias.  Otherwise, false.  */
    1162              : 
    1163              : static tree
    1164          249 : eval_is_namespace_alias (const_tree r)
    1165              : {
    1166          249 :   if (TREE_CODE (r) == NAMESPACE_DECL && DECL_NAMESPACE_ALIAS (r))
    1167           10 :     return boolean_true_node;
    1168              :   else
    1169          239 :     return boolean_false_node;
    1170              : }
    1171              : 
    1172              : /* Process std::meta::is_function.
    1173              :    Returns: true if r represents a function.  Otherwise, false.  */
    1174              : 
    1175              : static tree
    1176         3392 : eval_is_function (tree r)
    1177              : {
    1178         3392 :   r = maybe_get_first_fn (r);
    1179              : 
    1180         3392 :   if (TREE_CODE (r) == FUNCTION_DECL)
    1181          970 :     return boolean_true_node;
    1182              :   else
    1183         2422 :     return boolean_false_node;
    1184              : }
    1185              : 
    1186              : /* Process std::meta::is_function_template.
    1187              :    Returns: true if r represents a function template.  Otherwise, false.  */
    1188              : 
    1189              : static tree
    1190         2374 : eval_is_function_template (tree r)
    1191              : {
    1192         2374 :   r = maybe_get_first_fn (r);
    1193              : 
    1194         2374 :   if (DECL_FUNCTION_TEMPLATE_P (r))
    1195           84 :     return boolean_true_node;
    1196              : 
    1197         2290 :   return boolean_false_node;
    1198              : }
    1199              : 
    1200              : /* Process std::meta::is_variable_template.
    1201              :    Returns: true if r represents a variable template.  Otherwise, false.  */
    1202              : 
    1203              : static tree
    1204         2120 : eval_is_variable_template (tree r)
    1205              : {
    1206         2120 :   if (variable_template_p (r))
    1207           52 :     return boolean_true_node;
    1208              :   else
    1209         2068 :     return boolean_false_node;
    1210              : }
    1211              : 
    1212              : /* Process std::meta::is_class_template.
    1213              :    Returns: true if r represents a class template.  Otherwise, false.  */
    1214              : 
    1215              : static tree
    1216         2316 : eval_is_class_template (const_tree r)
    1217              : {
    1218         2316 :   if (DECL_CLASS_TEMPLATE_P (r))
    1219          184 :     return boolean_true_node;
    1220              :   else
    1221         2132 :     return boolean_false_node;
    1222              : }
    1223              : 
    1224              : /* Process std::meta::is_alias_template.
    1225              :    Returns: true if r represents an alias template.  Otherwise, false.  */
    1226              : 
    1227              : static tree
    1228         2070 : eval_is_alias_template (const_tree r)
    1229              : {
    1230         2070 :   if (DECL_ALIAS_TEMPLATE_P (r))
    1231           38 :     return boolean_true_node;
    1232              :   else
    1233         2032 :     return boolean_false_node;
    1234              : }
    1235              : 
    1236              : /* Process std::meta::is_concept.
    1237              :    Returns: true if r represents a concept.  Otherwise, false.  */
    1238              : 
    1239              : static tree
    1240         2098 : eval_is_concept (const_tree r)
    1241              : {
    1242         2179 :   if (concept_definition_p (r))
    1243            6 :     return boolean_true_node;
    1244              :   else
    1245         2005 :     return boolean_false_node;
    1246              : }
    1247              : 
    1248              : /* Process std::meta::is_object.
    1249              :    Returns: true if r represents an object.  Otherwise, false.  */
    1250              : 
    1251              : static tree
    1252         1397 : eval_is_object (reflect_kind kind)
    1253              : {
    1254          585 :   if (kind == REFLECT_OBJECT)
    1255           43 :     return boolean_true_node;
    1256              :   else
    1257         1257 :     return boolean_false_node;
    1258              : }
    1259              : 
    1260              : /* Process std::meta::is_value.
    1261              :    Returns: true if r represents a value.  Otherwise, false.  */
    1262              : 
    1263              : static tree
    1264         1044 : eval_is_value (reflect_kind kind)
    1265              : {
    1266          385 :   if (kind == REFLECT_VALUE)
    1267           31 :     return boolean_true_node;
    1268              :   else
    1269          975 :     return boolean_false_node;
    1270              : }
    1271              : 
    1272              : /* Like get_info_vec, but throw exception if any of the elements aren't
    1273              :    eval_is_type reflections and change their content to the corresponding
    1274              :    REFLECT_EXPR_HANDLE.  */
    1275              : 
    1276              : static tree
    1277         1071 : get_type_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
    1278              :                    bool *non_constant_p, bool *overflow_p, tree *jump_target,
    1279              :                    tree fun)
    1280              : {
    1281         1071 :   tree vec = get_info_vec (loc, ctx, call, n, non_constant_p, overflow_p,
    1282              :                            jump_target, fun);
    1283         1071 :   if (*jump_target || *non_constant_p)
    1284              :     return NULL_TREE;
    1285         2623 :   for (int i = 0; i < TREE_VEC_LENGTH (vec); i++)
    1286              :     {
    1287         1568 :       tree type = REFLECT_EXPR_HANDLE (TREE_VEC_ELT (vec, i));
    1288         1568 :       if (eval_is_type (type) != boolean_true_node)
    1289           16 :         return throw_exception_nontype (loc, ctx, fun, non_constant_p,
    1290           16 :                                         jump_target);
    1291         1552 :       TREE_VEC_ELT (vec, i) = type;
    1292              :     }
    1293              :   return vec;
    1294              : }
    1295              : 
    1296              : /* Process std::meta::is_structured_binding.
    1297              :    Returns: true if r represents a structured binding.  Otherwise, false.  */
    1298              : 
    1299              : static tree
    1300          641 : eval_is_structured_binding (const_tree r, reflect_kind kind)
    1301              : {
    1302           50 :   if (DECL_DECOMPOSITION_P (r)
    1303           46 :       && !DECL_DECOMP_IS_BASE (r)
    1304          684 :       && kind != REFLECT_VAR)
    1305           35 :     return boolean_true_node;
    1306              :   else
    1307          606 :     return boolean_false_node;
    1308              : }
    1309              : 
    1310              : /* Process std::meta::is_class_member.
    1311              :    Returns: true if r represents a class member.  Otherwise, false.  */
    1312              : 
    1313              : static tree
    1314        38596 : eval_is_class_member (tree r)
    1315              : {
    1316        38596 :   r = maybe_get_first_fn (r);
    1317        38596 :   if (TREE_CODE (r) == CONST_DECL)
    1318              :     {
    1319              :       /* [class.mem.general]/5 - The enumerators of an unscoped enumeration
    1320              :          defined in the class are members of the class.  */
    1321           93 :       if (UNSCOPED_ENUM_P (DECL_CONTEXT (r)))
    1322           69 :         r = DECL_CONTEXT (r);
    1323              :       else
    1324           24 :         return boolean_false_node;
    1325              :     }
    1326        38503 :   else if (TYPE_P (r) && typedef_variant_p (r))
    1327         1610 :     r = TYPE_NAME (r);
    1328        38572 :   if (DECL_P (r) && DECL_CLASS_SCOPE_P (r))
    1329        35812 :     return boolean_true_node;
    1330         2760 :   else if (TYPE_P (r) && TYPE_CLASS_SCOPE_P (r))
    1331         1098 :     return boolean_true_node;
    1332              :   else
    1333         1662 :     return boolean_false_node;
    1334              : }
    1335              : 
    1336              : /* For direct base class relationship R return the binfo related
    1337              :    to the derived type.  */
    1338              : 
    1339              : static tree
    1340         1765 : direct_base_derived_binfo (tree r)
    1341              : {
    1342              :   /* Looping needed for multiple virtual inheritance.  */
    1343         3551 :   while (BINFO_INHERITANCE_CHAIN (r))
    1344              :     r = BINFO_INHERITANCE_CHAIN (r);
    1345         1765 :   return r;
    1346              : }
    1347              : 
    1348              : /* For direct base class relationship R return the derived type
    1349              :    (i.e. when R is (D, B) it returns D).  */
    1350              : 
    1351              : tree
    1352         1732 : direct_base_derived (tree r)
    1353              : {
    1354         1732 :   return BINFO_TYPE (direct_base_derived_binfo (r));
    1355              : }
    1356              : 
    1357              : /* Helper function for eval_is_{public, protected, private}.  */
    1358              : 
    1359              : static tree
    1360          219 : eval_is_expected_access (tree r, reflect_kind kind, tree expected_access)
    1361              : {
    1362          219 :   if (eval_is_class_member (r) == boolean_true_node)
    1363              :     {
    1364          193 :       r = maybe_get_first_fn (r);
    1365              : 
    1366          193 :       if (TYPE_P (r))
    1367              :         {
    1368           45 :           if (TYPE_NAME (r) == NULL_TREE || !DECL_P (TYPE_NAME (r)))
    1369            0 :             return boolean_false_node;
    1370           45 :           r = TYPE_NAME (r);
    1371              :         }
    1372              : 
    1373          193 :       bool matches = false;
    1374          193 :       if (expected_access == access_private_node)
    1375           55 :         matches = TREE_PRIVATE (r);
    1376          138 :       else if (expected_access == access_protected_node)
    1377           60 :         matches = TREE_PROTECTED (r);
    1378           78 :       else if (expected_access == access_public_node)
    1379           78 :         matches = !(TREE_PRIVATE (r) || TREE_PROTECTED (r));
    1380              :       else
    1381            0 :         gcc_unreachable ();
    1382              : 
    1383          115 :       if (matches)
    1384              :         return boolean_true_node;
    1385              :       else
    1386          106 :         return boolean_false_node;
    1387              :     }
    1388              : 
    1389           26 :   if (kind == REFLECT_BASE)
    1390              :     {
    1391            5 :       gcc_assert (TREE_CODE (r) == TREE_BINFO);
    1392            5 :       tree c = direct_base_derived_binfo (r);
    1393              : 
    1394            5 :       tree base_binfo;
    1395           15 :       for (unsigned ix = 0; BINFO_BASE_ITERATE (c, ix, base_binfo); ix++)
    1396           15 :         if (base_binfo == r)
    1397              :           {
    1398            5 :             tree access = BINFO_BASE_ACCESS (c, ix);
    1399            5 :             if (access == expected_access)
    1400              :               return boolean_true_node;
    1401              :             else
    1402            0 :               return boolean_false_node;
    1403              :           }
    1404            0 :       gcc_unreachable ();
    1405              :     }
    1406              : 
    1407           21 :   return boolean_false_node;
    1408              : }
    1409              : 
    1410              : /* Process std::meta::is_public.
    1411              :    Returns: true if r represents either:
    1412              :    - a class member or unnamed bit-field that is public or
    1413              :    - a direct base class relationship (D, B) for which
    1414              :    B is a public base class of D.
    1415              :    Otherwise, false.  */
    1416              : 
    1417              : static tree
    1418           86 : eval_is_public (tree r, reflect_kind kind)
    1419              : {
    1420            0 :   return eval_is_expected_access (r, kind, access_public_node);
    1421              : }
    1422              : 
    1423              : /* Process std::meta::is_protected.
    1424              :    Returns: true if r represents either:
    1425              :    - a class member or unnamed bit-field that is protected, or
    1426              :    - a direct base class relationship (D, B) for which
    1427              :    B is a protected base class of D.
    1428              :    Otherwise, false.  */
    1429              : 
    1430              : static tree
    1431           69 : eval_is_protected (tree r, reflect_kind kind)
    1432              : {
    1433            0 :   return eval_is_expected_access (r, kind, access_protected_node);
    1434              : }
    1435              : 
    1436              : /* Process std::meta::is_private
    1437              :    Returns: true if r represents either:
    1438              :    - a class member or unnamed bit-field that is private, or
    1439              :    - a direct base class relationship (D, B) for which
    1440              :    B is a private base class of D.
    1441              :    Otherwise, false.  */
    1442              : 
    1443              : static tree
    1444           64 : eval_is_private (tree r, reflect_kind kind)
    1445              : {
    1446            0 :   return eval_is_expected_access (r, kind, access_private_node);
    1447              : }
    1448              : 
    1449              : /* Process std::meta::is_virtual.
    1450              :    Returns: true if r represents either a virtual member function or a direct
    1451              :    base class relationship (D,B) for which B is a virtual base class of D.
    1452              :    Otherwise, false.  */
    1453              : 
    1454              : static tree
    1455           17 : eval_is_virtual (tree r, reflect_kind kind)
    1456              : {
    1457           17 :   r = maybe_get_first_fn (r);
    1458           17 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_VIRTUAL_P (r))
    1459           11 :     return boolean_true_node;
    1460              : 
    1461            8 :   if (kind == REFLECT_BASE && BINFO_VIRTUAL_P (r))
    1462            1 :     return boolean_true_node;
    1463              : 
    1464            5 :   return boolean_false_node;
    1465              : }
    1466              : 
    1467              : /* Process std::meta::is_pure_virtual.
    1468              :    Returns: true if r represents a member function that is pure virtual.
    1469              :    Otherwise, false.  */
    1470              : 
    1471              : static tree
    1472           14 : eval_is_pure_virtual (tree r)
    1473              : {
    1474           14 :   r = maybe_get_first_fn (r);
    1475           14 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (r))
    1476            3 :     return boolean_true_node;
    1477              :   else
    1478           11 :     return boolean_false_node;
    1479              : }
    1480              : 
    1481              : /* Helper function for eval_is_override, return true if FNDECL in TYPE
    1482              :    overrides another function.  */
    1483              : 
    1484              : static bool
    1485           21 : is_override (tree type, tree fndecl)
    1486              : {
    1487           21 :   tree binfo = TYPE_BINFO (type), base_binfo;
    1488              : 
    1489           22 :   for (unsigned ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    1490              :     {
    1491           10 :       tree basetype = BINFO_TYPE (base_binfo);
    1492           10 :       if (TYPE_POLYMORPHIC_P (basetype))
    1493              :         {
    1494           10 :           if (look_for_overrides_here (basetype, fndecl))
    1495              :             return true;
    1496            1 :           if (is_override (basetype, fndecl))
    1497              :             return true;
    1498              :         }
    1499              :     }
    1500              :   return false;
    1501              : }
    1502              : 
    1503              : /* Process std::meta::is_override.
    1504              :    Returns: true if r represents a member function that overrides another
    1505              :    member function.  Otherwise, false.  */
    1506              : 
    1507              : static tree
    1508           70 : eval_is_override (tree r)
    1509              : {
    1510           70 :   r = maybe_get_first_fn (r);
    1511           70 :   if (TREE_CODE (r) == FUNCTION_DECL
    1512           27 :       && DECL_VIRTUAL_P (r)
    1513           20 :       && !DECL_STATIC_FUNCTION_P (r)
    1514           90 :       && is_override (DECL_CONTEXT (r), r))
    1515            9 :     return boolean_true_node;
    1516           61 :   return boolean_false_node;
    1517              : }
    1518              : 
    1519              : /* Process std::meta::is_namespace_member.
    1520              :    Returns: true if r represents a namespace member.  Otherwise, false.  */
    1521              : 
    1522              : static tree
    1523           71 : eval_is_namespace_member (tree r)
    1524              : {
    1525           71 :   r = maybe_get_first_fn (r);
    1526           71 :   if (TREE_CODE (r) == CONST_DECL)
    1527              :     {
    1528           11 :       if (UNSCOPED_ENUM_P (DECL_CONTEXT (r)))
    1529            8 :         r = DECL_CONTEXT (r);
    1530              :       else
    1531            3 :         return boolean_false_node;
    1532              :     }
    1533           60 :   else if (TYPE_P (r) && typedef_variant_p (r))
    1534            3 :     r = TYPE_NAME (r);
    1535           68 :   if (r == global_namespace || r == unknown_type_node)
    1536            2 :     return boolean_false_node;
    1537           85 :   if (DECL_P (r) && DECL_NAMESPACE_SCOPE_P (r))
    1538           27 :     return boolean_true_node;
    1539           47 :   else if (TYPE_P (r) && TYPE_NAMESPACE_SCOPE_P (r))
    1540           10 :     return boolean_true_node;
    1541              :   else
    1542           29 :     return boolean_false_node;
    1543              : }
    1544              : 
    1545              : /* Process std::meta::is_nonstatic_data_member.
    1546              :    Returns: true if r represents a non-static data member.
    1547              :    Otherwise, false.  */
    1548              : 
    1549              : static tree
    1550         4703 : eval_is_nonstatic_data_member (const_tree r)
    1551              : {
    1552         4703 :   if (TREE_CODE (r) == FIELD_DECL && !DECL_UNNAMED_BIT_FIELD (r))
    1553          900 :     return boolean_true_node;
    1554              :   else
    1555         3803 :     return boolean_false_node;
    1556              : }
    1557              : 
    1558              : /* Process std::meta::is_static_member.
    1559              :    Returns: true if r represents a static member.
    1560              :    Otherwise, false.  */
    1561              : 
    1562              : static tree
    1563           68 : eval_is_static_member (tree r)
    1564              : {
    1565           68 :   r = maybe_get_first_fn (r);
    1566           68 :   r = STRIP_TEMPLATE (r);
    1567           68 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (r))
    1568            4 :     return boolean_true_node;
    1569           64 :   else if (VAR_P (r) && DECL_CLASS_SCOPE_P (r))
    1570            1 :     return boolean_true_node;
    1571              :   else
    1572           63 :     return boolean_false_node;
    1573              : }
    1574              : 
    1575              : /* Process std::meta::is_base.
    1576              :    Returns: true if r represents a direct base class relationship.
    1577              :    Otherwise, false.  */
    1578              : 
    1579              : static tree
    1580          100 : eval_is_base (tree r, reflect_kind kind)
    1581              : {
    1582          100 :   if (kind == REFLECT_BASE)
    1583              :     {
    1584           53 :       gcc_assert (TREE_CODE (r) == TREE_BINFO);
    1585           53 :       return boolean_true_node;
    1586              :     }
    1587              :   else
    1588           47 :     return boolean_false_node;
    1589              : }
    1590              : 
    1591              : /* Process std::meta::has_default_member_initializer.
    1592              :    Returns: true if r represents a non-static data member that has a default
    1593              :    member initializer.  Otherwise, false.  */
    1594              : 
    1595              : static tree
    1596           64 : eval_has_default_member_initializer (const_tree r)
    1597              : {
    1598           64 :   if (TREE_CODE (r) == FIELD_DECL
    1599            5 :       && !DECL_UNNAMED_BIT_FIELD (r)
    1600           69 :       && DECL_INITIAL (r) != NULL_TREE)
    1601            2 :     return boolean_true_node;
    1602              :   else
    1603           62 :     return boolean_false_node;
    1604              : }
    1605              : 
    1606              : /* Process std::meta::has_static_storage_duration.
    1607              :    Returns: true if r represents an object or variable that has static
    1608              :    storage duration.  Otherwise, false.  */
    1609              : 
    1610              : static tree
    1611          139 : eval_has_static_storage_duration (const_tree r, reflect_kind kind)
    1612              : {
    1613          139 :   if (eval_is_variable (r, kind) == boolean_true_node
    1614          139 :       && decl_storage_duration (const_cast<tree> (r)) == dk_static)
    1615           49 :     return boolean_true_node;
    1616              :   /* This includes DECL_NTTP_OBJECT_P objects.  */
    1617          180 :   else if (eval_is_object (kind) == boolean_true_node)
    1618              :     return boolean_true_node;
    1619              :   else
    1620           85 :     return boolean_false_node;
    1621              : }
    1622              : 
    1623              : /* Process std::meta::has_thread_storage_duration.
    1624              :    Returns: true if r represents an object or variable that has thread
    1625              :    storage duration.  Otherwise, false.  */
    1626              : 
    1627              : static tree
    1628           70 : eval_has_thread_storage_duration (const_tree r, reflect_kind kind)
    1629              : {
    1630           70 :   if (eval_is_variable (r, kind) == boolean_true_node
    1631           70 :       && decl_storage_duration (const_cast<tree> (r)) == dk_thread)
    1632            4 :     return boolean_true_node;
    1633              :   else
    1634           66 :     return boolean_false_node;
    1635              : }
    1636              : 
    1637              : /* Process std::meta::has_automatic_storage_duration.
    1638              :    Returns: true if r represents an object or variable that has automatic
    1639              :    storage duration.  Otherwise, false.  */
    1640              : 
    1641              : static tree
    1642           70 : eval_has_automatic_storage_duration (const_tree r, reflect_kind kind)
    1643              : {
    1644           70 :   if (eval_is_variable (r, kind) == boolean_true_node
    1645           70 :       && decl_storage_duration (const_cast<tree> (r)) == dk_auto)
    1646            4 :     return boolean_true_node;
    1647              :   else
    1648           66 :     return boolean_false_node;
    1649              : }
    1650              : 
    1651              : /* Process std::meta::is_mutable_member.
    1652              :    Returns: true if r represents a mutable non-static data member.
    1653              :    Otherwise, false.  */
    1654              : 
    1655              : static tree
    1656           64 : eval_is_mutable_member (tree r)
    1657              : {
    1658           64 :   if (TREE_CODE (r) == FIELD_DECL
    1659            6 :       && !DECL_UNNAMED_BIT_FIELD (r)
    1660           70 :       && DECL_MUTABLE_P (r))
    1661            3 :     return boolean_true_node;
    1662              :   else
    1663           61 :     return boolean_false_node;
    1664              : }
    1665              : 
    1666              : /* Process std::meta::is_template.
    1667              :    Returns: true if r represents a function template, class template, variable
    1668              :    template, alias template, or concept.  Otherwise, false.  */
    1669              : 
    1670              : static tree
    1671         2153 : eval_is_template (tree r)
    1672              : {
    1673         2153 :   if (eval_is_function_template (r) == boolean_true_node
    1674         2089 :       || eval_is_class_template (r) == boolean_true_node
    1675         1922 :       || eval_is_variable_template (r) == boolean_true_node
    1676         1879 :       || eval_is_alias_template (r) == boolean_true_node
    1677         4004 :       || eval_is_concept (r) == boolean_true_node)
    1678              :     return boolean_true_node;
    1679              :   else
    1680         1770 :     return boolean_false_node;
    1681              : }
    1682              : 
    1683              : /* Process std::meta::is_function_parameter.
    1684              :    Returns: true if r represents a function parameter.  Otherwise, false.  */
    1685              : 
    1686              : static tree
    1687         1924 : eval_is_function_parameter (const_tree r, reflect_kind kind)
    1688              : {
    1689         1924 :   if (kind == REFLECT_PARM)
    1690              :     {
    1691          344 :       gcc_checking_assert (TREE_CODE (r) == PARM_DECL);
    1692          344 :       return boolean_true_node;
    1693              :     }
    1694              :   else
    1695         1580 :     return boolean_false_node;
    1696              : }
    1697              : 
    1698              : /* Process std::meta::is_data_member_spec.
    1699              :    Returns: true if r represents a data member description.
    1700              :    Otherwise, false.  */
    1701              : 
    1702              : static tree
    1703           94 : eval_is_data_member_spec (const_tree r, reflect_kind kind)
    1704              : {
    1705           94 :   if (kind == REFLECT_DATA_MEMBER_SPEC)
    1706              :     {
    1707           48 :       gcc_checking_assert (TREE_CODE (r) == TREE_VEC);
    1708           48 :       return boolean_true_node;
    1709              :     }
    1710              :   else
    1711           46 :     return boolean_false_node;
    1712              : }
    1713              : 
    1714              : /* Process std::meta::is_explicit_object_parameter.
    1715              :    Returns: true if r represents a function parameter that is an explicit
    1716              :    object parameter.  Otherwise, false.  */
    1717              : 
    1718              : static tree
    1719           73 : eval_is_explicit_object_parameter (const_tree r, reflect_kind kind)
    1720              : {
    1721           73 :   if (eval_is_function_parameter (r, kind) == boolean_true_node
    1722            8 :       && r == DECL_ARGUMENTS (DECL_CONTEXT (r))
    1723           75 :       && DECL_XOBJ_MEMBER_FUNCTION_P (DECL_CONTEXT (r)))
    1724              :     return boolean_true_node;
    1725              :   else
    1726           71 :     return boolean_false_node;
    1727              : }
    1728              : 
    1729              : /* Process std::meta::has_default_argument.
    1730              :    Returns: If r represents a parameter P of a function F, then:
    1731              :    -- If F is a specialization of a templated function T, then true if there
    1732              :       exists a declaration D of T that precedes some point in the evaluation
    1733              :       context and D specifies a default argument for the parameter of T
    1734              :       corresponding to P.  Otherwise, false.
    1735              :    -- Otherwise, if there exists a declaration D of F that precedes some
    1736              :       point in the evaluation context and D specifies a default argument
    1737              :       for P, then true.
    1738              :    Otherwise, false.  */
    1739              : 
    1740              : static tree
    1741           79 : eval_has_default_argument (tree r, reflect_kind kind)
    1742              : {
    1743           79 :   if (eval_is_function_parameter (r, kind) == boolean_false_node)
    1744              :     return boolean_false_node;
    1745           30 :   r = maybe_update_function_parm (r);
    1746           30 :   if (DECL_HAS_DEFAULT_ARGUMENT_P (r))
    1747            4 :     return boolean_true_node;
    1748           26 :   tree fn = DECL_CONTEXT (r);
    1749           26 :   tree args = FUNCTION_FIRST_USER_PARM (fn);
    1750           26 :   tree types = FUNCTION_FIRST_USER_PARMTYPE (fn);
    1751           66 :   while (r != args)
    1752              :     {
    1753           14 :       args = DECL_CHAIN (args);
    1754           14 :       types = TREE_CHAIN (types);
    1755              :     }
    1756           26 :   if (TREE_PURPOSE (types))
    1757           17 :     return boolean_true_node;
    1758              :   else
    1759            9 :     return boolean_false_node;
    1760              : }
    1761              : 
    1762              : /* Process std::meta::has_ellipsis_parameter.
    1763              :    Returns: true if r represents a function or function type that has an
    1764              :    ellipsis in its parameter-type-list.  Otherwise, false.  */
    1765              : 
    1766              : static tree
    1767           72 : eval_has_ellipsis_parameter (tree r)
    1768              : {
    1769           72 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    1770           72 :   if (TREE_CODE (r) == FUNCTION_DECL)
    1771           16 :     r = TREE_TYPE (r);
    1772           72 :   if (FUNC_OR_METHOD_TYPE_P (r) && stdarg_p (r))
    1773           12 :     return boolean_true_node;
    1774              :   else
    1775           60 :     return boolean_false_node;
    1776              : }
    1777              : 
    1778              : /* Process std::meta::is_deleted.
    1779              :    Returns: true if r represents a function that is deleted.
    1780              :    Otherwise, false.  */
    1781              : 
    1782              : static tree
    1783           82 : eval_is_deleted (tree r)
    1784              : {
    1785           82 :   r = maybe_get_first_fn (r);
    1786           82 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_MAYBE_DELETED (r))
    1787              :     {
    1788            2 :       ++function_depth;
    1789            2 :       maybe_synthesize_method (r);
    1790            2 :       --function_depth;
    1791              :     }
    1792           82 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_DELETED_FN (r))
    1793           20 :     return boolean_true_node;
    1794              :   else
    1795           62 :     return boolean_false_node;
    1796              : }
    1797              : 
    1798              : /* Process std::meta::is_defaulted.
    1799              :    Returns: true if r represents a function that is defaulted.
    1800              :    Otherwise, false.  */
    1801              : 
    1802              : static tree
    1803          347 : eval_is_defaulted (tree r)
    1804              : {
    1805          347 :   r = maybe_get_first_fn (r);
    1806          347 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_DEFAULTED_FN (r))
    1807          275 :     return boolean_true_node;
    1808              :   else
    1809           72 :     return boolean_false_node;
    1810              : }
    1811              : 
    1812              : /* Process std::meta::is_user_provided.
    1813              :    Returns: true if r represents a function that is user-provided.
    1814              :    Otherwise, false.  */
    1815              : 
    1816              : static tree
    1817          106 : eval_is_user_provided (tree r)
    1818              : {
    1819          106 :   r = maybe_get_first_fn (r);
    1820          106 :   if (TREE_CODE (r) == FUNCTION_DECL && user_provided_p (r))
    1821           12 :     return boolean_true_node;
    1822              :   else
    1823           94 :     return boolean_false_node;
    1824              : }
    1825              : 
    1826              : /* Process std::meta::is_user_declared.
    1827              :    Returns: true if r represents a function that is user-declared.
    1828              :    Otherwise, false.  */
    1829              : 
    1830              : static tree
    1831          106 : eval_is_user_declared (tree r)
    1832              : {
    1833          106 :   r = maybe_get_first_fn (r);
    1834          106 :   if (TREE_CODE (r) == FUNCTION_DECL && !DECL_ARTIFICIAL (r))
    1835           40 :     return boolean_true_node;
    1836              :   else
    1837           66 :     return boolean_false_node;
    1838              : }
    1839              : 
    1840              : /* Process std::meta::is_explicit.
    1841              :    Returns: true if r represents
    1842              :    a member function that is declared explicit.
    1843              :    Otherwise, false.
    1844              :    If r represents a member function template
    1845              :    that is declared explicit, is_explicit(r)
    1846              :    is still false because in general such queries
    1847              :    for templates cannot be answered.  */
    1848              : 
    1849              : static tree
    1850           22 : eval_is_explicit (tree r)
    1851              : {
    1852           22 :   r = maybe_get_first_fn (r);
    1853              : 
    1854           22 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_NONCONVERTING_P (r))
    1855            4 :     return boolean_true_node;
    1856              :   else
    1857           18 :     return boolean_false_node;
    1858              : }
    1859              : 
    1860              : /* Process std::meta::is_bit_field.
    1861              :    Returns: true if r represents a bit-field, or if r represents a data member
    1862              :    description (T,N,A,W,NUA) for which W is not _|_.  Otherwise, false.  */
    1863              : 
    1864              : static tree
    1865          110 : eval_is_bit_field (const_tree r, reflect_kind kind)
    1866              : {
    1867          110 :   if (TREE_CODE (r) == FIELD_DECL && DECL_C_BIT_FIELD (r))
    1868           36 :     return boolean_true_node;
    1869           74 :   else if (kind == REFLECT_DATA_MEMBER_SPEC && TREE_VEC_ELT (r, 3))
    1870            2 :     return boolean_true_node;
    1871              :   else
    1872           72 :     return boolean_false_node;
    1873              : }
    1874              : 
    1875              : /* Process std::meta::is_enumerator.
    1876              :    Returns: true if r represents an enumerator.  Otherwise, false.  */
    1877              : 
    1878              : static tree
    1879         1223 : eval_is_enumerator (const_tree r)
    1880              : {
    1881              :   /* This doesn't check !DECL_TEMPLATE_PARM_P because such CONST_DECLs
    1882              :      would already have been rejected in get_reflection.  */
    1883          652 :   if (TREE_CODE (r) == CONST_DECL)
    1884            4 :     return boolean_true_node;
    1885              :   else
    1886         1146 :     return boolean_false_node;
    1887              : }
    1888              : 
    1889              : /* Get the linkage name for T, or NULL_TREE for types with no name
    1890              :    or for typedefs.  */
    1891              : 
    1892              : static tree
    1893           52 : reflection_type_linkage_name (tree t)
    1894              : {
    1895           52 :   if (OVERLOAD_TYPE_P (t) && !typedef_variant_p (t))
    1896           36 :     return TYPE_NAME (t);
    1897              :   return NULL_TREE;
    1898              : }
    1899              : 
    1900              : /* Process std::meta::has_internal_linkage.
    1901              :    Returns: true if r represents a variable, function, type, template, or
    1902              :    namespace whose name has internal linkage.  Otherwise, false.  */
    1903              : 
    1904              : static tree
    1905           63 : eval_has_internal_linkage (tree r, reflect_kind kind)
    1906              : {
    1907           63 :   if (eval_is_variable (r, kind) == boolean_false_node
    1908           44 :       && eval_is_function (r) == boolean_false_node
    1909           36 :       && eval_is_type (r) == boolean_false_node
    1910           23 :       && eval_is_template (r) == boolean_false_node
    1911           81 :       && eval_is_namespace (r) == boolean_false_node)
    1912              :     return boolean_false_node;
    1913           52 :   r = maybe_get_first_fn (r);
    1914           52 :   r = STRIP_TEMPLATE (r);
    1915           52 :   if (TYPE_P (r))
    1916              :     {
    1917           13 :       r = reflection_type_linkage_name (r);
    1918           13 :       if (!r)
    1919              :         return boolean_false_node;
    1920              :     }
    1921           48 :   if (decl_linkage (r) == lk_internal)
    1922            8 :     return boolean_true_node;
    1923              :   else
    1924           40 :     return boolean_false_node;
    1925              : }
    1926              : 
    1927              : /* Process std::meta::has_module_linkage.
    1928              :    Returns: true if r represents a variable, function, type, template, or
    1929              :    namespace whose name has module linkage.  Otherwise, false.  */
    1930              : 
    1931              : static tree
    1932           63 : eval_has_module_linkage (tree r, reflect_kind kind)
    1933              : {
    1934           63 :   if (eval_is_variable (r, kind) == boolean_false_node
    1935           44 :       && eval_is_function (r) == boolean_false_node
    1936           36 :       && eval_is_type (r) == boolean_false_node
    1937           23 :       && eval_is_template (r) == boolean_false_node
    1938           81 :       && eval_is_namespace (r) == boolean_false_node)
    1939              :     return boolean_false_node;
    1940           52 :   r = maybe_get_first_fn (r);
    1941           52 :   r = STRIP_TEMPLATE (r);
    1942           52 :   if (TYPE_P (r))
    1943              :     {
    1944           13 :       r = reflection_type_linkage_name (r);
    1945           13 :       if (!r)
    1946              :         return boolean_false_node;
    1947              :     }
    1948           48 :   if (decl_linkage (r) == lk_external
    1949           36 :       && DECL_LANG_SPECIFIC (r)
    1950           18 :       && DECL_MODULE_ATTACH_P (r)
    1951           49 :       && !DECL_MODULE_EXPORT_P (r))
    1952            1 :     return boolean_true_node;
    1953              :   else
    1954           47 :     return boolean_false_node;
    1955              : }
    1956              : 
    1957              : /* Process std::meta::has_external_linkage.
    1958              :    Returns: true if r represents a variable, function, type, template, or
    1959              :    namespace whose name has external linkage.  Otherwise, false.  */
    1960              : 
    1961              : static tree
    1962           63 : eval_has_external_linkage (tree r, reflect_kind kind)
    1963              : {
    1964           63 :   if (eval_is_variable (r, kind) == boolean_false_node
    1965           44 :       && eval_is_function (r) == boolean_false_node
    1966           36 :       && eval_is_type (r) == boolean_false_node
    1967           23 :       && eval_is_template (r) == boolean_false_node
    1968           81 :       && eval_is_namespace (r) == boolean_false_node)
    1969              :     return boolean_false_node;
    1970           52 :   r = maybe_get_first_fn (r);
    1971           52 :   r = STRIP_TEMPLATE (r);
    1972           52 :   if (TYPE_P (r))
    1973              :     {
    1974           13 :       r = reflection_type_linkage_name (r);
    1975           13 :       if (!r)
    1976              :         return boolean_false_node;
    1977              :     }
    1978           48 :   if (decl_linkage (r) == lk_external
    1979           48 :       && !(DECL_LANG_SPECIFIC (r)
    1980           18 :            && DECL_MODULE_ATTACH_P (r)
    1981            1 :            && !DECL_MODULE_EXPORT_P (r)))
    1982           35 :     return boolean_true_node;
    1983              :   else
    1984           13 :     return boolean_false_node;
    1985              : }
    1986              : 
    1987              : /* Process std::meta::has_c_language_linkage
    1988              :    Returns: true if r represents a variable, function, or function type with
    1989              :    C language linkage. Otherwise, false.  */
    1990              : 
    1991              : static tree
    1992           66 : eval_has_c_language_linkage (tree r, reflect_kind kind)
    1993              : {
    1994           66 :   if (eval_is_variable (r, kind) == boolean_false_node
    1995           48 :       && eval_is_function (r) == boolean_false_node
    1996          103 :       && eval_is_function_type (r) == boolean_false_node)
    1997              :     return boolean_false_node;
    1998           29 :   r = maybe_get_first_fn (r);
    1999           29 :   r = STRIP_TEMPLATE (r);
    2000           29 :   if (TYPE_P (r))
    2001              :     {
    2002            0 :       r = reflection_type_linkage_name (r);
    2003            0 :       if (!r)
    2004              :         return boolean_false_node;
    2005              :     }
    2006           29 :   if (decl_linkage (r) != lk_none && DECL_LANGUAGE (r) == lang_c)
    2007            4 :     return boolean_true_node;
    2008              :   else
    2009           25 :     return boolean_false_node;
    2010              : }
    2011              : 
    2012              : /* Process std::meta::has_linkage.
    2013              :    Returns: true if r represents a variable, function, type, template, or
    2014              :    namespace whose name has any linkage.  Otherwise, false.  */
    2015              : 
    2016              : static tree
    2017           62 : eval_has_linkage (tree r, reflect_kind kind)
    2018              : {
    2019           62 :   if (eval_is_variable (r, kind) == boolean_false_node
    2020           44 :       && eval_is_function (r) == boolean_false_node
    2021           36 :       && eval_is_type (r) == boolean_false_node
    2022           23 :       && eval_is_template (r) == boolean_false_node
    2023           80 :       && eval_is_namespace (r) == boolean_false_node)
    2024              :     return boolean_false_node;
    2025           51 :   r = maybe_get_first_fn (r);
    2026           51 :   r = STRIP_TEMPLATE (r);
    2027           51 :   if (TYPE_P (r))
    2028              :     {
    2029           13 :       r = reflection_type_linkage_name (r);
    2030           13 :       if (!r)
    2031              :         return boolean_false_node;
    2032              :     }
    2033           47 :   if (decl_linkage (r) != lk_none)
    2034           43 :     return boolean_true_node;
    2035              :   else
    2036            4 :     return boolean_false_node;
    2037              : }
    2038              : 
    2039              : /* Process std::meta::is_complete_type.
    2040              :    Returns: true if is_type(r) is true and there is some point in the
    2041              :    evaluation context from which the type represented by dealias(r) is
    2042              :    not an incomplete type.  Otherwise, false.  */
    2043              : 
    2044              : static tree
    2045          190 : eval_is_complete_type (const_tree r)
    2046              : {
    2047          190 :   if (eval_is_type (r) == boolean_true_node)
    2048              :     {
    2049          154 :       complete_type (const_cast<tree> (r));
    2050          154 :       if (COMPLETE_TYPE_P (r))
    2051          129 :         return boolean_true_node;
    2052              :     }
    2053           61 :   return boolean_false_node;
    2054              : }
    2055              : 
    2056              : /* Process std::meta::is_enumerable_type.
    2057              :    A type T is enumerable from a point P if either
    2058              :    -- T is a class type complete at point P or
    2059              :    -- T is an enumeration type defined by a declaration D such that D is
    2060              :       reachable from P but P does not occur within an enum-specifier of D.
    2061              :   Returns: true if dealias(r) represents a type that is enumerable from some
    2062              :   point in the evaluation context.  Otherwise, false.  */
    2063              : 
    2064              : static tree
    2065          176 : eval_is_enumerable_type (const_tree r)
    2066              : {
    2067          176 :   if (CLASS_TYPE_P (r))
    2068              :     {
    2069            7 :       complete_type (const_cast<tree> (r));
    2070            7 :       if (COMPLETE_TYPE_P (r))
    2071            5 :         return boolean_true_node;
    2072              :      }
    2073          169 :   else if (TREE_CODE (r) == ENUMERAL_TYPE)
    2074              :     {
    2075          163 :       r = TYPE_MAIN_VARIANT (r);
    2076          163 :       if (!ENUM_IS_OPAQUE (r) && !ENUM_BEING_DEFINED_P (r))
    2077           97 :         return boolean_true_node;
    2078              :     }
    2079           74 :   return boolean_false_node;
    2080              : }
    2081              : 
    2082              : /* Process std::meta::is_annotation.
    2083              :    Returns: true if r represents an annotation.  Otherwise, false.  */
    2084              : 
    2085              : static tree
    2086         2863 : eval_is_annotation (const_tree r, reflect_kind kind)
    2087              : {
    2088         2863 :   if (kind == REFLECT_ANNOTATION)
    2089              :     {
    2090          446 :       gcc_assert (TREE_CODE (r) == TREE_LIST);
    2091          446 :       return boolean_true_node;
    2092              :     }
    2093              :   else
    2094         2417 :     return boolean_false_node;
    2095              : }
    2096              : 
    2097              : /* Process std::meta::is_conversion_function.
    2098              :    Returns: true if r represents a function that is a conversion function.
    2099              :    Otherwise, false.  */
    2100              : 
    2101              : static tree
    2102          283 : eval_is_conversion_function (tree r)
    2103              : {
    2104          283 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2105          283 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_CONV_FN_P (r))
    2106            5 :     return boolean_true_node;
    2107              :   else
    2108          278 :     return boolean_false_node;
    2109              : }
    2110              : 
    2111              : /* Process std::meta::is_operator_function.
    2112              :    Returns: true if r represents a function that is an operator function.
    2113              :    Otherwise, false.  */
    2114              : 
    2115              : static tree
    2116          674 : eval_is_operator_function (tree r)
    2117              : {
    2118          674 :   r = maybe_get_first_fn (r);
    2119              : 
    2120          674 :   if (TREE_CODE (r) == FUNCTION_DECL
    2121          535 :       && DECL_OVERLOADED_OPERATOR_P (r)
    2122          850 :       && !DECL_CONV_FN_P (r))
    2123          171 :     return boolean_true_node;
    2124              :   else
    2125          503 :     return boolean_false_node;
    2126              : }
    2127              : 
    2128              : /* Process std::meta::is_literal_operator.
    2129              :    Returns: true if r represents a function that is a literal operator.
    2130              :    Otherwise, false.  */
    2131              : 
    2132              : static tree
    2133           15 : eval_is_literal_operator (const_tree r)
    2134              : {
    2135              :   /* No MAYBE_BASELINK_FUNCTIONS here because a literal operator
    2136              :      must be a non-member function.  */
    2137           15 :   if (TREE_CODE (r) == FUNCTION_DECL && UDLIT_OPER_P (DECL_NAME (r)))
    2138            1 :     return boolean_true_node;
    2139              :   else
    2140           14 :     return boolean_false_node;
    2141              : }
    2142              : 
    2143              : /* Process std::meta::is_special_member_function.
    2144              :    Returns: true if r represents a function that is a special member function.
    2145              :    Otherwise, false.  */
    2146              : 
    2147              : static tree
    2148          810 : eval_is_special_member_function (tree r)
    2149              : {
    2150          810 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2151          810 :   if (TREE_CODE (r) == FUNCTION_DECL && special_memfn_p (r) != sfk_none)
    2152          331 :     return boolean_true_node;
    2153              :   else
    2154          479 :     return boolean_false_node;
    2155              : }
    2156              : 
    2157              : /* Process std::meta::is_constructor.
    2158              :    Returns: true if r represents a function that is a constructor.
    2159              :    Otherwise, false.  */
    2160              : 
    2161              : static tree
    2162         1192 : eval_is_constructor (tree r)
    2163              : {
    2164         1192 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2165         2030 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (r))
    2166          150 :     return boolean_true_node;
    2167              :   else
    2168         1042 :     return boolean_false_node;
    2169              : }
    2170              : 
    2171              : /* Process std::meta::is_default_constructor.
    2172              :    Returns: true if r represents a function that is a default constructor.
    2173              :    Otherwise, false.  */
    2174              : 
    2175              : static tree
    2176          371 : eval_is_default_constructor (tree r)
    2177              : {
    2178          371 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2179          371 :   if (TREE_CODE (r) == FUNCTION_DECL && default_ctor_p (r))
    2180           41 :     return boolean_true_node;
    2181              :   else
    2182          330 :     return boolean_false_node;
    2183              : }
    2184              : 
    2185              : /* Process std::meta::is_copy_constructor.
    2186              :    Returns: true if r represents a function that is a copy constructor.
    2187              :    Otherwise, false.  */
    2188              : 
    2189              : static tree
    2190          380 : eval_is_copy_constructor (tree r)
    2191              : {
    2192          380 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2193          640 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_COPY_CONSTRUCTOR_P (r))
    2194           43 :     return boolean_true_node;
    2195              :   else
    2196          337 :     return boolean_false_node;
    2197              : }
    2198              : 
    2199              : /* Process std::meta::is_move_constructor.
    2200              :    Returns: true if r represents a function that is a move constructor.
    2201              :    Otherwise, false.  */
    2202              : 
    2203              : static tree
    2204          359 : eval_is_move_constructor (tree r)
    2205              : {
    2206          359 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2207          600 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_MOVE_CONSTRUCTOR_P (r))
    2208           36 :     return boolean_true_node;
    2209              :   else
    2210          323 :     return boolean_false_node;
    2211              : }
    2212              : 
    2213              : /* Process std::meta::is_assignment.
    2214              :    Returns: true if r represents a function that is an assignment operator.
    2215              :    Otherwise, false.  */
    2216              : 
    2217              : static tree
    2218           10 : eval_is_assignment (tree r)
    2219              : {
    2220           10 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2221           10 :   if (TREE_CODE (r) == FUNCTION_DECL
    2222            7 :       && DECL_ASSIGNMENT_OPERATOR_P (r)
    2223           15 :       && DECL_OVERLOADED_OPERATOR_IS (r, NOP_EXPR))
    2224            3 :     return boolean_true_node;
    2225              :   else
    2226            7 :     return boolean_false_node;
    2227              : }
    2228              : 
    2229              : /* Process std::meta::is_copy_assignment.
    2230              :    Returns: true if r represents a function that is a copy assignment
    2231              :    operator.  Otherwise, false.  */
    2232              : 
    2233              : static tree
    2234          382 : eval_is_copy_assignment (tree r)
    2235              : {
    2236          382 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2237          382 :   if (TREE_CODE (r) == FUNCTION_DECL
    2238          382 :       && special_function_p (r) == sfk_copy_assignment)
    2239           43 :     return boolean_true_node;
    2240              :   else
    2241          339 :     return boolean_false_node;
    2242              : }
    2243              : 
    2244              : /* Process std::meta::is_move_assignment.
    2245              :    Returns: true if r represents a function that is a move assignment
    2246              :    operator.  Otherwise, false.  */
    2247              : 
    2248              : static tree
    2249          376 : eval_is_move_assignment (tree r)
    2250              : {
    2251          376 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2252          376 :   if (TREE_CODE (r) == FUNCTION_DECL
    2253          376 :       && special_function_p (r) == sfk_move_assignment)
    2254           36 :     return boolean_true_node;
    2255              :   else
    2256          340 :     return boolean_false_node;
    2257              : }
    2258              : 
    2259              : /* Process std::meta::is_destructor.
    2260              :    Returns: true if r represents a function that is a destructor.
    2261              :    Otherwise, false.  */
    2262              : 
    2263              : static tree
    2264         1603 : eval_is_destructor (tree r)
    2265              : {
    2266         1603 :   r = maybe_get_first_fn (r);
    2267         1603 :   if (TREE_CODE (r) == FUNCTION_DECL
    2268         1603 :       && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (r))
    2269           97 :     return boolean_true_node;
    2270              :   else
    2271         1506 :     return boolean_false_node;
    2272              : }
    2273              : 
    2274              : /* Process std::meta::is_conversion_function_template.
    2275              :    Returns: true if r represents a conversion function template.
    2276              :    Otherwise, false.  */
    2277              : 
    2278              : static tree
    2279           46 : eval_is_conversion_function_template (tree r)
    2280              : {
    2281           46 :   r = maybe_get_first_fn (r);
    2282              : 
    2283           46 :   if (DECL_FUNCTION_TEMPLATE_P (r) && DECL_CONV_FN_P (r))
    2284            4 :     return boolean_true_node;
    2285              :   else
    2286           42 :     return boolean_false_node;
    2287              : }
    2288              : 
    2289              : /* Process std::meta::is_operator_function_template.
    2290              :    Returns: true if r represents an operator function template.
    2291              :    Otherwise, false.  */
    2292              : 
    2293              : static tree
    2294          188 : eval_is_operator_function_template (tree r)
    2295              : {
    2296          188 :   r = maybe_get_first_fn (r);
    2297              : 
    2298          188 :   if (DECL_FUNCTION_TEMPLATE_P (r))
    2299              :     {
    2300           76 :       r = STRIP_TEMPLATE (r);
    2301           76 :       if (DECL_OVERLOADED_OPERATOR_P (r) && !DECL_CONV_FN_P (r))
    2302           58 :         return boolean_true_node;
    2303              :     }
    2304              : 
    2305          130 :   return boolean_false_node;
    2306              : }
    2307              : 
    2308              : /* Process std::meta::is_literal_operator_template.
    2309              :    Returns: true if r represents a literal operator template.
    2310              :    Otherwise, false.  */
    2311              : 
    2312              : static tree
    2313           15 : eval_is_literal_operator_template (tree r)
    2314              : {
    2315              :   /* No MAYBE_BASELINK_FUNCTIONS here because a literal operator
    2316              :      template must be a non-member function template.  */
    2317           15 :   r = OVL_FIRST (r);
    2318              : 
    2319           15 :   if (DECL_FUNCTION_TEMPLATE_P (r) && UDLIT_OPER_P (DECL_NAME (r)))
    2320            1 :     return boolean_true_node;
    2321              :   else
    2322           14 :     return boolean_false_node;
    2323              : }
    2324              : 
    2325              : /* Process std::meta::is_constructor_template.
    2326              :    Returns: true if r represents a function that is an operator function
    2327              :    template.  Otherwise, false.  */
    2328              : 
    2329              : static tree
    2330           46 : eval_is_constructor_template (tree r)
    2331              : {
    2332           46 :   r = maybe_get_first_fn (r);
    2333              : 
    2334           46 :   if (DECL_FUNCTION_TEMPLATE_P (r) && DECL_CONSTRUCTOR_P (r))
    2335            4 :     return boolean_true_node;
    2336              :   else
    2337           42 :     return boolean_false_node;
    2338              : }
    2339              : 
    2340              : /* Process std::meta::operator_of.
    2341              :    Returns: The value of the enumerator from the operators whose corresponding
    2342              :    operator-function-id is the unqualified name of the entity represented by
    2343              :    r.
    2344              :    Throws: meta::exception unless r represents an operator function or
    2345              :    operator function template.  */
    2346              : 
    2347              : static tree
    2348          240 : eval_operator_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2349              :                   bool *non_constant_p, tree *jump_target, tree ret_type,
    2350              :                   tree fun)
    2351              : {
    2352          240 :   if (eval_is_operator_function (r) == boolean_false_node
    2353          240 :       && eval_is_operator_function_template (r) == boolean_false_node)
    2354           90 :     return throw_exception (loc, ctx,
    2355              :                             "reflection does not represent an operator "
    2356              :                             "function or operator function template",
    2357           90 :                             fun, non_constant_p, jump_target);
    2358          150 :   r = maybe_get_first_fn (r);
    2359          150 :   r = STRIP_TEMPLATE (r);
    2360          150 :   maybe_init_meta_operators (loc);
    2361          150 :   int i = IDENTIFIER_ASSIGN_OP_P (DECL_NAME (r)) ? 1 : 0;
    2362          150 :   int j = IDENTIFIER_CP_INDEX (DECL_NAME (r));
    2363          150 :   return build_int_cst (ret_type, meta_operators[i][j]);
    2364              : }
    2365              : 
    2366              : /* Helper to build a string literal containing '\0' terminated NAME.
    2367              :    ELT_TYPE must be either char_type_node or char8_type_node, and the
    2368              :    function takes care of converting the name from SOURCE_CHARSET
    2369              :    to ordinary literal charset resp. UTF-8.  Returns the string
    2370              :    literal, or NULL_TREE if the conversion failed.  */
    2371              : 
    2372              : static tree
    2373         2318 : get_string_literal (const char *name, tree elt_type)
    2374              : {
    2375         2318 :   cpp_string istr, ostr;
    2376         2318 :   istr.len = strlen (name) + 1;
    2377         2318 :   istr.text = (const unsigned char *) name;
    2378         2318 :   if (!cpp_translate_string (parse_in, &istr, &ostr,
    2379         2318 :                              elt_type == char_type_node
    2380              :                              ? CPP_STRING : CPP_UTF8STRING, false))
    2381              :     return NULL_TREE;
    2382         2316 :   name = (const char *) ostr.text;
    2383         2316 :   tree ret = build_string_literal (strlen (name) + 1, name, elt_type);
    2384         2316 :   free (const_cast <char *> (name));
    2385         2316 :   return ret;
    2386              : }
    2387              : 
    2388              : /* Process std::meta::{,u8}symbol_of.
    2389              :    Returns: A string_view or u8string_view containing the characters of the
    2390              :    operator symbol name corresponding to op, respectively encoded with the
    2391              :    ordinary literal encoding or with UTF-8.
    2392              :    Throws: meta::exception unless the value of op corresponds to one of the
    2393              :    enumerators in operators.  */
    2394              : 
    2395              : static tree
    2396          138 : eval_symbol_of (location_t loc, const constexpr_ctx *ctx, tree expr,
    2397              :                 bool *non_constant_p, tree *jump_target, tree elt_type,
    2398              :                 tree ret_type, tree fun)
    2399              : {
    2400          138 :   maybe_init_meta_operators (loc);
    2401          138 :   if (!tree_fits_uhwi_p (expr))
    2402              :     {
    2403            0 :     fail:
    2404            6 :       return throw_exception (loc, ctx,
    2405              :                               "operators argument is not a valid operator",
    2406            6 :                               fun, non_constant_p, jump_target);
    2407              :     }
    2408          138 :   unsigned HOST_WIDE_INT val = tree_to_uhwi (expr);
    2409          183 :   for (int i = 0; i < 2; ++i)
    2410         5598 :     for (int j = OVL_OP_ERROR_MARK + 1; j < OVL_OP_MAX; ++j)
    2411         5553 :       if (ovl_op_info[i][j].meta_name && meta_operators[i][j] == val)
    2412              :         {
    2413          132 :           const char *name = ovl_op_info[i][j].name;
    2414          132 :           char buf[64];
    2415          132 :           if (const char *sp = strchr (name, ' '))
    2416              :             {
    2417            6 :               memcpy (buf, name, sp - name);
    2418            6 :               strcpy (buf + (sp - name), sp + 1);
    2419            6 :               name = buf;
    2420              :             }
    2421          132 :           tree str = get_string_literal (name, elt_type);
    2422              :           /* Basic character set ought to be better convertible
    2423              :              into ordinary literal character set and must be always
    2424              :              convertible into UTF-8.  */
    2425          132 :           gcc_checking_assert (str);
    2426          132 :           releasing_vec args (make_tree_vector_single (str));
    2427          132 :           tree r = build_special_member_call (NULL_TREE,
    2428              :                                               complete_ctor_identifier,
    2429              :                                               &args, ret_type, LOOKUP_NORMAL,
    2430              :                                               tf_warning_or_error);
    2431          132 :           return build_cplus_new (ret_type, r, tf_warning_or_error);
    2432          132 :         }
    2433            6 :   goto fail;
    2434              : }
    2435              : 
    2436              : /* has-type (exposition only).
    2437              :    Returns: true if r represents a value, annotation, object, variable,
    2438              :    function whose type does not contain an undeduced placeholder type and
    2439              :    that is not a constructor or destructor, enumerator, non-static data
    2440              :    member, unnamed bit-field, direct base class relationship, data member
    2441              :    description, or function parameter.  Otherwise, false.  */
    2442              : 
    2443              : static bool
    2444         1447 : has_type (tree r, reflect_kind kind)
    2445              : {
    2446         1447 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2447         1447 :   if (TREE_CODE (r) == FUNCTION_DECL)
    2448              :     {
    2449          129 :       if (DECL_CONSTRUCTOR_P (r) || DECL_DESTRUCTOR_P (r))
    2450              :         return false;
    2451          111 :       if (undeduced_auto_decl (r))
    2452              :         return false;
    2453              :       return true;
    2454              :     }
    2455         1318 :   if (CONSTANT_CLASS_P (r)
    2456         1110 :       || eval_is_variable (r, kind) == boolean_true_node
    2457          616 :       || eval_is_enumerator (r) == boolean_true_node
    2458          560 :       || TREE_CODE (r) == FIELD_DECL
    2459          488 :       || eval_is_annotation (r, kind) == boolean_true_node
    2460          325 :       || eval_is_function_parameter (r, kind) == boolean_true_node
    2461          284 :       || eval_is_object (kind) == boolean_true_node
    2462          222 :       || eval_is_value (kind) == boolean_true_node
    2463              :       || kind == REFLECT_BASE
    2464         1506 :       || kind == REFLECT_DATA_MEMBER_SPEC)
    2465              :     return true;
    2466              :   return false;
    2467              : }
    2468              : 
    2469              : /* Helper function for eval_type_of.  Assuming has_type is true, return
    2470              :    the std::meta::type_of type (rather than reflection thereof).  */
    2471              : 
    2472              : static tree
    2473         1271 : type_of (tree r, reflect_kind kind)
    2474              : {
    2475         1271 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2476         1271 :   if (TREE_CODE (r) == PARM_DECL && kind == REFLECT_PARM)
    2477              :     {
    2478           41 :       r = maybe_update_function_parm (r);
    2479           41 :       tree fn = DECL_CONTEXT (r);
    2480           41 :       tree args = FUNCTION_FIRST_USER_PARM (fn);
    2481           41 :       tree type = FUNCTION_FIRST_USER_PARMTYPE (fn);
    2482          137 :       while (r != args)
    2483              :         {
    2484           55 :           args = DECL_CHAIN (args);
    2485           55 :           type = TREE_CHAIN (type);
    2486              :         }
    2487           41 :       r = TREE_VALUE (type);
    2488           41 :     }
    2489         1230 :   else if (kind == REFLECT_BASE)
    2490          112 :     r = BINFO_TYPE (r);
    2491         1118 :   else if (kind == REFLECT_DATA_MEMBER_SPEC)
    2492           22 :     r = TREE_VEC_ELT (r, 0);
    2493         1096 :   else if (eval_is_annotation (r, kind) == boolean_true_node)
    2494              :     {
    2495          163 :       r = TREE_TYPE (TREE_VALUE (TREE_VALUE (r)));
    2496          163 :       if (CLASS_TYPE_P (r))
    2497              :         {
    2498           15 :           int quals = cp_type_quals (r);
    2499           15 :           quals |= TYPE_QUAL_CONST;
    2500           15 :           r = cp_build_qualified_type (r, quals);
    2501              :         }
    2502              :     }
    2503          933 :   else if (TREE_CODE (r) == FIELD_DECL && DECL_BIT_FIELD_TYPE (r))
    2504              :     r = DECL_BIT_FIELD_TYPE (r);
    2505          912 :   else if (TREE_CODE (r) == FUNCTION_DECL)
    2506           95 :     r = static_fn_type (r);
    2507              :   else
    2508          817 :     r = TREE_TYPE (r);
    2509         1271 :   return strip_typedefs (r);
    2510              : }
    2511              : 
    2512              : /* Process std::meta::type_of.  Returns:
    2513              :    -- If r represents the ith parameter of a function F, then the ith type
    2514              :       in the parameter-type-list of F.
    2515              :    -- Otherwise, if r represents a value, object, variable, function,
    2516              :       non-static data member, or unnamed bit-field, then the type of what is
    2517              :       represented by r.
    2518              :    -- Otherwise, if r represents an annotation, then type_of(constant_of(r)).
    2519              :    -- Otherwise, if r represents an enumerator N of an enumeration E, then:
    2520              :       -- If E is defined by a declaration D that precedes a point P in the
    2521              :          evaluation context and P does not occur within an enum-specifier of
    2522              :          D, then a reflection of E.
    2523              :       -- Otherwise, a reflection of the type of N prior to the closing brace
    2524              :          of the enum-specifier as specified in [dcl.enum].
    2525              :    -- Otherwise, if r represents a direct base class relationship (D,B), then
    2526              :       a reflection of B.
    2527              :    -- Otherwise, for a data member description (T,N,A,W,NUA), a reflection of
    2528              :       the type T.  */
    2529              : 
    2530              : static tree
    2531          609 : eval_type_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2532              :               reflect_kind kind, bool *non_constant_p, tree *jump_target,
    2533              :               tree fun)
    2534              : {
    2535          609 :   if (!has_type (r, kind))
    2536           26 :     return throw_exception (loc, ctx, "reflection does not have a type",
    2537           26 :                             fun, non_constant_p, jump_target);
    2538          583 :   return get_reflection_raw (loc, type_of (r, kind));
    2539              : }
    2540              : 
    2541              : /* Process std::meta::source_location_of.
    2542              :    Returns: If r represents a value, a type other than a class type or an
    2543              :    enumeration type, the global namespace, or a data member description,
    2544              :    then source_location{}.  Otherwise, an implementation-defined
    2545              :    source_location value.  */
    2546              : 
    2547              : static tree
    2548           58 : eval_source_location_of (location_t loc, tree r, reflect_kind kind,
    2549              :                          tree std_source_location)
    2550              : {
    2551           58 :   if (!NON_UNION_CLASS_TYPE_P (std_source_location))
    2552              :     {
    2553            0 :       error_at (loc, "%qT is not a class type", std_source_location);
    2554            0 :       return error_mark_node;
    2555              :     }
    2556           58 :   location_t rloc = UNKNOWN_LOCATION;
    2557           58 :   if (kind == REFLECT_BASE)
    2558              :     /* We don't track location_t of the base specifiers, so at least
    2559              :        for now use location_t of the base parent (i.e. the derived
    2560              :        class).  */
    2561            4 :     r = direct_base_derived (r);
    2562           58 :   if (OVERLOAD_TYPE_P (r) || (TYPE_P (r) && typedef_variant_p (r)))
    2563           10 :     rloc = DECL_SOURCE_LOCATION (TYPE_NAME (r));
    2564           48 :   else if (DECL_P (r) && r != global_namespace)
    2565           30 :     rloc = DECL_SOURCE_LOCATION (r);
    2566           18 :   else if (eval_is_annotation (r, kind) == boolean_true_node)
    2567           13 :     rloc = EXPR_LOCATION (TREE_VALUE (TREE_VALUE (r)));
    2568           58 :   tree decl = NULL_TREE, field = NULL_TREE;
    2569           51 :   if (rloc != UNKNOWN_LOCATION)
    2570              :     {
    2571              :       /* Make sure __builtin_source_location (which depends on
    2572              :          std::source_location::__impl) will work without errors.  */
    2573           51 :       tree name = get_identifier ("__impl");
    2574           51 :       decl = lookup_qualified_name (std_source_location, name);
    2575           51 :       if (TREE_CODE (decl) != TYPE_DECL)
    2576              :         decl = NULL_TREE;
    2577              :       else
    2578              :         {
    2579           51 :           name = get_identifier ("__builtin_source_location");
    2580           51 :           decl = lookup_qualified_name (global_namespace, name);
    2581           51 :           if (TREE_CODE (decl) != FUNCTION_DECL
    2582           51 :               || !fndecl_built_in_p (decl, BUILT_IN_FRONTEND)
    2583           51 :               || DECL_FE_FUNCTION_CODE (decl) != CP_BUILT_IN_SOURCE_LOCATION
    2584          102 :               || !require_deduced_type (decl, tf_warning_or_error))
    2585              :             decl = NULL_TREE;
    2586              :         }
    2587              :     }
    2588           51 :   if (decl)
    2589              :     {
    2590           51 :       field = TYPE_FIELDS (std_source_location);
    2591           51 :       field = next_aggregate_field (field);
    2592              :       /* Make sure std::source_location has exactly a single non-static
    2593              :          data member (_M_impl in libstdc++, __ptr_ in libc++) with pointer
    2594              :          type.  Return {._M_impl = &*.Lsrc_locN}.  */
    2595           51 :       if (field != NULL_TREE
    2596           51 :           && POINTER_TYPE_P (TREE_TYPE (field))
    2597          102 :           && !next_aggregate_field (DECL_CHAIN (field)))
    2598              :         {
    2599           51 :           tree call = build_call_nary (TREE_TYPE (TREE_TYPE (decl)), decl, 0);
    2600           51 :           SET_EXPR_LOCATION (call, rloc);
    2601           51 :           call = fold_builtin_source_location (call);
    2602           51 :           return build_constructor_single (std_source_location, field, call);
    2603              :         }
    2604              :     }
    2605            7 :   return build_constructor (std_source_location, nullptr);
    2606              : }
    2607              : 
    2608              : /* If R is (const T &) &foo, get foo.  */
    2609              : 
    2610              : static tree
    2611          427 : maybe_get_reference_referent (tree r)
    2612              : {
    2613          427 :   if (TREE_CODE (r) == NOP_EXPR
    2614          191 :       && TYPE_REF_P (TREE_TYPE (r))
    2615          616 :       && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
    2616              :     {
    2617          189 :       STRIP_NOPS (r);
    2618          189 :       r = TREE_OPERAND (r, 0);
    2619              :     }
    2620          427 :   return r;
    2621              : }
    2622              : 
    2623              : /* Process std::meta::object_of.
    2624              :    Returns:
    2625              :    -- If r represents an object, then r.
    2626              :    -- Otherwise, if r represents a reference, then a reflection of the object
    2627              :       referred to by that reference.
    2628              :    -- Otherwise, r represents a variable; a reflection of the object declared
    2629              :       by that variable.
    2630              :    Throws: meta::exception unless r is a reflection representing either
    2631              :    -- an object with static storage duration, or
    2632              :    -- a variable that either declares or refers to such an object, and if that
    2633              :       variable is a reference R, then either
    2634              :       -- R is usable in constant expressions, or
    2635              :       -- the lifetime of R began within the core constant expression currently
    2636              :          under evaluation.  */
    2637              : 
    2638              : static tree
    2639           67 : eval_object_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2640              :                 reflect_kind kind, bool *non_constant_p, bool *overflow_p,
    2641              :                 tree *jump_target, tree fun)
    2642              : {
    2643           67 :   tree orig = r;
    2644           67 :   tree type = TREE_TYPE (r);
    2645           67 :   if (type && TYPE_REF_P (type))
    2646           14 :     r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p,
    2647              :                                       overflow_p, jump_target);
    2648           67 :   r = maybe_get_reference_referent (r);
    2649           67 :   if (eval_has_static_storage_duration (orig, kind) == boolean_false_node
    2650           67 :       && (orig == r
    2651            2 :           || eval_has_static_storage_duration (r, kind) == boolean_false_node))
    2652           33 :     return throw_exception (loc, ctx, "reflection does not represent an"
    2653              :                                       " object with static storage duration,"
    2654              :                                       " or a reference to such an object",
    2655           33 :                             fun, non_constant_p, jump_target);
    2656           34 :   return get_reflection_raw (loc, r, REFLECT_OBJECT);
    2657              : }
    2658              : 
    2659              : /* Process std::meta::constant_of.
    2660              :    Let R be a constant expression of type info such that R == r is true.
    2661              :    If r represents an annotation, then let C be its underlying constant.
    2662              :    Effects: Equivalent to:
    2663              :      if constexpr (is_annotation(R)) {
    2664              :        return C;
    2665              :      } else if constexpr (is_array_type(type_of(R)) {
    2666              :        return reflect_constant_array([: R :]);
    2667              :      } else if constexpr (is_function_type(type_of(R)) {
    2668              :        return reflect_function([: R :]);
    2669              :      } else {
    2670              :        return reflect_constant([: R :]);
    2671              :      }
    2672              :    Throws: meta::exception unless either r represents an annotation or
    2673              :    [: R :] is a valid splice-expression.  */
    2674              : 
    2675              : static tree
    2676          508 : eval_constant_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2677              :                   reflect_kind kind, bool *non_constant_p, bool *overflow_p,
    2678              :                   tree *jump_target, tree fun)
    2679              : {
    2680          508 :   tree type;
    2681          508 :   if (has_type (r, kind))
    2682          490 :     type = type_of (r, kind);
    2683              :   else
    2684           18 :     type = maybe_strip_typedefs (r);
    2685              : 
    2686              :   /* So that outer_automatic_var_p works below in check_splice_expr.  */
    2687          508 :   temp_override<tree> ovr (current_function_decl);
    2688          508 :   current_function_decl = cxx_constexpr_caller (ctx);
    2689              : 
    2690          508 :   if (eval_is_annotation (r, kind) == boolean_true_node)
    2691           87 :     r = tree_strip_any_location_wrapper (TREE_VALUE (TREE_VALUE (r)));
    2692          842 :   else if (eval_is_array_type (loc, type) == boolean_true_node)
    2693              :     {
    2694          175 :       const tsubst_flags_t complain = complain_flags (ctx);
    2695              :       /* Create a call to reflect_constant_array so that we can simply
    2696              :          let eval_reflect_constant_array do its job.  */
    2697          175 :       tree name = get_identifier ("reflect_constant_array");
    2698          175 :       tree call = lookup_qualified_name (std_meta_node, name);
    2699          175 :       if (error_operand_p (call) || !is_overloaded_fn (call))
    2700              :         {
    2701            0 :           if (complain)
    2702            0 :             error_at (loc, "couldn%'t look up %<%D::%D%>", std_meta_node, name);
    2703            0 :           *non_constant_p = true;
    2704            0 :           return NULL_TREE;
    2705              :         }
    2706              :       /* We want the argument to be a CONSTRUCTOR or a STRING_CST.  */
    2707          175 :       r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p,
    2708              :                                         overflow_p, jump_target);
    2709          175 :       if (*jump_target || *non_constant_p)
    2710              :         return NULL_TREE;
    2711          175 :       releasing_vec args (make_tree_vector_single (r));
    2712          175 :       call = finish_call_expr (call, &args, /*disallow_virtual=*/true,
    2713              :                                /*koenig_p=*/false, complain);
    2714          175 :       if (call == error_mark_node)
    2715              :         {
    2716            0 :           *non_constant_p = true;
    2717            0 :           return NULL_TREE;
    2718              :         }
    2719          175 :       return eval_reflect_constant_array (loc, ctx, call, non_constant_p,
    2720          175 :                                           overflow_p, jump_target, fun);
    2721          175 :     }
    2722          246 :   else if (eval_is_function_type (type) == boolean_true_node)
    2723            2 :     return eval_reflect_function (loc, ctx, type, r, non_constant_p,
    2724            2 :                                   jump_target, fun);
    2725          244 :   else if (!check_splice_expr (loc, UNKNOWN_LOCATION, r,
    2726              :                                /*address_p=*/false,
    2727              :                                /*member_access_p=*/false,
    2728              :                                /*complain_p=*/false)
    2729              :            /* One cannot query the value of a function template.
    2730              :               ??? But if [:^^X:] where X is a template is OK, should we
    2731              :               really throw?  We need an LWG issue.  */
    2732          244 :            || eval_is_template (r) == boolean_true_node)
    2733           24 :     return throw_exception (loc, ctx, "reflection does not represent an "
    2734              :                                       "annotation or a valid argument to "
    2735              :                                       "a splice-expression",
    2736           24 :                             fun, non_constant_p, jump_target);
    2737              : 
    2738          307 :   r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p,
    2739              :                                     overflow_p, jump_target);
    2740          307 :   if (*jump_target || *non_constant_p)
    2741              :     return NULL_TREE;
    2742              :   /* Figure out the type for reflect_constant.  */
    2743          300 :   type = TREE_TYPE (convert_from_reference (r));
    2744          300 :   type = type_decays_to (type);
    2745          300 :   type = cv_unqualified (type);
    2746              : 
    2747          300 :   return eval_reflect_constant (loc, ctx, type, r, non_constant_p, jump_target,
    2748          300 :                                 fun);
    2749          508 : }
    2750              : 
    2751              : /* Process std::meta::dealias.
    2752              :    Returns: If r represents an entity, then a reflection representing the
    2753              :    underlying entity of what r represents.  Otherwise, r.
    2754              :    This implements LWG 4427 so we do not throw.  */
    2755              : 
    2756              : static tree
    2757           94 : eval_dealias (location_t loc, tree r, reflect_kind kind)
    2758              : {
    2759           94 :   r = maybe_strip_typedefs (r);
    2760           94 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    2761            4 :     r = ORIGINAL_NAMESPACE (r);
    2762           94 :   return get_reflection_raw (loc, r, kind);
    2763              : }
    2764              : 
    2765              : /* Process std::meta::is_noexcept.
    2766              :    Returns: true if r represents a noexcept function type or a function
    2767              :    with a non-throwing exception specification ([except.spec]).
    2768              :    Otherwise, false.
    2769              :    Note: If r represents a function template that is declared noexcept,
    2770              :    is_noexcept (r) is still false because in general such queries
    2771              :    for templates cannot be answered.  */
    2772              : 
    2773              : static tree
    2774          171 : eval_is_noexcept (tree r)
    2775              : {
    2776          171 :   if (eval_is_function (r) == boolean_true_node)
    2777              :     {
    2778           73 :       r = maybe_get_first_fn (r);
    2779           73 :       maybe_instantiate_noexcept (r);
    2780           73 :       if (TYPE_NOTHROW_P (TREE_TYPE (r)))
    2781           41 :         return boolean_true_node;
    2782              :       else
    2783           32 :         return boolean_false_node;
    2784              :     }
    2785              : 
    2786          196 :   if (eval_is_function_type (r) == boolean_true_node
    2787           98 :       && TYPE_NOTHROW_P (r))
    2788            8 :     return boolean_true_node;
    2789              : 
    2790           90 :   return boolean_false_node;
    2791              : }
    2792              : 
    2793              : /* Process std::meta::is_const.
    2794              :    Let T be type_of(r) if has-type(r) is true.  Otherwise, let T be dealias(r).
    2795              :    Returns: true if T represents a const type, or a const-qualified function
    2796              :    type.  Otherwise, false.  */
    2797              : 
    2798              : static tree
    2799           73 : eval_is_const (tree r, reflect_kind kind)
    2800              : {
    2801           73 :   if (has_type (r, kind))
    2802           50 :     r = type_of (r, kind);
    2803              :   else
    2804           23 :     r = maybe_strip_typedefs (r);
    2805           73 :   r = strip_array_types (r);
    2806           73 :   if (TREE_CODE (r) == METHOD_TYPE)
    2807              :     {
    2808            0 :       if (type_memfn_quals (r) & TYPE_QUAL_CONST)
    2809            0 :         return boolean_true_node;
    2810              :     }
    2811           73 :   else if (TYPE_P (r) && TYPE_READONLY (r))
    2812           22 :     return boolean_true_node;
    2813           51 :   return boolean_false_node;
    2814              : }
    2815              : 
    2816              : /* Process std::meta::is_volatile.
    2817              :    Let T be type_of(r) if has-type(r) is true.  Otherwise, let T be dealias(r).
    2818              :    Returns: true if T represents a volatile type, or a volatile-qualified
    2819              :    function type.  Otherwise, false.  */
    2820              : 
    2821              : static tree
    2822           55 : eval_is_volatile (tree r, reflect_kind kind)
    2823              : {
    2824           55 :   if (has_type (r, kind))
    2825           32 :     r = type_of (r, kind);
    2826              :   else
    2827           23 :     r = maybe_strip_typedefs (r);
    2828           55 :   r = strip_array_types (r);
    2829           55 :   if (TREE_CODE (r) == METHOD_TYPE)
    2830              :     {
    2831            0 :       if (type_memfn_quals (r) & TYPE_QUAL_VOLATILE)
    2832            0 :         return boolean_true_node;
    2833              :     }
    2834           55 :   else if (TYPE_P (r) && TYPE_VOLATILE (r))
    2835           15 :     return boolean_true_node;
    2836           40 :   return boolean_false_node;
    2837              : }
    2838              : 
    2839              : /* Process std::meta::has_template_arguments.
    2840              :    Returns: true if r represents a specialization of a function template,
    2841              :    variable template, class template, or an alias template.  Otherwise,
    2842              :    false.  */
    2843              : 
    2844              : static tree
    2845          807 : eval_has_template_arguments (tree r)
    2846              : {
    2847          807 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2848              :   /* For
    2849              :        typedef cls_tmpl<int> TYPE;
    2850              :      'has_template_arguments (^^TYPE)' should be false.  */
    2851          807 :   if (TYPE_P (r) && typedef_variant_p (r))
    2852           59 :     return (alias_template_specialization_p (r, nt_opaque)
    2853           59 :             ? boolean_true_node : boolean_false_node);
    2854          748 :   if (primary_template_specialization_p (r)
    2855          748 :       || variable_template_specialization_p (r))
    2856          152 :     return boolean_true_node;
    2857              :   else
    2858          596 :     return boolean_false_node;
    2859              : }
    2860              : 
    2861              : /* Process std::meta::template_of.
    2862              :    Returns: A reflection of the template of the specialization represented
    2863              :    by r.
    2864              :    Throws: meta::exception unless has_template_arguments(r) is true.  */
    2865              : 
    2866              : static tree
    2867           39 : eval_template_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2868              :                   bool *non_constant_p, tree *jump_target, tree fun)
    2869              : {
    2870           39 :   if (eval_has_template_arguments (r) != boolean_true_node)
    2871            1 :     return throw_exception_notargs (loc, ctx, fun, non_constant_p, jump_target);
    2872              : 
    2873           38 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2874           38 :   if (TYPE_P (r) && typedef_variant_p (r))
    2875           14 :     r = TI_TEMPLATE (TYPE_ALIAS_TEMPLATE_INFO (r));
    2876           31 :   else if (CLASS_TYPE_P (r) && CLASSTYPE_TEMPLATE_INFO (r))
    2877           23 :     r = CLASSTYPE_TI_TEMPLATE (r);
    2878            8 :   else if (VAR_OR_FUNCTION_DECL_P (r) && DECL_TEMPLATE_INFO (r))
    2879            8 :     r = DECL_TI_TEMPLATE (r);
    2880              :   else
    2881            0 :     gcc_assert (false);
    2882              : 
    2883           38 :   gcc_assert (TREE_CODE (r) == TEMPLATE_DECL);
    2884           38 :   return get_reflection_raw (loc, r);
    2885              : }
    2886              : 
    2887              : /* Process std::meta::has_parent
    2888              :    Returns:
    2889              :    -- If r represents the global namespace, then false.
    2890              :    -- Otherwise, if r represents an entity that has C language linkage,
    2891              :       then false.
    2892              :    -- Otherwise, if r represents an entity that has a language linkage
    2893              :       other than C++ language linkage, then an implementation-defined value.
    2894              :    -- Otherwise, if r represents a type that is neither a class nor enumeration
    2895              :       type, then false.
    2896              :    -- Otherwise, if r represents an entity or direct base class relationship,
    2897              :       then true.
    2898              :    -- Otherwise, false.  */
    2899              : 
    2900              : static tree
    2901          465 : eval_has_parent (tree r, reflect_kind kind)
    2902              : {
    2903          465 :   if (kind == REFLECT_OBJECT
    2904          465 :       || CONSTANT_CLASS_P (r)
    2905          459 :       || r == global_namespace
    2906          456 :       || kind == REFLECT_DATA_MEMBER_SPEC)
    2907           12 :     return boolean_false_node;
    2908          453 :   if (TYPE_P (r))
    2909              :     {
    2910           45 :       if (TYPE_NAME (r)
    2911           45 :           && DECL_P (TYPE_NAME (r))
    2912           90 :           && DECL_LANGUAGE (TYPE_NAME (r)) == lang_c)
    2913            0 :         return boolean_false_node;
    2914           45 :       else if (OVERLOAD_TYPE_P (r) || typedef_variant_p (r))
    2915           40 :         return boolean_true_node;
    2916              :       else
    2917            5 :         return boolean_false_node;
    2918              :     }
    2919          408 :   r = maybe_get_first_fn (r);
    2920          408 :   if (kind == REFLECT_BASE)
    2921           46 :     return boolean_true_node;
    2922          362 :   if (!DECL_P (r))
    2923            0 :     return boolean_false_node;
    2924          362 :   if (TREE_CODE (r) != NAMESPACE_DECL && DECL_LANGUAGE (r) == lang_c)
    2925            9 :     return boolean_false_node;
    2926          353 :   return boolean_true_node;
    2927              : }
    2928              : 
    2929              : /* Process std::meta::parent_of.
    2930              :    Returns:
    2931              :    -- If r represents a non-static data member that is a direct member of an
    2932              :       anonymous union, or an unnamed bit-field declared within the
    2933              :       member-specification of such a union, then a reflection representing the
    2934              :       innermost enclosing anonymous union.
    2935              :    -- Otherwise, if r represents an enumerator, then a reflection representing
    2936              :       the corresponding enumeration type.
    2937              :    -- Otherwise, if r represents a direct base class relationship (D,B), then
    2938              :       a reflection representing D.
    2939              :    -- Otherwise, let E be a class, function, or namespace whose class scope,
    2940              :       function parameter scope, or namespace scope, respectively, is the
    2941              :       innermost such scope that either is, or encloses, the target scope of a
    2942              :       declaration of what is represented by r.
    2943              :       -- If E is the function call operator of a closure type for a
    2944              :          consteval-block-declaration, then parent_of(parent_of(^^E)).
    2945              :       -- Otherwise, ^^E.  */
    2946              : 
    2947              : static tree
    2948          408 : eval_parent_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2949              :                 reflect_kind kind, bool *non_constant_p, tree *jump_target,
    2950              :                 tree fun)
    2951              : {
    2952          408 :   if (eval_has_parent (r, kind) != boolean_true_node)
    2953           17 :     return throw_exception (loc, ctx, "reflection does not represent an "
    2954              :                                       "entity with parent",
    2955           17 :                             fun, non_constant_p, jump_target);
    2956          391 :   tree c;
    2957          391 :   r = maybe_get_first_fn (r);
    2958          391 :   if (TYPE_P (r))
    2959              :     {
    2960           29 :       if (TYPE_NAME (r) && DECL_P (TYPE_NAME (r)))
    2961           29 :         c = CP_DECL_CONTEXT (TYPE_NAME (r));
    2962              :       else
    2963            0 :         c = CP_TYPE_CONTEXT (r);
    2964              :     }
    2965          362 :   else if (kind == REFLECT_BASE)
    2966           45 :     c = direct_base_derived (r);
    2967              :   else
    2968          317 :     c = CP_DECL_CONTEXT (r);
    2969              :   tree lam;
    2970          437 :   while (LAMBDA_FUNCTION_P (c)
    2971           28 :          && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (c)))
    2972          437 :          && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
    2973           18 :     c = CP_TYPE_CONTEXT (CP_DECL_CONTEXT (c));
    2974          391 :   return get_reflection_raw (loc, c);
    2975              : }
    2976              : 
    2977              : /* Return std::vector<info>.  */
    2978              : 
    2979              : static tree
    2980         4043 : get_vector_info ()
    2981              : {
    2982         4043 :   tree args = make_tree_vec (1);
    2983         4043 :   TREE_VEC_ELT (args, 0) = meta_info_type_node;
    2984         4043 :   tree inst = lookup_template_class (get_identifier ("vector"), args,
    2985              :                                      /*in_decl*/NULL_TREE,
    2986              :                                      /*context*/std_node, tf_none);
    2987         4043 :   inst = complete_type (inst);
    2988         4043 :   if (inst == error_mark_node || !COMPLETE_TYPE_P (inst))
    2989              :     {
    2990            0 :       error ("couldn%'t look up %qs", "std::vector");
    2991            0 :       return NULL_TREE;
    2992              :     }
    2993              : 
    2994              :   return inst;
    2995              : }
    2996              : 
    2997              : /* Build std::vector<info>{ ELTS }.  */
    2998              : 
    2999              : static tree
    3000         4043 : get_vector_of_info_elts (vec<constructor_elt, va_gc> *elts)
    3001              : {
    3002         4043 :   tree ctor = build_constructor (init_list_type_node, elts);
    3003         4043 :   CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
    3004         4043 :   TREE_CONSTANT (ctor) = true;
    3005         4043 :   TREE_STATIC (ctor) = true;
    3006         4043 :   tree type = get_vector_info ();
    3007         4043 :   if (!type)
    3008            0 :     return error_mark_node;
    3009         4043 :   tree r = finish_compound_literal (type, ctor, tf_warning_or_error,
    3010              :                                     fcl_functional);
    3011              :   /* Here, we're evaluating an AGGR_INIT_EXPR, which is already
    3012              :      embedded in a TARGET_EXPR, so we don't want to add another
    3013              :      TARGET_EXPR inside it.  Note that SIMPLE_TARGET_EXPR_P would
    3014              :      always be false because the TARGET_EXPR_INITIAL is an
    3015              :      AGGR_INIT_EXPR with void type.  */
    3016         4043 :   if (TREE_CODE (r) == TARGET_EXPR)
    3017         4043 :     r = TARGET_EXPR_INITIAL (r);
    3018              :   return r;
    3019              : }
    3020              : 
    3021              : /* Process std::meta::parameters_of.
    3022              :    Returns:
    3023              :    -- If r represents a function F, then a vector containing reflections of
    3024              :       the parameters of F, in the order in which they appear in a declaration
    3025              :       of F.
    3026              :    -- Otherwise, r represents a function type T; a vector containing
    3027              :       reflections of the types in parameter-type-list of T, in the order in
    3028              :       which they appear in the parameter-type-list.
    3029              : 
    3030              :    Throws: meta::exception unless r represents a function or a function
    3031              :    type.  */
    3032              : 
    3033              : static tree
    3034          325 : eval_parameters_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3035              :                     bool *non_constant_p, tree *jump_target, tree fun)
    3036              : {
    3037          325 :   if (eval_is_function (r) != boolean_true_node
    3038          355 :       && eval_is_function_type (r) != boolean_true_node)
    3039            6 :     return throw_exception_nofn (loc, ctx, fun, non_constant_p, jump_target);
    3040              : 
    3041          319 :   r = maybe_get_first_fn (r);
    3042          319 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3043          319 :   if (TREE_CODE (r) == FUNCTION_DECL)
    3044         1348 :     for (tree arg = FUNCTION_FIRST_USER_PARM (r); arg; arg = DECL_CHAIN (arg))
    3045         1053 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3046              :                               get_reflection_raw (loc, arg, REFLECT_PARM));
    3047              :   else
    3048           95 :     for (tree arg = TYPE_ARG_TYPES (r); arg && arg != void_list_node;
    3049           71 :          arg = TREE_CHAIN (arg))
    3050              :       {
    3051           71 :         tree type = maybe_strip_typedefs (TREE_VALUE (arg));
    3052           71 :         CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3053              :                                 get_reflection_raw (loc, type));
    3054              :       }
    3055          319 :   return get_vector_of_info_elts (elts);
    3056              : }
    3057              : 
    3058              : /* Process std::meta::variable_of.
    3059              :    Returns: The reflection of the parameter variable corresponding to r.
    3060              : 
    3061              :    Throws: meta::exception unless
    3062              :    -- r represents a parameter of a function F and
    3063              :    -- there is a point P in the evaluation context for which the innermost
    3064              :       non-block scope enclosing P is the function parameter scope associated
    3065              :       with F.  */
    3066              : 
    3067              : static tree
    3068          111 : eval_variable_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3069              :                   reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3070              :                   tree fun)
    3071              : {
    3072          111 :   if (eval_is_function_parameter (r, kind) == boolean_false_node
    3073              :       /* This doesn't consider the points corresponding to injected
    3074              :          declarations, but that doesn't seem needed.  */
    3075          111 :       || DECL_CONTEXT (r) != current_function_decl)
    3076           58 :     return throw_exception (loc, ctx, "reflection does not represent "
    3077              :                                       "parameter of current function",
    3078           58 :                             fun, non_constant_p, jump_target);
    3079           53 :   r = maybe_update_function_parm (r);
    3080           53 :   return get_reflection_raw (loc, r, REFLECT_UNDEF);
    3081              : }
    3082              : 
    3083              : /* Process std::meta::return_type_of.
    3084              :    Returns: The reflection of the return type of the function or function type
    3085              :    represented by r.
    3086              : 
    3087              :    Throws: meta::exception unless either r represents a function and
    3088              :    has-type(r) is true or r represents a function type.  */
    3089              : 
    3090              : static tree
    3091           63 : eval_return_type_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3092              :                      reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3093              :                      tree fun)
    3094              : {
    3095           24 :   if ((eval_is_function (r) != boolean_true_node || !has_type (r, kind))
    3096          118 :       && eval_is_function_type (r) != boolean_true_node)
    3097           50 :     return throw_exception (loc, ctx, "reflection does not represent a "
    3098              :                             "function or function type with a return type",
    3099           50 :                             fun, non_constant_p, jump_target);
    3100              : 
    3101           13 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    3102           13 :   if (TREE_CODE (r) == FUNCTION_DECL)
    3103            8 :     r = TREE_TYPE (r);
    3104           13 :   r = TREE_TYPE (r);
    3105           13 :   return get_reflection_raw (loc, r, REFLECT_UNDEF);
    3106              : }
    3107              : 
    3108              : /* Process std::meta::offset_of.
    3109              :    Let V be the offset in bits from the beginning of a complete object of the
    3110              :    type represented by parent_of(r) to the subobject associated with the
    3111              :    entity represented by r.
    3112              :    Returns: {V / CHAR_BIT, V % CHAR_BIT}.
    3113              :    Throws: meta::exception unless r represents a non-static data member,
    3114              :    unnamed bit-field, or direct base class relationship (D,B) for which either
    3115              :    B is not a virtual base class or D is not an abstract class.  */
    3116              : 
    3117              : static tree
    3118          123 : eval_offset_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3119              :                 reflect_kind kind, tree member_offset, bool *non_constant_p,
    3120              :                 tree *jump_target, tree fun)
    3121              : {
    3122          123 :   tree byte_off = NULL_TREE, bit_off = NULL_TREE;
    3123          123 :   if (kind == REFLECT_BASE)
    3124              :     {
    3125           44 :       tree d = direct_base_derived (r);
    3126           44 :       if (BINFO_VIRTUAL_P (r) && ABSTRACT_CLASS_TYPE_P (d))
    3127            0 :         return throw_exception (loc, ctx,
    3128              :                                 "reflection of virtual direct base "
    3129              :                                 "relationship with abstract derived "
    3130            0 :                                 "class", fun, non_constant_p, jump_target);
    3131           44 :       byte_off = BINFO_OFFSET (r);
    3132              :     }
    3133           79 :   else if (TREE_CODE (r) != FIELD_DECL)
    3134           46 :     return throw_exception (loc, ctx, "reflection unsuitable for offset_of",
    3135           46 :                             fun, non_constant_p, jump_target);
    3136              :   else
    3137           33 :     bit_off = bit_position (r);
    3138           77 :   if (TREE_CODE (bit_off ? bit_off : byte_off) != INTEGER_CST)
    3139            0 :     return throw_exception (loc, ctx, "non-constant offset for offset_of",
    3140            0 :                             fun, non_constant_p, jump_target);
    3141           77 :   if (TREE_CODE (member_offset) != RECORD_TYPE)
    3142              :     {
    3143            0 :     fail:
    3144            0 :       error_at (loc, "unexpected return type of %qs", "std::meta::offset_of");
    3145            0 :       return build_zero_cst (member_offset);
    3146              :     }
    3147           77 :   tree bytes = next_aggregate_field (TYPE_FIELDS (member_offset));
    3148           77 :   if (!bytes || !INTEGRAL_TYPE_P (TREE_TYPE (bytes)))
    3149            0 :     goto fail;
    3150           77 :   tree bits = next_aggregate_field (DECL_CHAIN (bytes));
    3151           77 :   if (!bits || !INTEGRAL_TYPE_P (TREE_TYPE (bits)))
    3152            0 :     goto fail;
    3153           77 :   if (next_aggregate_field (DECL_CHAIN (bits)))
    3154            0 :     goto fail;
    3155           77 :   tree bytesv;
    3156           77 :   if (byte_off)
    3157              :     bytesv = byte_off;
    3158              :   else
    3159           33 :     bytesv = size_binop (TRUNC_DIV_EXPR, bit_off, bitsize_unit_node);
    3160           77 :   bytesv = fold_convert (TREE_TYPE (bytes), bytesv);
    3161           77 :   tree bitsv;
    3162           77 :   if (byte_off)
    3163           44 :     bitsv = build_zero_cst (TREE_TYPE (bits));
    3164              :   else
    3165              :     {
    3166           33 :       bitsv = size_binop (TRUNC_MOD_EXPR, bit_off, bitsize_unit_node);
    3167           33 :       bitsv = fold_convert (TREE_TYPE (bits), bitsv);
    3168              :     }
    3169           77 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3170           77 :   CONSTRUCTOR_APPEND_ELT (elts, bytes, bytesv);
    3171           77 :   CONSTRUCTOR_APPEND_ELT (elts, bits, bitsv);
    3172           77 :   return build_constructor (member_offset, elts);
    3173              : }
    3174              : 
    3175              : /* Process std::meta::size_of.
    3176              :    Returns: If r represents
    3177              :      -- a non-static data member of type T,
    3178              :      -- a data member description (T,N,A,W,NUA), or
    3179              :      -- dealias(r) represents a type T,
    3180              :    then sizeof(T) if T is not a reference type and size_of(add_pointer(^^T))
    3181              :    otherwise.  Otherwise, size_of(type_of(r)).
    3182              : 
    3183              :    Throws: meta::exception unless all of the following conditions are met:
    3184              :      -- dealias(r) is a reflection of a type, object, value, variable of
    3185              :         non-reference type, non-static data member that is not a bit-field,
    3186              :         direct base class relationship, or data member description
    3187              :         (T,N,A,W,NUA) where W is not _|_.
    3188              :      -- If dealias(r) represents a type, then is_complete_type(r) is true.  */
    3189              : 
    3190              : static tree
    3191           99 : eval_size_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3192              :               reflect_kind kind, tree ret_type, bool *non_constant_p,
    3193              :               tree *jump_target, tree fun)
    3194              : {
    3195           99 :   if (eval_is_type (r) != boolean_true_node
    3196           80 :       && eval_is_object (kind) != boolean_true_node
    3197           78 :       && eval_is_value (kind) != boolean_true_node
    3198           76 :       && (eval_is_variable (r, kind) != boolean_true_node
    3199           18 :           || TYPE_REF_P (TREE_TYPE (r)))
    3200           62 :       && (TREE_CODE (r) != FIELD_DECL || DECL_C_BIT_FIELD (r))
    3201           57 :       && kind != REFLECT_BASE
    3202          139 :       && (kind != REFLECT_DATA_MEMBER_SPEC || TREE_VEC_ELT (r, 3)))
    3203           38 :     return throw_exception (loc, ctx, "reflection not suitable for size_of",
    3204           38 :                             fun, non_constant_p, jump_target);
    3205           61 :   if (!INTEGRAL_TYPE_P (ret_type))
    3206              :     {
    3207            0 :       error_at (loc, "unexpected return type of %qs", "std::meta::size_of");
    3208            0 :       return build_zero_cst (ret_type);
    3209              :     }
    3210           61 :   tree type;
    3211           61 :   if (TYPE_P (r))
    3212              :     type = r;
    3213              :   else
    3214           42 :     type = type_of (r, kind);
    3215           61 :   tree ret;
    3216           61 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, tf_none)
    3217              :       /* No special casing of references needed, c_sizeof_or_alignof_type
    3218              :          returns the same size for POINTER_TYPE and REFERENCE_TYPE.  */
    3219           61 :       || ((ret = c_sizeof_or_alignof_type (loc, type, true, false, 0))
    3220           59 :           == error_mark_node))
    3221            4 :     return throw_exception (loc, ctx,
    3222              :                             "reflection with incomplete type in size_of",
    3223            4 :                             fun, non_constant_p, jump_target);
    3224           57 :   return fold_convert (ret_type, ret);
    3225              : }
    3226              : 
    3227              : /* Process std::meta::alignment_of.
    3228              :    Returns:
    3229              :    -- If dealias(r) represents a type T, then alignment_of(add_pointer(r)) if
    3230              :       T is a reference type and the alignment requirement of T otherwise.
    3231              :    -- Otherwise, if dealias(r) represents a variable or object, then the
    3232              :       alignment requirement of the variable or object.
    3233              :    -- Otherwise, if r represents a direct base class relationship, then
    3234              :       alignment_of(type_of(r)).
    3235              :    -- Otherwise, if r represents a non-static data member M of a class C,
    3236              :       then the alignment of the direct member subobject corresponding to M of a
    3237              :       complete object of type C.
    3238              :    -- Otherwise, r represents a data member description (T,N,A,W,NUA).
    3239              :       If A is not _|_, then the value A.  Otherwise, alignment_of(^^T).
    3240              :    Throws: meta::exception unless all of the following conditions are met:
    3241              :    -- dealias(r) is a reflection of a type, object, variable of non-reference
    3242              :       type, non-static data member that is not a bit-field, direct base class
    3243              :       relationship, or data member description (T,N,A,W,NUA) where W is _|_.
    3244              :    -- If dealias(r) represents a type, then is_complete_type(r) is true.  */
    3245              : 
    3246              : static tree
    3247          105 : eval_alignment_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3248              :                    reflect_kind kind, tree ret_type, bool *non_constant_p,
    3249              :                    tree *jump_target, tree fun)
    3250              : {
    3251          105 :   if (eval_is_type (r) != boolean_true_node
    3252           89 :       && eval_is_object (kind) != boolean_true_node
    3253           83 :       && (eval_is_variable (r, kind) != boolean_true_node
    3254           25 :           || TYPE_REF_P (TREE_TYPE (r)))
    3255           62 :       && (TREE_CODE (r) != FIELD_DECL || DECL_C_BIT_FIELD (r))
    3256           44 :       && kind != REFLECT_BASE
    3257          147 :       && (kind != REFLECT_DATA_MEMBER_SPEC || TREE_VEC_ELT (r, 3)))
    3258           40 :     return throw_exception (loc, ctx, "reflection not suitable for alignment_of",
    3259           40 :                             fun, non_constant_p, jump_target);
    3260           65 :   if (!INTEGRAL_TYPE_P (ret_type))
    3261              :     {
    3262            0 :       error_at (loc, "unexpected return type of %qs", "std::meta::alignment_of");
    3263            0 :       return build_zero_cst (ret_type);
    3264              :     }
    3265           65 :   tree type;
    3266           65 :   if (kind == REFLECT_DATA_MEMBER_SPEC)
    3267              :     {
    3268            2 :       if (TREE_VEC_ELT (r, 2))
    3269            0 :         return fold_convert (ret_type, TREE_VEC_ELT (r, 2));
    3270              :       else
    3271            2 :         type = TREE_VEC_ELT (r, 0);
    3272              :     }
    3273           63 :   else if (kind == REFLECT_BASE)
    3274            2 :     type = BINFO_TYPE (r);
    3275           61 :   else if (TREE_CODE (r) == FIELD_DECL
    3276           43 :            || eval_is_variable (r, kind) == boolean_true_node
    3277           83 :            || (eval_is_object (kind) == boolean_true_node
    3278            6 :                && ((DECL_P (r) && TREE_CODE (r) != FUNCTION_DECL)
    3279            4 :                    || TREE_CODE (r) == COMPONENT_REF)))
    3280              :     {
    3281           43 :       if (TREE_CODE (r) == COMPONENT_REF)
    3282            2 :         r = TREE_OPERAND (r, 1);
    3283           43 :       return build_int_cst (ret_type, MAX (DECL_ALIGN_UNIT (r), 1));
    3284              :     }
    3285           18 :   else if (TYPE_P (r))
    3286              :     type = r;
    3287            2 :   else if (eval_is_object (kind) == boolean_true_node)
    3288            2 :     type = TREE_TYPE (r);
    3289              :   else
    3290            0 :     gcc_unreachable ();
    3291           22 :   if (TYPE_REF_P (type))
    3292            4 :     type = ptr_type_node;
    3293           22 :   if (FUNC_OR_METHOD_TYPE_P (type))
    3294            2 :     return throw_exception (loc, ctx, "alignment_of on function type",
    3295            2 :                             fun, non_constant_p, jump_target);
    3296           20 :   tree ret;
    3297           20 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, tf_none)
    3298              :       /* No special casing of references needed, c_sizeof_or_alignof_type
    3299              :          returns the same alignment for POINTER_TYPE and REFERENCE_TYPE.  */
    3300           20 :       || ((ret = c_sizeof_or_alignof_type (loc, type, false, true, 0))
    3301           20 :           == error_mark_node))
    3302            0 :     return throw_exception (loc, ctx,
    3303              :                             "reflection with incomplete type in alignment_of",
    3304            0 :                             fun, non_constant_p, jump_target);
    3305           20 :   return fold_convert (ret_type, ret);
    3306              : }
    3307              : 
    3308              : /* Process std::meta::bit_size_of.
    3309              :    Returns:
    3310              :      -- If r represents an unnamed bit-field or a non-static data member that
    3311              :         is a bit-field with width W, then W.
    3312              :      -- Otherwise, if r represents a data member description (T,N,A,W,NUA)
    3313              :         and W is not _|_, then W.
    3314              :      -- Otherwise, CHAR_BIT * size_of(r).
    3315              : 
    3316              :    Throws: meta::exception unless all of the following conditions are met:
    3317              : 
    3318              :      -- dealias(r) is a reflection of a type, object, value, variable of
    3319              :         non-reference type, non-static data member, unnamed bit-field, direct
    3320              :         base class relationship, or data member description.
    3321              :      -- If dealias(r) represents a type T, there is a point within the
    3322              :         evaluation context from which T is not incomplete.  */
    3323              : 
    3324              : static tree
    3325          100 : eval_bit_size_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3326              :                   reflect_kind kind, tree ret_type, bool *non_constant_p,
    3327              :                   tree *jump_target, tree fun)
    3328              : {
    3329          100 :   if (eval_is_type (r) != boolean_true_node
    3330           86 :       && eval_is_object (kind) != boolean_true_node
    3331           85 :       && eval_is_value (kind) != boolean_true_node
    3332           83 :       && (eval_is_variable (r, kind) != boolean_true_node
    3333           18 :           || TYPE_REF_P (TREE_TYPE (r)))
    3334           69 :       && TREE_CODE (r) != FIELD_DECL
    3335              :       && kind != REFLECT_BASE
    3336          136 :       && kind != REFLECT_DATA_MEMBER_SPEC)
    3337           30 :     return throw_exception (loc, ctx,
    3338              :                             "reflection not suitable for bit_size_of",
    3339           30 :                             fun, non_constant_p, jump_target);
    3340           70 :   if (!INTEGRAL_TYPE_P (ret_type))
    3341              :     {
    3342            0 :       error_at (loc, "unexpected return type of %qs",
    3343              :                 "std::meta::bit_size_of");
    3344            0 :       return build_zero_cst (ret_type);
    3345              :     }
    3346           70 :   tree type;
    3347           70 :   if (TREE_CODE (r) == FIELD_DECL && DECL_C_BIT_FIELD (r))
    3348           28 :     return fold_convert (ret_type, DECL_SIZE (r));
    3349           42 :   else if (TYPE_P (r))
    3350              :     type = r;
    3351           28 :   else if (kind == REFLECT_DATA_MEMBER_SPEC && TREE_VEC_ELT (r, 3))
    3352            2 :     return fold_convert (ret_type, TREE_VEC_ELT (r, 3));
    3353              :   else
    3354           26 :     type = type_of (r, kind);
    3355           40 :   tree ret;
    3356           40 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, tf_none)
    3357              :       /* No special casing of references needed, c_sizeof_or_alignof_type
    3358              :          returns the same size for POINTER_TYPE and REFERENCE_TYPE.  */
    3359           40 :       || ((ret = c_sizeof_or_alignof_type (loc, type, true, false, 0))
    3360           38 :           == error_mark_node))
    3361            4 :     return throw_exception (loc, ctx,
    3362              :                             "reflection with incomplete type in bit_size_of",
    3363            4 :                             fun, non_constant_p, jump_target);
    3364           36 :   ret = size_binop (MULT_EXPR, ret, size_int (BITS_PER_UNIT));
    3365           36 :   return fold_convert (ret_type, ret);
    3366              : }
    3367              : 
    3368              : /* Process std::meta::has_identifier.
    3369              :    Returns:
    3370              :    -- If r represents an entity that has a typedef name for linkage purposes,
    3371              :       then true.
    3372              :    -- Otherwise, if r represents an unnamed entity, then false.
    3373              :    -- Otherwise, if r represents a type alias, then !has_template_arguments(r).
    3374              :    -- Otherwise, if r represents a type, then true if
    3375              :       -- r represents a cv-unqualified class type and has_template_arguments(r)
    3376              :          is false, or
    3377              :       -- r represents a cv-unqualified enumeration type.
    3378              :       Otherwise, false.
    3379              :    -- Otherwise, if r represents a class type, then !has_template_arguments(r).
    3380              :    -- Otherwise, if r represents a function, then true if
    3381              :       has_template_arguments(r) is false and the function is not a constructor,
    3382              :       destructor, operator function, or conversion function.  Otherwise, false.
    3383              :    -- Otherwise, if r represents a template, then true if r does not represent
    3384              :       a constructor template, operator function template, or conversion
    3385              :       function template.  Otherwise, false.
    3386              :    -- Otherwise, if r represents the ith parameter of a function F that is an
    3387              :       (implicit or explicit) specialization of a templated function T and the
    3388              :       ith parameter of the instantiated declaration of T whose template
    3389              :       arguments are those of F would be instantiated from a pack, then false.
    3390              :    -- Otherwise, if r represents the parameter P of a function F, then let S
    3391              :       be the set of declarations, ignoring any explicit instantiations, that
    3392              :       precede some point in the evaluation context and that declare either F
    3393              :       or a templated function of which F is a specialization; true if
    3394              :       -- there is a declaration D in S that introduces a name N for either P
    3395              :          or the parameter corresponding to P in the templated function that
    3396              :          D declares and
    3397              :       -- no declaration in S does so using any name other than N.
    3398              :       Otherwise, false.
    3399              :    -- Otherwise, if r represents a variable, then false if the declaration of
    3400              :       that variable was instantiated from a function parameter pack.
    3401              :       Otherwise, !has_template_arguments(r).
    3402              :    -- Otherwise, if r represents a structured binding, then false if the
    3403              :       declaration of that structured binding was instantiated from a
    3404              :       structured binding pack.  Otherwise, true.
    3405              :    -- Otherwise, if r represents an enumerator, non-static-data member,
    3406              :       namespace, or namespace alias, then true.
    3407              :    -- Otherwise, if r represents a direct base class relationship, then
    3408              :       has_identifier(type_of(r)).
    3409              :    -- Otherwise, r represents a data member description (T,N,A,W,NUA); true if
    3410              :       N is not _|_.  Otherwise, false.  */
    3411              : 
    3412              : static tree
    3413          904 : eval_has_identifier (tree r, reflect_kind kind)
    3414              : {
    3415          904 :   r = maybe_get_first_fn (r);
    3416          904 :   if (kind == REFLECT_BASE)
    3417              :     {
    3418           15 :       r = type_of (r, kind);
    3419           15 :       kind = REFLECT_UNDEF;
    3420              :     }
    3421          904 :   if (DECL_P (r)
    3422          690 :       && kind != REFLECT_PARM
    3423         1475 :       && (!DECL_NAME (r) || IDENTIFIER_ANON_P (DECL_NAME (r))))
    3424           31 :     return boolean_false_node;
    3425          873 :   if (TYPE_P (r) && (!TYPE_NAME (r)
    3426          402 :                      || (TYPE_ANON_P (r) && !typedef_variant_p (r))
    3427          192 :                      || (DECL_P (TYPE_NAME (r))
    3428          192 :                          && !DECL_NAME (TYPE_NAME (r)))))
    3429           11 :     return boolean_false_node;
    3430          862 :   if (eval_is_type_alias (r) == boolean_true_node
    3431          862 :       || (CLASS_TYPE_P (r) && !cv_qualified_p (r)))
    3432              :     {
    3433          158 :       if (eval_has_template_arguments (r) == boolean_true_node)
    3434            0 :         return boolean_false_node;
    3435              :       else
    3436              :         return boolean_true_node;
    3437              :     }
    3438          704 :   if (TYPE_P (r))
    3439              :     {
    3440           34 :       if (TREE_CODE (r) == ENUMERAL_TYPE && !cv_qualified_p (r))
    3441           18 :         return boolean_true_node;
    3442              :       else
    3443           16 :         return boolean_false_node;
    3444              :     }
    3445          670 :   if (eval_is_function (r) == boolean_true_node)
    3446              :     {
    3447          282 :       if (eval_has_template_arguments (r) == boolean_true_node
    3448          280 :           || eval_is_constructor (r) == boolean_true_node
    3449          276 :           || eval_is_destructor (r) == boolean_true_node
    3450          275 :           || eval_is_operator_function (r) == boolean_true_node
    3451          550 :           || eval_is_conversion_function (r) == boolean_true_node)
    3452           18 :         return boolean_false_node;
    3453              :       else
    3454              :         return boolean_true_node;
    3455              :     }
    3456          388 :   if (eval_is_template (r) == boolean_true_node)
    3457              :     {
    3458           28 :       if (eval_is_constructor_template (r) == boolean_true_node
    3459           28 :           || eval_is_operator_function_template (r) == boolean_true_node
    3460           55 :           || eval_is_conversion_function_template (r) == boolean_true_node)
    3461            1 :         return boolean_false_node;
    3462              :       else
    3463              :         return boolean_true_node;
    3464              :     }
    3465          360 :   if (eval_is_function_parameter (r, kind) == boolean_true_node)
    3466              :     {
    3467          119 :       r = maybe_update_function_parm (r);
    3468          119 :       if (MULTIPLE_NAMES_PARM_P (r))
    3469           16 :         return boolean_false_node;
    3470          103 :       if (DECL_NAME (r))
    3471              :         {
    3472           59 :           if (strchr (IDENTIFIER_POINTER (DECL_NAME (r)), '#'))
    3473            1 :             return boolean_false_node;
    3474              :           else
    3475           58 :             return boolean_true_node;
    3476              :         }
    3477           44 :       if (lookup_attribute ("old parm name", DECL_ATTRIBUTES (r)))
    3478           26 :         return boolean_true_node;
    3479              :       else
    3480           18 :         return boolean_false_node;
    3481              :     }
    3482          241 :   if (eval_is_variable (r, kind) == boolean_true_node)
    3483              :     {
    3484          131 :       if (strchr (IDENTIFIER_POINTER (DECL_NAME (r)), '#'))
    3485            0 :         return boolean_false_node;
    3486          131 :       if (eval_has_template_arguments (r) == boolean_true_node)
    3487            0 :         return boolean_false_node;
    3488              :       else
    3489              :         return boolean_true_node;
    3490              :     }
    3491          110 :   if (eval_is_structured_binding (r, kind) == boolean_true_node)
    3492              :     {
    3493           12 :       if (strchr (IDENTIFIER_POINTER (DECL_NAME (r)), '#'))
    3494            0 :         return boolean_false_node;
    3495              :       else
    3496              :         return boolean_true_node;
    3497              :     }
    3498           98 :   if (eval_is_enumerator (r) == boolean_true_node
    3499           94 :       || TREE_CODE (r) == FIELD_DECL
    3500          131 :       || (TREE_CODE (r) == NAMESPACE_DECL && r != global_namespace))
    3501              :     return boolean_true_node;
    3502           13 :   if (kind == REFLECT_DATA_MEMBER_SPEC && TREE_VEC_ELT (r, 1))
    3503              :     return boolean_true_node;
    3504            5 :   return boolean_false_node;
    3505              : }
    3506              : 
    3507              : /* Process std::meta::{,u8}identifier_of.
    3508              :    Let E be UTF-8 for u8identifier_of, and otherwise the ordinary literal
    3509              :    encoding.
    3510              :    Returns: An NTMBS, encoded with E, determined as follows:
    3511              :    -- If r represents an entity with a typedef name for linkage purposes,
    3512              :       then that name.
    3513              :    -- Otherwise, if r represents a literal operator or literal operator
    3514              :       template, then the ud-suffix of the operator or operator template.
    3515              :    -- Otherwise, if r represents the parameter P of a function F, then let S
    3516              :       be the set of declarations, ignoring any explicit instantiations, that
    3517              :       precede some point in the evaluation context and that declare either F
    3518              :       or a templated function of which F is a specialization; the name that
    3519              :       was introduced by a declaration in S for the parameter corresponding
    3520              :       to P.
    3521              :    -- Otherwise, if r represents an entity, then the identifier introduced by
    3522              :       the declaration of that entity.
    3523              :    -- Otherwise, if r represents a direct base class relationship, then
    3524              :       identifier_of(type_of(r)) or u8identifier_of(type_of(r)), respectively.
    3525              :    -- Otherwise, r represents a data member description (T,N,A,W,NUA);
    3526              :       a string_view or u8string_view, respectively, containing the identifier
    3527              :       N.
    3528              :    Throws: meta::exception unless has_identifier(r) is true and the identifier
    3529              :    that would be returned (see above) is representable by E.  */
    3530              : 
    3531              : static tree
    3532          484 : eval_identifier_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3533              :                     reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3534              :                     tree elt_type, tree ret_type, tree fun)
    3535              : {
    3536          484 :   if (eval_has_identifier (r, kind) == boolean_false_node)
    3537            6 :     return throw_exception (loc, ctx,
    3538              :                             "reflection with has_identifier false",
    3539            6 :                             fun, non_constant_p, jump_target);
    3540          478 :   r = maybe_get_first_fn (r);
    3541          478 :   const char *name = NULL;
    3542          478 :   if (kind == REFLECT_BASE)
    3543              :     {
    3544           15 :       r = type_of (r, kind);
    3545           15 :       kind = REFLECT_UNDEF;
    3546              :     }
    3547          478 :   if (eval_is_function_parameter (r, kind) == boolean_true_node)
    3548              :     {
    3549           57 :       r = maybe_update_function_parm (r);
    3550           57 :       if (DECL_NAME (r))
    3551           41 :         name = IDENTIFIER_POINTER (DECL_NAME (r));
    3552              :       else
    3553              :         {
    3554           16 :           tree opn = lookup_attribute ("old parm name", DECL_ATTRIBUTES (r));
    3555           16 :           opn = TREE_VALUE (TREE_VALUE (opn));
    3556           16 :           name = IDENTIFIER_POINTER (opn);
    3557              :         }
    3558              :     }
    3559          421 :   else if (DECL_P (r) && UDLIT_OPER_P (DECL_NAME (r)))
    3560            3 :     name = UDLIT_OP_SUFFIX (DECL_NAME (r));
    3561          418 :   else if (DECL_P (r))
    3562          305 :     name = IDENTIFIER_POINTER (DECL_NAME (r));
    3563          113 :   else if (TYPE_P (r))
    3564              :     {
    3565          107 :       if (DECL_P (TYPE_NAME (r)))
    3566          107 :         name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (r)));
    3567              :       else
    3568            0 :         name = IDENTIFIER_POINTER (TYPE_NAME (r));
    3569              :     }
    3570            6 :   else if (kind == REFLECT_DATA_MEMBER_SPEC)
    3571            6 :     name = IDENTIFIER_POINTER (TREE_VEC_ELT (r, 1));
    3572              :   else
    3573            0 :     gcc_unreachable ();
    3574          478 :   tree str = get_string_literal (name, elt_type);
    3575          478 :   if (str == NULL_TREE)
    3576              :     {
    3577            0 :       if (elt_type == char_type_node)
    3578            0 :         return throw_exception (loc, ctx, "identifier_of not representable"
    3579              :                                           " in ordinary literal encoding",
    3580            0 :                                 fun, non_constant_p, jump_target);
    3581              :       else
    3582            0 :         return throw_exception (loc, ctx, "u8identifier_of not representable"
    3583              :                                           " in UTF-8",
    3584            0 :                                 fun, non_constant_p, jump_target);
    3585              :     }
    3586          478 :   releasing_vec args (make_tree_vector_single (str));
    3587          478 :   tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    3588              :                                         &args, ret_type, LOOKUP_NORMAL,
    3589              :                                         tf_warning_or_error);
    3590          478 :   return build_cplus_new (ret_type, ret, tf_warning_or_error);
    3591          478 : }
    3592              : 
    3593              : /* Process std::meta::{,u8}display_string_of.
    3594              :    Returns: An implementation-defined string_view or u8string_view,
    3595              :    respectively.
    3596              :    Recommended practice: Where possible, implementations should return a
    3597              :    string suitable for identifying the represented construct.  */
    3598              : 
    3599              : static tree
    3600          209 : eval_display_string_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3601              :                         reflect_kind kind, bool *non_constant_p,
    3602              :                         tree *jump_target, tree elt_type, tree ret_type,
    3603              :                         tree fun)
    3604              : {
    3605              : #if __GNUC__ >= 10
    3606          209 : #pragma GCC diagnostic push
    3607          209 : #pragma GCC diagnostic ignored "-Wformat"
    3608          209 : #pragma GCC diagnostic ignored "-Wformat-diag"
    3609              : #endif
    3610          209 :   r = maybe_get_first_fn (r);
    3611          209 :   pretty_printer pp, *refpp = global_dc->get_reference_printer ();
    3612          209 :   pp_format_decoder (&pp) = pp_format_decoder (refpp);
    3613          209 :   pp.set_format_postprocessor (pp_format_postprocessor (refpp)->clone ());
    3614          209 :   if (r == unknown_type_node)
    3615            2 :     pp_printf (&pp, "<null reflection>");
    3616          207 :   else if (TYPE_P (r))
    3617           33 :     pp_printf (&pp, "%T", r);
    3618          174 :   else if (kind == REFLECT_PARM)
    3619              :     {
    3620           36 :       r = maybe_update_function_parm (r);
    3621           36 :       tree fn = DECL_CONTEXT (r);
    3622           36 :       if (DECL_NAME (r))
    3623           28 :         pp_printf (&pp, "<parameter %D of %D>", r, fn);
    3624              :       else
    3625              :         {
    3626            8 :           int idx = 1;
    3627            8 :           for (tree args = FUNCTION_FIRST_USER_PARM (fn);
    3628           20 :                r != args; args = DECL_CHAIN (args))
    3629           12 :             ++idx;
    3630            8 :           pp_printf (&pp, "<unnamed parameter %d of %D>", idx, fn);
    3631              :         }
    3632              :     }
    3633          138 :   else if (kind == REFLECT_VALUE || kind == REFLECT_OBJECT)
    3634            8 :     pp_printf (&pp, "%E", r);
    3635          130 :   else if (DECL_P (r) && (DECL_NAME (r) || TREE_CODE (r) == NAMESPACE_DECL))
    3636          102 :     pp_printf (&pp, "%D", r);
    3637           28 :   else if (TREE_CODE (r) == FIELD_DECL)
    3638              :     {
    3639            8 :       if (DECL_UNNAMED_BIT_FIELD (r))
    3640            4 :         pp_printf (&pp, "%T::<unnamed bit-field>", DECL_CONTEXT (r));
    3641            4 :       else if (ANON_UNION_TYPE_P (TREE_TYPE (r)))
    3642            4 :         pp_printf (&pp, "%T::<anonymous union>", DECL_CONTEXT (r));
    3643              :       else
    3644            0 :         pp_printf (&pp, "%T::<unnamed member>", DECL_CONTEXT (r));
    3645              :     }
    3646           20 :   else if (kind == REFLECT_BASE)
    3647              :     {
    3648            4 :       tree d = direct_base_derived (r);
    3649            4 :       pp_printf (&pp, "%T: %T", d, BINFO_TYPE (r));
    3650              :     }
    3651           16 :   else if (kind == REFLECT_DATA_MEMBER_SPEC)
    3652            8 :     pp_printf (&pp, "(%T, %E, %E, %E, %s)", TREE_VEC_ELT (r, 0),
    3653            8 :                TREE_VEC_ELT (r, 1), TREE_VEC_ELT (r, 2), TREE_VEC_ELT (r, 3),
    3654            8 :                TREE_VEC_ELT (r, 4) == boolean_true_node
    3655              :                ? "true" : "false");
    3656            8 :   else if (eval_is_annotation (r, kind) == boolean_true_node)
    3657           16 :     pp_printf (&pp, "[[=%E]]",
    3658            8 :                tree_strip_any_location_wrapper (TREE_VALUE (TREE_VALUE (r))));
    3659              :   else
    3660            0 :     pp_string (&pp, "<unsupported reflection>");
    3661              : #if __GNUC__ >= 10
    3662          209 : #pragma GCC diagnostic pop
    3663              : #endif
    3664          209 :   tree str = get_string_literal (pp_formatted_text (&pp), elt_type);
    3665          209 :   if (str == NULL_TREE)
    3666              :     {
    3667            0 :       if (elt_type == char_type_node)
    3668            0 :         return throw_exception (loc, ctx, "identifier_of not representable"
    3669              :                                           " in ordinary literal encoding",
    3670            0 :                                 fun, non_constant_p, jump_target);
    3671              :       else
    3672            0 :         return throw_exception (loc, ctx, "u8identifier_of not representable"
    3673              :                                           " in UTF-8", fun, non_constant_p,
    3674            0 :                                           jump_target);
    3675              :     }
    3676          209 :   releasing_vec args (make_tree_vector_single (str));
    3677          209 :   tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    3678              :                                         &args, ret_type, LOOKUP_NORMAL,
    3679              :                                         tf_warning_or_error);
    3680          209 :   return build_cplus_new (ret_type, ret, tf_warning_or_error);
    3681          209 : }
    3682              : 
    3683              : /* Determine the reflection kind for R.  */
    3684              : 
    3685              : static reflect_kind
    3686          886 : get_reflection_kind (tree r)
    3687              : {
    3688          886 :   if (eval_is_type (r) == boolean_true_node
    3689          818 :       || eval_is_template (r) == boolean_true_node
    3690         1671 :       || eval_is_function (r) == boolean_true_node)
    3691              :     return REFLECT_UNDEF;
    3692          782 :   return obvalue_p (r) ? REFLECT_OBJECT : REFLECT_VALUE;
    3693              : }
    3694              : 
    3695              : /* Get the reflection of template argument ARG as per
    3696              :    std::meta::template_arguments_of.  */
    3697              : 
    3698              : static tree
    3699          207 : get_reflection_of_targ (tree arg)
    3700              : {
    3701          207 :   const location_t loc = location_of (arg);
    3702              :   /* canonicalize_type_argument already strip_typedefs.  */
    3703          207 :   arg = STRIP_REFERENCE_REF (arg);
    3704          207 :   arg = maybe_get_reference_referent (arg);
    3705          207 :   return get_reflection_raw (loc, arg, get_reflection_kind (arg));
    3706              : }
    3707              : 
    3708              : /* Process std::meta::template_arguments_of.
    3709              :    Returns: A vector containing reflections of the template arguments of the
    3710              :    template specialization represented by r, in the order in which they appear
    3711              :    in the corresponding template argument list.
    3712              :    For a given template argument A, its corresponding reflection R is
    3713              :    determined as follows:
    3714              : 
    3715              :    -- If A denotes a type or type alias, then R is a reflection representing
    3716              :       the underlying entity of A.
    3717              :    -- Otherwise, if A denotes a class template, variable template, concept,
    3718              :       or alias template, then R is a reflection representing A.
    3719              :    -- Otherwise, A is a constant template argument.  Let P be the
    3720              :       corresponding template parameter.
    3721              :       -- If P has reference type, then R is a reflection representing the
    3722              :          object or function referred to by A.
    3723              :       -- Otherwise, if P has class type, then R represents the corresponding
    3724              :          template parameter object.
    3725              :       -- Otherwise, R is a reflection representing the value of A.
    3726              : 
    3727              :    Throws: meta::exception unless has_template_arguments(r) is true.  */
    3728              : 
    3729              : static tree
    3730          101 : eval_template_arguments_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3731              :                             bool *non_constant_p, tree *jump_target, tree fun)
    3732              : {
    3733          101 :   if (eval_has_template_arguments (r) != boolean_true_node)
    3734            0 :     return throw_exception_notargs (loc, ctx, fun, non_constant_p, jump_target);
    3735              : 
    3736          101 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3737          101 :   tree args = NULL_TREE;
    3738          101 :   if (TYPE_P (r) && typedef_variant_p (r))
    3739              :     {
    3740           12 :       if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (r))
    3741           12 :         args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo));
    3742              :     }
    3743              :   else
    3744           89 :     args = get_template_innermost_arguments (r);
    3745          101 :   gcc_assert (args);
    3746          302 :   for (tree arg : tree_vec_range (args))
    3747              :     {
    3748          201 :       if (ARGUMENT_PACK_P (arg))
    3749              :         {
    3750           11 :           tree pargs = ARGUMENT_PACK_ARGS (arg);
    3751           28 :           for (tree a : tree_vec_range (pargs))
    3752           17 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3753              :                                     get_reflection_of_targ (a));
    3754              :         }
    3755              :       else
    3756          391 :         CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, get_reflection_of_targ (arg));
    3757              :     }
    3758          101 :   return get_vector_of_info_elts (elts);
    3759              : }
    3760              : 
    3761              : /* Helper for eval_remove_const to build non-const type.  */
    3762              : 
    3763              : static tree
    3764           94 : remove_const (tree type)
    3765              : {
    3766           94 :   return cp_build_qualified_type (type,
    3767           94 :                                   cp_type_quals (type) & ~TYPE_QUAL_CONST);
    3768              : }
    3769              : 
    3770              : /* Process std::meta::annotations_of and annotations_of_with_type.
    3771              :    Let E be
    3772              :    -- the corresponding base-specifier if item represents a direct base class
    3773              :       relationship,
    3774              :    -- otherwise, the entity represented by item.
    3775              :    Returns: A vector containing all of the reflections R representing each
    3776              :    annotation applying to each declaration of E that precedes either some
    3777              :    point in the evaluation context or a point immediately following the
    3778              :    class-specifier of the outermost class for which such a point is in a
    3779              :    complete-class context.
    3780              :    For any two reflections R1 and R2 in the returned vector, if the annotation
    3781              :    represented by R1 precedes the annotation represented by R2, then R1
    3782              :    appears before R2.
    3783              :    If R1 and R2 represent annotations from the same translation unit T, any
    3784              :    element in the returned vector between R1 and R2 represents an annotation
    3785              :    from T.
    3786              : 
    3787              :    Throws: meta::exception unless item represents a type, type alias,
    3788              :    variable, function, namespace, enumerator, direct base class relationship,
    3789              :    or non-static data member.  */
    3790              : 
    3791              : static tree
    3792          269 : eval_annotations_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3793              :                      reflect_kind kind, tree type, bool *non_constant_p,
    3794              :                      tree *jump_target, tree fun)
    3795              : {
    3796          275 :   if (!(eval_is_type (r) == boolean_true_node
    3797          228 :         || eval_is_type_alias (r) == boolean_true_node
    3798          228 :         || eval_is_variable (r, kind) == boolean_true_node
    3799          120 :         || eval_is_function (r) == boolean_true_node
    3800           52 :         || eval_is_namespace (r) == boolean_true_node
    3801           36 :         || eval_is_enumerator (r) == boolean_true_node
    3802           34 :         || eval_is_base (r, kind) == boolean_true_node
    3803            6 :         || eval_is_nonstatic_data_member (r) == boolean_true_node))
    3804            0 :     return throw_exception (loc, ctx,
    3805              :                             "reflection does not represent a type,"
    3806              :                             " type alias, variable, function, namespace,"
    3807              :                             " enumerator, direct base class relationship,"
    3808              :                             " or non-static data member",
    3809            0 :                             fun, non_constant_p, jump_target);
    3810              : 
    3811          269 :   if (type)
    3812              :     {
    3813           14 :       type = maybe_strip_typedefs (type);
    3814           14 :       if (!TYPE_P (type)
    3815           14 :           || !complete_type_or_maybe_complain (type, NULL_TREE, tf_none))
    3816            0 :         return throw_exception (loc, ctx,
    3817              :                                 "reflection does not represent a complete"
    3818              :                                 " type or type alias", fun, non_constant_p,
    3819            0 :                                 jump_target);
    3820           14 :       type = remove_const (type);
    3821              :     }
    3822              : 
    3823          269 :   r = maybe_get_first_fn (r);
    3824          269 :   if (kind == REFLECT_BASE)
    3825              :     {
    3826           28 :       gcc_assert (TREE_CODE (r) == TREE_BINFO);
    3827           28 :       tree c = direct_base_derived_binfo (r), binfo = r, base_binfo;
    3828              : 
    3829           28 :       r = NULL_TREE;
    3830           72 :       for (unsigned ix = 0; BINFO_BASE_ITERATE (c, ix, base_binfo); ix++)
    3831           72 :         if (base_binfo == binfo)
    3832              :           {
    3833           56 :             if (ix + BINFO_BASE_BINFOS (c)->length ()
    3834           28 :                 < vec_safe_length (BINFO_BASE_ACCESSES (c)))
    3835           26 :               r = BINFO_BASE_ACCESS (c, ix + BINFO_BASE_BINFOS (c)->length ());
    3836              :             break;
    3837              :           }
    3838              :     }
    3839          241 :   else if (TYPE_P (r))
    3840              :     {
    3841           41 :       complete_type (r);
    3842           41 :       if (typedef_variant_p (r))
    3843            4 :         r = DECL_ATTRIBUTES (TYPE_NAME (r));
    3844              :       else
    3845           37 :         r = TYPE_ATTRIBUTES (r);
    3846              :     }
    3847          200 :   else if (DECL_P (r))
    3848          200 :     r = DECL_ATTRIBUTES (r);
    3849              :   else
    3850            0 :     gcc_unreachable ();
    3851          269 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3852         1272 :   for (tree a = r; (a = lookup_attribute ("internal ", "annotation ", a));
    3853         1003 :        a = TREE_CHAIN (a))
    3854              :     {
    3855         1003 :       gcc_checking_assert (TREE_CODE (TREE_VALUE (a)) == TREE_LIST);
    3856         1003 :       tree val = TREE_VALUE (TREE_VALUE (a));
    3857         1003 :       if (type)
    3858              :         {
    3859           91 :           tree at = TREE_TYPE (val);
    3860           91 :           if (at != type && !same_type_p (remove_const (at), type))
    3861           69 :             continue;
    3862              :         }
    3863         1937 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3864              :                               get_reflection_raw (loc, a, REFLECT_ANNOTATION));
    3865              :     }
    3866          269 :   if (elts)
    3867              :     {
    3868              :       /* Reverse the order.  */
    3869          256 :       unsigned l = elts->length ();
    3870          256 :       constructor_elt *ptr = elts->address ();
    3871              : 
    3872          665 :       for (unsigned i = 0; i < l / 2; i++)
    3873          409 :         std::swap (ptr[i], ptr[l - i - 1]);
    3874              :     }
    3875          269 :   return get_vector_of_info_elts (elts);
    3876              : }
    3877              : 
    3878              : /* Process std::meta::reflect_constant.
    3879              :    Mandates: is_copy_constructible_v<T> is true and T is a cv-unqualified
    3880              :    structural type that is not a reference type.
    3881              :    Let V be:
    3882              :    -- if T is a class type, then an object that is template-argument-equivalent
    3883              :       to the value of expr;
    3884              :    -- otherwise, the value of expr.
    3885              :    Returns: template_arguments_of(^^TCls<V>)[0], with TCls as defined below.
    3886              :    Throws: meta::exception unless the template-id TCls<V> would be valid given
    3887              :    the invented template
    3888              :      template<T P> struct TCls;  */
    3889              : 
    3890              : static tree
    3891          697 : eval_reflect_constant (location_t loc, const constexpr_ctx *ctx, tree type,
    3892              :                        tree expr, bool *non_constant_p, tree *jump_target,
    3893              :                        tree fun)
    3894              : {
    3895          697 :   if (!structural_type_p (type)
    3896          694 :       || CP_TYPE_VOLATILE_P (type)
    3897          694 :       || CP_TYPE_CONST_P (type)
    3898         1391 :       || TYPE_REF_P (type))
    3899              :     {
    3900            3 :       error_at (loc, "%qT must be a cv-unqualified structural type that is "
    3901              :                 "not a reference type", type);
    3902            3 :       return error_mark_node;
    3903              :     }
    3904          694 :   expr = convert_reflect_constant_arg (type, convert_from_reference (expr));
    3905          694 :   if (expr == error_mark_node)
    3906           15 :     return throw_exception (loc, ctx, "reflect_constant failed", fun,
    3907           15 :                             non_constant_p, jump_target);
    3908          679 :   return get_reflection_raw (loc, expr, get_reflection_kind (expr));
    3909              : }
    3910              : 
    3911              : /* Process std::meta::reflect_object.
    3912              :    Mandates: T is an object type.
    3913              :    Returns: A reflection of the object designated by expr.
    3914              :    Throws: meta::exception unless expr is suitable for use as a constant
    3915              :    template argument for a constant template parameter of type T&.  */
    3916              : 
    3917              : static tree
    3918          121 : eval_reflect_object (location_t loc, const constexpr_ctx *ctx, tree type,
    3919              :                      tree expr, bool *non_constant_p, tree *jump_target,
    3920              :                      tree fun)
    3921              : {
    3922          242 :   if (eval_is_object_type (loc, type) != boolean_true_node)
    3923              :     {
    3924            0 :       error_at (loc, "%qT must be an object type", TREE_TYPE (type));
    3925            0 :       return error_mark_node;
    3926              :     }
    3927          121 :   type = cp_build_reference_type (type, /*rval=*/false);
    3928          121 :   tree e = convert_reflect_constant_arg (type, convert_from_reference (expr));
    3929          121 :   if (e == error_mark_node)
    3930            4 :     return throw_exception (loc, ctx, "reflect_object failed", fun,
    3931            4 :                             non_constant_p, jump_target);
    3932              :   /* We got (const T &) &foo.  Get the referent, since we want the object
    3933              :      designated by EXPR.  */
    3934          117 :   expr = maybe_get_reference_referent (expr);
    3935          117 :   return get_reflection_raw (loc, expr, REFLECT_OBJECT);
    3936              : }
    3937              : 
    3938              : /* Process std::meta::reflect_function.
    3939              :    Mandates: T is a function type.
    3940              :    Returns: A reflection of the function designated by fn.
    3941              :    Throws: meta::exception unless fn is suitable for use as a constant
    3942              :    template argument for a constant template parameter of type T&.  */
    3943              : 
    3944              : static tree
    3945           31 : eval_reflect_function (location_t loc, const constexpr_ctx *ctx, tree type,
    3946              :                        tree expr, bool *non_constant_p, tree *jump_target,
    3947              :                        tree fun)
    3948              : {
    3949           31 :   if (eval_is_function_type (type) != boolean_true_node)
    3950              :     {
    3951            0 :       error_at (loc, "%qT must be a function type", TREE_TYPE (type));
    3952            0 :       return error_mark_node;
    3953              :     }
    3954           31 :   type = cp_build_reference_type (type, /*rval=*/false);
    3955           31 :   tree e = convert_reflect_constant_arg (type, convert_from_reference (expr));
    3956           31 :   if (e == error_mark_node)
    3957            2 :     return throw_exception (loc, ctx, "reflect_function failed", fun,
    3958            2 :                             non_constant_p, jump_target);
    3959              :   /* We got (void (&<Ta885>) (void)) fn.  Get the function.  */
    3960           29 :   expr = maybe_get_reference_referent (expr);
    3961           29 :   return get_reflection_raw (loc, expr);
    3962              : }
    3963              : 
    3964              : /* Reflection type traits [meta.reflection.traits].
    3965              : 
    3966              :    Every function and function template declared in this subclause throws
    3967              :    an exception of type meta::exception unless the following conditions are
    3968              :    met:
    3969              :    -- For every parameter p of type info, is_type(p) is true.
    3970              :    -- For every parameter r whose type is constrained on reflection_range,
    3971              :       ranges::all_of(r, is_type) is true.  */
    3972              : 
    3973              : /* Evaluate reflection type traits for which we have corresponding built-in
    3974              :    traits.  KIND says which trait we are interested in; TYPE1 and TYPE2 are
    3975              :    arguments to the trait.  */
    3976              : 
    3977              : static tree
    3978         2501 : eval_type_trait (location_t loc, tree type1, tree type2, cp_trait_kind kind)
    3979              : {
    3980         2501 :   tree r = finish_trait_expr (loc, kind, type1, type2);
    3981         2501 :   gcc_checking_assert (r != error_mark_node);
    3982         2501 :   STRIP_ANY_LOCATION_WRAPPER (r);
    3983         2501 :   return r;
    3984              : }
    3985              : 
    3986              : /* Like above, but for type traits that take only one type.  */
    3987              : 
    3988              : static tree
    3989         1794 : eval_type_trait (location_t loc, tree type, cp_trait_kind kind)
    3990              : {
    3991            0 :   return eval_type_trait (loc, type, NULL_TREE, kind);
    3992              : }
    3993              : 
    3994              : /* Process std::meta::is_function_type.  */
    3995              : 
    3996              : static tree
    3997          537 : eval_is_function_type (tree type)
    3998              : {
    3999          497 :   if (FUNC_OR_METHOD_TYPE_P (type))
    4000           46 :     return boolean_true_node;
    4001              :   else
    4002          407 :     return boolean_false_node;
    4003              : }
    4004              : 
    4005              : /* Process std::meta::is_void_type.  */
    4006              : 
    4007              : static tree
    4008           29 : eval_is_void_type (tree type)
    4009              : {
    4010            0 :   if (VOID_TYPE_P (type))
    4011            3 :     return boolean_true_node;
    4012              :   else
    4013           26 :     return boolean_false_node;
    4014              : }
    4015              : 
    4016              : /* Process std::meta::is_null_pointer_type.  */
    4017              : 
    4018              : static tree
    4019           26 : eval_is_null_pointer_type (tree type)
    4020              : {
    4021            0 :   if (NULLPTR_TYPE_P (type))
    4022            1 :     return boolean_true_node;
    4023              :   else
    4024           25 :     return boolean_false_node;
    4025              : }
    4026              : 
    4027              : /* Process std::meta::is_integral_type.  */
    4028              : 
    4029              : static tree
    4030          130 : eval_is_integral_type (tree type)
    4031              : {
    4032            0 :   if (CP_INTEGRAL_TYPE_P (type))
    4033           60 :     return boolean_true_node;
    4034              :   else
    4035           70 :     return boolean_false_node;
    4036              : }
    4037              : 
    4038              : /* Process std::meta::is_floating_point_type.  */
    4039              : 
    4040              : static tree
    4041           28 : eval_is_floating_point_type (tree type)
    4042              : {
    4043           28 :   if (FLOAT_TYPE_P (type))
    4044            3 :     return boolean_true_node;
    4045              :   else
    4046           25 :     return boolean_false_node;
    4047              : }
    4048              : 
    4049              : /* Process std::meta::is_array_type.  */
    4050              : 
    4051              : static tree
    4052          514 : eval_is_array_type (location_t loc, tree type)
    4053              : {
    4054          421 :   return eval_type_trait (loc, type, CPTK_IS_ARRAY);
    4055              : }
    4056              : 
    4057              : /* Process std::meta::is_pointer_type.  */
    4058              : 
    4059              : static tree
    4060           28 : eval_is_pointer_type (location_t loc, tree type)
    4061              : {
    4062            0 :   return eval_type_trait (loc, type, CPTK_IS_POINTER);
    4063              : }
    4064              : 
    4065              : /* Process std::meta::is_lvalue_reference_type.  */
    4066              : 
    4067              : static tree
    4068           26 : eval_is_lvalue_reference_type (tree type)
    4069              : {
    4070            2 :   if (TYPE_REF_P (type) && !TYPE_REF_IS_RVALUE (type))
    4071            1 :     return boolean_true_node;
    4072              :   else
    4073           25 :     return boolean_false_node;
    4074              : }
    4075              : 
    4076              : /* Process std::meta::is_rvalue_reference_type.  */
    4077              : 
    4078              : static tree
    4079           26 : eval_is_rvalue_reference_type (tree type)
    4080              : {
    4081            2 :   if (TYPE_REF_P (type) && TYPE_REF_IS_RVALUE (type))
    4082            1 :     return boolean_true_node;
    4083              :   else
    4084           25 :     return boolean_false_node;
    4085              : }
    4086              : 
    4087              : /* Process std::meta::is_member_object_pointer_type.  */
    4088              : 
    4089              : static tree
    4090           26 : eval_is_member_object_pointer_type (location_t loc, tree type)
    4091              : {
    4092            0 :   return eval_type_trait (loc, type, CPTK_IS_MEMBER_OBJECT_POINTER);
    4093              : }
    4094              : 
    4095              : /* Process std::meta::is_member_function_pointer_type.  */
    4096              : 
    4097              : static tree
    4098           26 : eval_is_member_function_pointer_type (location_t loc, tree type)
    4099              : {
    4100            0 :   return eval_type_trait (loc, type, CPTK_IS_MEMBER_FUNCTION_POINTER);
    4101              : }
    4102              : 
    4103              : /* Process std::meta::is_enum_type.  */
    4104              : 
    4105              : static tree
    4106           26 : eval_is_enum_type (location_t loc, tree type)
    4107              : {
    4108            0 :   return eval_type_trait (loc, type, CPTK_IS_ENUM);
    4109              : }
    4110              : 
    4111              : /* Process std::meta::is_union_type.  */
    4112              : 
    4113              : static tree
    4114           38 : eval_is_union_type (location_t loc, tree type)
    4115              : {
    4116            0 :   return eval_type_trait (loc, type, CPTK_IS_UNION);
    4117              : }
    4118              : 
    4119              : /* Process std::meta::is_class_type.  */
    4120              : 
    4121              : static tree
    4122          147 : eval_is_class_type (location_t loc, tree type)
    4123              : {
    4124            0 :   return eval_type_trait (loc, type, CPTK_IS_CLASS);
    4125              : }
    4126              : 
    4127              : /* Process std::meta::is_reflection_type.  */
    4128              : 
    4129              : static tree
    4130           26 : eval_is_reflection_type (tree type)
    4131              : {
    4132            0 :   if (REFLECTION_TYPE_P (type))
    4133            1 :     return boolean_true_node;
    4134              :   else
    4135           25 :     return boolean_false_node;
    4136              : }
    4137              : 
    4138              : /* Process std::meta::is_reference_type.  */
    4139              : 
    4140              : static tree
    4141          517 : eval_is_reference_type (location_t loc, tree type)
    4142              : {
    4143            0 :   return eval_type_trait (loc, type, CPTK_IS_REFERENCE);
    4144              : }
    4145              : 
    4146              : /* Process std::meta::is_arithmetic_type.  */
    4147              : 
    4148              : static tree
    4149           28 : eval_is_arithmetic_type (tree type)
    4150              : {
    4151           28 :   if (ARITHMETIC_TYPE_P (type))
    4152            6 :     return boolean_true_node;
    4153              :   else
    4154           22 :     return boolean_false_node;
    4155              : }
    4156              : 
    4157              : /* Process std::meta::is_object_type.  */
    4158              : 
    4159              : static tree
    4160          149 : eval_is_object_type (location_t loc, tree type)
    4161              : {
    4162          121 :   return eval_type_trait (loc, type, CPTK_IS_OBJECT);
    4163              : }
    4164              : 
    4165              : /* Process std::meta::is_scalar_type.  */
    4166              : 
    4167              : static tree
    4168           28 : eval_is_scalar_type (tree type)
    4169              : {
    4170           28 :   if (SCALAR_TYPE_P (type))
    4171           13 :     return boolean_true_node;
    4172              :   else
    4173           15 :     return boolean_false_node;
    4174              : }
    4175              : 
    4176              : /* Process std::meta::is_fundamental_type.  */
    4177              : 
    4178              : static tree
    4179           56 : eval_is_fundamental_type (tree type)
    4180              : {
    4181           56 :   if (ARITHMETIC_TYPE_P (type)
    4182              :       || VOID_TYPE_P (type)
    4183              :       || NULLPTR_TYPE_P (type)
    4184              :       || REFLECTION_TYPE_P (type))
    4185           18 :     return boolean_true_node;
    4186              :   else
    4187           38 :     return boolean_false_node;
    4188              : }
    4189              : 
    4190              : /* Process std::meta::is_compound_type.  */
    4191              : 
    4192              : static tree
    4193           28 : eval_is_compound_type (tree type)
    4194              : {
    4195           28 :   if (eval_is_fundamental_type (type) == boolean_false_node)
    4196           19 :     return boolean_true_node;
    4197              :   else
    4198              :     return boolean_false_node;
    4199              : }
    4200              : 
    4201              : /* Process std::meta::is_member_pointer_type.  */
    4202              : 
    4203              : static tree
    4204           28 : eval_is_member_pointer_type (location_t loc, tree type)
    4205              : {
    4206            0 :   return eval_type_trait (loc, type, CPTK_IS_MEMBER_POINTER);
    4207              : }
    4208              : 
    4209              : /* Process std::meta::is_const_type.  */
    4210              : 
    4211              : static tree
    4212            8 : eval_is_const_type (tree type)
    4213              : {
    4214            8 :   if (CP_TYPE_CONST_P (type))
    4215            4 :     return boolean_true_node;
    4216              :   else
    4217            4 :     return boolean_false_node;
    4218              : }
    4219              : 
    4220              : /* Process std::meta::is_volatile_type.  */
    4221              : 
    4222              : static tree
    4223            8 : eval_is_volatile_type (tree type)
    4224              : {
    4225            8 :   if (CP_TYPE_VOLATILE_P (type))
    4226            4 :     return boolean_true_node;
    4227              :   else
    4228            4 :     return boolean_false_node;
    4229              : }
    4230              : 
    4231              : /* Process std::meta::is_trivially_copyable_type.  */
    4232              : 
    4233              : static tree
    4234           39 : eval_is_trivially_copyable_type (tree type)
    4235              : {
    4236           39 :   if (trivially_copyable_p (type))
    4237           29 :     return boolean_true_node;
    4238              :   else
    4239           10 :     return boolean_false_node;
    4240              : }
    4241              : 
    4242              : /* Process std::meta::is_standard_layout_type.  */
    4243              : 
    4244              : static tree
    4245            4 : eval_is_standard_layout_type (tree type)
    4246              : {
    4247            4 :   if (std_layout_type_p (type))
    4248            2 :     return boolean_true_node;
    4249              :   else
    4250            2 :     return boolean_false_node;
    4251              : }
    4252              : 
    4253              : /* Process std::meta::is_empty_type.  */
    4254              : 
    4255              : static tree
    4256           15 : eval_is_empty_type (location_t loc, tree type)
    4257              : {
    4258            0 :   return eval_type_trait (loc, type, CPTK_IS_EMPTY);
    4259              : }
    4260              : 
    4261              : /* Process std::meta::is_polymorphic_type.  */
    4262              : 
    4263              : static tree
    4264           10 : eval_is_polymorphic_type (location_t loc, tree type)
    4265              : {
    4266            0 :   return eval_type_trait (loc, type, CPTK_IS_POLYMORPHIC);
    4267              : }
    4268              : 
    4269              : /* Process std::meta::is_abstract_type.  */
    4270              : 
    4271              : static tree
    4272            5 : eval_is_abstract_type (tree type)
    4273              : {
    4274            5 :   if (ABSTRACT_CLASS_TYPE_P (type))
    4275            1 :     return boolean_true_node;
    4276              :   else
    4277            4 :     return boolean_false_node;
    4278              : }
    4279              : 
    4280              : /* Process std::meta::is_final_type.  */
    4281              : 
    4282              : static tree
    4283            3 : eval_is_final_type (location_t loc, tree type)
    4284              : {
    4285            0 :   return eval_type_trait (loc, type, CPTK_IS_FINAL);
    4286              : }
    4287              : 
    4288              : /* Process std::meta::is_final.
    4289              :    Returns: true if r represents a final class or a final member function.
    4290              :    Otherwise, false.  */
    4291              : 
    4292              : static tree
    4293           20 : eval_is_final (tree r)
    4294              : {
    4295           20 :   if (eval_is_function (r) == boolean_true_node)
    4296              :     {
    4297            9 :       r = maybe_get_first_fn (r);
    4298            9 :       if (TREE_CODE (r) == FUNCTION_DECL && DECL_FINAL_P (r))
    4299              :         return boolean_true_node;
    4300              :       else
    4301            4 :         return boolean_false_node;
    4302              :     }
    4303              : 
    4304           11 :   if (eval_is_type (r) == boolean_true_node
    4305            7 :       && CLASS_TYPE_P (r)
    4306           18 :       && CLASSTYPE_FINAL (r))
    4307              :     return boolean_true_node;
    4308              : 
    4309            8 :   return boolean_false_node;
    4310              : }
    4311              : 
    4312              : /* Process std::meta::is_aggregate_type.  */
    4313              : 
    4314              : static tree
    4315           24 : eval_is_aggregate_type (tree type)
    4316              : {
    4317           24 :   if (CP_AGGREGATE_TYPE_P (type))
    4318           11 :     return boolean_true_node;
    4319              :   else
    4320           13 :     return boolean_false_node;
    4321              : }
    4322              : 
    4323              : /* Process std::meta::is_consteval_only_type.  */
    4324              : 
    4325              : static tree
    4326           39 : eval_is_consteval_only_type (tree type)
    4327              : {
    4328           39 :   if (consteval_only_p (type))
    4329           24 :     return boolean_true_node;
    4330              :   else
    4331           15 :     return boolean_false_node;
    4332              : }
    4333              : 
    4334              : /* Process std::meta::is_signed_type.  */
    4335              : 
    4336              : static tree
    4337           17 : eval_is_signed_type (tree type)
    4338              : {
    4339           17 :   if (ARITHMETIC_TYPE_P (type) && !TYPE_UNSIGNED (type))
    4340           10 :     return boolean_true_node;
    4341              :   else
    4342            7 :     return boolean_false_node;
    4343              : }
    4344              : 
    4345              : /* Process std::meta::is_unsigned_type.  */
    4346              : 
    4347              : static tree
    4348           17 : eval_is_unsigned_type (tree type)
    4349              : {
    4350           17 :   if (ARITHMETIC_TYPE_P (type) && TYPE_UNSIGNED (type))
    4351            5 :     return boolean_true_node;
    4352              :   else
    4353           12 :     return boolean_false_node;
    4354              : }
    4355              : 
    4356              : /* Process std::meta::is_bounded_array_type.  */
    4357              : 
    4358              : static tree
    4359          107 : eval_is_bounded_array_type (location_t loc, tree type)
    4360              : {
    4361           89 :   return eval_type_trait (loc, type, CPTK_IS_BOUNDED_ARRAY);
    4362              : }
    4363              : 
    4364              : /* Process std::meta::is_unbounded_array_type.  */
    4365              : 
    4366              : static tree
    4367           21 : eval_is_unbounded_array_type (tree type)
    4368              : {
    4369           21 :   if (array_of_unknown_bound_p (type))
    4370            7 :     return boolean_true_node;
    4371              :   else
    4372           14 :     return boolean_false_node;
    4373              : }
    4374              : 
    4375              : /* Process std::meta::is_scoped_enum_type.  */
    4376              : 
    4377              : static tree
    4378           18 : eval_is_scoped_enum_type (tree type)
    4379              : {
    4380            4 :   if (SCOPED_ENUM_P (type))
    4381            2 :     return boolean_true_node;
    4382              :   else
    4383           16 :     return boolean_false_node;
    4384              : }
    4385              : 
    4386              : /* Process std::meta::is_constructible_type.  */
    4387              : 
    4388              : static tree
    4389          622 : eval_is_constructible_type (tree type, tree tvec)
    4390              : {
    4391          622 :   if (is_xible (INIT_EXPR, type, tvec))
    4392          158 :     return boolean_true_node;
    4393              :   else
    4394          464 :     return boolean_false_node;
    4395              : }
    4396              : 
    4397              : /* Process std::meta::is_default_constructible_type.  */
    4398              : 
    4399              : static tree
    4400          104 : eval_is_default_constructible_type (tree type)
    4401              : {
    4402          104 :   if (is_xible (INIT_EXPR, type, make_tree_vec (0)))
    4403           63 :     return boolean_true_node;
    4404              :   else
    4405           41 :     return boolean_false_node;
    4406              : }
    4407              : 
    4408              : /* Process std::meta::is_copy_constructible_type.  */
    4409              : 
    4410              : static tree
    4411           25 : eval_is_copy_constructible_type (tree type)
    4412              : {
    4413           25 :   tree arg = make_tree_vec (1);
    4414           25 :   TREE_VEC_ELT (arg, 0)
    4415           25 :     = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST, false);
    4416           25 :   if (is_xible (INIT_EXPR, type, arg))
    4417           11 :     return boolean_true_node;
    4418              :   else
    4419           14 :     return boolean_false_node;
    4420              : }
    4421              : 
    4422              : /* Process std::meta::is_move_constructible_type.  */
    4423              : 
    4424              : static tree
    4425           25 : eval_is_move_constructible_type (tree type)
    4426              : {
    4427           25 :   tree arg = make_tree_vec (1);
    4428           25 :   TREE_VEC_ELT (arg, 0) = cp_build_reference_type (type, /*rval=*/true);
    4429           25 :   if (is_xible (INIT_EXPR, type, arg))
    4430           10 :     return boolean_true_node;
    4431              :   else
    4432           15 :     return boolean_false_node;
    4433              : }
    4434              : 
    4435              : /* Process std::meta::is_assignable_type.  */
    4436              : 
    4437              : static tree
    4438          497 : eval_is_assignable_type (location_t loc, tree type1, tree type2)
    4439              : {
    4440            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_ASSIGNABLE);
    4441              : }
    4442              : 
    4443              : /* Process std::meta::is_copy_assignable_type.  */
    4444              : 
    4445              : static tree
    4446           25 : eval_is_copy_assignable_type (tree type)
    4447              : {
    4448           25 :   tree type1 = cp_build_reference_type (type, /*rval=*/false);
    4449           25 :   tree type2 = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST,
    4450              :                                 false);
    4451           25 :   if (is_xible (MODIFY_EXPR, type1, type2))
    4452            9 :     return boolean_true_node;
    4453              :   else
    4454           16 :     return boolean_false_node;
    4455              : }
    4456              : 
    4457              : /* Process std::meta::is_move_assignable_type.  */
    4458              : 
    4459              : static tree
    4460           25 : eval_is_move_assignable_type (tree type)
    4461              : {
    4462           25 :   tree type1 = cp_build_reference_type (type, /*rval=*/false);
    4463           25 :   tree type2 = cp_build_reference_type (type, /*rval=*/true);
    4464           25 :   if (is_xible (MODIFY_EXPR, type1, type2))
    4465           11 :     return boolean_true_node;
    4466              :   else
    4467           14 :     return boolean_false_node;
    4468              : }
    4469              : 
    4470              : /* Process std::meta::is_destructible_type.  */
    4471              : 
    4472              : static tree
    4473           72 : eval_is_destructible_type (location_t loc, tree type)
    4474              : {
    4475            0 :   return eval_type_trait (loc, type, CPTK_IS_DESTRUCTIBLE);
    4476              : }
    4477              : 
    4478              : /* Process std::meta::is_trivially_constructible_type.  */
    4479              : 
    4480              : static tree
    4481           73 : eval_is_trivially_constructible_type (tree type, tree tvec)
    4482              : {
    4483           73 :   if (is_trivially_xible (INIT_EXPR, type, tvec))
    4484           30 :     return boolean_true_node;
    4485              :   else
    4486           43 :     return boolean_false_node;
    4487              : }
    4488              : 
    4489              : /* Process std::meta::is_trivially_default_constructible_type.  */
    4490              : 
    4491              : static tree
    4492           17 : eval_is_trivially_default_constructible_type (tree type)
    4493              : {
    4494           17 :   if (is_trivially_xible (INIT_EXPR, type, make_tree_vec (0)))
    4495            4 :     return boolean_true_node;
    4496              :   else
    4497           13 :     return boolean_false_node;
    4498              : }
    4499              : 
    4500              : /* Process std::meta::is_trivially_copy_constructible_type.  */
    4501              : 
    4502              : static tree
    4503           20 : eval_is_trivially_copy_constructible_type (tree type)
    4504              : {
    4505           20 :   tree arg = make_tree_vec (1);
    4506           20 :   TREE_VEC_ELT (arg, 0)
    4507           20 :     = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST, false);
    4508           20 :   if (is_trivially_xible (INIT_EXPR, type, arg))
    4509            9 :     return boolean_true_node;
    4510              :   else
    4511           11 :     return boolean_false_node;
    4512              : }
    4513              : 
    4514              : /* Process std::meta::is_trivially_move_constructible_type.  */
    4515              : 
    4516              : static tree
    4517           20 : eval_is_trivially_move_constructible_type (tree type)
    4518              : {
    4519           20 :   tree arg = make_tree_vec (1);
    4520           20 :   TREE_VEC_ELT (arg, 0) = cp_build_reference_type (type, /*rval=*/true);
    4521           20 :   if (is_trivially_xible (INIT_EXPR, type, arg))
    4522            9 :     return boolean_true_node;
    4523              :   else
    4524           11 :     return boolean_false_node;
    4525              : }
    4526              : 
    4527              : /* Process std::meta::is_trivially_assignable_type.  */
    4528              : 
    4529              : static tree
    4530           54 : eval_is_trivially_assignable_type (location_t loc, tree type1, tree type2)
    4531              : {
    4532            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_TRIVIALLY_ASSIGNABLE);
    4533              : }
    4534              : 
    4535              : /* Process std::meta::is_trivially_copy_assignable_type.  */
    4536              : 
    4537              : static tree
    4538           23 : eval_is_trivially_copy_assignable_type (tree type)
    4539              : {
    4540           23 :   tree type1 = cp_build_reference_type (type, /*rval=*/false);
    4541           23 :   tree type2 = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST,
    4542              :                                 false);
    4543           23 :   if (is_trivially_xible (MODIFY_EXPR, type1, type2))
    4544           13 :     return boolean_true_node;
    4545              :   else
    4546           10 :     return boolean_false_node;
    4547              : }
    4548              : 
    4549              : /* Process std::meta::is_trivially_move_assignable_type.  */
    4550              : 
    4551              : static tree
    4552           23 : eval_is_trivially_move_assignable_type (tree type)
    4553              : {
    4554           23 :   tree type1 = cp_build_reference_type (type, /*rval=*/false);
    4555           23 :   tree type2 = cp_build_reference_type (type, /*rval=*/true);
    4556           23 :   if (is_trivially_xible (MODIFY_EXPR, type1, type2))
    4557           15 :     return boolean_true_node;
    4558              :   else
    4559            8 :     return boolean_false_node;
    4560              : }
    4561              : 
    4562              : /* Process std::meta::is_trivially_destructible_type.  */
    4563              : 
    4564              : static tree
    4565            5 : eval_is_trivially_destructible_type (location_t loc, tree type)
    4566              : {
    4567            0 :   return eval_type_trait (loc, type, CPTK_IS_TRIVIALLY_DESTRUCTIBLE);
    4568              : }
    4569              : 
    4570              : /* Process std::meta::is_nothrow_constructible_type.  */
    4571              : 
    4572              : static tree
    4573           50 : eval_is_nothrow_constructible_type (tree type, tree tvec)
    4574              : {
    4575           50 :   if (is_nothrow_xible (INIT_EXPR, type, tvec))
    4576           26 :     return boolean_true_node;
    4577              :   else
    4578           24 :     return boolean_false_node;
    4579              : }
    4580              : 
    4581              : /* Process std::meta::is_nothrow_default_constructible_type.  */
    4582              : 
    4583              : static tree
    4584           20 : eval_is_nothrow_default_constructible_type (tree type)
    4585              : {
    4586           20 :   if (is_nothrow_xible (INIT_EXPR, type, make_tree_vec (0)))
    4587           13 :     return boolean_true_node;
    4588              :   else
    4589            7 :     return boolean_false_node;
    4590              : }
    4591              : 
    4592              : /* Process std::meta::is_nothrow_copy_constructible_type.  */
    4593              : 
    4594              : static tree
    4595           25 : eval_is_nothrow_copy_constructible_type (tree type)
    4596              : {
    4597           25 :   tree arg = make_tree_vec (1);
    4598           25 :   TREE_VEC_ELT (arg, 0)
    4599           25 :     = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST, false);
    4600           25 :   if (is_nothrow_xible (INIT_EXPR, type, arg))
    4601            9 :     return boolean_true_node;
    4602              :   else
    4603           16 :     return boolean_false_node;
    4604              : }
    4605              : 
    4606              : /* Process std::meta::is_nothrow_move_constructible_type.  */
    4607              : 
    4608              : static tree
    4609           25 : eval_is_nothrow_move_constructible_type (tree type)
    4610              : {
    4611           25 :   tree arg = make_tree_vec (1);
    4612           25 :   TREE_VEC_ELT (arg, 0) = cp_build_reference_type (type, /*rval=*/true);
    4613           25 :   if (is_nothrow_xible (INIT_EXPR, type, arg))
    4614            8 :     return boolean_true_node;
    4615              :   else
    4616           17 :     return boolean_false_node;
    4617              : }
    4618              : 
    4619              : /* Process std::meta::is_nothrow_assignable_type.  */
    4620              : 
    4621              : static tree
    4622           10 : eval_is_nothrow_assignable_type (location_t loc, tree type1, tree type2)
    4623              : {
    4624            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_NOTHROW_ASSIGNABLE);
    4625              : }
    4626              : 
    4627              : /* Process std::meta::is_nothrow_copy_assignable_type.  */
    4628              : 
    4629              : static tree
    4630           25 : eval_is_nothrow_copy_assignable_type (tree type)
    4631              : {
    4632           25 :   tree type1 = cp_build_reference_type (type, /*rval=*/false);
    4633           25 :   tree type2 = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST,
    4634              :                                 false);
    4635           25 :   if (is_nothrow_xible (MODIFY_EXPR, type1, type2))
    4636            8 :     return boolean_true_node;
    4637              :   else
    4638           17 :     return boolean_false_node;
    4639              : }
    4640              : 
    4641              : /* Process std::meta::is_nothrow_move_assignable_type.  */
    4642              : 
    4643              : static tree
    4644           25 : eval_is_nothrow_move_assignable_type (tree type)
    4645              : {
    4646           25 :   tree type1 = cp_build_reference_type (type, /*rval=*/false);
    4647           25 :   tree type2 = cp_build_reference_type (type, /*rval=*/true);
    4648           25 :   if (is_nothrow_xible (MODIFY_EXPR, type1, type2))
    4649            9 :     return boolean_true_node;
    4650              :   else
    4651           16 :     return boolean_false_node;
    4652              : }
    4653              : 
    4654              : /* Process std::meta::is_nothrow_destructible_type.  */
    4655              : 
    4656              : static tree
    4657           83 : eval_is_nothrow_destructible_type (location_t loc, tree type)
    4658              : {
    4659            0 :   return eval_type_trait (loc, type, CPTK_IS_NOTHROW_DESTRUCTIBLE);
    4660              : }
    4661              : 
    4662              : /* Process std::meta::is_implicit_lifetime_type.  */
    4663              : 
    4664              : static tree
    4665           74 : eval_is_implicit_lifetime_type (tree type)
    4666              : {
    4667           74 :   if (implicit_lifetime_type_p (type))
    4668           58 :     return boolean_true_node;
    4669              :   else
    4670           16 :     return boolean_false_node;
    4671              : }
    4672              : 
    4673              : /* Process std::meta::has_virtual_destructor.  */
    4674              : 
    4675              : static tree
    4676           10 : eval_has_virtual_destructor (tree type)
    4677              : {
    4678           10 :   if (type_has_virtual_destructor (type))
    4679            1 :     return boolean_true_node;
    4680              :   else
    4681            9 :     return boolean_false_node;
    4682              : }
    4683              : 
    4684              : /* Process std::meta::has_unique_object_representations.  */
    4685              : 
    4686              : static tree
    4687           31 : eval_has_unique_object_representations (tree type)
    4688              : {
    4689           31 :   if (type_has_unique_obj_representations (type))
    4690           14 :     return boolean_true_node;
    4691              :   else
    4692           17 :     return boolean_false_node;
    4693              : }
    4694              : 
    4695              : /* Process std::meta::reference_constructs_from_temporary.  */
    4696              : 
    4697              : static tree
    4698           31 : eval_reference_constructs_from_temporary (location_t loc, tree type1,
    4699              :                                           tree type2)
    4700              : {
    4701            0 :   return eval_type_trait (loc, type1, type2,
    4702            0 :                           CPTK_REF_CONSTRUCTS_FROM_TEMPORARY);
    4703              : }
    4704              : 
    4705              : /* Process std::meta::reference_converts_from_temporary.  */
    4706              : 
    4707              : static tree
    4708           31 : eval_reference_converts_from_temporary (location_t loc, tree type1, tree type2)
    4709              : {
    4710            0 :   return eval_type_trait (loc, type1, type2, CPTK_REF_CONVERTS_FROM_TEMPORARY);
    4711              : }
    4712              : 
    4713              : /* Process std::meta::rank.  */
    4714              : 
    4715              : static tree
    4716           15 : eval_rank (tree type)
    4717              : {
    4718           15 :   size_t rank = 0;
    4719           43 :   for (; TREE_CODE (type) == ARRAY_TYPE; type = TREE_TYPE (type))
    4720           28 :     ++rank;
    4721           15 :   return build_int_cst (size_type_node, rank);
    4722              : }
    4723              : 
    4724              : /* Process std::meta::extent.  */
    4725              : 
    4726              : static tree
    4727          102 : eval_extent (location_t loc, tree type, tree i)
    4728              : {
    4729          102 :   size_t rank = tree_to_uhwi (i);
    4730          118 :   while (rank && TREE_CODE (type) == ARRAY_TYPE)
    4731              :     {
    4732           16 :       --rank;
    4733           16 :       type = TREE_TYPE (type);
    4734              :     }
    4735          102 :   tree r;
    4736          102 :   if (rank
    4737           98 :       || TREE_CODE (type) != ARRAY_TYPE
    4738          191 :       || eval_is_bounded_array_type (loc, type) == boolean_false_node)
    4739           21 :     r = size_zero_node;
    4740              :   else
    4741           81 :     r = size_binop (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
    4742              :                     size_one_node);
    4743              :   /* std::meta::extent returns a value of type size_t.  */
    4744          102 :   return cp_fold_convert (size_type_node, r);
    4745              : }
    4746              : 
    4747              : /* Process std::meta::is_same_type.  */
    4748              : 
    4749              : static tree
    4750           10 : eval_is_same_type (location_t loc, tree type1, tree type2)
    4751              : {
    4752            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_SAME);
    4753              : }
    4754              : 
    4755              : /* Process std::meta::is_base_of_type.  */
    4756              : 
    4757              : static tree
    4758            9 : eval_is_base_of_type (location_t loc, tree type1, tree type2)
    4759              : {
    4760            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_BASE_OF);
    4761              : }
    4762              : 
    4763              : /* Process std::meta::is_virtual_base_of_type.  */
    4764              : 
    4765              : static tree
    4766           19 : eval_is_virtual_base_of_type (location_t loc, tree type1, tree type2)
    4767              : {
    4768            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_VIRTUAL_BASE_OF);
    4769              : }
    4770              : 
    4771              : /* Process std::meta::is_convertible_type.  */
    4772              : 
    4773              : static tree
    4774            5 : eval_is_convertible_type (location_t loc, tree type1, tree type2)
    4775              : {
    4776            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_CONVERTIBLE);
    4777              : }
    4778              : 
    4779              : /* Process std::meta::is_nothrow_convertible_type.  */
    4780              : 
    4781              : static tree
    4782            7 : eval_is_nothrow_convertible_type (location_t loc, tree type1, tree type2)
    4783              : {
    4784            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_NOTHROW_CONVERTIBLE);
    4785              : }
    4786              : 
    4787              : /* Process std::meta::is_layout_compatible_type.  */
    4788              : 
    4789              : static tree
    4790           18 : eval_is_layout_compatible_type (location_t loc, tree type1, tree type2)
    4791              : {
    4792            0 :   return eval_type_trait (loc, type1, type2, CPTK_IS_LAYOUT_COMPATIBLE);
    4793              : }
    4794              : 
    4795              : /* Process std::meta::is_pointer_interconvertible_base_of_type.  */
    4796              : 
    4797              : static tree
    4798           16 : eval_is_pointer_interconvertible_base_of_type (location_t loc,
    4799              :                                                tree type1, tree type2)
    4800              : {
    4801            0 :   return eval_type_trait (loc, type1, type2,
    4802            0 :                           CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF);
    4803              : }
    4804              : 
    4805              : /* Process std::meta::is_invocable_type.  */
    4806              : 
    4807              : static tree
    4808           38 : eval_is_invocable_type (location_t loc, tree type, tree tvec)
    4809              : {
    4810           38 :   tree r = finish_trait_expr (loc, CPTK_IS_INVOCABLE, type, tvec);
    4811           38 :   STRIP_ANY_LOCATION_WRAPPER (r);
    4812           38 :   return r;
    4813              : }
    4814              : 
    4815              : /* Helper for various eval_* type trait functions which can't use builtin
    4816              :    trait and have to instantiate std::NAME<ARGS>::value.  */
    4817              : 
    4818              : static tree
    4819          377 : finish_library_value_trait (location_t loc, const constexpr_ctx *ctx,
    4820              :                             const char *name, tree args, tree call,
    4821              :                             bool *non_constant_p, tree *jump_target, tree fun)
    4822              : {
    4823          377 :   tree inst = lookup_template_class (get_identifier (name), args,
    4824              :                                      /*in_decl*/NULL_TREE, /*context*/std_node,
    4825              :                                      tf_warning_or_error);
    4826          377 :   inst = complete_type (inst);
    4827          377 :   if (inst == error_mark_node
    4828          377 :       || !COMPLETE_TYPE_P (inst)
    4829          748 :       || !CLASS_TYPE_P (inst))
    4830              :     {
    4831            6 :       if (!cxx_constexpr_quiet_p (ctx))
    4832            2 :         error_at (loc, "couldn%'t instantiate %<std::%s<%T>%>",
    4833              :                   name, args);
    4834            6 :       *non_constant_p = true;
    4835            6 :       return call;
    4836              :     }
    4837          371 :   tree val = lookup_qualified_name (inst, value_identifier,
    4838              :                                     LOOK_want::NORMAL, /*complain*/false);
    4839          371 :   if (val == error_mark_node)
    4840            0 :     return throw_exception (loc, ctx, "value member missing",
    4841            0 :                             fun, non_constant_p, jump_target);
    4842          371 :   if (VAR_P (val) || TREE_CODE (val) == CONST_DECL)
    4843          371 :     val = maybe_constant_value (val, NULL_TREE, mce_true);
    4844          371 :   if (TREE_CODE (TREE_TYPE (call)) == BOOLEAN_TYPE)
    4845              :     {
    4846          339 :       if (integer_zerop (val))
    4847          160 :         return boolean_false_node;
    4848          179 :       else if (integer_nonzerop (val))
    4849          179 :         return boolean_true_node;
    4850              :       else
    4851            0 :         return throw_exception (loc, ctx, "unexpected value of value member",
    4852            0 :                                 fun, non_constant_p, jump_target);
    4853              :     }
    4854           32 :   else if (TREE_CODE (val) == INTEGER_CST)
    4855              :     {
    4856           32 :       val = build_converted_constant_expr (TREE_TYPE (call), val, tf_none);
    4857           32 :       if (TREE_CODE (val) == INTEGER_CST)
    4858              :         return val;
    4859              :     }
    4860            0 :   return throw_exception (loc, ctx, "unexpected value of value member",
    4861            0 :                           fun, non_constant_p, jump_target);
    4862              : }
    4863              : 
    4864              : /* Process std::meta::is_{,nothrow_}invocable_r_type.  */
    4865              : 
    4866              : static tree
    4867          113 : eval_is_invocable_r_type (location_t loc, const constexpr_ctx *ctx,
    4868              :                           tree tres, tree type, tree tvec, tree call,
    4869              :                           bool *non_constant_p, tree *jump_target, tree fun,
    4870              :                           const char *name)
    4871              : {
    4872              :   /* Create std::is_invocable_r<TYPE>::value.  */
    4873          113 :   tree args = make_tree_vec (TREE_VEC_LENGTH (tvec) + 2);
    4874          113 :   TREE_VEC_ELT (args, 0) = tres;
    4875          113 :   TREE_VEC_ELT (args, 1) = type;
    4876          226 :   for (int i = 0; i < TREE_VEC_LENGTH (tvec); ++i)
    4877          113 :     TREE_VEC_ELT (args, i + 2) = TREE_VEC_ELT (tvec, i);
    4878          113 :   return finish_library_value_trait (loc, ctx, name, args, call,
    4879          113 :                                      non_constant_p, jump_target, fun);
    4880              : }
    4881              : 
    4882              : /* Process std::meta::is_nothrow_invocable_type.  */
    4883              : 
    4884              : static tree
    4885           28 : eval_is_nothrow_invocable_type (location_t loc, tree type, tree tvec)
    4886              : {
    4887           28 :   tree r = finish_trait_expr (loc, CPTK_IS_NOTHROW_INVOCABLE, type, tvec);
    4888           28 :   STRIP_ANY_LOCATION_WRAPPER (r);
    4889           28 :   return r;
    4890              : }
    4891              : 
    4892              : /* Process std::meta::is_{,nothrow_}swappable_with_type.  */
    4893              : 
    4894              : static tree
    4895           48 : eval_is_swappable_with_type (location_t loc, const constexpr_ctx *ctx,
    4896              :                              tree type1, tree type2, tree call,
    4897              :                              bool *non_constant_p, tree *jump_target, tree fun,
    4898              :                              const char *name)
    4899              : {
    4900              :   /* Create std::is_swappable_with<TYPE>::value.  */
    4901           48 :   tree args = make_tree_vec (2);
    4902           48 :   TREE_VEC_ELT (args, 0) = type1;
    4903           48 :   TREE_VEC_ELT (args, 1) = type2;
    4904           48 :   return finish_library_value_trait (loc, ctx, name, args, call,
    4905           48 :                                      non_constant_p, jump_target, fun);
    4906              : }
    4907              : 
    4908              : /* Process std::meta::is_{,nothrow_}swappable_type.  */
    4909              : 
    4910              : static tree
    4911          178 : eval_is_swappable_type (location_t loc, const constexpr_ctx *ctx,
    4912              :                         tree type, tree call, bool *non_constant_p,
    4913              :                         tree *jump_target, tree fun, const char *name)
    4914              : {
    4915              :   /* Create std::is_swappable<TYPE>::value.  */
    4916          178 :   tree args = make_tree_vec (1);
    4917          178 :   TREE_VEC_ELT (args, 0) = type;
    4918          178 :   return finish_library_value_trait (loc, ctx, name, args, call,
    4919          178 :                                      non_constant_p, jump_target, fun);
    4920              : }
    4921              : 
    4922              : /* Process std::meta::remove_cvref.  */
    4923              : 
    4924              : static tree
    4925           17 : eval_remove_cvref (location_t loc, tree type)
    4926              : {
    4927           17 :   if (TYPE_REF_P (type))
    4928            8 :     type = TREE_TYPE (type);
    4929           17 :   type = finish_trait_type (CPTK_REMOVE_CV, type, NULL_TREE, tf_none);
    4930           17 :   type = strip_typedefs (type);
    4931           17 :   return get_reflection_raw (loc, type);
    4932              : }
    4933              : 
    4934              : /* Process std::meta::decay.  */
    4935              : 
    4936              : static tree
    4937           21 : eval_decay (location_t loc, tree type)
    4938              : {
    4939           21 :   type = finish_trait_type (CPTK_DECAY, type, NULL_TREE, tf_none);
    4940           21 :   type = strip_typedefs (type);
    4941           21 :   return get_reflection_raw (loc, type);
    4942              : }
    4943              : 
    4944              : /* Helper for various eval_* type trait functions which can't use builtin
    4945              :    trait and have to instantiate std::NAME<ARGS>::type.  */
    4946              : 
    4947              : static tree
    4948          205 : finish_library_type_trait (location_t loc, const constexpr_ctx *ctx,
    4949              :                            const char *name, tree args, tree call,
    4950              :                            bool *non_constant_p, tree *jump_target, tree fun)
    4951              : {
    4952          205 :   tree inst = lookup_template_class (get_identifier (name), args,
    4953              :                                      /*in_decl*/NULL_TREE,
    4954              :                                      /*context*/std_node,
    4955              :                                      tf_warning_or_error);
    4956          205 :   if (inst == error_mark_node)
    4957              :     {
    4958            0 :       if (!cxx_constexpr_quiet_p (ctx))
    4959            0 :         error_at (loc, "couldn%'t instantiate %<std::%s<%T>%>",
    4960              :                   name, args);
    4961            0 :       *non_constant_p = true;
    4962            0 :       return call;
    4963              :     }
    4964          205 :   tree type = make_typename_type (inst, type_identifier,
    4965              :                                   none_type, tf_none);
    4966          205 :   if (type == error_mark_node)
    4967            9 :     return throw_exception (loc, ctx, "type member missing",
    4968            9 :                             fun, non_constant_p, jump_target);
    4969          196 :   type = strip_typedefs (type);
    4970          196 :   return get_reflection_raw (loc, type);
    4971              : }
    4972              : 
    4973              : /* Process std::meta::common_{type,reference}.  */
    4974              : 
    4975              : static tree
    4976          121 : eval_common_type (location_t loc, const constexpr_ctx *ctx, tree tvec,
    4977              :                   tree call, bool *non_constant_p, tree *jump_target, tree fun,
    4978              :                   const char *name)
    4979              : {
    4980            0 :   return finish_library_type_trait (loc, ctx, name, tvec, call,
    4981            0 :                                     non_constant_p, jump_target, fun);
    4982              : }
    4983              : 
    4984              : /* Process std::meta::underlying_type.  */
    4985              : 
    4986              : static tree
    4987           12 : eval_underlying_type (location_t loc, const constexpr_ctx *ctx, tree type,
    4988              :                       bool *non_constant_p, tree *jump_target, tree fun)
    4989              : {
    4990           12 :   if (TREE_CODE (type) != ENUMERAL_TYPE || !COMPLETE_TYPE_P (type))
    4991            4 :     return throw_exception (loc, ctx, "reflection does not represent "
    4992              :                                       "a complete enumeration type",
    4993            4 :                             fun, non_constant_p, jump_target);
    4994            8 :   type = finish_underlying_type (type);
    4995            8 :   type = strip_typedefs (type);
    4996            8 :   return get_reflection_raw (loc, type);
    4997              : }
    4998              : 
    4999              : /* Process std::meta::invoke_result.  */
    5000              : 
    5001              : static tree
    5002           10 : eval_invoke_result (location_t loc, const constexpr_ctx *ctx, tree type,
    5003              :                     tree tvec, tree call, bool *non_constant_p,
    5004              :                     tree *jump_target, tree fun)
    5005              : {
    5006           10 :   tree args = make_tree_vec (TREE_VEC_LENGTH (tvec) + 1);
    5007           10 :   TREE_VEC_ELT (args, 0) = type;
    5008           32 :   for (int i = 0; i < TREE_VEC_LENGTH (tvec); ++i)
    5009           22 :     TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (tvec, i);
    5010           10 :   return finish_library_type_trait (loc, ctx, "invoke_result", args, call,
    5011           10 :                                     non_constant_p, jump_target, fun);
    5012              : }
    5013              : 
    5014              : /* Process std::meta::unwrap_{reference,ref_decay}.  */
    5015              : 
    5016              : static tree
    5017           26 : eval_unwrap_reference (location_t loc, const constexpr_ctx *ctx, tree type,
    5018              :                        tree call, bool *non_constant_p, tree *jump_target,
    5019              :                        tree fun, const char *name)
    5020              : {
    5021           26 :   tree args = make_tree_vec (1);
    5022           26 :   TREE_VEC_ELT (args, 0) = type;
    5023           26 :   return finish_library_type_trait (loc, ctx, name, args, call,
    5024           26 :                                     non_constant_p, jump_target, fun);
    5025              : }
    5026              : 
    5027              : /* Process std::meta::type_order.  */
    5028              : 
    5029              : static tree
    5030           58 : eval_type_order (tree type1, tree type2)
    5031              : {
    5032           58 :   return type_order_value (strip_typedefs (type1), strip_typedefs (type2));
    5033              : }
    5034              : 
    5035              : /* Process std::meta::enumerators_of.
    5036              :    Returns: A vector containing the reflections of each enumerator of the
    5037              :    enumeration represented by dealias(type_enum), in the order in which they
    5038              :    are declared.
    5039              :    Throws: meta::exception unless dealias(type_enum) represents an enumeration
    5040              :    type, and is_enumerable_type(type_enum) is true.  */
    5041              : 
    5042              : static tree
    5043          157 : eval_enumerators_of (location_t loc, const constexpr_ctx *ctx, tree r,
    5044              :                      bool *non_constant_p, tree *jump_target, tree fun)
    5045              : {
    5046          157 :   if (TREE_CODE (r) != ENUMERAL_TYPE
    5047          157 :       || eval_is_enumerable_type (r) == boolean_false_node)
    5048           73 :     return throw_exception (loc, ctx, "reflection does not represent an "
    5049              :                                       "enumerable enumeration type", fun,
    5050           73 :                             non_constant_p, jump_target);
    5051           84 :   vec<constructor_elt, va_gc> *elts = nullptr;
    5052          434 :   for (tree t = TYPE_VALUES (r); t; t = TREE_CHAIN (t))
    5053              :     {
    5054          350 :       tree e = TREE_VALUE (t);
    5055          350 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, get_reflection_raw (loc, e));
    5056              :     }
    5057           84 :   return get_vector_of_info_elts (elts);
    5058              : }
    5059              : 
    5060              : /* Process std::meta::remove_const.
    5061              :    Returns: a reflection representing the type denoted by
    5062              :    std::remove_const_t<T>, where T is the type or type alias
    5063              :    represented by type.  */
    5064              : 
    5065              : static tree
    5066           11 : eval_remove_const (location_t loc, tree type)
    5067              : {
    5068           11 :   return get_reflection_raw (loc, remove_const (strip_typedefs (type)));
    5069              : }
    5070              : 
    5071              : /* Process std::meta::remove_volatile.
    5072              :    Returns: a reflection representing the type denoted by
    5073              :    std::remove_volatile_t<T>, where T is the type or type alias
    5074              :    represented by type.  */
    5075              : 
    5076              : static tree
    5077           12 : eval_remove_volatile (location_t loc, tree type)
    5078              : {
    5079           12 :   type = strip_typedefs (type);
    5080           12 :   int quals = cp_type_quals (type);
    5081           12 :   quals &= ~TYPE_QUAL_VOLATILE;
    5082           12 :   type = cp_build_qualified_type (type, quals);
    5083           12 :   return get_reflection_raw (loc, type);
    5084              : }
    5085              : 
    5086              : /* Process std::meta::remove_cv.
    5087              :    Returns: a reflection representing the type denoted by
    5088              :    std::remove_cv_t<T>, where T is the type or type alias
    5089              :    represented by type.  */
    5090              : 
    5091              : static tree
    5092           11 : eval_remove_cv (location_t loc, tree type)
    5093              : {
    5094           11 :   type = strip_typedefs (type);
    5095           11 :   type = finish_trait_type (CPTK_REMOVE_CV, type, NULL_TREE, tf_none);
    5096           11 :   return get_reflection_raw (loc, type);
    5097              : }
    5098              : 
    5099              : /* Process std::meta::add_const.
    5100              :    Returns: a reflection representing the type denoted by
    5101              :    std::add_const_t<T>, where T is the type or type alias
    5102              :    represented by type.  */
    5103              : 
    5104              : static tree
    5105           13 : eval_add_const (location_t loc, tree type)
    5106              : {
    5107           13 :   type = strip_typedefs (type);
    5108           13 :   if (!TYPE_REF_P (type) && !FUNC_OR_METHOD_TYPE_P (type))
    5109              :     {
    5110           10 :       int quals = cp_type_quals (type);
    5111           10 :       quals |= TYPE_QUAL_CONST;
    5112           10 :       type = cp_build_qualified_type (type, quals);
    5113              :     }
    5114           13 :   return get_reflection_raw (loc, type);
    5115              : }
    5116              : 
    5117              : /* Process std::meta::add_volatile.
    5118              :    Returns: a reflection representing the type denoted by
    5119              :    std::add_volatile_t<T>, where T is the type or type alias
    5120              :    represented by type.  */
    5121              : 
    5122              : static tree
    5123           13 : eval_add_volatile (location_t loc, tree type)
    5124              : {
    5125           13 :   type = strip_typedefs (type);
    5126           13 :   if (!TYPE_REF_P (type) && !FUNC_OR_METHOD_TYPE_P (type))
    5127              :     {
    5128           10 :       int quals = cp_type_quals (type);
    5129           10 :       quals |= TYPE_QUAL_VOLATILE;
    5130           10 :       type = cp_build_qualified_type (type, quals);
    5131              :     }
    5132           13 :   return get_reflection_raw (loc, type);
    5133              : }
    5134              : 
    5135              : /* Process std::meta::add_cv.
    5136              :    Returns: a reflection representing the type denoted by
    5137              :    std::add_cv_t<T>, where T is the type or type alias
    5138              :    represented by type.  */
    5139              : 
    5140              : static tree
    5141           13 : eval_add_cv (location_t loc, tree type)
    5142              : {
    5143           13 :   type = strip_typedefs (type);
    5144           13 :   if (!TYPE_REF_P (type) && !FUNC_OR_METHOD_TYPE_P (type))
    5145              :     {
    5146           10 :       int quals = cp_type_quals (type);
    5147           10 :       quals |= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
    5148           10 :       type = cp_build_qualified_type (type, quals);
    5149              :     }
    5150           13 :   return get_reflection_raw (loc, type);
    5151              : }
    5152              : 
    5153              : /* Process std::meta::remove_reference.
    5154              :    Returns: a reflection representing the type denoted by
    5155              :    std::remove_reference_t<T>, where T is the type or type alias
    5156              :    represented by type.  */
    5157              : 
    5158              : static tree
    5159           15 : eval_remove_reference (location_t loc, tree type)
    5160              : {
    5161           15 :   if (TYPE_REF_P (type))
    5162           10 :     type = TREE_TYPE (type);
    5163           15 :   type = strip_typedefs (type);
    5164           15 :   return get_reflection_raw (loc, type);
    5165              : }
    5166              : 
    5167              : /* Process std::meta::add_lvalue_reference.
    5168              :    Returns: a reflection representing the type denoted by
    5169              :    std::add_lvalue_reference_t<T>, where T is the type or type alias
    5170              :    represented by type.  */
    5171              : 
    5172              : static tree
    5173           16 : eval_add_lvalue_reference (location_t loc, tree type)
    5174              : {
    5175           16 :   type = strip_typedefs (type);
    5176           16 :   type = finish_trait_type (CPTK_ADD_LVALUE_REFERENCE, type, NULL_TREE, tf_none);
    5177           16 :   return get_reflection_raw (loc, type);
    5178              : }
    5179              : 
    5180              : /* Process std::meta::add_rvalue_reference.
    5181              :    Returns: a reflection representing the type denoted by
    5182              :    std::add_rvalue_reference_t<T>, where T is the type or type alias
    5183              :    represented by type.  */
    5184              : 
    5185              : static tree
    5186           15 : eval_add_rvalue_reference (location_t loc, tree type)
    5187              : {
    5188           15 :   type = strip_typedefs (type);
    5189           15 :   type = finish_trait_type (CPTK_ADD_RVALUE_REFERENCE, type, NULL_TREE, tf_none);
    5190           15 :   return get_reflection_raw (loc, type);
    5191              : }
    5192              : 
    5193              : /* Process std::meta::make_signed and std::meta::make_unsigned.
    5194              :    Returns: a reflection representing the type denoted by
    5195              :    std::make_signed_t<T> or std::make_unsigned_t<T>, respectively, where T is
    5196              :    the type or type alias represented by type.  */
    5197              : 
    5198              : static tree
    5199           50 : eval_make_signed (location_t loc, const constexpr_ctx *ctx, tree type,
    5200              :                   bool unsignedp, bool *non_constant_p, tree *jump_target,
    5201              :                   tree fun)
    5202              : {
    5203           50 :   if (!INTEGRAL_TYPE_P (type) || TREE_CODE (type) == BOOLEAN_TYPE)
    5204            6 :     return throw_exception (loc, ctx, "reflection represents non-integral "
    5205              :                                       "or bool type", fun, non_constant_p,
    5206            6 :                                       jump_target);
    5207           44 :   tree ret = type;
    5208           44 :   if (TREE_CODE (type) == ENUMERAL_TYPE
    5209           36 :       || TYPE_MAIN_VARIANT (type) == wchar_type_node
    5210           34 :       || TYPE_MAIN_VARIANT (type) == char8_type_node
    5211           32 :       || TYPE_MAIN_VARIANT (type) == char16_type_node
    5212           74 :       || TYPE_MAIN_VARIANT (type) == char32_type_node)
    5213              :     {
    5214           16 :       tree unit = TYPE_SIZE_UNIT (type);
    5215           16 :       tree types[] = {
    5216           16 :         signed_char_type_node,
    5217           16 :         short_integer_type_node,
    5218           16 :         integer_type_node,
    5219           16 :         long_integer_type_node,
    5220           16 :         long_long_integer_type_node };
    5221           16 :       ret = NULL_TREE;
    5222           38 :       for (unsigned i = 0; i < ARRAY_SIZE (types); ++i)
    5223           38 :         if (tree_int_cst_equal (TYPE_SIZE_UNIT (types[i]), unit))
    5224              :           {
    5225           16 :             ret = c_common_signed_or_unsigned_type (unsignedp, types[i]);
    5226           16 :             break;
    5227              :           }
    5228           16 :       if (!ret)
    5229            0 :         ret = c_common_type_for_size (TYPE_PRECISION (type), unsignedp);
    5230              :     }
    5231           28 :   else if (TYPE_MAIN_VARIANT (type) == char_type_node)
    5232            2 :     ret = unsignedp ? unsigned_char_type_node : signed_char_type_node;
    5233           26 :   else if (unsignedp ^ (!!TYPE_UNSIGNED (type)))
    5234           12 :     ret = c_common_signed_or_unsigned_type (unsignedp, type);
    5235           44 :   if (ret != type)
    5236              :     {
    5237           30 :       int quals = cp_type_quals (type);
    5238           30 :       quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
    5239           30 :       ret = cp_build_qualified_type (ret, quals);
    5240              :     }
    5241              :   else
    5242           14 :     ret = strip_typedefs (type);
    5243           44 :   return get_reflection_raw (loc, ret);
    5244              : }
    5245              : 
    5246              : /* Process std::meta::remove_extent.
    5247              :    Returns: a reflection representing the type denoted by
    5248              :    std::remove_extent_t<T>, where T is the type or type alias
    5249              :    represented by type.  */
    5250              : 
    5251              : static tree
    5252           12 : eval_remove_extent (location_t loc, tree type)
    5253              : {
    5254           12 :   if (TREE_CODE (type) == ARRAY_TYPE)
    5255            9 :     type = TREE_TYPE (type);
    5256           12 :   type = strip_typedefs (type);
    5257           12 :   return get_reflection_raw (loc, type);
    5258              : }
    5259              : 
    5260              : /* Process std::meta::remove_all_extents.
    5261              :    Returns: a reflection representing the type denoted by
    5262              :    std::remove_all_extents_t<T>, where T is the type or type alias
    5263              :    represented by type.  */
    5264              : 
    5265              : static tree
    5266           11 : eval_remove_all_extents (location_t loc, tree type)
    5267              : {
    5268           11 :   type = strip_array_types (type);
    5269           11 :   type = strip_typedefs (type);
    5270           11 :   return get_reflection_raw (loc, type);
    5271              : }
    5272              : 
    5273              : /* Process std::meta::remove_pointer.
    5274              :    Returns: a reflection representing the type denoted by
    5275              :    std::remove_pointer_t<T>, where T is the type or type alias
    5276              :    represented by type.  */
    5277              : 
    5278              : static tree
    5279           13 : eval_remove_pointer (location_t loc, tree type)
    5280              : {
    5281           13 :   if (TYPE_PTR_P (type))
    5282            9 :     type = TREE_TYPE (type);
    5283           13 :   type = strip_typedefs (type);
    5284           13 :   return get_reflection_raw (loc, type);
    5285              : }
    5286              : 
    5287              : /* Process std::meta::add_pointer.
    5288              :    Returns: a reflection representing the type denoted by
    5289              :    std::add_pointer_t<T>, where T is the type or type alias
    5290              :    represented by type.  */
    5291              : 
    5292              : static tree
    5293           17 : eval_add_pointer (location_t loc, tree type)
    5294              : {
    5295           17 :   type = strip_typedefs (type);
    5296           17 :   type = finish_trait_type (CPTK_ADD_POINTER, type, NULL_TREE, tf_none);
    5297           17 :   return get_reflection_raw (loc, type);
    5298              : }
    5299              : 
    5300              : /* Process std::meta::is_lvalue_reference_qualified and
    5301              :    std::meta::is_rvalue_reference_qualified.
    5302              :    Let T be type_of(r) if has-type(r) is true.  Otherwise, let T be
    5303              :    dealias(r).
    5304              :    Returns: true if T represents an lvalue- or rvalue-qualified
    5305              :    function type, respectively.  Otherwise, false.
    5306              :    RVALUE_P is true if we're processing is_rvalue_*, false if we're
    5307              :    processing is_lvalue_*.  */
    5308              : 
    5309              : static tree
    5310           45 : eval_is_lrvalue_reference_qualified (tree r, reflect_kind kind,
    5311              :                                      bool rvalue_p)
    5312              : {
    5313           45 :   if (has_type (r, kind))
    5314           18 :     r = type_of (r, kind);
    5315              :   else
    5316           27 :     r = maybe_strip_typedefs (r);
    5317           45 :   if (FUNC_OR_METHOD_TYPE_P (r)
    5318           42 :       && FUNCTION_REF_QUALIFIED (r)
    5319           65 :       && rvalue_p == FUNCTION_RVALUE_QUALIFIED (r))
    5320           10 :     return boolean_true_node;
    5321              : 
    5322           35 :   return boolean_false_node;
    5323              : }
    5324              : 
    5325              : /* Process std::meta::can_substitute.
    5326              :    Let Z be the template represented by templ and let Args... be a sequence of
    5327              :    prvalue constant expressions that compute the reflections held by the
    5328              :    elements of arguments, in order.
    5329              :    Returns: true if Z<[:Args:]...> is a valid template-id that does not name
    5330              :    a function whose type contains an undeduced placeholder type.
    5331              :    Otherwise, false.
    5332              :    Throws: meta::exception unless templ represents a template, and every
    5333              :    reflection in arguments represents a construct usable as a template
    5334              :    argument.  */
    5335              : 
    5336              : static tree
    5337          436 : eval_can_substitute (location_t loc, const constexpr_ctx *ctx,
    5338              :                      tree r, tree rvec, bool *non_constant_p, tree *jump_target,
    5339              :                      tree fun)
    5340              : {
    5341          436 :   if (eval_is_template (r) != boolean_true_node)
    5342          158 :     return throw_exception (loc, ctx,
    5343              :                             "reflection does not represent a template",
    5344          158 :                             fun, non_constant_p, jump_target);
    5345          603 :   for (int i = 0; i < TREE_VEC_LENGTH (rvec); ++i)
    5346              :     {
    5347          355 :       tree ra = TREE_VEC_ELT (rvec, i);
    5348          355 :       tree a = REFLECT_EXPR_HANDLE (ra);
    5349          355 :       reflect_kind kind = REFLECT_EXPR_KIND (ra);
    5350              :       // TODO: It is unclear on what kinds of reflections we should throw
    5351              :       // and what kinds of exceptions should merely result in can_substitute
    5352              :       // returning false.
    5353          355 :       if (a == unknown_type_node
    5354          351 :           || kind == REFLECT_PARM
    5355          347 :           || eval_is_namespace (a) == boolean_true_node
    5356          333 :           || eval_is_constructor (a) == boolean_true_node
    5357          333 :           || eval_is_destructor (a) == boolean_true_node
    5358          329 :           || eval_is_annotation (a, kind) == boolean_true_node
    5359          325 :           || (TREE_CODE (a) == FIELD_DECL && !DECL_UNNAMED_BIT_FIELD (a))
    5360              :           || kind == REFLECT_DATA_MEMBER_SPEC
    5361          325 :           || kind == REFLECT_BASE
    5362          680 :           || (!TYPE_P (a)
    5363          137 :               && eval_is_template (a) == boolean_false_node
    5364          133 :               && !has_type (a, kind)))
    5365           30 :         return throw_exception (loc, ctx,
    5366              :                                 "invalid argument to can_substitute",
    5367           30 :                                 fun, non_constant_p, jump_target);
    5368          325 :       a = convert_from_reference (a);
    5369          325 :       TREE_VEC_ELT (rvec, i) = a;
    5370              :     }
    5371          248 :   if (DECL_TYPE_TEMPLATE_P (r) || DECL_TEMPLATE_TEMPLATE_PARM_P (r))
    5372              :     {
    5373          106 :       tree type = lookup_template_class (r, rvec, NULL_TREE, NULL_TREE,
    5374              :                                          tf_none);
    5375          106 :       if (type == error_mark_node)
    5376           48 :         return boolean_false_node;
    5377              :       else
    5378           58 :         return boolean_true_node;
    5379              :     }
    5380          251 :   else if (concept_definition_p (r))
    5381              :     {
    5382           76 :       tree c = build_concept_check (r, rvec, tf_none);
    5383           76 :       if (c == error_mark_node)
    5384           15 :         return boolean_false_node;
    5385              :       else
    5386           61 :         return boolean_true_node;
    5387              :     }
    5388           66 :   else if (variable_template_p (r))
    5389              :     {
    5390           31 :       tree var = lookup_template_variable (r, rvec, tf_none);
    5391           31 :       if (var == error_mark_node)
    5392           12 :         return boolean_false_node;
    5393           19 :       var = finish_template_variable (var, tf_none);
    5394           19 :       if (var == error_mark_node)
    5395            0 :         return boolean_false_node;
    5396              :       else
    5397           19 :         return boolean_true_node;
    5398              :     }
    5399              :   else
    5400              :     {
    5401           35 :       tree fn = lookup_template_function (r, rvec);
    5402           35 :       if (fn == error_mark_node)
    5403            0 :         return boolean_false_node;
    5404           35 :       fn = resolve_nondeduced_context_or_error (fn, tf_none);
    5405           35 :       if (fn == error_mark_node || undeduced_auto_decl (fn))
    5406           17 :         return boolean_false_node;
    5407           18 :       return boolean_true_node;
    5408              :     }
    5409              : }
    5410              : 
    5411              : /* Process std::meta::substitute.
    5412              :    Let Z be the template represented by templ and let Args... be a sequence of
    5413              :    prvalue constant expressions that compute the reflections held by the
    5414              :    elements of arguments, in order.
    5415              :    Returns: ^^Z<[:Args:]...>.
    5416              :    Throws: meta::exception unless can_substitute(templ, arguments) is true.  */
    5417              : 
    5418              : static tree
    5419          290 : eval_substitute (location_t loc, const constexpr_ctx *ctx,
    5420              :                  tree r, tree rvec, bool *non_constant_p, tree *jump_target,
    5421              :                  tree fun)
    5422              : {
    5423          290 :   tree cs = eval_can_substitute (loc, ctx, r, rvec, non_constant_p, jump_target,
    5424              :                                  fun);
    5425          290 :   if (*jump_target)
    5426              :     return cs;
    5427          197 :   if (cs == boolean_false_node)
    5428           61 :     return throw_exception (loc, ctx, "can_substitute returned false",
    5429           61 :                             fun, non_constant_p, jump_target);
    5430          136 :   tree ret = NULL_TREE;
    5431          136 :   if (DECL_TYPE_TEMPLATE_P (r) || DECL_TEMPLATE_TEMPLATE_PARM_P (r))
    5432           45 :     ret = lookup_template_class (r, rvec, NULL_TREE, NULL_TREE, tf_none);
    5433          169 :   else if (concept_definition_p (r))
    5434              :     {
    5435           59 :       ret = build_concept_check (r, rvec, tf_none);
    5436           59 :       ret = evaluate_concept_check (ret);
    5437           59 :       return get_reflection_raw (loc, ret, REFLECT_VALUE);
    5438              :     }
    5439           32 :   else if (variable_template_p (r))
    5440           17 :     ret = lookup_and_finish_template_variable (r, rvec, tf_none);
    5441              :   else
    5442              :     {
    5443           15 :       if (DECL_FUNCTION_TEMPLATE_P (r))
    5444            2 :         r = ovl_make (r, NULL_TREE);
    5445           15 :       ret = lookup_template_function (r, rvec);
    5446           15 :       ret = resolve_nondeduced_context (ret, tf_none);
    5447              :     }
    5448           77 :   return get_reflection_raw (loc, ret);
    5449              : }
    5450              : 
    5451              : /* Process std::meta::tuple_size.
    5452              :    Returns: tuple_size_v<T>, where T is the type represented by
    5453              :    dealias(type).  */
    5454              : 
    5455              : static tree
    5456           28 : eval_tuple_size (location_t loc, const constexpr_ctx *ctx, tree type,
    5457              :                  tree call, bool *non_constant_p, tree *jump_target,
    5458              :                  tree fun)
    5459              : {
    5460              :   /* Create std::tuple_size<TYPE>::value.  */
    5461           28 :   tree args = make_tree_vec (1);
    5462           28 :   TREE_VEC_ELT (args, 0) = type;
    5463           28 :   return finish_library_value_trait (loc, ctx, "tuple_size", args, call,
    5464           28 :                                      non_constant_p, jump_target, fun);
    5465              : }
    5466              : 
    5467              : /* Process std::meta::tuple_element.
    5468              :    Returns: A reflection representing the type denoted by
    5469              :    tuple_element_t<I, T>, where T is the type represented by dealias(type)
    5470              :    and I is a constant equal to index.  */
    5471              : 
    5472              : static tree
    5473           31 : eval_tuple_element (location_t loc, const constexpr_ctx *ctx, tree i,
    5474              :                     tree type, tree call, bool *non_constant_p,
    5475              :                     tree *jump_target, tree fun)
    5476              : {
    5477              :   /* Create std::tuple_element<I,TYPE>::type.  */
    5478           31 :   tree args = make_tree_vec (2);
    5479           31 :   TREE_VEC_ELT (args, 0) = i;
    5480           31 :   TREE_VEC_ELT (args, 1) = type;
    5481           31 :   return finish_library_type_trait (loc, ctx, "tuple_element",
    5482              :                                     args, call, non_constant_p, jump_target,
    5483           31 :                                     fun);
    5484              : }
    5485              : 
    5486              : /* Process std::meta::variant_size.
    5487              :    Returns: variant_size_v<T>, where T is the type represented by
    5488              :    dealias(type).  */
    5489              : 
    5490              : static tree
    5491           10 : eval_variant_size (location_t loc, const constexpr_ctx *ctx, tree type,
    5492              :                    tree call, bool *non_constant_p, tree *jump_target,
    5493              :                    tree fun)
    5494              : {
    5495              :   /* Create std::variant_size<TYPE>::value.  */
    5496           10 :   tree args = make_tree_vec (1);
    5497           10 :   TREE_VEC_ELT (args, 0) = type;
    5498           10 :   return finish_library_value_trait (loc, ctx, "variant_size", args, call,
    5499           10 :                                      non_constant_p, jump_target, fun);
    5500              : }
    5501              : 
    5502              : /* Process std::meta::variant_alternative.
    5503              :    Returns: A reflection representing the type denoted by
    5504              :    variant_alternative_t<I, T>, where T is the type represented by
    5505              :    dealias(type) and I is a constant equal to index.  */
    5506              : 
    5507              : static tree
    5508           17 : eval_variant_alternative (location_t loc, const constexpr_ctx *ctx, tree i,
    5509              :                           tree type, tree call, bool *non_constant_p,
    5510              :                           tree *jump_target, tree fun)
    5511              : {
    5512              :   /* Create std::variant_alternative<I,TYPE>::type.  */
    5513           17 :   tree args = make_tree_vec (2);
    5514           17 :   TREE_VEC_ELT (args, 0) = i;
    5515           17 :   TREE_VEC_ELT (args, 1) = type;
    5516           17 :   return finish_library_type_trait (loc, ctx, "variant_alternative",
    5517              :                                     args, call, non_constant_p, jump_target,
    5518           17 :                                     fun);
    5519              : }
    5520              : 
    5521              : /* Process std::meta::data_member_spec.
    5522              :    Returns: A reflection of a data member description (T,N,A,W,NUA) where
    5523              :    -- T is the type represented by dealias(type),
    5524              :    -- N is either the identifier encoded by options.name or _|_ if
    5525              :       options.name does not contain a value,
    5526              :    -- A is either the alignment value held by options.alignment or _|_ if
    5527              :       options.alignment does not contain a value,
    5528              :    -- W is either the value held by options.bit_width or _|_ if
    5529              :       options.bit_width does not contain a value, and
    5530              :    -- NUA is the value held by options.no_unique_address.
    5531              :    Throws: meta::exception unless the following conditions are met:
    5532              :    -- dealias(type) represents either an object type or a reference type;
    5533              :    -- if options.name contains a value, then:
    5534              :       -- holds_alternative<u8string>(options.name->contents) is true and
    5535              :          get<u8string>(options.name->contents) contains a valid identifier
    5536              :          that is not a keyword when interpreted with UTF-8, or
    5537              :       -- holds_alternative<string>(options.name->contents) is true and
    5538              :          get<string>(options.name->contents) contains a valid identifier
    5539              :          that is not a keyword when interpreted with the ordinary literal
    5540              :          encoding;
    5541              :    -- if options.name does not contain a value, then options.bit_width
    5542              :       contains a value;
    5543              :    -- if options.bit_width contains a value V, then
    5544              :       -- is_integral_type(type) || is_enum_type(type) is true,
    5545              :       -- options.alignment does not contain a value,
    5546              :       -- options.no_unique_address is false,
    5547              :       -- V is not negative, and
    5548              :       -- if V equals 0, then options.name does not contain a value; and
    5549              :    -- if options.alignment contains a value, it is an alignment value not less
    5550              :       than alignment_of(type).  */
    5551              : 
    5552              : static tree
    5553          327 : eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
    5554              :                        tree type, tree opts, bool *non_constant_p,
    5555              :                        bool *overflow_p, tree *jump_target, tree fun)
    5556              : {
    5557          327 :   type = strip_typedefs (type);
    5558          327 :   if (!TYPE_OBJ_P (type) && !TYPE_REF_P (type))
    5559            4 :     return throw_exception (loc, ctx, "type is not object or reference type",
    5560            4 :                             fun, non_constant_p, jump_target);
    5561          323 :   opts = convert_from_reference (opts);
    5562          323 :   if (!CLASS_TYPE_P (TREE_TYPE (opts)))
    5563              :     {
    5564            0 :     fail:
    5565            0 :       error_at (loc, "unexpected %<data_member_options%> argument");
    5566            0 :       *non_constant_p = true;
    5567            0 :       return NULL_TREE;
    5568              :     }
    5569          323 :   tree args[5] = { type, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
    5570          323 :   for (tree field = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (opts)));
    5571         1615 :        field; field = next_aggregate_field (DECL_CHAIN (field)))
    5572         1292 :     if (tree name = DECL_NAME (field))
    5573              :       {
    5574         1292 :         if (id_equal (name, "name"))
    5575          323 :           args[1] = field;
    5576          969 :         else if (id_equal (name, "alignment"))
    5577          323 :           args[2] = field;
    5578          646 :         else if (id_equal (name, "bit_width"))
    5579          323 :           args[3] = field;
    5580          323 :         else if (id_equal (name, "no_unique_address"))
    5581          323 :           args[4] = field;
    5582              :       }
    5583         1319 :   for (int i = 1; i < 5; ++i)
    5584              :     {
    5585         1070 :       if (args[i] == NULL_TREE)
    5586            0 :         goto fail;
    5587         1070 :       tree opt = build3 (COMPONENT_REF, TREE_TYPE (args[i]), opts, args[i],
    5588              :                          NULL_TREE);
    5589         1070 :       if (i == 4)
    5590              :         {
    5591              :           /* The no_unique_address handling is simple.  */
    5592          249 :           if (TREE_CODE (TREE_TYPE (opt)) != BOOLEAN_TYPE)
    5593            0 :             goto fail;
    5594          249 :           opt = cxx_eval_constant_expression (ctx, opt, vc_prvalue,
    5595              :                                               non_constant_p, overflow_p,
    5596              :                                               jump_target);
    5597          249 :           if (*jump_target || *non_constant_p)
    5598           74 :             return NULL_TREE;
    5599          249 :           if (TREE_CODE (opt) != INTEGER_CST)
    5600            0 :             goto fail;
    5601          249 :           if (integer_zerop (opt))
    5602          234 :             args[i] = boolean_false_node;
    5603              :           else
    5604           15 :             args[i] = boolean_true_node;
    5605          781 :           continue;
    5606              :         }
    5607              :       /* Otherwise the member is optional<something>.  */
    5608          821 :       if (!CLASS_TYPE_P (TREE_TYPE (opt)))
    5609            0 :         goto fail;
    5610          821 :       tree has_value = build_static_cast (loc, boolean_type_node, opt,
    5611              :                                           tf_warning_or_error);
    5612          821 :       if (error_operand_p (has_value))
    5613            0 :         goto fail;
    5614          821 :       has_value = cxx_eval_constant_expression (ctx, has_value, vc_prvalue,
    5615              :                                                 non_constant_p, overflow_p,
    5616              :                                                 jump_target);
    5617          821 :       if (*jump_target || *non_constant_p)
    5618              :         return NULL_TREE;
    5619          821 :       if (TREE_CODE (has_value) != INTEGER_CST)
    5620            0 :         goto fail;
    5621          821 :       if (integer_zerop (has_value))
    5622              :         {
    5623              :           /* If it doesn't have value, store NULL_TREE.  */
    5624          443 :           args[i] = NULL_TREE;
    5625          443 :           continue;
    5626              :         }
    5627          378 :       tree deref = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, opt,
    5628              :                                  NULL_TREE, tf_warning_or_error);
    5629          378 :       if (error_operand_p (deref))
    5630            0 :         goto fail;
    5631          378 :       if (i != 1)
    5632              :         {
    5633              :           /* For alignment and bit_width otherwise it should be int.  */
    5634           89 :           if (TYPE_MAIN_VARIANT (TREE_TYPE (deref)) != integer_type_node)
    5635            0 :             goto fail;
    5636           89 :           deref = cxx_eval_constant_expression (ctx, deref, vc_prvalue,
    5637              :                                                 non_constant_p, overflow_p,
    5638              :                                                 jump_target);
    5639           89 :           if (*jump_target || *non_constant_p)
    5640              :             return NULL_TREE;
    5641           89 :           if (TREE_CODE (deref) != INTEGER_CST)
    5642            0 :             goto fail;
    5643           89 :           args[i] = deref;
    5644           89 :           continue;
    5645              :         }
    5646              :       /* Otherwise it is a name.  */
    5647          289 :       if (!CLASS_TYPE_P (TREE_TYPE (deref)))
    5648            0 :         goto fail;
    5649          289 :       tree fields[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
    5650          289 :       for (tree field = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (deref)));
    5651         1445 :            field; field = next_aggregate_field (DECL_CHAIN (field)))
    5652         1156 :         if (tree name = DECL_NAME (field))
    5653              :           {
    5654         1156 :             if (id_equal (name, "_M_is_u8"))
    5655          289 :               fields[0] = field;
    5656          867 :             else if (id_equal (name, "_M_u8s"))
    5657          289 :               fields[1] = field;
    5658          578 :             else if (id_equal (name, "_M_s"))
    5659          289 :               fields[2] = field;
    5660              :           }
    5661         1034 :       for (int j = 0; j < 3; ++j)
    5662              :         {
    5663          819 :           if (fields[j] == NULL_TREE)
    5664            0 :             goto fail;
    5665         1237 :           if (j && j == (fields[0] == boolean_true_node ? 2 : 1))
    5666          530 :             continue;
    5667          578 :           tree f = build3 (COMPONENT_REF, TREE_TYPE (fields[j]), deref,
    5668              :                            fields[j], NULL_TREE);
    5669          578 :           if (j == 0)
    5670              :             {
    5671              :               /* The _M_is_u8 handling is simple.  */
    5672          289 :               if (TREE_CODE (TREE_TYPE (f)) != BOOLEAN_TYPE)
    5673            0 :                 goto fail;
    5674          289 :               f = cxx_eval_constant_expression (ctx, f, vc_prvalue,
    5675              :                                                 non_constant_p, overflow_p,
    5676              :                                                 jump_target);
    5677          289 :               if (*jump_target || *non_constant_p)
    5678           74 :                 return NULL_TREE;
    5679          289 :               if (TREE_CODE (f) != INTEGER_CST)
    5680            0 :                 goto fail;
    5681          289 :               if (integer_zerop (f))
    5682          209 :                 fields[0] = boolean_false_node;
    5683              :               else
    5684           80 :                 fields[0] = boolean_true_node;
    5685          289 :               continue;
    5686              :             }
    5687              :           /* _M_u8s/_M_s handling is the same except for encoding.  */
    5688          289 :           if (!CLASS_TYPE_P (TREE_TYPE (f)))
    5689            0 :             goto fail;
    5690          289 :           tree fns = lookup_qualified_name (TREE_TYPE (f),
    5691              :                                             get_identifier ("c_str"));
    5692          289 :           if (error_operand_p (fns))
    5693            0 :             goto fail;
    5694          289 :           f = build_new_method_call (f, fns, NULL, NULL_TREE, LOOKUP_NORMAL,
    5695              :                                      NULL, tf_warning_or_error);
    5696          289 :           if (error_operand_p (f))
    5697            0 :             goto fail;
    5698          289 :           f = cxx_eval_constant_expression (ctx, f, vc_prvalue,
    5699              :                                             non_constant_p, overflow_p,
    5700              :                                             jump_target);
    5701          289 :           if (*jump_target || *non_constant_p)
    5702              :             return NULL_TREE;
    5703          289 :           STRIP_NOPS (f);
    5704          289 :           if (TREE_CODE (f) != ADDR_EXPR)
    5705            0 :             goto fail;
    5706          289 :           f = TREE_OPERAND (f, 0);
    5707          289 :           f = cxx_eval_constant_expression (ctx, f, vc_prvalue,
    5708              :                                             non_constant_p, overflow_p,
    5709              :                                             jump_target);
    5710          289 :           if (*jump_target || *non_constant_p)
    5711              :             return NULL_TREE;
    5712          289 :           if (TREE_CODE (f) != CONSTRUCTOR
    5713          289 :               || TREE_CODE (TREE_TYPE (f)) != ARRAY_TYPE)
    5714            0 :             goto fail;
    5715          289 :           tree eltt = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (f)));
    5716          289 :           if (eltt != (j == 1 ? char8_type_node : char_type_node))
    5717            0 :             goto fail;
    5718              :           tree field, value;
    5719              :           unsigned k;
    5720              :           unsigned HOST_WIDE_INT l = 0;
    5721         1620 :           bool ntmbs = false;
    5722         1620 :           FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (f), k, field, value)
    5723         1620 :             if (!tree_fits_shwi_p (value))
    5724            0 :               goto fail;
    5725         1620 :             else if (field == NULL_TREE)
    5726              :               {
    5727            0 :                 if (integer_zerop (value))
    5728              :                   {
    5729              :                     ntmbs = true;
    5730              :                     break;
    5731              :                   }
    5732            0 :                 ++l;
    5733              :               }
    5734         1620 :             else if (TREE_CODE (field) == RANGE_EXPR)
    5735              :               {
    5736            0 :                 tree lo = TREE_OPERAND (field, 0);
    5737            0 :                 tree hi = TREE_OPERAND (field, 1);
    5738            0 :                 if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
    5739            0 :                   goto fail;
    5740            0 :                 if (integer_zerop (value))
    5741              :                   {
    5742            0 :                     l = tree_to_uhwi (lo);
    5743            0 :                     ntmbs = true;
    5744            0 :                     break;
    5745              :                   }
    5746            0 :                 l = tree_to_uhwi (hi) + 1;
    5747              :               }
    5748         1620 :             else if (tree_fits_uhwi_p (field))
    5749              :               {
    5750         1620 :                 l = tree_to_uhwi (field);
    5751         1620 :                 if (integer_zerop (value))
    5752              :                   {
    5753              :                     ntmbs = true;
    5754              :                     break;
    5755              :                   }
    5756         1331 :                 ++l;
    5757              :               }
    5758              :             else
    5759            0 :               goto fail;
    5760          289 :           if (!ntmbs || l > INT_MAX - 1)
    5761            0 :             goto fail;
    5762          289 :           char *namep;
    5763          289 :           unsigned len = l;
    5764          289 :           if (l < 64)
    5765          289 :             namep = XALLOCAVEC (char, l + 1);
    5766              :           else
    5767            0 :             namep = XNEWVEC (char, l + 1);
    5768          289 :           memset (namep, 0, l + 1);
    5769          289 :           l = 0;
    5770         1620 :           FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (f), k, field, value)
    5771         1620 :             if (integer_zerop (value))
    5772              :               break;
    5773         1331 :             else if (field == NULL_TREE)
    5774              :               {
    5775            0 :                 namep[l] = tree_to_shwi (value);
    5776            0 :                 ++l;
    5777              :               }
    5778         1331 :             else if (TREE_CODE (field) == RANGE_EXPR)
    5779              :               {
    5780            0 :                 tree lo = TREE_OPERAND (field, 0);
    5781            0 :                 tree hi = TREE_OPERAND (field, 1);
    5782            0 :                 unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
    5783            0 :                 for (l = tree_to_uhwi (lo); l <= m; ++l)
    5784            0 :                   namep[l] = tree_to_shwi (value);
    5785              :               }
    5786              :             else
    5787              :               {
    5788         1331 :                 l = tree_to_uhwi (field);
    5789         1331 :                 namep[l++] = tree_to_shwi (value);
    5790              :               }
    5791          289 :           namep[len] = '\0';
    5792              :           /* Convert namep from execution charset to SOURCE_CHARSET.  */
    5793          289 :           cpp_string istr, ostr;
    5794          289 :           istr.len = strlen (namep) + 1;
    5795          289 :           istr.text = (const unsigned char *) namep;
    5796          369 :           if (!cpp_translate_string (parse_in, &istr, &ostr,
    5797              :                                      j == 2 ? CPP_STRING : CPP_UTF8STRING,
    5798              :                                      true))
    5799              :             {
    5800            0 :               if (len >= 64)
    5801            0 :                 XDELETEVEC (namep);
    5802            0 :               if (j == 1)
    5803            0 :                 return throw_exception (loc, ctx,
    5804              :                                         "conversion from ordinary literal "
    5805              :                                         "encoding to source charset "
    5806              :                                         "failed", fun, non_constant_p,
    5807            0 :                                         jump_target);
    5808              :               else
    5809            0 :                 return throw_exception (loc, ctx,
    5810              :                                         "conversion from UTF-8 encoding to "
    5811              :                                         "source charset failed",
    5812            0 :                                         fun, non_constant_p, jump_target);
    5813              :             }
    5814          289 :           if (len >= 64)
    5815            0 :             XDELETEVEC (namep);
    5816          289 :           if (!cpp_valid_identifier (parse_in, ostr.text))
    5817           58 :             return throw_exception (loc, ctx,
    5818              :                                     "name is not a valid identifier",
    5819           58 :                                     fun, non_constant_p, jump_target);
    5820          231 :           args[i] = get_identifier ((const char *) ostr.text);
    5821          231 :           switch (get_identifier_kind (args[i]))
    5822              :             {
    5823           12 :             case cik_keyword:
    5824           12 :               return throw_exception (loc, ctx, "name is a keyword",
    5825           12 :                                       fun, non_constant_p, jump_target);
    5826            4 :             case cik_trait:
    5827            4 :               return throw_exception (loc, ctx, "name is a built-in trait",
    5828            4 :                                       fun, non_constant_p, jump_target);
    5829          215 :             default:
    5830          215 :               break;
    5831              :             }
    5832              :         }
    5833              :     }
    5834          249 :   if (args[1] == NULL_TREE && args[3] == NULL_TREE)
    5835            6 :     return throw_exception (loc, ctx,
    5836              :                             "neither name nor bit_width specified",
    5837            6 :                             fun, non_constant_p, jump_target);
    5838          243 :   if (args[3])
    5839              :     {
    5840           64 :       if (!CP_INTEGRAL_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
    5841            2 :         return throw_exception (loc, ctx,
    5842              :                                 "bit_width specified with non-integral "
    5843              :                                 "and non-enumeration type",
    5844            2 :                                 fun, non_constant_p, jump_target);
    5845           62 :       if (args[2])
    5846            2 :         return throw_exception (loc, ctx,
    5847              :                                 "both alignment and bit_width specified",
    5848            2 :                                 fun, non_constant_p, jump_target);
    5849           60 :       if (args[4] == boolean_true_node)
    5850            2 :         return throw_exception (loc, ctx,
    5851              :                                 "bit_width specified with "
    5852              :                                 "no_unique_address true",
    5853            2 :                                 fun, non_constant_p, jump_target);
    5854           58 :       if (integer_zerop (args[3]) && args[1])
    5855            2 :         return throw_exception (loc, ctx,
    5856              :                                 "bit_width 0 with specified name",
    5857            2 :                                 fun, non_constant_p, jump_target);
    5858           56 :       if (tree_int_cst_sgn (args[3]) < 0)
    5859            2 :         return throw_exception (loc, ctx, "bit_width is negative",
    5860            2 :                                 fun, non_constant_p, jump_target);
    5861              :     }
    5862          233 :   if (args[2])
    5863              :     {
    5864           21 :       if (!integer_pow2p (args[2]))
    5865            2 :         return throw_exception (loc, ctx,
    5866              :                                 "alignment is not power of two",
    5867            2 :                                 fun, non_constant_p, jump_target);
    5868           19 :       if (tree_int_cst_sgn (args[2]) < 0)
    5869            2 :         return throw_exception (loc, ctx, "alignment is negative",
    5870            2 :                                 fun, non_constant_p, jump_target);
    5871           17 :       tree al = cxx_sizeof_or_alignof_type (loc, type, ALIGNOF_EXPR, true,
    5872              :                                             tf_none);
    5873           17 :       if (TREE_CODE (al) == INTEGER_CST
    5874           17 :           && wi::to_widest (al) > wi::to_widest (args[2]))
    5875            2 :         return throw_exception (loc, ctx,
    5876              :                                 "alignment is smaller than alignment_of",
    5877            2 :                                 fun, non_constant_p, jump_target);
    5878              :     }
    5879          227 :   tree ret = make_tree_vec (5);
    5880         1362 :   for (int i = 0; i < 5; ++i)
    5881         1135 :     TREE_VEC_ELT (ret, i) = args[i];
    5882          227 :   return get_reflection_raw (loc, ret, REFLECT_DATA_MEMBER_SPEC);
    5883              : }
    5884              : 
    5885              : /* Process std::meta::define_aggregate.
    5886              :    Let C be the type represented by class_type and r_K be the Kth reflection
    5887              :    value in mdescrs.
    5888              :    For every r_K in mdescrs, let (T_K,N_K,A_K,W_K,NUA_K) be the corresponding
    5889              :    data member description represented by r_K.
    5890              :    Constant When:
    5891              :    -- class_type represents a cv-unqualified class type;
    5892              :    -- C is incomplete from every point in the evaluation context;
    5893              :    -- is_data_member_spec(r_K) is true for every r_K;
    5894              :    -- is_complete_type(T_K) is true for every r_K; and
    5895              :    -- for every pair (r_K,r_L) where K<L, if N_K is not _|_ and N_L is not
    5896              :       _|_, then either:
    5897              :       -- N_K is not the same identifier as N_L or
    5898              :       -- N_K is the identifier _ (U+005F LOW LINE).
    5899              :    Effects: Produces an injected declaration D that defines C and has
    5900              :    properties as follows:
    5901              :    -- The target scope of D is the scope to which C belongs.
    5902              :    -- The locus of D follows immediately after the core constant expression
    5903              :       currently under evaluation.
    5904              :    -- The characteristic sequence of D is the sequence of reflection values
    5905              :       r_K.
    5906              :    -- If C is a specialization of a templated class T, and C is not a local
    5907              :       class, then D is an explicit specialization of T.
    5908              :    -- For each r_K, there is a corresponding entity M_K with public access
    5909              :       belonging to the class scope of D with the following properties:
    5910              :       -- If N_K is _|_, M_K is an unnamed bit-field.
    5911              :          Otherwise, M_K is a non-static data member whose name is the
    5912              :          identifier N_K.
    5913              :       -- The type of M_K is T_K.
    5914              :       -- M_K is declared with the attribute [[no_unique_address]] if and only
    5915              :          if NUA_K is true.
    5916              :       -- If W_K is not _|_, M_K is a bit-field whose width is that value.
    5917              :          Otherwise, M_K is not a bit-field.
    5918              :       -- If A_K is not _|_, M_K has the alignment-specifier alignas(A_K).
    5919              :          Otherwise, M_K has no alignment-specifier.
    5920              :    -- For every r_L in mdescrs such that K<L, the declaration corresponding to
    5921              :       r_K precedes the declaration corresponding to r_L.
    5922              :    Returns: class_type.
    5923              :    Remarks: If C is a specialization of a templated class and it has not been
    5924              :    instantiated, C is treated as an explicit specialization.  */
    5925              : 
    5926              : static tree
    5927           92 : eval_define_aggregate (location_t loc, const constexpr_ctx *ctx,
    5928              :                        tree type, tree rvec, tree call, bool *non_constant_p)
    5929              : {
    5930           92 :   tree orig_type = type;
    5931           92 :   if (!CLASS_TYPE_P (type))
    5932              :     {
    5933            3 :       if (!cxx_constexpr_quiet_p (ctx))
    5934            3 :         error_at (loc, "first %<define_aggregate%> argument is not a class "
    5935              :                        "type reflection");
    5936            3 :       *non_constant_p = true;
    5937            3 :       return call;
    5938              :     }
    5939           89 :   if (typedef_variant_p (type))
    5940              :     {
    5941            1 :       if (!cxx_constexpr_quiet_p (ctx))
    5942            1 :         error_at (loc, "first %<define_aggregate%> argument is a reflection "
    5943              :                        "of a type alias");
    5944            1 :       *non_constant_p = true;
    5945            1 :       return call;
    5946              :     }
    5947           88 :   if (cv_qualified_p (type))
    5948              :     {
    5949            3 :       if (!cxx_constexpr_quiet_p (ctx))
    5950            3 :         error_at (loc, "first %<define_aggregate%> argument is a "
    5951              :                        "cv-qualified class type reflection");
    5952            3 :       *non_constant_p = true;
    5953            3 :       return call;
    5954              :     }
    5955           85 :   if (COMPLETE_TYPE_P (type))
    5956              :     {
    5957            2 :       if (!cxx_constexpr_quiet_p (ctx))
    5958            2 :         error_at (loc, "first %<define_aggregate%> argument is a complete "
    5959              :                        "class type reflection");
    5960            2 :       *non_constant_p = true;
    5961            2 :       return call;
    5962              :     }
    5963           83 :   if (TYPE_BEING_DEFINED (type))
    5964              :     {
    5965            5 :       if (!cxx_constexpr_quiet_p (ctx))
    5966            5 :         error_at (loc, "first %<define_aggregate%> argument is a reflection "
    5967              :                        "of a class type %qT being defined", type);
    5968            5 :       *non_constant_p = true;
    5969            5 :       return call;
    5970              :     }
    5971           78 :   hash_set<tree> nameset;
    5972          149 :   for (int i = 0; i < TREE_VEC_LENGTH (rvec); ++i)
    5973              :     {
    5974           75 :       tree ra = TREE_VEC_ELT (rvec, i);
    5975           75 :       tree a = REFLECT_EXPR_HANDLE (ra);
    5976           75 :       if (REFLECT_EXPR_KIND (ra) != REFLECT_DATA_MEMBER_SPEC)
    5977              :         {
    5978            1 :           if (!cxx_constexpr_quiet_p (ctx))
    5979            1 :             error_at (loc, "%<define_aggregate%> argument not a data member "
    5980              :                            "description");
    5981            1 :           *non_constant_p = true;
    5982            1 :           return call;
    5983              :         }
    5984           74 :       if (eval_is_complete_type (TREE_VEC_ELT (a, 0)) != boolean_true_node)
    5985              :         {
    5986            1 :           if (!cxx_constexpr_quiet_p (ctx))
    5987            1 :             error_at (loc, "%<define_aggregate%> argument data member "
    5988              :                            "description without complete type");
    5989            1 :           *non_constant_p = true;
    5990            1 :           return call;
    5991              :         }
    5992           73 :       if (TREE_VEC_ELT (a, 1)
    5993           67 :           && !id_equal (TREE_VEC_ELT (a, 1), "_")
    5994          124 :           && nameset.add (TREE_VEC_ELT (a, 1)))
    5995              :         {
    5996            2 :           if (!cxx_constexpr_quiet_p (ctx))
    5997            2 :             error_at (loc, "name %qD used in multiple data member "
    5998            2 :                            "descriptions", TREE_VEC_ELT (a, 1));
    5999            2 :           *non_constant_p = true;
    6000            2 :           return call;
    6001              :         }
    6002           71 :       if (TYPE_WARN_IF_NOT_ALIGN (type)
    6003            0 :           && TREE_VEC_ELT (a, 3))
    6004              :         {
    6005            0 :           if (!cxx_constexpr_quiet_p (ctx))
    6006            0 :             error_at (loc, "cannot declare bit-field in "
    6007              :                            "%<warn_if_not_aligned%> type");
    6008            0 :           *non_constant_p = true;
    6009            0 :           return call;
    6010              :         }
    6011              :     }
    6012           74 :   tree consteval_block = cxx_constexpr_consteval_block (ctx);
    6013           74 :   if (consteval_block == NULL_TREE)
    6014              :     {
    6015           12 :       if (!cxx_constexpr_quiet_p (ctx))
    6016            4 :         error_at (loc, "%<define_aggregate%> not evaluated from "
    6017              :                        "%<consteval%> block");
    6018           12 :       *non_constant_p = true;
    6019           12 :       return call;
    6020              :     }
    6021           62 :   iloc_sentinel ils = loc;
    6022           62 :   type = TYPE_MAIN_VARIANT (type);
    6023           62 :   type = strip_typedefs (type);
    6024           62 :   tree cscope = NULL_TREE, tscope = NULL_TREE;
    6025           95 :   for (tree c = TYPE_CONTEXT (CP_DECL_CONTEXT (consteval_block)); c;
    6026           33 :        c = get_containing_scope (c))
    6027           62 :     if (TYPE_P (c) || TREE_CODE (c) == FUNCTION_DECL)
    6028              :       {
    6029              :         cscope = c;
    6030              :         break;
    6031              :       }
    6032          155 :   for (tree c = TYPE_CONTEXT (type); c; c = get_containing_scope (c))
    6033              :     {
    6034           96 :       if (c == consteval_block)
    6035              :         {
    6036            3 :           auto_diagnostic_group d;
    6037            3 :           error_at (loc, "%<define_aggregate%> evaluated from "
    6038              :                          "%<consteval%> block which encloses %qT being "
    6039              :                          "defined", type);
    6040            3 :           inform (DECL_SOURCE_LOCATION (consteval_block),
    6041              :                   "%<consteval%> block defined here");
    6042            3 :           return get_reflection_raw (loc, orig_type);
    6043            3 :         }
    6044           93 :       if (tscope == NULL_TREE
    6045           60 :           && (TYPE_P (c) || TREE_CODE (c) == FUNCTION_DECL))
    6046           27 :         tscope = c;
    6047              :     }
    6048           59 :   if (cscope != tscope)
    6049              :     {
    6050           16 :       auto_diagnostic_group d;
    6051           16 :       if (cscope && tscope)
    6052              :         {
    6053           25 :           for (tree c = tscope; c; c = get_containing_scope (c))
    6054           19 :             if (c == cscope)
    6055              :               {
    6056            3 :                 if (DECL_P (tscope))
    6057            1 :                   error_at (loc, "%qD intervenes between %qT scope and "
    6058              :                                  "%<consteval%> block %<define_aggregate%> "
    6059              :                                  "is evaluated from", tscope, type);
    6060              :                 else
    6061            2 :                   error_at (loc, "%qT intervenes between %qT scope and "
    6062              :                                  "%<consteval%> block %<define_aggregate%> "
    6063              :                                  "is evaluated from", tscope, type);
    6064              :                 cscope = NULL_TREE;
    6065              :                 tscope = NULL_TREE;
    6066              :                 break;
    6067              :               }
    6068           21 :           for (tree c = cscope; c; c = get_containing_scope (c))
    6069           14 :             if (c == tscope)
    6070              :               {
    6071            2 :                 if (DECL_P (cscope))
    6072            2 :                   error_at (loc, "%qD intervenes between %<consteval%> block "
    6073              :                                  "%<define_aggregate%> is evaluated from and "
    6074              :                                  "%qT scope", cscope, type);
    6075              :                 else
    6076            0 :                   error_at (loc, "%qT intervenes between %<consteval%> block "
    6077              :                                  "%<define_aggregate%> is evaluated from and "
    6078              :                                  "%qT scope", cscope, type);
    6079              :                 cscope = NULL_TREE;
    6080              :                 tscope = NULL_TREE;
    6081              :                 break;
    6082              :               }
    6083            9 :           if (cscope && tscope)
    6084              :             {
    6085            4 :               if (DECL_P (cscope) && DECL_P (tscope))
    6086            1 :                 error_at (loc, "%<define_aggregate%> evaluated from "
    6087              :                                "%<consteval%> block enclosed by %qD while "
    6088              :                                "%qT type being defined is enclosed by %qD",
    6089              :                           cscope, type, tscope);
    6090            3 :               else if (DECL_P (cscope))
    6091            1 :                 error_at (loc, "%<define_aggregate%> evaluated from "
    6092              :                                "%<consteval%> block enclosed by %qD while "
    6093              :                                "%qT type being defined is enclosed by %qT",
    6094              :                           cscope, type, tscope);
    6095            2 :               else if (DECL_P (tscope))
    6096            1 :                 error_at (loc, "%<define_aggregate%> evaluated from "
    6097              :                                "%<consteval%> block enclosed by %qT while "
    6098              :                                "%qT type being defined is enclosed by %qD",
    6099              :                           cscope, type, tscope);
    6100            1 :               else if (tscope)
    6101            1 :                 error_at (loc, "%<define_aggregate%> evaluated from "
    6102              :                                "%<consteval%> block enclosed by %qT while "
    6103              :                                "%qT type being defined is enclosed by %qT",
    6104              :                           cscope, type, tscope);
    6105              :             }
    6106              :         }
    6107            7 :       else if (cscope && DECL_P (cscope))
    6108            3 :         error_at (loc, "%qD intervenes between %<consteval%> block "
    6109              :                        "%<define_aggregate%> is evaluated from and %qT scope",
    6110              :                   cscope, type);
    6111            4 :       else if (cscope)
    6112            2 :         error_at (loc, "%qT intervenes between %<consteval%> block "
    6113              :                        "%<define_aggregate%> is evaluated from and %qT scope",
    6114              :                   cscope, type);
    6115            2 :       else if (tscope && DECL_P (tscope))
    6116            1 :         error_at (loc, "%qD intervenes between %qT scope and %<consteval%> "
    6117              :                        "block %<define_aggregate%> is evaluated from",
    6118              :                   tscope, type);
    6119              :       else
    6120            1 :         error_at (loc, "%qT intervenes between %qT scope and %<consteval%> "
    6121              :                        "block %<define_aggregate%> is evaluated from",
    6122              :                   tscope, type);
    6123           16 :       inform (DECL_SOURCE_LOCATION (consteval_block),
    6124              :               "%<consteval%> block defined here");
    6125           16 :       return get_reflection_raw (loc, orig_type);
    6126           16 :     }
    6127           43 :   if (primary_template_specialization_p (type))
    6128              :     {
    6129           12 :       type = maybe_process_partial_specialization (type);
    6130           12 :       if (type == error_mark_node)
    6131              :         {
    6132            0 :           *non_constant_p = true;
    6133            0 :           return call;
    6134              :         }
    6135              :     }
    6136           43 :   if (!TYPE_BINFO (type))
    6137           43 :     xref_basetypes (type, NULL_TREE);
    6138           43 :   pushclass (type);
    6139           43 :   TYPE_BEING_DEFINED (type) = 1;
    6140           43 :   build_self_reference ();
    6141           43 :   tree fields = TYPE_FIELDS (type);
    6142          112 :   for (int i = 0; i < TREE_VEC_LENGTH (rvec); ++i)
    6143              :     {
    6144           69 :       tree ra = TREE_VEC_ELT (rvec, i);
    6145           69 :       tree a = REFLECT_EXPR_HANDLE (ra);
    6146           69 :       tree f = build_decl (cp_expr_loc_or_input_loc (ra), FIELD_DECL,
    6147           69 :                            TREE_VEC_ELT (a, 1), TREE_VEC_ELT (a, 0));
    6148           69 :       DECL_CHAIN (f) = fields;
    6149           69 :       DECL_IN_AGGR_P (f) = 1;
    6150           69 :       DECL_CONTEXT (f) = type;
    6151           69 :       TREE_PUBLIC (f) = 1;
    6152              :       /* Bit-field.  */
    6153           69 :       if (TREE_VEC_ELT (a, 3))
    6154              :         {
    6155              :           /* Temporarily stash the width in DECL_BIT_FIELD_REPRESENTATIVE.
    6156              :              check_bitfield_decl picks it from there later and sets DECL_SIZE
    6157              :              accordingly.  */
    6158           12 :           DECL_BIT_FIELD_REPRESENTATIVE (f) = TREE_VEC_ELT (a, 3);
    6159           12 :           SET_DECL_C_BIT_FIELD (f);
    6160           12 :           DECL_NONADDRESSABLE_P (f) = 1;
    6161              :           /* If this bit-field is unnamed, it's padding.  */
    6162           12 :           if (!TREE_VEC_ELT (a, 1))
    6163            6 :             DECL_PADDING_P (f) = 1;
    6164              :         }
    6165           57 :       else if (TREE_VEC_ELT (a, 2))
    6166              :         {
    6167            5 :           SET_DECL_ALIGN (f, tree_to_uhwi (TREE_VEC_ELT (a, 2))
    6168              :                               * BITS_PER_UNIT);
    6169            5 :           DECL_USER_ALIGN (f) = 1;
    6170              :         }
    6171           69 :       if (TREE_VEC_ELT (a, 4) == boolean_true_node)
    6172              :         {
    6173            4 :           tree attr = build_tree_list (NULL_TREE,
    6174              :                                        get_identifier ("no_unique_address"));
    6175            4 :           attr = build_tree_list (attr, NULL_TREE);
    6176            4 :           cplus_decl_attributes (&f, attr, 0);
    6177              :         }
    6178           69 :       fields = f;
    6179              :     }
    6180           43 :   TYPE_FIELDS (type) = fields;
    6181           43 :   finish_struct (type, NULL_TREE);
    6182           43 :   return get_reflection_raw (loc, orig_type);
    6183          140 : }
    6184              : 
    6185              : /* Implement std::meta::reflect_constant_string.
    6186              :    Let CharT be ranges::range_value_t<R>.
    6187              :    Mandates: CharT is one of char, wchar_t, char8_t, char16_t, char32_t.
    6188              :    Let V be the pack of values of type CharT whose elements are the
    6189              :    corresponding elements of r, except that if r refers to a string literal
    6190              :    object, then V does not include the trailing null terminator of r.
    6191              :    Let P be the template parameter object of type
    6192              :    const CharT[sizeof...(V) + 1] initialized with {V..., CharT()}.
    6193              :    Returns: ^^P.  */
    6194              : 
    6195              : static tree
    6196          137 : eval_reflect_constant_string (location_t loc, const constexpr_ctx *ctx,
    6197              :                               tree call, bool *non_constant_p,
    6198              :                               bool *overflow_p, tree *jump_target, tree fun)
    6199              : {
    6200          137 :   tree str = get_range_elts (loc, ctx, call, 0, non_constant_p, overflow_p,
    6201              :                              jump_target, REFLECT_CONSTANT_STRING, fun);
    6202          137 :   if (*jump_target || *non_constant_p)
    6203              :     return NULL_TREE;
    6204          128 :   tree decl = get_template_parm_object (str,
    6205              :                                         mangle_template_parm_object (str));
    6206          128 :   DECL_MERGEABLE (decl) = 1;
    6207          128 :   return get_reflection_raw (loc, decl);
    6208              : }
    6209              : 
    6210              : /* Implement std::meta::reflect_constant_array.
    6211              :    Let T be ranges::range_value_t<R>.
    6212              :    Mandates: T is a structural type,
    6213              :    is_constructible_v<T, ranges::range_reference_t<R>> is true, and
    6214              :    is_copy_constructible_v<T> is true.
    6215              :    Let V be the pack of values of type info of the same size as r, where the
    6216              :    ith element is reflect_constant(e_i), where e_i is the ith element of r.
    6217              :    Let P be
    6218              :    -- If sizeof...(V) > 0 is true, then the template parameter object of type
    6219              :       const T[sizeof...(V)] initialized with {[:V:]...}.
    6220              :    -- Otherwise, the template parameter object of type array<T, 0> initialized
    6221              :       with {}.
    6222              :    Returns: ^^P.  */
    6223              : 
    6224              : static tree
    6225          289 : eval_reflect_constant_array (location_t loc, const constexpr_ctx *ctx,
    6226              :                              tree call, bool *non_constant_p,
    6227              :                              bool *overflow_p, tree *jump_target, tree fun)
    6228              : {
    6229          289 :   tree str = get_range_elts (loc, ctx, call, 0, non_constant_p, overflow_p,
    6230              :                              jump_target, REFLECT_CONSTANT_ARRAY, fun);
    6231          289 :   if (*jump_target || *non_constant_p)
    6232              :     return NULL_TREE;
    6233          283 :   tree decl = get_template_parm_object (str,
    6234              :                                         mangle_template_parm_object (str));
    6235          283 :   DECL_MERGEABLE (decl) = 1;
    6236          283 :   return get_reflection_raw (loc, decl);
    6237              : }
    6238              : 
    6239              : /* Process std::meta::access_context::current.  */
    6240              : 
    6241              : static tree
    6242          249 : eval_access_context_current (location_t loc, const constexpr_ctx *ctx,
    6243              :                              tree call, bool *non_constant_p)
    6244              : {
    6245          249 :   tree scope = cxx_constexpr_caller (ctx);
    6246              :   /* Ignore temporary current_function_decl changes caused by
    6247              :      push_access_scope.  */
    6248          249 :   if (scope == NULL_TREE && current_function_decl)
    6249           70 :     scope = current_function_decl_without_access_scope ();
    6250              :   /* [meta.reflection.access.context]/(5.1.2): Otherwise, if an initialization
    6251              :      by an inherited constructor is using I, a point whose immediate scope is
    6252              :      the class scope corresponding to C.  */
    6253          390 :   if (scope && DECL_INHERITED_CTOR (scope))
    6254            2 :     scope = DECL_CONTEXT (scope);
    6255          249 :   if (scope == NULL_TREE)
    6256              :     {
    6257          108 :       if (cxx_constexpr_manifestly_const_eval (ctx) != mce_true)
    6258              :         {
    6259              :           /* Outside of functions limit this to manifestly constant-evaluation
    6260              :              so that we don't fold it prematurely.  */
    6261            0 :           if (!cxx_constexpr_quiet_p (ctx))
    6262            0 :             error_at (loc, "%<access_context::current%> used outside of "
    6263              :                            "manifestly constant-evaluation");
    6264            0 :           *non_constant_p = true;
    6265            0 :           return call;
    6266              :         }
    6267          108 :       if (current_class_type)
    6268              :         scope = current_class_type;
    6269           92 :       else if (current_namespace)
    6270              :         scope = current_namespace;
    6271              :       else
    6272            0 :         scope = global_namespace;
    6273              :     }
    6274              :   tree lam;
    6275          304 :   while (LAMBDA_FUNCTION_P (scope)
    6276           29 :          && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (scope)))
    6277          304 :          && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
    6278           26 :     scope = CP_TYPE_CONTEXT (CP_DECL_CONTEXT (scope));
    6279          249 :   tree access_context = TREE_TYPE (call);
    6280          249 :   if (TREE_CODE (access_context) != RECORD_TYPE)
    6281              :     {
    6282            0 :     fail:
    6283            0 :       error_at (loc, "unexpected return type of %qs",
    6284              :                 "std::meta::access_context::current");
    6285            0 :       return build_zero_cst (access_context);
    6286              :     }
    6287          249 :   tree scopef = next_aggregate_field (TYPE_FIELDS (access_context));
    6288          249 :   if (!scopef || !REFLECTION_TYPE_P (TREE_TYPE (scopef)))
    6289            0 :     goto fail;
    6290          249 :   tree classf = next_aggregate_field (DECL_CHAIN (scopef));
    6291          249 :   if (!classf || !REFLECTION_TYPE_P (TREE_TYPE (classf)))
    6292            0 :     goto fail;
    6293          249 :   if (next_aggregate_field (DECL_CHAIN (classf)))
    6294            0 :     goto fail;
    6295          249 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6296          249 :   CONSTRUCTOR_APPEND_ELT (elts, scopef, get_reflection_raw (loc, scope));
    6297          249 :   CONSTRUCTOR_APPEND_ELT (elts, classf, get_null_reflection ());
    6298          249 :   return build_constructor (access_context, elts);
    6299              : }
    6300              : 
    6301              : /* Helper function to extract scope and designating class from
    6302              :    access_context ACTX.  */
    6303              : 
    6304              : static bool
    6305        38315 : extract_access_context (location_t loc, tree actx, tree *scope,
    6306              :                         tree *designating_class)
    6307              : {
    6308        38315 :   if (TREE_CODE (actx) != CONSTRUCTOR
    6309        38315 :       || CONSTRUCTOR_NELTS (actx) != 2
    6310        38315 :       || !REFLECT_EXPR_P (CONSTRUCTOR_ELT (actx, 0)->value)
    6311        76630 :       || !REFLECT_EXPR_P (CONSTRUCTOR_ELT (actx, 1)->value))
    6312              :     {
    6313            0 :       error_at (loc, "invalid %<access_context%> argument");
    6314            0 :       return false;
    6315              :     }
    6316        38315 :   *scope = REFLECT_EXPR_HANDLE (CONSTRUCTOR_ELT (actx, 0)->value);
    6317        38315 :   *designating_class = REFLECT_EXPR_HANDLE (CONSTRUCTOR_ELT (actx, 1)->value);
    6318        38315 :   if (*scope == unknown_type_node)
    6319        28813 :     *scope = NULL_TREE;
    6320         9502 :   else if (TREE_CODE (*scope) != FUNCTION_DECL
    6321         8880 :            && TREE_CODE (*scope) != NAMESPACE_DECL
    6322        13652 :            && !CLASS_TYPE_P (*scope))
    6323              :     {
    6324            0 :       error_at (loc, "unexpected %<access_context::scope()%>");
    6325            0 :       return false;
    6326              :     }
    6327         9502 :   else if (CLASS_TYPE_P (*scope))
    6328         4150 :     *scope = TYPE_MAIN_VARIANT (*scope);
    6329        38315 :   if (*designating_class == unknown_type_node)
    6330        34203 :     *designating_class = NULL_TREE;
    6331         4112 :   else if (!CLASS_TYPE_P (*designating_class)
    6332         8224 :            || !COMPLETE_TYPE_P (*designating_class))
    6333              :     {
    6334            0 :       error_at (loc, "unexpected %<access_context::designating_class()%>");
    6335            0 :       return false;
    6336              :     }
    6337              :   else
    6338         4112 :     *designating_class = TYPE_MAIN_VARIANT (*designating_class);
    6339              :   return true;
    6340              : }
    6341              : 
    6342              : /* Process std::meta::is_accessible.
    6343              :    Let PARENT-CLS(r) be:
    6344              :    -- If parent_of(r) represents a class C, then C.
    6345              :    -- Otherwise, PARENT-CLS(parent_of(r)).
    6346              :    Let DESIGNATING-CLS(r, ctx) be:
    6347              :    -- If ctx.designating_class() represents a class C, then C.
    6348              :    -- Otherwise, PARENT-CLS(r).
    6349              :    Returns:
    6350              :    -- If r represents an unnamed bit-field F, then is_accessible(r_H, ctx),
    6351              :       where r_H represents a hypothetical non-static data member of the class
    6352              :       represented by PARENT-CLS(r) with the same access as F.
    6353              :    -- Otherwise, if r does not represent a class member or a direct base class
    6354              :       relationship, then true.
    6355              :    -- Otherwise, if r represents
    6356              :       -- a class member that is not a (possibly indirect or variant) member of
    6357              :          DESIGNATING-CLS(r, ctx) or
    6358              :       -- a direct base class relationship such that parent_of(r) does not
    6359              :          represent DESIGNATING-CLS(r, ctx) or a (direct or indirect) base
    6360              :          class thereof,
    6361              :       then false.
    6362              :    -- Otherwise, if ctx.scope() is the null reflection, then true.
    6363              :    -- Otherwise, letting P be a program point whose immediate scope is the
    6364              :       function parameter scope, class scope, or namespace scope corresponding
    6365              :       to the function, class, or namespace represented by ctx.scope():
    6366              :       -- If r represents a direct base class relationship (D,B), then true if
    6367              :          base class B of DESIGNATING-CLS(r, ctx) is accessible at P;
    6368              :          otherwise false.
    6369              :       -- Otherwise, r represents a class member M; true if M would be
    6370              :          accessible at P with the designating class (as DESIGNATING-CLS(r, ctx)
    6371              :          if the effect of any using-declarations were ignored.  Otherwise,
    6372              :          false.
    6373              :    Throws: meta::exception if r represents a class member for which
    6374              :    PARENT-CLS(r) is an incomplete class.  */
    6375              : 
    6376              : static tree
    6377        38315 : eval_is_accessible (location_t loc, const constexpr_ctx *ctx, tree r,
    6378              :                     reflect_kind kind, tree actx, tree call,
    6379              :                     bool *non_constant_p, tree *jump_target, tree fun)
    6380              : {
    6381        38315 :   tree scope = NULL_TREE, designating_class = NULL_TREE, c;
    6382        38315 :   if (!extract_access_context (loc, actx, &scope, &designating_class))
    6383              :     {
    6384            0 :       *non_constant_p = true;
    6385            0 :       return call;
    6386              :     }
    6387              : 
    6388        38315 :   if (eval_is_class_member (r) == boolean_true_node)
    6389              :     {
    6390        36698 :       r = maybe_get_first_fn (r);
    6391        36698 :       c = r;
    6392        36698 :       if (TREE_CODE (r) == CONST_DECL && UNSCOPED_ENUM_P (DECL_CONTEXT (r)))
    6393           39 :         c = DECL_CONTEXT (r);
    6394        36698 :       if (TYPE_P (c))
    6395              :         {
    6396         2630 :           if (TYPE_NAME (c) && DECL_P (TYPE_NAME (c)))
    6397         2630 :             c = CP_DECL_CONTEXT (TYPE_NAME (c));
    6398              :           else
    6399            0 :             c = CP_TYPE_CONTEXT (c);
    6400              :         }
    6401              :       else
    6402        34068 :         c = CP_DECL_CONTEXT (r);
    6403              :     }
    6404         1617 :   else if (kind == REFLECT_BASE)
    6405              :     {
    6406         1575 :       c = direct_base_derived (r);
    6407         1575 :       r = BINFO_TYPE (r);
    6408              :     }
    6409              :   else
    6410              :     return boolean_true_node;
    6411        38273 :   if (!CLASS_TYPE_P (c) || !COMPLETE_TYPE_P (c))
    6412            0 :     return throw_exception (loc, ctx,
    6413              :                             "incomplete parent class",
    6414            0 :                             fun, non_constant_p, jump_target);
    6415        38273 :   if (designating_class)
    6416              :     {
    6417              :       tree p = c;
    6418         4118 :       while (ANON_AGGR_TYPE_P (p) && p != designating_class)
    6419            6 :         p = CP_TYPE_CONTEXT (p);
    6420         4112 :       if (p != designating_class
    6421         4112 :           && (!CLASS_TYPE_P (p)
    6422         4109 :               || !DERIVED_FROM_P (p, designating_class)))
    6423            1 :         return boolean_false_node;
    6424              :     }
    6425        38272 :   if (scope == NULL_TREE)
    6426        28813 :     return boolean_true_node;
    6427         9459 :   if (designating_class == NULL_TREE)
    6428         5348 :     designating_class = c;
    6429         9459 :   if (TREE_CODE (scope) == NAMESPACE_DECL)
    6430         4688 :     push_to_top_level ();
    6431         4771 :   else if (TYPE_P (scope))
    6432         4149 :     push_access_scope (TYPE_NAME (scope));
    6433              :   else
    6434          622 :     push_access_scope (scope);
    6435         9459 :   tree ret = boolean_false_node;
    6436         9459 :   if (kind == REFLECT_BASE)
    6437              :     {
    6438          406 :       if (accessible_base_p (designating_class, r, /*consider_local_p=*/true))
    6439          284 :         ret = boolean_true_node;
    6440              :     }
    6441              :   else
    6442              :     {
    6443         9053 :       tree o = TYPE_P (r) ? TYPE_NAME (r) : r;
    6444         9053 :       if (accessible_p (TYPE_BINFO (designating_class), o,
    6445              :                         /*consider_local_p=*/true))
    6446         6642 :         ret = boolean_true_node;
    6447              :     }
    6448         9459 :   if (TREE_CODE (scope) == NAMESPACE_DECL)
    6449         4688 :     pop_from_top_level ();
    6450         4771 :   else if (TYPE_P (scope))
    6451         4149 :     pop_access_scope (TYPE_NAME (scope));
    6452              :   else
    6453          622 :     pop_access_scope (scope);
    6454              :   return ret;
    6455              : }
    6456              : 
    6457              : /* Returns true if R is C-members-of-representable from
    6458              :    current point P.  */
    6459              : 
    6460              : static bool
    6461        45443 : members_of_representable_p (tree c, tree r)
    6462              : {
    6463        45443 :   if (TREE_CODE (r) == CONST_DECL)
    6464              :     return false;
    6465        87702 :   if (LAMBDA_TYPE_P (c) && !LAMBDA_FUNCTION_P (r))
    6466              :     return false;
    6467        44296 :   if (TYPE_P (r))
    6468              :     {
    6469         4349 :       if (CP_DECL_CONTEXT (TYPE_NAME (r)) != c)
    6470              :         return false;
    6471         5516 :       if (LAMBDA_TYPE_P (r))
    6472              :         return false;
    6473         3988 :       if (OVERLOAD_TYPE_P (r))
    6474              :         return true;
    6475         2094 :       if (typedef_variant_p (r))
    6476              :         return true;
    6477              :     }
    6478        39947 :   else if (DECL_P (r))
    6479              :     {
    6480        39947 :       if (CP_DECL_CONTEXT (r) != c)
    6481              :         return false;
    6482        10078 :       if (DECL_CLASS_TEMPLATE_P (r)
    6483        38918 :           || DECL_FUNCTION_TEMPLATE_P (r)
    6484        32004 :           || variable_template_p (r)
    6485        30918 :           || DECL_ALIAS_TEMPLATE_P (r)
    6486        29889 :           || concept_definition_p (r)
    6487        29869 :           || TREE_CODE (r) == FIELD_DECL
    6488        63655 :           || TREE_CODE (r) == NAMESPACE_DECL)
    6489              :         return true;
    6490        23648 :       if (VAR_OR_FUNCTION_DECL_P (r) && !undeduced_auto_decl (r))
    6491              :         return true;
    6492              :     }
    6493              :   return false;
    6494              : }
    6495              : 
    6496              : /* Callback for vector qsort to compare members by ascending DECL_UID.  */
    6497              : 
    6498              : static int
    6499       351094 : members_cmp (const void *a, const void *b)
    6500              : {
    6501       351094 :   const constructor_elt *ea = (const constructor_elt *) a;
    6502       351094 :   const constructor_elt *eb = (const constructor_elt *) b;
    6503       351094 :   tree vala = REFLECT_EXPR_HANDLE (ea->value);
    6504       351094 :   tree valb = REFLECT_EXPR_HANDLE (eb->value);
    6505       351094 :   if (TYPE_P (vala))
    6506        62357 :     vala = TYPE_NAME (vala);
    6507       351094 :   if (TYPE_P (valb))
    6508        54456 :     valb = TYPE_NAME (valb);
    6509       351094 :   if (DECL_UID (vala) < DECL_UID (valb))
    6510              :     return -1;
    6511       180768 :   if (DECL_UID (vala) > DECL_UID (valb))
    6512              :     return 1;
    6513            0 :   gcc_assert (ea == eb);
    6514              :   return 0;
    6515              : }
    6516              : 
    6517              : /* Enumerate members of namespace NS for eval_members_of.  */
    6518              : 
    6519              : static vec<constructor_elt, va_gc> *
    6520          102 : namespace_members_of (location_t loc, tree ns)
    6521              : {
    6522          102 :   struct data_t {
    6523              :     location_t loc = UNKNOWN_LOCATION;
    6524              :     tree ns = NULL_TREE;
    6525              :     vec<constructor_elt, va_gc> *elts = nullptr;
    6526              :     hash_set<tree> *seen = nullptr;
    6527              : 
    6528          102 :     data_t (location_t loc, tree ns) : loc (loc), ns (ns) {}
    6529          122 :     ~data_t () { delete seen; }
    6530              :   };
    6531              : 
    6532          759 :   const auto walker = [](tree b, void *data_)
    6533              :     {
    6534          657 :       auto *data = static_cast<data_t *>(data_);
    6535          657 :       tree m = b;
    6536              : 
    6537          657 :       if (VAR_P (b) && DECL_ANON_UNION_VAR_P (b))
    6538              :         {
    6539              :           /* TODO: This doesn't handle namespace N { static union {}; }
    6540              :              but we pedwarn on that, so perhaps it doesn't need to be
    6541              :              handled.  */
    6542            7 :           tree v = DECL_VALUE_EXPR (b);
    6543            7 :           gcc_assert (v && TREE_CODE (v) == COMPONENT_REF);
    6544            7 :           tree var = TREE_OPERAND (v, 0);
    6545            7 :           tree type = TREE_TYPE (var);
    6546            7 :           if (!data->seen)
    6547            7 :             data->seen = new hash_set<tree>;
    6548            7 :           if (members_of_representable_p (data->ns, type)
    6549            7 :               && !data->seen->add (type))
    6550            7 :             CONSTRUCTOR_APPEND_ELT (data->elts, NULL_TREE,
    6551              :                                     get_reflection_raw (data->loc, type));
    6552            7 :           if (members_of_representable_p (data->ns, var)
    6553            7 :               && !data->seen->add (var))
    6554            7 :             CONSTRUCTOR_APPEND_ELT (data->elts, NULL_TREE,
    6555              :                                     get_reflection_raw (data->loc, var));
    6556            7 :           return;
    6557              :         }
    6558              : 
    6559          650 :       if (TREE_CODE (b) == TYPE_DECL)
    6560          288 :         m = TREE_TYPE (b);
    6561              : 
    6562          650 :       if (!members_of_representable_p (data->ns, m))
    6563              :         return;
    6564              : 
    6565          650 :       if (DECL_DECOMPOSITION_P (m) && !DECL_DECOMP_IS_BASE (m))
    6566              :         {
    6567           51 :           tree base = DECL_DECOMP_BASE (m);
    6568           51 :           if (!data->seen)
    6569           13 :             data->seen = new hash_set<tree>;
    6570           51 :           if (members_of_representable_p (data->ns, base)
    6571           51 :               && !data->seen->add (base))
    6572           13 :             CONSTRUCTOR_APPEND_ELT (data->elts, NULL_TREE,
    6573              :                                     get_reflection_raw (data->loc, base));
    6574           51 :           if (!DECL_HAS_VALUE_EXPR_P (m))
    6575           28 :             CONSTRUCTOR_APPEND_ELT (data->elts, NULL_TREE,
    6576              :                                     get_reflection_raw (data->loc, m,
    6577              :                                                         REFLECT_VAR));
    6578           51 :           return;
    6579              :         }
    6580              : 
    6581              :       /* eval_is_accessible should be always true for namespace members,
    6582              :          so don't bother calling it here.  */
    6583          599 :       CONSTRUCTOR_APPEND_ELT (data->elts, NULL_TREE,
    6584              :                               get_reflection_raw (data->loc, m));
    6585              : 
    6586              :       /* For typedef struct { ... } S; include both the S type
    6587              :          alias (added above) and dealias of that for the originally
    6588              :          unnamed type (added below).  */
    6589          599 :       if (TREE_CODE (b) == TYPE_DECL
    6590          599 :           && TYPE_DECL_FOR_LINKAGE_PURPOSES_P (b))
    6591            6 :         CONSTRUCTOR_APPEND_ELT (data->elts, NULL_TREE,
    6592              :                                 get_reflection_raw (data->loc,
    6593              :                                                     strip_typedefs (m)));
    6594              :     };
    6595              : 
    6596          102 :   data_t data (loc, ns);
    6597          102 :   walk_namespace_bindings (ns, walker, &data);
    6598              : 
    6599          102 :   if (data.elts)
    6600          100 :     data.elts->qsort (members_cmp);
    6601          204 :   return data.elts;
    6602          102 : }
    6603              : 
    6604              : /* Enumerate members of class R for eval_*members_of.  KIND is
    6605              :    one of METAFN_{,{,NON}STATIC_DATA_}MEMBERS_OF or
    6606              :    METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS.
    6607              :    For the last kind don't append any elts except for the first one for
    6608              :    which is_accessible returned false.  */
    6609              : 
    6610              : static vec<constructor_elt, va_gc> *
    6611         2704 : class_members_of (location_t loc, const constexpr_ctx *ctx, tree r,
    6612              :                   tree actx, tree call, bool *non_constant_p,
    6613              :                   tree *jump_target, enum metafn_code kind, tree fun)
    6614              : {
    6615         2704 :   r = TYPE_MAIN_VARIANT (r);
    6616         2704 :   if (kind == METAFN_MEMBERS_OF)
    6617              :     {
    6618         2259 :       if (modules_p ())
    6619            0 :         lazy_load_pendings (TYPE_NAME (r));
    6620         2259 :       if (CLASSTYPE_LAZY_DEFAULT_CTOR (r))
    6621           76 :         lazily_declare_fn (sfk_constructor, r);
    6622         2259 :       if (CLASSTYPE_LAZY_COPY_CTOR (r))
    6623           85 :         lazily_declare_fn (sfk_copy_constructor, r);
    6624         2259 :       if (CLASSTYPE_LAZY_MOVE_CTOR (r))
    6625           72 :         lazily_declare_fn (sfk_move_constructor, r);
    6626         2259 :       if (CLASSTYPE_LAZY_DESTRUCTOR (r))
    6627           83 :         lazily_declare_fn (sfk_destructor, r);
    6628         2259 :       if (CLASSTYPE_LAZY_COPY_ASSIGN (r))
    6629           97 :         lazily_declare_fn (sfk_copy_assignment, r);
    6630         2259 :       if (CLASSTYPE_LAZY_MOVE_ASSIGN (r))
    6631           86 :         lazily_declare_fn (sfk_move_assignment, r);
    6632              :     }
    6633         2704 :   auto_vec <tree, 8> implicitly_declared;
    6634         2704 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6635        70662 :   for (tree field = TYPE_FIELDS (r); field; field = DECL_CHAIN (field))
    6636              :     {
    6637        67958 :       tree m = field;
    6638        67958 :       if (TREE_CODE (field) == FIELD_DECL && DECL_ARTIFICIAL (field))
    6639        42938 :         continue; /* Ignore bases and the vptr.  */
    6640        66890 :       else if (DECL_SELF_REFERENCE_P (field))
    6641         2704 :         continue;
    6642        64186 :       else if (TREE_CODE (field) == TYPE_DECL)
    6643         4054 :         m = TREE_TYPE (field);
    6644        60132 :       else if (TREE_CODE (field) == FUNCTION_DECL)
    6645              :         {
    6646              :           /* Ignore cloned cdtors.  */
    6647        39274 :           if (DECL_CLONED_FUNCTION_P (field))
    6648        19438 :             continue;
    6649              :           /* Ignore functions with unsatisfied constraints.  */
    6650        19836 :           if (!constraints_satisfied_p (field))
    6651           20 :             continue;
    6652        19816 :           if (DECL_MAYBE_DELETED (field))
    6653              :             {
    6654           11 :               ++function_depth;
    6655           11 :               maybe_synthesize_method (field);
    6656           11 :               --function_depth;
    6657              :             }
    6658              :         }
    6659        44728 :       if (members_of_representable_p (r, m))
    6660              :         {
    6661        44940 :           if (kind == METAFN_STATIC_DATA_MEMBERS_OF
    6662        42191 :               && eval_is_variable (m, REFLECT_UNDEF) != boolean_true_node)
    6663         2749 :             continue; /* For static_data_members_of only include
    6664              :                          is_variable.  */
    6665        42530 :           else if ((kind == METAFN_NONSTATIC_DATA_MEMBERS_OF
    6666        39442 :                     || kind == METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS)
    6667        39442 :                    && eval_is_nonstatic_data_member (m) != boolean_true_node)
    6668         3088 :             continue; /* For nonstatic_data_members_of only include
    6669              :                          is_nonstatic_data_member.  */
    6670        36354 :           tree a = eval_is_accessible (loc, ctx, m, REFLECT_UNDEF, actx, call,
    6671              :                                        non_constant_p, jump_target, fun);
    6672        36354 :           if (*jump_target || *non_constant_p)
    6673            0 :             return nullptr;
    6674        36354 :           if (a == boolean_false_node)
    6675              :             {
    6676         2318 :               if (kind == METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS
    6677            7 :                   && elts == nullptr)
    6678            3 :                 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, boolean_true_node);
    6679         2318 :               continue;
    6680         2318 :             }
    6681        34036 :           gcc_assert (a == boolean_true_node);
    6682        45552 :           if (kind == METAFN_MEMBERS_OF
    6683        32714 :               && TREE_CODE (m) == FUNCTION_DECL
    6684        51216 :               && DECL_ARTIFICIAL (m))
    6685              :             {
    6686              :               /* Implicitly-declared special members or operator== members
    6687              :                  appear after any user declared members.  */
    6688        11516 :               implicitly_declared.safe_push (m);
    6689        11516 :               continue;
    6690              :             }
    6691        22520 :           else if (kind == METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS)
    6692           37 :             continue;
    6693        22483 :           CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6694              :                                   get_reflection_raw (loc, m));
    6695              :         }
    6696              :     }
    6697              :   /* TYPE_DECLs in TYPE_FIELDS come after other decls due to the "struct
    6698              :      stat hack" (see finish_member_declaration), so for members_of the
    6699              :      declaration order is not preserved.  */
    6700         2704 :   if (kind == METAFN_MEMBERS_OF && elts)
    6701         2216 :     elts->qsort (members_cmp);
    6702         2259 :   if (kind == METAFN_MEMBERS_OF && !implicitly_declared.is_empty ())
    6703              :     {
    6704         2179 :       gcc_assert (implicitly_declared.length () <= 8);
    6705        12990 :       for (tree m : implicitly_declared)
    6706        11497 :         if (default_ctor_p (m))
    6707              :           {
    6708          686 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6709              :                                     get_reflection_raw (loc, m));
    6710          686 :             break;
    6711              :           }
    6712        15174 :       for (tree m : implicitly_declared)
    6713        21622 :         if (DECL_COPY_CONSTRUCTOR_P (m))
    6714              :           {
    6715         2174 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6716              :                                     get_reflection_raw (loc, m));
    6717         2174 :             break;
    6718              :           }
    6719         8711 :       for (tree m : implicitly_declared)
    6720         4344 :         if (special_function_p (m) == sfk_copy_assignment)
    6721              :           {
    6722         2170 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6723              :                                     get_reflection_raw (loc, m));
    6724         2170 :             break;
    6725              :           }
    6726        13075 :       for (tree m : implicitly_declared)
    6727        17370 :         if (DECL_MOVE_CONSTRUCTOR_P (m))
    6728              :           {
    6729         2147 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6730              :                                     get_reflection_raw (loc, m));
    6731         2147 :             break;
    6732              :           }
    6733         6636 :       for (tree m : implicitly_declared)
    6734         2246 :         if (special_function_p (m) == sfk_move_assignment)
    6735              :           {
    6736         2147 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6737              :                                     get_reflection_raw (loc, m));
    6738         2147 :             break;
    6739              :           }
    6740        10867 :       for (tree m : implicitly_declared)
    6741         6505 :         if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (m))
    6742              :           {
    6743         2175 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6744              :                                     get_reflection_raw (loc, m));
    6745         2175 :             break;
    6746              :           }
    6747        18036 :       for (tree m : implicitly_declared)
    6748        11516 :         if (DECL_OVERLOADED_OPERATOR_IS (m, EQ_EXPR))
    6749              :           {
    6750           17 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6751              :                                     get_reflection_raw (loc, m));
    6752           17 :             break;
    6753              :           }
    6754              :     }
    6755         2704 :   return elts;
    6756         2704 : }
    6757              : 
    6758              : /* Enumerate bases of class R for eval_*of.  KIND is METAFN_BASES_OF
    6759              :    or METAFN_HAS_INACCESSIBLE_BASES.  */
    6760              : 
    6761              : static vec<constructor_elt, va_gc> *
    6762          701 : class_bases_of (location_t loc, const constexpr_ctx *ctx, tree r,
    6763              :                 tree actx, tree call, bool *non_constant_p,
    6764              :                 tree *jump_target, enum metafn_code kind, tree fun)
    6765              : {
    6766          701 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6767          701 :   tree binfo = TYPE_BINFO (r), base_binfo;
    6768         2245 :   for (unsigned i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    6769              :     {
    6770         1544 :       tree a = eval_is_accessible (loc, ctx, base_binfo, REFLECT_BASE, actx,
    6771              :                                    call, non_constant_p, jump_target, fun);
    6772         1544 :       if (*jump_target || *non_constant_p)
    6773              :         return nullptr;
    6774         1544 :       if (a == boolean_false_node)
    6775              :         {
    6776          106 :           if (kind == METAFN_HAS_INACCESSIBLE_BASES && elts == nullptr)
    6777            8 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, boolean_true_node);
    6778          106 :           continue;
    6779          106 :         }
    6780         1438 :       gcc_assert (a == boolean_true_node);
    6781         1438 :       if (kind == METAFN_HAS_INACCESSIBLE_BASES)
    6782           53 :         continue;
    6783         2929 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6784              :                               get_reflection_raw (loc, base_binfo,
    6785              :                                                   REFLECT_BASE));
    6786              :     }
    6787          701 :   return elts;
    6788              : }
    6789              : 
    6790              : /* Implement std::meta::members_of.
    6791              :    A declaration D members-of-precedes a point P if D precedes either P or the
    6792              :    point immediately following the class-specifier of the outermost class for
    6793              :    which P is in a complete-class context.
    6794              :    A declaration D of a member M of a class or namespace Q is
    6795              :    Q-members-of-eligible if
    6796              :    -- the host scope of D is the class scope or namespace scope associated
    6797              :       with Q,
    6798              :    -- D is not a friend declaration,
    6799              :    -- M is not a closure type,
    6800              :    -- M is not a specialization of a template,
    6801              :    -- if Q is a class that is not a closure type, then M is a direct member of
    6802              :       Q that is not a variant member of a nested anonymous union of Q, and
    6803              :    -- if Q is a closure type, then M is a function call operator or function
    6804              :       call operator template.
    6805              :    It is implementation-defined whether declarations of other members of a
    6806              :    closure type Q are Q-members-of-eligible.
    6807              :    A member M of a class or namespace Q is Q-members-of-representable from a
    6808              :    point P if a Q-members-of-eligible declaration of M members-of-precedes P,
    6809              :    and M is
    6810              :    -- a class or enumeration type
    6811              :    -- a type alias
    6812              :    -- a class template, function template, variable template, alias template,
    6813              :       or concept,
    6814              :    -- a variable or reference V for which the type of V does not contain an
    6815              :       undeduced placeholder type,
    6816              :    -- a function F for which
    6817              :       -- the type of F does not contain an undeduced placeholder type,
    6818              :       -- the constraints (if any) of F are satisfied, and
    6819              :       -- if F is a prospective destructor, F is the selected destructor,
    6820              :    -- a non-static data member,
    6821              :    -- a namespace, or
    6822              :    -- a namespace alias.
    6823              :    Returns: A vector containing reflections of all members M of the entity Q
    6824              :    represented by dealias(r) for which
    6825              :    -- M is Q-members-of-representable from some point in the evaluation
    6826              :       context and
    6827              :    -- is_accessible(^^M, ctx) is true.
    6828              :    If dealias(r) represents a class C, then the vector also contains
    6829              :    reflections representing all unnamed bit-fields B whose declarations
    6830              :    inhabit the class scope corresponding to C for which
    6831              :    is_accessible(^^B, ctx) is true.
    6832              :    Reflections of class members and unnamed bit-fields that are declared
    6833              :    appear in the order in which they are declared.
    6834              :    Throws: meta::exception unless dealias(r) is a reflection representing
    6835              :    either a class type that is complete from some point in the evaluation
    6836              :    context or a namespace.  */
    6837              : 
    6838              : static tree
    6839         2361 : eval_members_of (location_t loc, const constexpr_ctx *ctx, tree r,
    6840              :                  tree actx, tree call, bool *non_constant_p,
    6841              :                  tree *jump_target, tree fun)
    6842              : {
    6843         2361 :   r = maybe_strip_typedefs (r);
    6844         2361 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    6845          102 :     r = ORIGINAL_NAMESPACE (r);
    6846         2361 :   vec<constructor_elt, va_gc> *elts;
    6847         2361 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    6848          102 :     elts = namespace_members_of (loc, r);
    6849         2259 :   else if (CLASS_TYPE_P (r)
    6850         4518 :            && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    6851              :     {
    6852         2259 :       elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
    6853              :                                jump_target, METAFN_MEMBERS_OF, fun);
    6854         2259 :       if (*jump_target || *non_constant_p)
    6855              :         return NULL_TREE;
    6856              :     }
    6857              :   else
    6858            0 :     return throw_exception (loc, ctx,
    6859              :                             "neither complete class type nor namespace",
    6860            0 :                             fun, non_constant_p, jump_target);
    6861         2361 :   return get_vector_of_info_elts (elts);
    6862              : }
    6863              : 
    6864              : /* Implement std::meta::bases_of.
    6865              :    Returns: Let C be the class represented by dealias(type).
    6866              :    A vector containing the reflections of all the direct base class
    6867              :    relationships B, if any, of C such that is_accessible(^^B, ctx) is true.
    6868              :    The direct base class relationships appear in the order in which the
    6869              :    corresponding base classes appear in the base-specifier-list of C.
    6870              :    Throws: meta::exception unless dealias(type) represents a class type that
    6871              :    is complete from some point in the evaluation context.  */
    6872              : 
    6873              : static tree
    6874          494 : eval_bases_of (location_t loc, const constexpr_ctx *ctx, tree r,
    6875              :                tree actx, tree call, bool *non_constant_p,
    6876              :                tree *jump_target, tree fun)
    6877              : {
    6878          494 :   r = maybe_strip_typedefs (r);
    6879          494 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6880          494 :   if (CLASS_TYPE_P (r)
    6881          988 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    6882              :     {
    6883          494 :       elts = class_bases_of (loc, ctx, r, actx, call, non_constant_p,
    6884              :                              jump_target, METAFN_BASES_OF, fun);
    6885          494 :       if (*jump_target || *non_constant_p)
    6886              :         return NULL_TREE;
    6887              :     }
    6888              :   else
    6889            0 :     return throw_exception (loc, ctx, "not a complete class type",
    6890            0 :                             fun, non_constant_p, jump_target);
    6891          494 :   return get_vector_of_info_elts (elts);
    6892              : }
    6893              : 
    6894              : /* Implement std::meta::static_data_members_of.
    6895              :    Returns: A vector containing each element e of members_of(type, ctx) such
    6896              :    that is_variable(e) is true, preserving their order.
    6897              :    Throws: meta::exception unless dealias(type) represents a class type that
    6898              :    is complete from some point in the evaluation context.  */
    6899              : 
    6900              : static tree
    6901           80 : eval_static_data_members_of (location_t loc, const constexpr_ctx *ctx, tree r,
    6902              :                              tree actx, tree call, bool *non_constant_p,
    6903              :                              tree *jump_target, tree fun)
    6904              : {
    6905           80 :   r = maybe_strip_typedefs (r);
    6906           80 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6907           80 :   if (CLASS_TYPE_P (r)
    6908          160 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    6909              :     {
    6910           80 :       elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
    6911              :                                jump_target, METAFN_STATIC_DATA_MEMBERS_OF,
    6912              :                                fun);
    6913           80 :       if (*jump_target || *non_constant_p)
    6914              :         return NULL_TREE;
    6915              :     }
    6916              :   else
    6917            0 :     return throw_exception (loc, ctx, "not a complete class type",
    6918            0 :                             fun, non_constant_p, jump_target);
    6919           80 :   return get_vector_of_info_elts (elts);
    6920              : }
    6921              : 
    6922              : /* Implement std::meta::nonstatic_data_members_of.
    6923              :    Returns: A vector containing each element e of members_of(type, ctx) such
    6924              :    that is_nonstatic_data_member(e) is true, preserving their order.
    6925              :    Throws: meta::exception unless dealias(type) represents a class type that
    6926              :    is complete from some point in the evaluation context.  */
    6927              : 
    6928              : static tree
    6929          159 : eval_nonstatic_data_members_of (location_t loc, const constexpr_ctx *ctx,
    6930              :                                 tree r, tree actx, tree call,
    6931              :                                 bool *non_constant_p, tree *jump_target,
    6932              :                                 tree fun)
    6933              : {
    6934          159 :   r = maybe_strip_typedefs (r);
    6935          159 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6936          159 :   if (CLASS_TYPE_P (r)
    6937          318 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    6938              :     {
    6939          159 :       elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
    6940              :                                jump_target, METAFN_NONSTATIC_DATA_MEMBERS_OF,
    6941              :                                fun);
    6942          159 :       if (*jump_target || *non_constant_p)
    6943              :         return NULL_TREE;
    6944              :     }
    6945              :   else
    6946            0 :     return throw_exception (loc, ctx, "not a complete class type",
    6947            0 :                             fun, non_constant_p, jump_target);
    6948          159 :   return get_vector_of_info_elts (elts);
    6949              : }
    6950              : 
    6951              : /* Implement std::meta::subobjects_of.
    6952              :    Returns: A vector containing each element of bases_of(type, ctx) followed
    6953              :    by each element of nonstatic_data_members_of(type, ctx), preserving their
    6954              :    order.
    6955              :    Throws: meta::exception unless dealias(type) represents a class type that
    6956              :    is complete from some point in the evaluation context.  */
    6957              : 
    6958              : static tree
    6959          176 : eval_subobjects_of (location_t loc, const constexpr_ctx *ctx, tree r,
    6960              :                     tree actx, tree call, bool *non_constant_p,
    6961              :                     tree *jump_target, tree fun)
    6962              : {
    6963          176 :   r = maybe_strip_typedefs (r);
    6964          176 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6965          176 :   if (CLASS_TYPE_P (r)
    6966          352 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    6967              :     {
    6968          176 :       elts = class_bases_of (loc, ctx, r, actx, call, non_constant_p,
    6969              :                              jump_target, METAFN_BASES_OF, fun);
    6970          176 :       if (*jump_target || *non_constant_p)
    6971              :         return NULL_TREE;
    6972          176 :       vec<constructor_elt, va_gc> *elts2
    6973          176 :         = class_members_of (loc, ctx, r, actx, call, non_constant_p,
    6974              :                             jump_target, METAFN_NONSTATIC_DATA_MEMBERS_OF,
    6975              :                             fun);
    6976          176 :       if (*jump_target || *non_constant_p)
    6977              :         return NULL_TREE;
    6978          176 :       if (elts == nullptr)
    6979           48 :         elts = elts2;
    6980          128 :       else if (elts2)
    6981          121 :         vec_safe_splice (elts, elts2);
    6982              :     }
    6983              :   else
    6984            0 :     return throw_exception (loc, ctx, "not a complete class type",
    6985            0 :                             fun, non_constant_p, jump_target);
    6986          176 :   return get_vector_of_info_elts (elts);
    6987              : }
    6988              : 
    6989              : /* Implement std::meta::has_inaccessible_nonstatic_data_members.
    6990              :    Returns: true if is_accessible(R, ctx) is false for any R in
    6991              :    nonstatic_data_members_of(r, access_context::unchecked()).
    6992              :    Otherwise, false.
    6993              :    Throws: meta::exception if
    6994              :    -- the evaluation of
    6995              :       nonstatic_data_members_of(r, access_context::unchecked()) would exit via
    6996              :       an exception and or
    6997              :    -- r represents a closure type.  */
    6998              : 
    6999              : static tree
    7000           30 : eval_has_inaccessible_nonstatic_data_members (location_t loc,
    7001              :                                               const constexpr_ctx *ctx,
    7002              :                                               tree r, tree actx, tree call,
    7003              :                                               bool *non_constant_p,
    7004              :                                               tree *jump_target, tree fun)
    7005              : {
    7006           30 :   r = maybe_strip_typedefs (r);
    7007           30 :   vec<constructor_elt, va_gc> *elts = nullptr;
    7008           30 :   if (CLASS_TYPE_P (r)
    7009           60 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    7010              :     {
    7011           60 :       if (LAMBDA_TYPE_P (r))
    7012            0 :         return throw_exception (loc, ctx, "closure type", fun,
    7013            0 :                                 non_constant_p, jump_target);
    7014           30 :       elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
    7015              :                                jump_target,
    7016              :                                METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS,
    7017              :                                fun);
    7018           30 :       if (*jump_target || *non_constant_p)
    7019              :         return NULL_TREE;
    7020              :     }
    7021              :   else
    7022            0 :     return throw_exception (loc, ctx, "not a complete class type",
    7023            0 :                             fun, non_constant_p, jump_target);
    7024           30 :   if (elts == nullptr)
    7025           27 :     return boolean_false_node;
    7026              :   else
    7027            3 :     return boolean_true_node;
    7028              : }
    7029              : 
    7030              : /* Implement std::meta::has_inaccessible_bases.
    7031              :    Returns: true if is_accessible(R, ctx) is false for any R in
    7032              :    bases_of(r, access_context::unchecked()).  Otherwise, false.
    7033              :    Throws: meta::exception if the evaluation of
    7034              :    bases_of(r, access_context::unchecked()) would exit via an exception.  */
    7035              : 
    7036              : static tree
    7037           31 : eval_has_inaccessible_bases (location_t loc, const constexpr_ctx *ctx,
    7038              :                              tree r, tree actx, tree call,
    7039              :                              bool *non_constant_p, tree *jump_target,
    7040              :                              tree fun)
    7041              : {
    7042           31 :   r = maybe_strip_typedefs (r);
    7043           31 :   vec<constructor_elt, va_gc> *elts = nullptr;
    7044           31 :   if (CLASS_TYPE_P (r)
    7045           62 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    7046              :     {
    7047           31 :       elts = class_bases_of (loc, ctx, r, actx, call, non_constant_p,
    7048              :                              jump_target, METAFN_HAS_INACCESSIBLE_BASES, fun);
    7049           31 :       if (*jump_target || *non_constant_p)
    7050              :         return NULL_TREE;
    7051              :     }
    7052              :   else
    7053            0 :     return throw_exception (loc, ctx, "not a complete class type",
    7054            0 :                             fun, non_constant_p, jump_target);
    7055           31 :   if (elts == nullptr)
    7056           23 :     return boolean_false_node;
    7057              :   else
    7058            8 :     return boolean_true_node;
    7059              : }
    7060              : 
    7061              : /* Implement std::meta::has_inaccessible_subobjects.
    7062              :    Effects: Equivalent to:
    7063              :    return has_inaccessible_bases(r, ctx)
    7064              :           || has_inaccessible_nonstatic_data_members(r, ctx);  */
    7065              : 
    7066              : static tree
    7067           19 : eval_has_inaccessible_subobjects (location_t loc, const constexpr_ctx *ctx,
    7068              :                                   tree r, tree actx, tree call,
    7069              :                                   bool *non_constant_p, tree *jump_target,
    7070              :                                   tree fun)
    7071              : {
    7072           19 :   tree b = eval_has_inaccessible_bases (loc, ctx, r, actx, call,
    7073              :                                         non_constant_p, jump_target, fun);
    7074           19 :   if (*jump_target || *non_constant_p)
    7075              :     return NULL_TREE;
    7076           19 :   if (b == boolean_true_node)
    7077              :     return b;
    7078           15 :   return eval_has_inaccessible_nonstatic_data_members (loc, ctx, r, actx,
    7079              :                                                        call, non_constant_p,
    7080           15 :                                                        jump_target, fun);
    7081              : }
    7082              : 
    7083              : /* Implement std::meta::exception::_S_exception_cvt_to_utf8 and
    7084              :    std::meta::exception::_S_exception_cvt_from_utf8.  This is
    7085              :    an implementation specific metafunction which translates string_view
    7086              :    into u8string_view resp. u8string_view into string_view for use in
    7087              :    std::meta::exception constructors.  On translation failure returns an empty
    7088              :    {u8,}string_view.  TO_UTF8 is true for _S_exception_cvt_to_utf8 and false
    7089              :    for _S_exception_cvt_from_utf8.  */
    7090              : 
    7091              : static tree
    7092         1497 : eval_exception__S_exception_cvt_tofrom_utf8 (location_t loc,
    7093              :                                              const constexpr_ctx *ctx,
    7094              :                                              tree call, bool *non_constant_p,
    7095              :                                              bool *overflow_p,
    7096              :                                              tree *jump_target, tree fun,
    7097              :                                              bool to_utf8)
    7098              : {
    7099         1497 :   tree str = get_range_elts (loc, ctx, call, 0, non_constant_p, overflow_p,
    7100              :                              jump_target, REFLECT_CONSTANT_STRING, fun);
    7101         1497 :   if (*jump_target || *non_constant_p)
    7102              :     return NULL_TREE;
    7103         1497 :   if (TREE_CODE (str) != STRING_CST
    7104         2994 :       || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)))
    7105         1497 :           != (to_utf8 ? char_type_node : char8_type_node)))
    7106              :     {
    7107            0 :       error_at (loc, "unexpected argument to %qs",
    7108              :                 to_utf8 ? "_S_exception_cvt_to_utf8"
    7109              :                 : "_S_exception_cvt_from_utf8");
    7110            0 :       *non_constant_p = true;
    7111            0 :       return call;
    7112              :     }
    7113              :   /* We need to translate the string twice for the theoretical case
    7114              :      of non-UTF8 SOURCE_CHARSET.  First translate from {exec charset,UTF-8} to
    7115              :      SOURCE_CHARSET...  */
    7116         1497 :   cpp_string istr, ostr;
    7117         1497 :   istr.len = TREE_STRING_LENGTH (str) + 1;
    7118         1497 :   istr.text = (const unsigned char *) TREE_STRING_POINTER (str);
    7119         1497 :   const char *name;
    7120         1525 :   if (!cpp_translate_string (parse_in, &istr, &ostr,
    7121              :                              to_utf8 ? CPP_STRING : CPP_UTF8STRING, true))
    7122              :     {
    7123            0 :       ostr.text = NULL;
    7124            0 :       name = "";
    7125              :     }
    7126              :   else
    7127         1497 :     name = (const char *) ostr.text;
    7128              :   /* And then let get_string_literal translate from SOURCE_CHARSET to
    7129              :      {UTF-8,exec charset}.  */
    7130         1497 :   tree dchar_type = to_utf8 ? char8_type_node : char_type_node;
    7131         1497 :   str = get_string_literal (name, dchar_type);
    7132         1497 :   free (const_cast <unsigned char *> (ostr.text));
    7133         1497 :   if (str == NULL_TREE)
    7134              :     {
    7135            2 :       str = get_string_literal ("", dchar_type);
    7136            2 :       gcc_assert (str);
    7137              :     }
    7138         1497 :   releasing_vec args (make_tree_vector_single (str));
    7139         1497 :   tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    7140         1497 :                                         &args, TREE_TYPE (call), LOOKUP_NORMAL,
    7141              :                                         tf_warning_or_error);
    7142         1497 :   return build_cplus_new (TREE_TYPE (call), ret, tf_warning_or_error);
    7143         1497 : }
    7144              : 
    7145              : /* Helper for eval_extract, extracting a reference type T.
    7146              :    Returns: If r represents an object O, then a reference to O.
    7147              :    Otherwise, a reference to the object declared, or referred to, by the
    7148              :    variable represented by r.
    7149              :    Throws: meta::exception unless
    7150              :    -- r represents a variable or object of type U,
    7151              :    -- is_convertible_v<remove_reference_t<U>(*)[],
    7152              :       remove_reference_t<T>(*)[]> is true, and
    7153              :    -- If r represents a variable, then either that variable is usable in
    7154              :       constant expressions or its lifetime began within the core constant
    7155              :       expression currently under evaluation.  */
    7156              : 
    7157              : static tree
    7158           66 : extract_ref (location_t loc, const constexpr_ctx *ctx, tree T, tree r,
    7159              :              reflect_kind kind, bool *non_constant_p, tree *jump_target,
    7160              :              tree fun)
    7161              : {
    7162          182 :   auto adjust_type = [](tree type) -> tree
    7163              :     {
    7164          116 :       if (TYPE_REF_P (type))
    7165           65 :         type = TREE_TYPE (type);
    7166          116 :       type = build_cplus_array_type (type, NULL_TREE);
    7167          116 :       return build_pointer_type (type);
    7168              :     };
    7169              : 
    7170           66 :   const bool var_p = eval_is_variable (r, kind) == boolean_true_node;
    7171           90 :   if (var_p || eval_is_object (kind) == boolean_true_node)
    7172              :     {
    7173              :       /* The wording is saying that U is the type of r.  */
    7174           58 :       tree U = TREE_TYPE (r);
    7175           58 :       if (is_convertible (adjust_type (U), adjust_type (T))
    7176           58 :           && (!var_p || is_constant_expression (r)))
    7177              :         {
    7178           54 :           if (TYPE_REF_P (TREE_TYPE (r)))
    7179              :             {
    7180            7 :               r = DECL_INITIAL (r);
    7181            7 :               r = maybe_get_reference_referent (r);
    7182            7 :               gcc_checking_assert (!TYPE_REF_P (TREE_TYPE (r)));
    7183              :             }
    7184           54 :           return build_address (r);
    7185              :         }
    7186              :     }
    7187              : 
    7188           12 :   return throw_exception (loc, ctx, "value cannot be extracted", fun,
    7189           12 :                           non_constant_p, jump_target);
    7190              : }
    7191              : 
    7192              : /* Helper for extract_value.  Return true iff we can extract value of
    7193              :    type U using type T.  */
    7194              : 
    7195              : static bool
    7196          342 : can_extract_value_p (tree T, tree U)
    7197              : {
    7198          342 :   if (POINTER_TYPE_P (U)
    7199           22 :       && (similar_type_p (T, U)
    7200            8 :           || (FUNCTION_POINTER_TYPE_P (T) && FUNCTION_POINTER_TYPE_P (U)))
    7201          360 :       && is_convertible (U, T))
    7202              :     return true;
    7203          330 :   else if (same_type_ignoring_top_level_qualifiers_p (T, U))
    7204              :     return true;
    7205          254 :   else if (TREE_CODE (U) == ARRAY_TYPE
    7206          169 :            && POINTER_TYPE_P (T)
    7207          423 :            && is_convertible (U, T))
    7208              :     {
    7209              :       /* remove_extent_t<U> */
    7210          163 :       U = TREE_TYPE (U);
    7211          163 :       U = strip_typedefs (U);
    7212              :       /* remove_extent_t<U>* */
    7213          163 :       U = build_pointer_type (U);
    7214          163 :       return similar_type_p (T, U);
    7215              :     }
    7216           18 :   else if (LAMBDA_TYPE_P (U)
    7217            7 :            && FUNCTION_POINTER_TYPE_P (T)
    7218           98 :            && is_convertible (U, T))
    7219              :     return true;
    7220              :   return false;
    7221              : }
    7222              : 
    7223              : /* Helper for eval_extract, extracting a value.
    7224              :    Let U be the type of the value or object that r represents.
    7225              :    Returns: static_cast<T>([:R:]), where R is a constant expression of
    7226              :    type info such that R == r is true.
    7227              :    Throws: meta::exception unless
    7228              :    -- U is a pointer type, T and U are either similar or both function pointer
    7229              :       types, and is_convertible_v<U, T> is true,
    7230              :    -- U is not a pointer type and the cv-unqualified types of T and U are the
    7231              :       same,
    7232              :    -- U is an array type, T is a pointer type, remove_extent_t<U>* and T are
    7233              :       similar types, and the value r represents is convertible to T, or
    7234              :    -- U is a closure type, T is a function pointer type, and the value that r
    7235              :       represents is convertible to T.  */
    7236              : 
    7237              : static tree
    7238          342 : extract_value (location_t loc, const constexpr_ctx *ctx, tree T, tree r,
    7239              :                bool *non_constant_p, tree *jump_target, tree fun)
    7240              : {
    7241          342 :   if (REFLECT_EXPR_P (r))
    7242              :     {
    7243          342 :       r = REFLECT_EXPR_HANDLE (r);
    7244          342 :       if (can_extract_value_p (T, TREE_TYPE (r)))
    7245          254 :         return build_static_cast (loc, T, r, tf_none);
    7246              :     }
    7247           88 :   return throw_exception (loc, ctx, "value cannot be extracted", fun,
    7248           88 :                           non_constant_p, jump_target);
    7249              : }
    7250              : 
    7251              : /* Helper for extract_member_or_function.  Return true iff we can
    7252              :    extract an NSDM or function R of kind KIND using type T.  */
    7253              : 
    7254              : static bool
    7255           78 : can_extract_member_or_function_p (tree T, tree r, reflect_kind kind)
    7256              : {
    7257           78 :   if (eval_is_nonstatic_data_member (r) == boolean_true_node)
    7258              :     {
    7259           15 :       if (eval_is_bit_field (r, kind) == boolean_true_node)
    7260              :         return false;
    7261              :       /* static union { int m; }; extract<int>(^^m); is invalid.  */
    7262           11 :       if (TREE_CODE (r) == FIELD_DECL
    7263           11 :           && ANON_UNION_TYPE_P (DECL_CONTEXT (r)))
    7264              :         {
    7265            2 :           tree c = CP_TYPE_CONTEXT (DECL_CONTEXT (r));
    7266            2 :           while (ANON_UNION_TYPE_P (c))
    7267            0 :             c = CP_TYPE_CONTEXT (c);
    7268            2 :           if (!TYPE_P (c))
    7269              :             return false;
    7270              :         }
    7271              :       /* Create the X C::* type.  */
    7272            9 :       tree type = build_offset_type (CP_DECL_CONTEXT (r), TREE_TYPE (r));
    7273            9 :       if (similar_type_p (type, T) && is_convertible (type, T))
    7274              :         return true;
    7275            0 :       return false;
    7276              :     }
    7277           63 :   else if (DECL_IOBJ_MEMBER_FUNCTION_P (r))
    7278              :     {
    7279           43 :       tree F = TREE_TYPE (r);
    7280           43 :       F = build_pointer_type (F);
    7281           43 :       F = build_ptrmemfunc_type (F);
    7282           43 :       if (same_type_p (T, F) || fnptr_conv_p (T, F))
    7283           17 :         return true;
    7284              :       return false;
    7285              :     }
    7286           20 :   else if (TREE_CODE (r) == FUNCTION_DECL)
    7287              :     {
    7288           20 :       tree F = TREE_TYPE (r);
    7289           20 :       F = build_pointer_type (F);
    7290           20 :       if (same_type_p (T, F) || fnptr_conv_p (T, F))
    7291           12 :         return true;
    7292              :       return false;
    7293              :     }
    7294              : 
    7295              :   return false;
    7296              : }
    7297              : 
    7298              : /* Helper for eval_extract, extracting a NSDM or function.
    7299              :    Returns:
    7300              :    -- If T is a pointer type, then a pointer value pointing to the function
    7301              :       represented by r.
    7302              :    -- Otherwise, a pointer-to-member value designating the non-static data
    7303              :       member or function represented by r.
    7304              :    Throws: meta::exception unless
    7305              :    -- r represents a non-static data member with type X, that is not
    7306              :       a bit-field, that is a direct member of class C, T and X C::*
    7307              :       are similar types, and is_convertible_v<X C::*, T> is true;
    7308              :    -- r represents an implicit object member function with type F or
    7309              :       F noexcept that is a direct member of a class C, and T is F C::*; or
    7310              :    -- r represents a non-member function, static member function, or
    7311              :       explicit object member function of function type F or F noexcept, and
    7312              :       T is F*.  */
    7313              : 
    7314              : static tree
    7315           78 : extract_member_or_function (location_t loc, const constexpr_ctx *ctx,
    7316              :                             tree T, tree r, reflect_kind kind,
    7317              :                             bool *non_constant_p, tree *jump_target, tree fun)
    7318              : {
    7319           78 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    7320           78 :   if (!can_extract_member_or_function_p (T, r, kind))
    7321           40 :     return throw_exception (loc, ctx, "value cannot be extracted", fun,
    7322           40 :                             non_constant_p, jump_target);
    7323              : 
    7324           38 :   const tsubst_flags_t complain = complain_flags (ctx);
    7325           38 :   if (POINTER_TYPE_P (T))
    7326              :     {
    7327           12 :       r = cp_build_addr_expr (r, complain);
    7328           12 :       return perform_implicit_conversion (T, r, complain);
    7329              :     }
    7330              :   else
    7331              :     {
    7332           26 :       if (!mark_used (r, complain))
    7333              :         {
    7334            0 :           *non_constant_p = true;
    7335            0 :           return NULL_TREE;
    7336              :         }
    7337           26 :       r = build_offset_ref (DECL_CONTEXT (r), r, /*address_p=*/true, complain);
    7338           26 :       r = cp_build_addr_expr (r, complain);
    7339           26 :       r = cp_convert (T, r, complain);
    7340           26 :       return r;
    7341              :     }
    7342              : }
    7343              : 
    7344              : /* Process std::meta::extract.
    7345              :    Let U be remove_cv_t<T>.
    7346              :    Effects: Equivalent to:
    7347              :      if constexpr (is_reference_type(^^T)) {
    7348              :        return extract-ref<T>(r);
    7349              :      } else if constexpr (is_nonstatic_data_member(r) || is_function(r)) {
    7350              :        return extract-member-or-function<U>(r);
    7351              :      } else {
    7352              :        return extract-value<U>(constant_of(r));
    7353              :      }
    7354              :   */
    7355              : 
    7356              : static tree
    7357          491 : eval_extract (location_t loc, const constexpr_ctx *ctx, tree type, tree r,
    7358              :               reflect_kind kind, bool *non_constant_p, bool *overflow_p,
    7359              :               tree *jump_target, tree fun)
    7360              : {
    7361          491 :   if (eval_is_reference_type (loc, type) == boolean_true_node)
    7362           66 :     return extract_ref (loc, ctx, type, r, kind, non_constant_p, jump_target,
    7363           66 :                         fun);
    7364          425 :   type = cv_unqualified (type);
    7365          425 :   if (eval_is_nonstatic_data_member (r) == boolean_true_node
    7366          425 :       || eval_is_function (r) == boolean_true_node)
    7367           78 :     return extract_member_or_function (loc, ctx, type, r, kind, non_constant_p,
    7368           78 :                                        jump_target, fun);
    7369              :   else
    7370              :     {
    7371          347 :       r = eval_constant_of (loc, ctx, r, kind, non_constant_p, overflow_p,
    7372              :                             jump_target, fun);
    7373          347 :       if (*jump_target || *non_constant_p)
    7374              :         return NULL_TREE;
    7375          342 :       return extract_value (loc, ctx, type, r, non_constant_p, jump_target,
    7376          342 :                             fun);
    7377              :     }
    7378              : }
    7379              : 
    7380              : /* Expand a call to a metafunction FUN.  CALL is the CALL_EXPR.
    7381              :    JUMP_TARGET is set if we are throwing std::meta::exception.  */
    7382              : 
    7383              : tree
    7384        25880 : process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
    7385              :                       bool *non_constant_p, bool *overflow_p,
    7386              :                       tree *jump_target)
    7387              : {
    7388        25880 :   tree name = DECL_NAME (fun);
    7389        25880 :   const char *ident = IDENTIFIER_POINTER (name);
    7390        25880 :   const location_t loc = cp_expr_loc_or_input_loc (call);
    7391        25880 :   const metafn_info *minfo
    7392        25880 :     = metafn_lookup::find (ident, IDENTIFIER_LENGTH (name));
    7393        25880 :   if (minfo == NULL)
    7394              :     {
    7395            0 :     not_found:
    7396            0 :       error_at (loc, "unknown metafunction %qD", fun);
    7397            0 :       *non_constant_p = true;
    7398            0 :       return NULL_TREE;
    7399              :     }
    7400              :   tree h = NULL_TREE, h1 = NULL_TREE, hvec = NULL_TREE, expr = NULL_TREE;
    7401              :   tree type = NULL_TREE, ht, info;
    7402              :   reflect_kind kind = REFLECT_UNDEF;
    7403       102303 :   for (int argno = 0; argno < 3; ++argno)
    7404        76839 :     switch (METAFN_KIND_ARG (argno))
    7405              :       {
    7406              :       case METAFN_KIND_ARG_VOID:
    7407              :         break;
    7408        24026 :       case METAFN_KIND_ARG_INFO:
    7409        24026 :       case METAFN_KIND_ARG_TINFO:
    7410        24026 :         gcc_assert (argno < 2);
    7411        24026 :         info = get_info (ctx, call, argno, non_constant_p, overflow_p,
    7412              :                          jump_target);
    7413        24026 :         if (*jump_target || *non_constant_p)
    7414              :           return NULL_TREE;
    7415        24000 :         ht = REFLECT_EXPR_HANDLE (info);
    7416        24000 :         if (METAFN_KIND_ARG (argno) == METAFN_KIND_ARG_TINFO
    7417        24000 :             && eval_is_type (ht) != boolean_true_node)
    7418          371 :           return throw_exception_nontype (loc, ctx, fun, non_constant_p,
    7419          371 :                                           jump_target);
    7420        23629 :         if (argno == 0)
    7421              :           {
    7422        22639 :             kind = REFLECT_EXPR_KIND (info);
    7423        22639 :             h = ht;
    7424              :           }
    7425              :         else
    7426              :           h1 = ht;
    7427              :         break;
    7428          529 :       case METAFN_KIND_ARG_REFLECTION_RANGE:
    7429          529 :         gcc_assert (argno == 1);
    7430          529 :         hvec = get_info_vec (loc, ctx, call, argno, non_constant_p,
    7431              :                              overflow_p, jump_target, fun);
    7432          529 :         if (*jump_target || *non_constant_p)
    7433              :           return NULL_TREE;
    7434              :         break;
    7435         1071 :       case METAFN_KIND_ARG_REFLECTION_RANGET:
    7436         1071 :         hvec = get_type_info_vec (loc, ctx, call, argno, non_constant_p,
    7437              :                                 overflow_p, jump_target, fun);
    7438         1071 :         if (*jump_target || *non_constant_p)
    7439              :           return NULL_TREE;
    7440              :         break;
    7441         1748 :       case METAFN_KIND_ARG_INPUT_RANGE:
    7442              :         /* Handled in eval_reflect_constant_*.  */
    7443         1748 :         gcc_assert (argno == 0);
    7444              :         break;
    7445          549 :       case METAFN_KIND_ARG_TEMPLATE_PARM:
    7446          549 :       case METAFN_KIND_ARG_TEMPLATE_PARM_REF:
    7447          549 :         type = TREE_VEC_ELT (get_template_innermost_arguments (fun), 0);
    7448              :         /* FALLTHRU */
    7449          738 :       case METAFN_KIND_ARG_SIZE_T:
    7450          738 :       case METAFN_KIND_ARG_OPERATORS:
    7451          738 :         gcc_assert (argno == 0);
    7452          738 :         expr = get_nth_callarg (call, 0);
    7453          738 :         expr = cxx_eval_constant_expression (ctx, expr, vc_prvalue,
    7454              :                                              non_constant_p, overflow_p,
    7455              :                                              jump_target);
    7456          738 :         if (*jump_target || *non_constant_p)
    7457              :           return NULL_TREE;
    7458              :         break;
    7459         4162 :       case METAFN_KIND_ARG_UNSIGNED:
    7460         4162 :       case METAFN_KIND_ARG_ACCESS_CONTEXT:
    7461         4162 :       case METAFN_KIND_ARG_DATA_MEMBER_OPTIONS:
    7462         4162 :         gcc_assert (argno == 1);
    7463         4162 :         expr = get_nth_callarg (call, argno);
    7464         4162 :         expr = cxx_eval_constant_expression (ctx, expr, vc_prvalue,
    7465              :                                              non_constant_p, overflow_p,
    7466              :                                              jump_target);
    7467         4162 :         if (*jump_target || *non_constant_p)
    7468              :           return NULL_TREE;
    7469              :         break;
    7470            0 :       default:
    7471            0 :         gcc_unreachable ();
    7472              :       }
    7473              : 
    7474        25464 :   switch (minfo->code)
    7475              :     {
    7476          240 :     case METAFN_OPERATOR_OF:
    7477          240 :       return eval_operator_of (loc, ctx, h, non_constant_p, jump_target,
    7478          480 :                                TREE_TYPE (call), fun);
    7479           92 :     case METAFN_SYMBOL_OF:
    7480           92 :       return eval_symbol_of (loc, ctx, expr, non_constant_p, jump_target,
    7481          184 :                              char_type_node, TREE_TYPE (call), fun);
    7482           46 :     case METAFN_U8SYMBOL_OF:
    7483           46 :       return eval_symbol_of (loc, ctx, expr, non_constant_p, jump_target,
    7484           92 :                              char8_type_node, TREE_TYPE (call), fun);
    7485          420 :     case METAFN_HAS_IDENTIFIER:
    7486          420 :       return eval_has_identifier (h, kind);
    7487          429 :     case METAFN_IDENTIFIER_OF:
    7488          429 :       return eval_identifier_of (loc, ctx, h, kind, non_constant_p, jump_target,
    7489          858 :                                  char_type_node, TREE_TYPE (call), fun);
    7490           55 :     case METAFN_U8IDENTIFIER_OF:
    7491           55 :       return eval_identifier_of (loc, ctx, h, kind, non_constant_p, jump_target,
    7492          110 :                                  char8_type_node, TREE_TYPE (call), fun);
    7493          105 :     case METAFN_DISPLAY_STRING_OF:
    7494          105 :       return eval_display_string_of (loc, ctx, h, kind, non_constant_p,
    7495              :                                      jump_target, char_type_node,
    7496          210 :                                      TREE_TYPE (call), fun);
    7497          104 :     case METAFN_U8DISPLAY_STRING_OF:
    7498          104 :       return eval_display_string_of (loc, ctx, h, kind, non_constant_p,
    7499              :                                      jump_target, char8_type_node,
    7500          208 :                                      TREE_TYPE (call), fun);
    7501           58 :     case METAFN_SOURCE_LOCATION_OF:
    7502           58 :       return eval_source_location_of (loc, h, kind, TREE_TYPE (call));
    7503          609 :     case METAFN_TYPE_OF:
    7504          609 :       return eval_type_of (loc, ctx, h, kind, non_constant_p, jump_target, fun);
    7505           67 :     case METAFN_OBJECT_OF:
    7506           67 :       return eval_object_of (loc, ctx, h, kind, non_constant_p, overflow_p,
    7507           67 :                              jump_target, fun);
    7508          161 :     case METAFN_CONSTANT_OF:
    7509          161 :       return eval_constant_of (loc, ctx, h, kind, non_constant_p, overflow_p,
    7510          161 :                                jump_target, fun);
    7511           86 :     case METAFN_IS_PUBLIC:
    7512           86 :       return eval_is_public (h, kind);
    7513           69 :     case METAFN_IS_PROTECTED:
    7514           69 :       return eval_is_protected (h, kind);
    7515           64 :     case METAFN_IS_PRIVATE:
    7516           64 :       return eval_is_private (h, kind);
    7517           17 :     case METAFN_IS_VIRTUAL:
    7518           17 :       return eval_is_virtual (h, kind);
    7519           14 :     case METAFN_IS_PURE_VIRTUAL:
    7520           14 :       return eval_is_pure_virtual (h);
    7521           70 :     case METAFN_IS_OVERRIDE:
    7522           70 :       return eval_is_override (h);
    7523           20 :     case METAFN_IS_FINAL:
    7524           20 :       return eval_is_final (h);
    7525           82 :     case METAFN_IS_DELETED:
    7526           82 :       return eval_is_deleted (h);
    7527          347 :     case METAFN_IS_DEFAULTED:
    7528          347 :       return eval_is_defaulted (h);
    7529          106 :     case METAFN_IS_USER_PROVIDED:
    7530          106 :       return eval_is_user_provided (h);
    7531          106 :     case METAFN_IS_USER_DECLARED:
    7532          106 :       return eval_is_user_declared (h);
    7533           22 :     case METAFN_IS_EXPLICIT:
    7534           22 :       return eval_is_explicit (h);
    7535          171 :     case METAFN_IS_NOEXCEPT:
    7536          171 :       return eval_is_noexcept (h);
    7537           95 :     case METAFN_IS_BIT_FIELD:
    7538           95 :       return eval_is_bit_field (h, kind);
    7539           49 :     case METAFN_IS_ENUMERATOR:
    7540           49 :       return eval_is_enumerator (h);
    7541            3 :     case METAFN_IS_ANNOTATION:
    7542            3 :       return eval_is_annotation (h, kind);
    7543           73 :     case METAFN_IS_CONST:
    7544           73 :       return eval_is_const (h, kind);
    7545           55 :     case METAFN_IS_VOLATILE:
    7546           55 :       return eval_is_volatile (h, kind);
    7547           64 :     case METAFN_IS_MUTABLE_MEMBER:
    7548           64 :       return eval_is_mutable_member (h);
    7549           24 :     case METAFN_IS_LVALUE_REFERENCE_QUALIFIED:
    7550           24 :       return eval_is_lrvalue_reference_qualified (h, kind, /*rvalue_p=*/false);
    7551           21 :     case METAFN_IS_RVALUE_REFERENCE_QUALIFIED:
    7552           21 :       return eval_is_lrvalue_reference_qualified (h, kind, /*rvalue_p=*/true);
    7553           70 :     case METAFN_HAS_STATIC_STORAGE_DURATION:
    7554           70 :       return eval_has_static_storage_duration (h, kind);
    7555           70 :     case METAFN_HAS_THREAD_STORAGE_DURATION:
    7556           70 :       return eval_has_thread_storage_duration (h, kind);
    7557           70 :     case METAFN_HAS_AUTOMATIC_STORAGE_DURATION:
    7558           70 :       return eval_has_automatic_storage_duration (h, kind);
    7559           63 :     case METAFN_HAS_INTERNAL_LINKAGE:
    7560           63 :       return eval_has_internal_linkage (h, kind);
    7561           63 :     case METAFN_HAS_MODULE_LINKAGE:
    7562           63 :       return eval_has_module_linkage (h, kind);
    7563           63 :     case METAFN_HAS_EXTERNAL_LINKAGE:
    7564           63 :       return eval_has_external_linkage (h, kind);
    7565           66 :     case METAFN_HAS_C_LANGUAGE_LINKAGE:
    7566           66 :       return eval_has_c_language_linkage (h, kind);
    7567           62 :     case METAFN_HAS_LINKAGE:
    7568           62 :       return eval_has_linkage (h, kind);
    7569          116 :     case METAFN_IS_COMPLETE_TYPE:
    7570          116 :       return eval_is_complete_type (h);
    7571           43 :     case METAFN_IS_ENUMERABLE_TYPE:
    7572           43 :       return eval_is_enumerable_type (h);
    7573          161 :     case METAFN_IS_VARIABLE:
    7574          161 :       return eval_is_variable (h, kind);
    7575          250 :     case METAFN_IS_TYPE:
    7576          250 :       return eval_is_type (h);
    7577          124 :     case METAFN_IS_NAMESPACE:
    7578          124 :       return eval_is_namespace (h);
    7579           84 :     case METAFN_IS_TYPE_ALIAS:
    7580           84 :       return eval_is_type_alias (h);
    7581          119 :     case METAFN_IS_NAMESPACE_ALIAS:
    7582          119 :       return eval_is_namespace_alias (h);
    7583          115 :     case METAFN_IS_FUNCTION:
    7584          115 :       return eval_is_function (h);
    7585           15 :     case METAFN_IS_CONVERSION_FUNCTION:
    7586           15 :       return eval_is_conversion_function (h);
    7587          159 :     case METAFN_IS_OPERATOR_FUNCTION:
    7588          159 :       return eval_is_operator_function (h);
    7589           15 :     case METAFN_IS_LITERAL_OPERATOR:
    7590           15 :       return eval_is_literal_operator (h);
    7591          810 :     case METAFN_IS_SPECIAL_MEMBER_FUNCTION:
    7592          810 :       return eval_is_special_member_function (h);
    7593          579 :     case METAFN_IS_CONSTRUCTOR:
    7594          579 :       return eval_is_constructor (h);
    7595          371 :     case METAFN_IS_DEFAULT_CONSTRUCTOR:
    7596          371 :       return eval_is_default_constructor (h);
    7597          380 :     case METAFN_IS_COPY_CONSTRUCTOR:
    7598          380 :       return eval_is_copy_constructor (h);
    7599          359 :     case METAFN_IS_MOVE_CONSTRUCTOR:
    7600          359 :       return eval_is_move_constructor (h);
    7601           10 :     case METAFN_IS_ASSIGNMENT:
    7602           10 :       return eval_is_assignment (h);
    7603          382 :     case METAFN_IS_COPY_ASSIGNMENT:
    7604          382 :       return eval_is_copy_assignment (h);
    7605          376 :     case METAFN_IS_MOVE_ASSIGNMENT:
    7606          376 :       return eval_is_move_assignment (h);
    7607          994 :     case METAFN_IS_DESTRUCTOR:
    7608          994 :       return eval_is_destructor (h);
    7609           58 :     case METAFN_IS_FUNCTION_PARAMETER:
    7610           58 :       return eval_is_function_parameter (h, kind);
    7611           73 :     case METAFN_IS_EXPLICIT_OBJECT_PARAMETER:
    7612           73 :       return eval_is_explicit_object_parameter (h, kind);
    7613           79 :     case METAFN_HAS_DEFAULT_ARGUMENT:
    7614           79 :       return eval_has_default_argument (h, kind);
    7615           72 :     case METAFN_HAS_ELLIPSIS_PARAMETER:
    7616           72 :       return eval_has_ellipsis_parameter (h);
    7617           56 :     case METAFN_IS_TEMPLATE:
    7618           56 :       return eval_is_template (h);
    7619           56 :     case METAFN_IS_FUNCTION_TEMPLATE:
    7620           56 :       return eval_is_function_template (h);
    7621           47 :     case METAFN_IS_VARIABLE_TEMPLATE:
    7622           47 :       return eval_is_variable_template (h);
    7623           47 :     case METAFN_IS_CLASS_TEMPLATE:
    7624           47 :       return eval_is_class_template (h);
    7625           47 :     case METAFN_IS_ALIAS_TEMPLATE:
    7626           47 :       return eval_is_alias_template (h);
    7627           19 :     case METAFN_IS_CONVERSION_FUNCTION_TEMPLATE:
    7628           19 :       return eval_is_conversion_function_template (h);
    7629           20 :     case METAFN_IS_OPERATOR_FUNCTION_TEMPLATE:
    7630           20 :       return eval_is_operator_function_template (h);
    7631           15 :     case METAFN_IS_LITERAL_OPERATOR_TEMPLATE:
    7632           15 :       return eval_is_literal_operator_template (h);
    7633           18 :     case METAFN_IS_CONSTRUCTOR_TEMPLATE:
    7634           18 :       return eval_is_constructor_template (h);
    7635          111 :     case METAFN_IS_CONCEPT:
    7636          111 :       return eval_is_concept (h);
    7637           69 :     case METAFN_IS_VALUE:
    7638           69 :       return eval_is_value (kind);
    7639          135 :     case METAFN_IS_OBJECT:
    7640          135 :       return eval_is_object (kind);
    7641           40 :     case METAFN_IS_STRUCTURED_BINDING:
    7642           40 :       return eval_is_structured_binding (h, kind);
    7643           62 :     case METAFN_IS_CLASS_MEMBER:
    7644           62 :       return eval_is_class_member (h);
    7645           71 :     case METAFN_IS_NAMESPACE_MEMBER:
    7646           71 :       return eval_is_namespace_member (h);
    7647           62 :     case METAFN_IS_NONSTATIC_DATA_MEMBER:
    7648           62 :       return eval_is_nonstatic_data_member (h);
    7649           68 :     case METAFN_IS_STATIC_MEMBER:
    7650           68 :       return eval_is_static_member (h);
    7651           15 :     case METAFN_IS_BASE:
    7652           15 :       return eval_is_base (h, kind);
    7653           64 :     case METAFN_HAS_DEFAULT_MEMBER_INITIALIZER:
    7654           64 :       return eval_has_default_member_initializer (h);
    7655           57 :     case METAFN_HAS_PARENT:
    7656           57 :       return eval_has_parent (h, kind);
    7657          408 :     case METAFN_PARENT_OF:
    7658          408 :       return eval_parent_of (loc, ctx, h, kind, non_constant_p, jump_target,
    7659          408 :                              fun);
    7660           94 :     case METAFN_DEALIAS:
    7661           94 :       return eval_dealias (loc, h, kind);
    7662           96 :     case METAFN_HAS_TEMPLATE_ARGUMENTS:
    7663           96 :       return eval_has_template_arguments (h);
    7664           39 :     case METAFN_TEMPLATE_OF:
    7665           39 :       return eval_template_of (loc, ctx, h, non_constant_p, jump_target, fun);
    7666          101 :     case METAFN_TEMPLATE_ARGUMENTS_OF:
    7667          101 :       return eval_template_arguments_of (loc, ctx, h, non_constant_p,
    7668          101 :                                          jump_target, fun);
    7669          325 :     case METAFN_PARAMETERS_OF:
    7670          325 :       return eval_parameters_of (loc, ctx, h, non_constant_p, jump_target,
    7671          325 :                                  fun);
    7672          111 :     case METAFN_VARIABLE_OF:
    7673          111 :       return eval_variable_of (loc, ctx, h, kind, non_constant_p, jump_target,
    7674          111 :                                fun);
    7675           63 :     case METAFN_RETURN_TYPE_OF:
    7676           63 :       return eval_return_type_of (loc, ctx, h, kind, non_constant_p,
    7677           63 :                                   jump_target, fun);
    7678          417 :     case METAFN_IS_ACCESSIBLE:
    7679          417 :       return eval_is_accessible (loc, ctx, h, kind, expr, call,
    7680          417 :                                  non_constant_p, jump_target, fun);
    7681           15 :     case METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS:
    7682           15 :       return eval_has_inaccessible_nonstatic_data_members (loc, ctx, h, expr,
    7683              :                                                            call,
    7684              :                                                            non_constant_p,
    7685           15 :                                                            jump_target, fun);
    7686           12 :     case METAFN_HAS_INACCESSIBLE_BASES:
    7687           12 :       return eval_has_inaccessible_bases (loc, ctx, h, expr, call,
    7688           12 :                                           non_constant_p, jump_target, fun);
    7689           19 :     case METAFN_HAS_INACCESSIBLE_SUBOBJECTS:
    7690           19 :       return eval_has_inaccessible_subobjects (loc, ctx, h, expr, call,
    7691              :                                                non_constant_p, jump_target,
    7692           19 :                                                fun);
    7693         2361 :     case METAFN_MEMBERS_OF:
    7694         2361 :       return eval_members_of (loc, ctx, h, expr, call, non_constant_p,
    7695         2361 :                               jump_target, fun);
    7696          494 :     case METAFN_BASES_OF:
    7697          494 :       return eval_bases_of (loc, ctx, h, expr, call, non_constant_p,
    7698          494 :                             jump_target, fun);
    7699           80 :     case METAFN_STATIC_DATA_MEMBERS_OF:
    7700           80 :       return eval_static_data_members_of (loc, ctx, h, expr, call,
    7701              :                                           non_constant_p, jump_target,
    7702           80 :                                           fun);
    7703          159 :     case METAFN_NONSTATIC_DATA_MEMBERS_OF:
    7704          159 :       return eval_nonstatic_data_members_of (loc, ctx, h, expr, call,
    7705              :                                              non_constant_p, jump_target,
    7706          159 :                                              fun);
    7707          176 :     case METAFN_SUBOBJECTS_OF:
    7708          176 :       return eval_subobjects_of (loc, ctx, h, expr, call, non_constant_p,
    7709          176 :                                  jump_target, fun);
    7710          157 :     case METAFN_ENUMERATORS_OF:
    7711          157 :       return eval_enumerators_of (loc, ctx, h, non_constant_p, jump_target,
    7712          157 :                                   fun);
    7713          123 :     case METAFN_OFFSET_OF:
    7714          123 :       return eval_offset_of (loc, ctx, h, kind, TREE_TYPE (call),
    7715          123 :                              non_constant_p, jump_target, fun);
    7716           99 :     case METAFN_SIZE_OF:
    7717           99 :       return eval_size_of (loc, ctx, h, kind, TREE_TYPE (call), non_constant_p,
    7718           99 :                            jump_target, fun);
    7719          105 :     case METAFN_ALIGNMENT_OF:
    7720          105 :       return eval_alignment_of (loc, ctx, h, kind, TREE_TYPE (call),
    7721          105 :                                 non_constant_p, jump_target, fun);
    7722          100 :     case METAFN_BIT_SIZE_OF:
    7723          100 :       return eval_bit_size_of (loc, ctx, h, kind, TREE_TYPE (call),
    7724          100 :                                non_constant_p, jump_target, fun);
    7725          491 :     case METAFN_EXTRACT:
    7726          491 :       {
    7727          491 :         type = TREE_VEC_ELT (get_template_innermost_arguments (fun), 0);
    7728          491 :         return eval_extract (loc, ctx, type, h, kind, non_constant_p,
    7729          491 :                              overflow_p, jump_target, fun);
    7730              :       }
    7731          146 :     case METAFN_CAN_SUBSTITUTE:
    7732          146 :       return eval_can_substitute (loc, ctx, h, hvec, non_constant_p,
    7733          146 :                                   jump_target, fun);
    7734          290 :     case METAFN_SUBSTITUTE:
    7735          290 :       return eval_substitute (loc, ctx, h, hvec, non_constant_p, jump_target,
    7736          290 :                               fun);
    7737          397 :     case METAFN_REFLECT_CONSTANT:
    7738          397 :       return eval_reflect_constant (loc, ctx, type, expr, non_constant_p,
    7739          397 :                                     jump_target, fun);
    7740          121 :     case METAFN_REFLECT_OBJECT:
    7741          121 :       return eval_reflect_object (loc, ctx, type, expr, non_constant_p,
    7742          121 :                                   jump_target, fun);
    7743           29 :     case METAFN_REFLECT_FUNCTION:
    7744           29 :       return eval_reflect_function (loc, ctx, type, expr, non_constant_p,
    7745           29 :                                     jump_target, fun);
    7746          137 :     case METAFN_REFLECT_CONSTANT_STRING:
    7747          137 :       return eval_reflect_constant_string (loc, ctx, call, non_constant_p,
    7748          137 :                                            overflow_p, jump_target, fun);
    7749          114 :     case METAFN_REFLECT_CONSTANT_ARRAY:
    7750          114 :       return eval_reflect_constant_array (loc, ctx, call, non_constant_p,
    7751          114 :                                           overflow_p, jump_target, fun);
    7752          327 :     case METAFN_DATA_MEMBER_SPEC:
    7753          327 :       return eval_data_member_spec (loc, ctx, h, expr, non_constant_p,
    7754          327 :                                     overflow_p, jump_target, fun);
    7755           53 :     case METAFN_IS_DATA_MEMBER_SPEC:
    7756           53 :       return eval_is_data_member_spec (h, kind);
    7757           92 :     case METAFN_DEFINE_AGGREGATE:
    7758           92 :       return eval_define_aggregate (loc, ctx, h, hvec, call, non_constant_p);
    7759           29 :     case METAFN_IS_VOID_TYPE:
    7760           29 :       return eval_is_void_type (h);
    7761           26 :     case METAFN_IS_NULL_POINTER_TYPE:
    7762           26 :       return eval_is_null_pointer_type (h);
    7763          130 :     case METAFN_IS_INTEGRAL_TYPE:
    7764          130 :       return eval_is_integral_type (h);
    7765           28 :     case METAFN_IS_FLOATING_POINT_TYPE:
    7766           28 :       return eval_is_floating_point_type (h);
    7767           93 :     case METAFN_IS_ARRAY_TYPE:
    7768           93 :       return eval_is_array_type (loc, h);
    7769           28 :     case METAFN_IS_POINTER_TYPE:
    7770           28 :       return eval_is_pointer_type (loc, h);
    7771           26 :     case METAFN_IS_LVALUE_REFERENCE_TYPE:
    7772           26 :       return eval_is_lvalue_reference_type (h);
    7773           26 :     case METAFN_IS_RVALUE_REFERENCE_TYPE:
    7774           26 :       return eval_is_rvalue_reference_type (h);
    7775           26 :     case METAFN_IS_MEMBER_OBJECT_POINTER_TYPE:
    7776           26 :       return eval_is_member_object_pointer_type (loc, h);
    7777           26 :     case METAFN_IS_MEMBER_FUNCTION_POINTER_TYPE:
    7778           26 :       return eval_is_member_function_pointer_type (loc, h);
    7779           26 :     case METAFN_IS_ENUM_TYPE:
    7780           26 :       return eval_is_enum_type (loc, h);
    7781           38 :     case METAFN_IS_UNION_TYPE:
    7782           38 :       return eval_is_union_type (loc, h);
    7783          147 :     case METAFN_IS_CLASS_TYPE:
    7784          147 :       return eval_is_class_type (loc, h);
    7785           40 :     case METAFN_IS_FUNCTION_TYPE:
    7786           40 :       return eval_is_function_type (h);
    7787           26 :     case METAFN_IS_REFLECTION_TYPE:
    7788           26 :       return eval_is_reflection_type (h);
    7789           26 :     case METAFN_IS_REFERENCE_TYPE:
    7790           26 :       return eval_is_reference_type (loc, h);
    7791           28 :     case METAFN_IS_ARITHMETIC_TYPE:
    7792           28 :       return eval_is_arithmetic_type (h);
    7793           28 :     case METAFN_IS_FUNDAMENTAL_TYPE:
    7794           28 :       return eval_is_fundamental_type (h);
    7795           28 :     case METAFN_IS_OBJECT_TYPE:
    7796           28 :       return eval_is_object_type (loc, h);
    7797           28 :     case METAFN_IS_SCALAR_TYPE:
    7798           28 :       return eval_is_scalar_type (h);
    7799           28 :     case METAFN_IS_COMPOUND_TYPE:
    7800           28 :       return eval_is_compound_type (h);
    7801           28 :     case METAFN_IS_MEMBER_POINTER_TYPE:
    7802           28 :       return eval_is_member_pointer_type (loc, h);
    7803            8 :     case METAFN_IS_CONST_TYPE:
    7804            8 :       return eval_is_const_type (h);
    7805            8 :     case METAFN_IS_VOLATILE_TYPE:
    7806            8 :       return eval_is_volatile_type (h);
    7807           39 :     case METAFN_IS_TRIVIALLY_COPYABLE_TYPE:
    7808           39 :       return eval_is_trivially_copyable_type (h);
    7809            4 :     case METAFN_IS_STANDARD_LAYOUT_TYPE:
    7810            4 :       return eval_is_standard_layout_type (h);
    7811           15 :     case METAFN_IS_EMPTY_TYPE:
    7812           15 :       return eval_is_empty_type (loc, h);
    7813           10 :     case METAFN_IS_POLYMORPHIC_TYPE:
    7814           10 :       return eval_is_polymorphic_type (loc, h);
    7815            5 :     case METAFN_IS_ABSTRACT_TYPE:
    7816            5 :       return eval_is_abstract_type (h);
    7817            3 :     case METAFN_IS_FINAL_TYPE:
    7818            3 :       return eval_is_final_type (loc, h);
    7819           24 :     case METAFN_IS_AGGREGATE_TYPE:
    7820           24 :       return eval_is_aggregate_type (h);
    7821           39 :     case METAFN_IS_CONSTEVAL_ONLY_TYPE:
    7822           39 :       return eval_is_consteval_only_type (h);
    7823           17 :     case METAFN_IS_SIGNED_TYPE:
    7824           17 :       return eval_is_signed_type (h);
    7825           17 :     case METAFN_IS_UNSIGNED_TYPE:
    7826           17 :       return eval_is_unsigned_type (h);
    7827           18 :     case METAFN_IS_BOUNDED_ARRAY_TYPE:
    7828           18 :       return eval_is_bounded_array_type (loc, h);
    7829           21 :     case METAFN_IS_UNBOUNDED_ARRAY_TYPE:
    7830           21 :       return eval_is_unbounded_array_type (h);
    7831           18 :     case METAFN_IS_SCOPED_ENUM_TYPE:
    7832           18 :       return eval_is_scoped_enum_type (h);
    7833          622 :     case METAFN_IS_CONSTRUCTIBLE_TYPE:
    7834          622 :       return eval_is_constructible_type (h, hvec);
    7835          104 :     case METAFN_IS_DEFAULT_CONSTRUCTIBLE_TYPE:
    7836          104 :       return eval_is_default_constructible_type (h);
    7837           25 :     case METAFN_IS_COPY_CONSTRUCTIBLE_TYPE:
    7838           25 :       return eval_is_copy_constructible_type (h);
    7839           25 :     case METAFN_IS_MOVE_CONSTRUCTIBLE_TYPE:
    7840           25 :       return eval_is_move_constructible_type (h);
    7841          497 :     case METAFN_IS_ASSIGNABLE_TYPE:
    7842          497 :       return eval_is_assignable_type (loc, h, h1);
    7843           25 :     case METAFN_IS_COPY_ASSIGNABLE_TYPE:
    7844           25 :       return eval_is_copy_assignable_type (h);
    7845           25 :     case METAFN_IS_MOVE_ASSIGNABLE_TYPE:
    7846           25 :       return eval_is_move_assignable_type (h);
    7847           21 :     case METAFN_IS_SWAPPABLE_WITH_TYPE:
    7848           21 :       return eval_is_swappable_with_type (loc, ctx, h, h1, call,
    7849              :                                           non_constant_p, jump_target, fun,
    7850           21 :                                           "is_swappable_with");
    7851           90 :     case METAFN_IS_SWAPPABLE_TYPE:
    7852           90 :       return eval_is_swappable_type (loc, ctx, h, call, non_constant_p,
    7853           90 :                                      jump_target, fun, "is_swappable");
    7854           72 :     case METAFN_IS_DESTRUCTIBLE_TYPE:
    7855           72 :       return eval_is_destructible_type (loc, h);
    7856           73 :     case METAFN_IS_TRIVIALLY_CONSTRUCTIBLE_TYPE:
    7857           73 :       return eval_is_trivially_constructible_type (h, hvec);
    7858           17 :     case METAFN_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_TYPE:
    7859           17 :       return eval_is_trivially_default_constructible_type (h);
    7860           20 :     case METAFN_IS_TRIVIALLY_COPY_CONSTRUCTIBLE_TYPE:
    7861           20 :       return eval_is_trivially_copy_constructible_type (h);
    7862           20 :     case METAFN_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE_TYPE:
    7863           20 :       return eval_is_trivially_move_constructible_type (h);
    7864           54 :     case METAFN_IS_TRIVIALLY_ASSIGNABLE_TYPE:
    7865           54 :       return eval_is_trivially_assignable_type (loc, h, h1);
    7866           23 :     case METAFN_IS_TRIVIALLY_COPY_ASSIGNABLE_TYPE:
    7867           23 :       return eval_is_trivially_copy_assignable_type (h);
    7868           23 :     case METAFN_IS_TRIVIALLY_MOVE_ASSIGNABLE_TYPE:
    7869           23 :       return eval_is_trivially_move_assignable_type (h);
    7870            5 :     case METAFN_IS_TRIVIALLY_DESTRUCTIBLE_TYPE:
    7871            5 :       return eval_is_trivially_destructible_type (loc, h);
    7872           50 :     case METAFN_IS_NOTHROW_CONSTRUCTIBLE_TYPE:
    7873           50 :       return eval_is_nothrow_constructible_type (h, hvec);
    7874           20 :     case METAFN_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE_TYPE:
    7875           20 :       return eval_is_nothrow_default_constructible_type (h);
    7876           25 :     case METAFN_IS_NOTHROW_COPY_CONSTRUCTIBLE_TYPE:
    7877           25 :       return eval_is_nothrow_copy_constructible_type (h);
    7878           25 :     case METAFN_IS_NOTHROW_MOVE_CONSTRUCTIBLE_TYPE:
    7879           25 :       return eval_is_nothrow_move_constructible_type (h);
    7880           10 :     case METAFN_IS_NOTHROW_ASSIGNABLE_TYPE:
    7881           10 :       return eval_is_nothrow_assignable_type (loc, h, h1);
    7882           25 :     case METAFN_IS_NOTHROW_COPY_ASSIGNABLE_TYPE:
    7883           25 :       return eval_is_nothrow_copy_assignable_type (h);
    7884           25 :     case METAFN_IS_NOTHROW_MOVE_ASSIGNABLE_TYPE:
    7885           25 :       return eval_is_nothrow_move_assignable_type (h);
    7886           27 :     case METAFN_IS_NOTHROW_SWAPPABLE_WITH_TYPE:
    7887           27 :       return eval_is_swappable_with_type (loc, ctx, h, h1, call,
    7888              :                                           non_constant_p, jump_target, fun,
    7889           27 :                                           "is_nothrow_swappable_with");
    7890           88 :     case METAFN_IS_NOTHROW_SWAPPABLE_TYPE:
    7891           88 :       return eval_is_swappable_type (loc, ctx, h, call, non_constant_p,
    7892           88 :                                      jump_target, fun, "is_nothrow_swappable");
    7893           83 :     case METAFN_IS_NOTHROW_DESTRUCTIBLE_TYPE:
    7894           83 :       return eval_is_nothrow_destructible_type (loc, h);
    7895           74 :     case METAFN_IS_IMPLICIT_LIFETIME_TYPE:
    7896           74 :       return eval_is_implicit_lifetime_type (h);
    7897           10 :     case METAFN_HAS_VIRTUAL_DESTRUCTOR:
    7898           10 :       return eval_has_virtual_destructor (h);
    7899           31 :     case METAFN_HAS_UNIQUE_OBJECT_REPRESENTATIONS:
    7900           31 :       return eval_has_unique_object_representations (h);
    7901           31 :     case METAFN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY:
    7902           31 :       return eval_reference_constructs_from_temporary (loc, h, h1);
    7903           31 :     case METAFN_REFERENCE_CONVERTS_FROM_TEMPORARY:
    7904           31 :       return eval_reference_converts_from_temporary (loc, h, h1);
    7905           15 :     case METAFN_RANK:
    7906           15 :       return eval_rank (h);
    7907          102 :     case METAFN_EXTENT:
    7908          102 :       return eval_extent (loc, h, expr);
    7909           10 :     case METAFN_IS_SAME_TYPE:
    7910           10 :       return eval_is_same_type (loc, h, h1);
    7911            9 :     case METAFN_IS_BASE_OF_TYPE:
    7912            9 :       return eval_is_base_of_type (loc, h, h1);
    7913           19 :     case METAFN_IS_VIRTUAL_BASE_OF_TYPE:
    7914           19 :       return eval_is_virtual_base_of_type (loc, h, h1);
    7915            5 :     case METAFN_IS_CONVERTIBLE_TYPE:
    7916            5 :       return eval_is_convertible_type (loc, h, h1);
    7917            7 :     case METAFN_IS_NOTHROW_CONVERTIBLE_TYPE:
    7918            7 :       return eval_is_nothrow_convertible_type (loc, h, h1);
    7919           18 :     case METAFN_IS_LAYOUT_COMPATIBLE_TYPE:
    7920           18 :       return eval_is_layout_compatible_type (loc, h, h1);
    7921           16 :     case METAFN_IS_POINTER_INTERCONVERTIBLE_BASE_OF_TYPE:
    7922           16 :       return eval_is_pointer_interconvertible_base_of_type (loc, h, h1);
    7923           38 :     case METAFN_IS_INVOCABLE_TYPE:
    7924           38 :       return eval_is_invocable_type (loc, h, hvec);
    7925           71 :     case METAFN_IS_INVOCABLE_R_TYPE:
    7926           71 :       return eval_is_invocable_r_type (loc, ctx, h, h1, hvec, call,
    7927              :                                        non_constant_p, jump_target, fun,
    7928           71 :                                        "is_invocable_r");
    7929           28 :     case METAFN_IS_NOTHROW_INVOCABLE_TYPE:
    7930           28 :       return eval_is_nothrow_invocable_type (loc, h, hvec);
    7931           42 :     case METAFN_IS_NOTHROW_INVOCABLE_R_TYPE:
    7932           42 :       return eval_is_invocable_r_type (loc, ctx, h, h1, hvec, call,
    7933              :                                        non_constant_p, jump_target, fun,
    7934           42 :                                        "is_nothrow_invocable_r");
    7935           11 :     case METAFN_REMOVE_CONST:
    7936           11 :       return eval_remove_const (loc, h);
    7937           12 :     case METAFN_REMOVE_VOLATILE:
    7938           12 :       return eval_remove_volatile (loc, h);
    7939           11 :     case METAFN_REMOVE_CV:
    7940           11 :       return eval_remove_cv (loc, h);
    7941           13 :     case METAFN_ADD_CONST:
    7942           13 :       return eval_add_const (loc, h);
    7943           13 :     case METAFN_ADD_VOLATILE:
    7944           13 :       return eval_add_volatile (loc, h);
    7945           13 :     case METAFN_ADD_CV:
    7946           13 :       return eval_add_cv (loc, h);
    7947           15 :     case METAFN_REMOVE_REFERENCE:
    7948           15 :       return eval_remove_reference (loc, h);
    7949           16 :     case METAFN_ADD_LVALUE_REFERENCE:
    7950           16 :       return eval_add_lvalue_reference (loc, h);
    7951           15 :     case METAFN_ADD_RVALUE_REFERENCE:
    7952           15 :       return eval_add_rvalue_reference (loc, h);
    7953           25 :     case METAFN_MAKE_SIGNED:
    7954           25 :       return eval_make_signed (loc, ctx, h, false, non_constant_p, jump_target,
    7955           25 :                                fun);
    7956           25 :     case METAFN_MAKE_UNSIGNED:
    7957           25 :       return eval_make_signed (loc, ctx, h, true, non_constant_p, jump_target,
    7958           25 :                                fun);
    7959           12 :     case METAFN_REMOVE_EXTENT:
    7960           12 :       return eval_remove_extent (loc, h);
    7961           11 :     case METAFN_REMOVE_ALL_EXTENTS:
    7962           11 :       return eval_remove_all_extents (loc, h);
    7963           13 :     case METAFN_REMOVE_POINTER:
    7964           13 :       return eval_remove_pointer (loc, h);
    7965           17 :     case METAFN_ADD_POINTER:
    7966           17 :       return eval_add_pointer (loc, h);
    7967           17 :     case METAFN_REMOVE_CVREF:
    7968           17 :       return eval_remove_cvref (loc, h);
    7969           21 :     case METAFN_DECAY:
    7970           21 :       return eval_decay (loc, h);
    7971           89 :     case METAFN_COMMON_TYPE:
    7972           89 :       return eval_common_type (loc, ctx, hvec, call, non_constant_p,
    7973           89 :                                jump_target, fun, ident);
    7974           32 :     case METAFN_COMMON_REFERENCE:
    7975           32 :       return eval_common_type (loc, ctx, hvec, call, non_constant_p,
    7976           32 :                                jump_target, fun, ident);
    7977           12 :     case METAFN_UNDERLYING_TYPE:
    7978           12 :       return eval_underlying_type (loc, ctx, h, non_constant_p, jump_target,
    7979           12 :                                    fun);
    7980           10 :     case METAFN_INVOKE_RESULT:
    7981           10 :       return eval_invoke_result (loc, ctx, h, hvec, call, non_constant_p,
    7982           10 :                                  jump_target, fun);
    7983           14 :     case METAFN_UNWRAP_REFERENCE:
    7984           14 :       return eval_unwrap_reference (loc, ctx, h, call, non_constant_p,
    7985           14 :                                     jump_target, fun, ident);
    7986           12 :     case METAFN_UNWRAP_REF_DECAY:
    7987           12 :       return eval_unwrap_reference (loc, ctx, h, call, non_constant_p,
    7988           12 :                                     jump_target, fun, ident);
    7989           28 :     case METAFN_TUPLE_SIZE:
    7990           28 :       return eval_tuple_size (loc, ctx, h, call, non_constant_p, jump_target,
    7991           28 :                               fun);
    7992           31 :     case METAFN_TUPLE_ELEMENT:
    7993           31 :       return eval_tuple_element (loc, ctx, expr, h1, call,
    7994           31 :                                  non_constant_p, jump_target, fun);
    7995           10 :     case METAFN_VARIANT_SIZE:
    7996           10 :       return eval_variant_size (loc, ctx, h, call, non_constant_p,
    7997           10 :                                 jump_target, fun);
    7998           17 :     case METAFN_VARIANT_ALTERNATIVE:
    7999           17 :       return eval_variant_alternative (loc, ctx, expr, h1, call,
    8000           17 :                                        non_constant_p, jump_target, fun);
    8001           58 :     case METAFN_TYPE_ORDER:
    8002           58 :       return eval_type_order (h, h1);
    8003          255 :     case METAFN_ANNOTATIONS_OF:
    8004          255 :       return eval_annotations_of (loc, ctx, h, kind, NULL_TREE, non_constant_p,
    8005          255 :                                   jump_target, fun);
    8006           14 :     case METAFN_ANNOTATIONS_OF_WITH_TYPE:
    8007           14 :       return eval_annotations_of (loc, ctx, h, kind, h1, non_constant_p,
    8008           14 :                                   jump_target, fun);
    8009              :     /* Special metafunctions.  */
    8010          249 :     case METAFN_ACCESS_CONTEXT_CURRENT:
    8011          498 :       if (DECL_CLASS_SCOPE_P (fun)
    8012          249 :           && TYPE_NAME (DECL_CONTEXT (fun))
    8013          249 :           && TREE_CODE (TYPE_NAME (DECL_CONTEXT (fun))) == TYPE_DECL
    8014          249 :           && DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun)))
    8015          498 :           && id_equal (DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun))),
    8016              :                        "access_context"))
    8017          249 :         return eval_access_context_current (loc, ctx, call, non_constant_p);
    8018            0 :       goto not_found;
    8019         1497 :     case METAFN_EXCEPTION__S_EXCEPTION_CVT_TO_UTF8:
    8020         1497 :     case METAFN_EXCEPTION__S_EXCEPTION_CVT_FROM_UTF8:
    8021         2994 :       if (DECL_CLASS_SCOPE_P (fun)
    8022         1497 :           && TYPE_NAME (DECL_CONTEXT (fun))
    8023         1497 :           && TREE_CODE (TYPE_NAME (DECL_CONTEXT (fun))) == TYPE_DECL
    8024         1497 :           && DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun)))
    8025         2994 :           && id_equal (DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun))),
    8026              :                        "exception"))
    8027              :         {
    8028         1497 :           bool to_utf8
    8029              :             = minfo->code == METAFN_EXCEPTION__S_EXCEPTION_CVT_TO_UTF8;
    8030         1497 :           return eval_exception__S_exception_cvt_tofrom_utf8 (loc, ctx, call,
    8031              :                                                               non_constant_p,
    8032              :                                                               overflow_p,
    8033              :                                                               jump_target,
    8034         1497 :                                                               fun, to_utf8);
    8035              :         }
    8036            0 :       goto not_found;
    8037              :     }
    8038            0 :   goto not_found;
    8039              : }
    8040              : 
    8041              : /* Splice reflection REFL; i.e., return its entity.  */
    8042              : 
    8043              : tree
    8044         2772 : splice (tree refl)
    8045              : {
    8046         2772 :   if (refl == error_mark_node)
    8047              :     return error_mark_node;
    8048              : 
    8049              :   /* Who in the world am I?  That's the great puzzle and we have to wait
    8050              :      until instantiation to find out.  */
    8051         2759 :   if (instantiation_dependent_expression_p (refl))
    8052          626 :     return build_nt (SPLICE_EXPR, refl);
    8053              : 
    8054              :   /* [basic.splice] "The constant-expression of a splice-specifier shall
    8055              :      be a converted constant expression of type std::meta::info."  */
    8056         2133 :   refl = build_converted_constant_expr (meta_info_type_node, refl,
    8057              :                                         tf_warning_or_error);
    8058              : 
    8059         2133 :   if (processing_template_decl)
    8060          437 :     refl = fold_non_dependent_expr (refl, tf_warning_or_error, true);
    8061              :   else
    8062         1696 :     refl = cxx_constant_value (refl);
    8063         2133 :   if (refl == error_mark_node)
    8064              :     {
    8065            6 :       gcc_checking_assert (seen_error ());
    8066            6 :       return error_mark_node;
    8067              :     }
    8068         2127 :   if (!REFLECT_EXPR_P (refl))
    8069              :     {
    8070            1 :       error_at (cp_expr_loc_or_input_loc (refl), "splice argument must be an "
    8071              :                 "expression of type %qs", "std::meta::info");
    8072            1 :       return error_mark_node;
    8073              :     }
    8074              : 
    8075              :   /* We are bringing some entity from the unevaluated expressions world
    8076              :      to possibly outside of that, mark it used.  */
    8077         2126 :   if (!mark_used (REFLECT_EXPR_HANDLE (refl)))
    8078            0 :     return error_mark_node;
    8079              : 
    8080         2126 :   refl = REFLECT_EXPR_HANDLE (refl);
    8081              :   /* Function templates are wrapped in OVERLOAD from name lookup
    8082              :      and a lot of places assume that.  Furthermore, if reflection comes
    8083              :      from ^^fntmpl, it is wrapped with OVERLOAD already, only when
    8084              :      it comes from e.g. members_of it is not.  */
    8085         2126 :   if (DECL_FUNCTION_TEMPLATE_P (refl))
    8086          542 :     refl = ovl_make (refl, NULL_TREE);
    8087              : 
    8088              :   return refl;
    8089              : }
    8090              : 
    8091              : /* A walker for consteval_only_p.  It cannot be a lambda, because we
    8092              :    have to call this recursively, sigh.  */
    8093              : 
    8094              : static tree
    8095    166360225 : consteval_only_type_r (tree *tp, int *walk_subtrees, void *data)
    8096              : {
    8097    166360225 :   tree t = *tp;
    8098              :   /* Types can contain themselves recursively, hence this.  */
    8099    166360225 :   auto visited = static_cast<hash_set<tree> *>(data);
    8100              : 
    8101    166360225 :   if (!TYPE_P (t))
    8102              :     return NULL_TREE;
    8103              : 
    8104    108342773 :   if (REFLECTION_TYPE_P (t))
    8105              :     return t;
    8106              : 
    8107    108320739 :   if (typedef_variant_p (t))
    8108              :     /* Tell cp_walk_subtrees to look through typedefs.  */
    8109     15745725 :     *walk_subtrees = 2;
    8110              : 
    8111    108320739 :   if (RECORD_OR_UNION_TYPE_P (t))
    8112              :     {
    8113              :       /* Don't walk template arguments; A<info>::type isn't a consteval-only
    8114              :          type.  */
    8115     28106768 :       *walk_subtrees = 0;
    8116              :       /* So we have to walk the fields manually.  */
    8117     28106768 :       for (tree member = TYPE_FIELDS (t);
    8118   1342227205 :            member; member = DECL_CHAIN (member))
    8119   1314151077 :         if (TREE_CODE (member) == FIELD_DECL)
    8120     47555144 :           if (tree r = cp_walk_tree (&TREE_TYPE (member),
    8121              :                                      consteval_only_type_r, visited, visited))
    8122              :             return r;
    8123              :     }
    8124              : 
    8125              :   return NULL_TREE;
    8126              : }
    8127              : 
    8128              : /* True if T is a consteval-only type as per [basic.types.general]:
    8129              :    "A type is consteval-only if it is either std::meta::info or a type
    8130              :    compounded from a consteval-only type", or something that has
    8131              :    a consteval-only type.  */
    8132              : 
    8133              : bool
    8134    374382397 : consteval_only_p (tree t)
    8135              : {
    8136    374382397 :   if (!flag_reflection)
    8137              :     return false;
    8138              : 
    8139     26937338 :   if (!TYPE_P (t))
    8140     26926341 :     t = TREE_TYPE (t);
    8141              : 
    8142     26937338 :   if (!t)
    8143              :     return false;
    8144              : 
    8145     26823546 :   if (TREE_CODE (t) == TREE_VEC)
    8146              :     {
    8147            4 :       for (tree arg : tree_vec_range (t))
    8148            3 :         if (arg && consteval_only_p (arg))
    8149            0 :           return true;
    8150            1 :       return false;
    8151              :     }
    8152              : 
    8153              :   /* We need the complete type otherwise we'd have no fields for class
    8154              :      templates and thus come up with zilch for things like
    8155              :        template<typename T>
    8156              :        struct X : T { };
    8157              :      which could be consteval-only, depending on T.  */
    8158     26823545 :   t = complete_type (t);
    8159              : 
    8160              :   /* Classes with std::meta::info members are also consteval-only.  */
    8161     26823545 :   hash_set<tree> visited;
    8162     26823545 :   return !!cp_walk_tree (&t, consteval_only_type_r, &visited, &visited);
    8163     26823545 : }
    8164              : 
    8165              : /* A walker for check_out_of_consteval_use_r.  It cannot be a lambda, because
    8166              :    we have to call this recursively.  */
    8167              : 
    8168              : static tree
    8169     24207284 : check_out_of_consteval_use_r (tree *tp, int *walk_subtrees, void *pset)
    8170              : {
    8171     24207284 :   tree t = *tp;
    8172              : 
    8173              :   /* No need to look into types or unevaluated operands.  */
    8174     24207284 :   if (TYPE_P (t)
    8175     24127195 :       || (unevaluated_p (TREE_CODE (t)) && !REFLECT_EXPR_P (t))
    8176              :       /* Don't walk INIT_EXPRs, because we'd emit bogus errors about
    8177              :          member initializers.  */
    8178     24096944 :       || TREE_CODE (t) == INIT_EXPR
    8179              :       /* And don't recurse on DECL_EXPRs.  */
    8180     23634784 :       || TREE_CODE (t) == DECL_EXPR
    8181              :       /* Blocks can appear in the TREE_VEC operand of OpenMP
    8182              :          depend/affinity/map/to/from OMP_CLAUSEs when using iterators.  */
    8183     47615042 :       || TREE_CODE (t) == BLOCK)
    8184              :     {
    8185       799527 :       *walk_subtrees = false;
    8186       799527 :       return NULL_TREE;
    8187              :     }
    8188              : 
    8189              :   /* A subexpression of a manifestly constant-evaluated expression is
    8190              :      an immediate function context.  For example,
    8191              : 
    8192              :       consteval void foo (std::meta::info) { }
    8193              :       void g() { foo (^^void); }
    8194              : 
    8195              :       is all good.  */
    8196     23407757 :   if (tree decl = cp_get_callee_fndecl_nofold (t))
    8197      1292944 :     if (immediate_invocation_p (decl))
    8198              :       {
    8199        10003 :         *walk_subtrees = false;
    8200        10003 :         return NULL_TREE;
    8201              :       }
    8202              : 
    8203     23397754 :   if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
    8204              :     {
    8205        36782 :       tree vexpr = DECL_VALUE_EXPR (t);
    8206        36782 :       if (tree ret = cp_walk_tree (&vexpr, check_out_of_consteval_use_r, pset,
    8207              :                                    (hash_set<tree> *) pset))
    8208            2 :         return ret;
    8209              :     }
    8210              : 
    8211     23397752 :   if (TREE_CODE (t) == BIND_EXPR)
    8212              :     {
    8213        63859 :       if (tree r = cp_walk_tree (&BIND_EXPR_BODY (t),
    8214              :                                  check_out_of_consteval_use_r, pset,
    8215              :                                  static_cast<hash_set<tree> *>(pset)))
    8216              :         return r;
    8217              :       /* Don't walk BIND_EXPR_VARS.  */
    8218        63859 :       *walk_subtrees = false;
    8219        63859 :       return NULL_TREE;
    8220              :     }
    8221              : 
    8222     23333893 :   if (TREE_CODE (t) == IF_STMT)
    8223              :     {
    8224       239774 :       if (IF_STMT_CONSTEVAL_P (t))
    8225              :         {
    8226         2609 :           if (tree r = cp_walk_tree (&ELSE_CLAUSE (t),
    8227              :                                      check_out_of_consteval_use_r, pset,
    8228              :                                      static_cast<hash_set<tree> *>(pset)))
    8229              :             return r;
    8230              :           /* Don't walk the consteval branch.  */
    8231         2605 :           *walk_subtrees = false;
    8232         2605 :           return NULL_TREE;
    8233              :         }
    8234       237165 :       else if (IF_STMT_CONSTEXPR_P (t))
    8235              :         {
    8236        21452 :           if (tree r = cp_walk_tree (&THEN_CLAUSE (t),
    8237              :                                      check_out_of_consteval_use_r, pset,
    8238              :                                      static_cast<hash_set<tree> *>(pset)))
    8239              :             return r;
    8240        21452 :           if (tree r = cp_walk_tree (&ELSE_CLAUSE (t),
    8241              :                                      check_out_of_consteval_use_r, pset,
    8242              :                                      static_cast<hash_set<tree> *>(pset)))
    8243              :             return r;
    8244              :           /* Don't walk the condition -- it's a manifestly constant-evaluated
    8245              :              context.  */
    8246        21452 :           *walk_subtrees = false;
    8247        21452 :           return NULL_TREE;
    8248              :         }
    8249              :     }
    8250              : 
    8251              :   /* Don't diagnose RETURN_EXPRs in cdtors on cdtor_returns_this
    8252              :      target.  Those don't exist on other targets.  */
    8253     23309832 :   if (TREE_CODE (t) == RETURN_EXPR
    8254       272357 :       && targetm.cxx.cdtor_returns_this ()
    8255     23309832 :       && (DECL_CONSTRUCTOR_P (current_function_decl)
    8256            0 :           || DECL_DESTRUCTOR_P (current_function_decl)))
    8257              :     {
    8258            0 :       *walk_subtrees = false;
    8259            0 :       return NULL_TREE;
    8260              :     }
    8261              : 
    8262              :   /* Now check the type to see if we are dealing with a consteval-only
    8263              :      expression.  */
    8264     23309832 :   if (!consteval_only_p (t))
    8265              :     return NULL_TREE;
    8266              : 
    8267              :   /* Already escalated?  */
    8268        16725 :   if (current_function_decl
    8269        33417 :       && DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
    8270              :     {
    8271         4624 :       *walk_subtrees = false;
    8272         4624 :       return NULL_TREE;
    8273              :     }
    8274              : 
    8275              :   /* We might have to escalate if we are in an immediate-escalating
    8276              :      function.  */
    8277        12101 :   if (immediate_escalating_function_p (current_function_decl))
    8278              :     {
    8279        12007 :       promote_function_to_consteval (current_function_decl);
    8280        12007 :       *walk_subtrees = false;
    8281        12007 :       return NULL_TREE;
    8282              :     }
    8283              : 
    8284           94 :   *walk_subtrees = false;
    8285           94 :   return t;
    8286              : }
    8287              : 
    8288              : /* Detect if a consteval-only expression EXPR or a consteval-only
    8289              :    variable EXPR not declared constexpr is used outside
    8290              :    a manifestly constant-evaluated context.  E.g.:
    8291              : 
    8292              :      void f() {
    8293              :        constexpr auto r = ^^int;  // OK
    8294              :        [: r :] i = 42;  // still OK
    8295              :        auto z = r;  // bad
    8296              :      }
    8297              : 
    8298              :    But
    8299              : 
    8300              :      consteval void g() {
    8301              :        constexpr auto r = ^^int;
    8302              :        auto z = r;
    8303              :      }
    8304              : 
    8305              :    is OK.  If COMPLAIN, emit an error; otherwise we're in the search-only
    8306              :    mode.  Return true if we found a problematic expression.  */
    8307              : 
    8308              : bool
    8309    273108390 : check_out_of_consteval_use (tree expr, bool complain/*=true*/)
    8310              : {
    8311    273108390 :   if (!flag_reflection || in_immediate_context () || expr == NULL_TREE)
    8312    270136571 :     return false;
    8313              : 
    8314      2971819 :   if (VAR_P (expr) && DECL_DECLARED_CONSTEXPR_P (expr))
    8315              :     return false;
    8316              : 
    8317      2488633 :   hash_set<tree> pset;
    8318      2488633 :   if (tree t = cp_walk_tree (&expr, check_out_of_consteval_use_r, &pset, &pset))
    8319              :     {
    8320           94 :       if (complain)
    8321              :         {
    8322           79 :           if (VAR_P (t) && !DECL_DECLARED_CONSTEXPR_P (t))
    8323              :             {
    8324           42 :               auto_diagnostic_group d;
    8325           84 :               error_at (cp_expr_loc_or_input_loc (t),
    8326              :                         "consteval-only variable %qD not declared %<constexpr%> "
    8327              :                         "used outside a constant-evaluated context", t);
    8328           42 :               inform (DECL_SOURCE_LOCATION (t), "add %<constexpr%>");
    8329           42 :             }
    8330              :           else
    8331           40 :             error_at (cp_expr_loc_or_input_loc (t),
    8332              :                       "consteval-only expressions are only allowed in "
    8333              :                       "a constant-evaluated context");
    8334              :         }
    8335           94 :       return true;
    8336              :     }
    8337              : 
    8338              :   return false;
    8339      2488633 : }
    8340              : 
    8341              : /* Return true if the reflections LHS and RHS are equal.  */
    8342              : 
    8343              : bool
    8344         1784 : compare_reflections (tree lhs, tree rhs)
    8345              : {
    8346         1785 :   reflect_kind lkind;
    8347         1785 :   do
    8348              :     {
    8349         1785 :       lkind = REFLECT_EXPR_KIND (lhs);
    8350         1785 :       if (lkind != REFLECT_EXPR_KIND (rhs))
    8351              :         return false;
    8352         1754 :       lhs = REFLECT_EXPR_HANDLE (lhs);
    8353         1754 :       rhs = REFLECT_EXPR_HANDLE (rhs);
    8354              :     }
    8355         1754 :   while (REFLECT_EXPR_P (lhs) && REFLECT_EXPR_P (rhs));
    8356              : 
    8357         1753 :   lhs = resolve_nondeduced_context (lhs, tf_warning_or_error);
    8358         1753 :   rhs = resolve_nondeduced_context (rhs, tf_warning_or_error);
    8359              : 
    8360              :   /* TEMPLATE_DECLs are wrapped in an OVERLOAD.  When we have
    8361              : 
    8362              :        template_of (^^fun_tmpl<int>) == ^^fun_tmpl
    8363              : 
    8364              :      the RHS will be OVERLOAD<TEMPLATE_DECL> but the LHS will
    8365              :      only be TEMPLATE_DECL.  They should compare equal, though.  */
    8366              :   // ??? Can we do something better?
    8367         1753 :   lhs = maybe_get_first_fn (lhs);
    8368         1753 :   rhs = maybe_get_first_fn (rhs);
    8369              : 
    8370              :   /* First handle reflection-specific comparisons, then fall back to
    8371              :      cp_tree_equal.  */
    8372         1753 :   if (lkind == REFLECT_PARM)
    8373              :     {
    8374            1 :       lhs = maybe_update_function_parm (lhs);
    8375            1 :       rhs = maybe_update_function_parm (rhs);
    8376              :     }
    8377         1752 :   else if (lkind == REFLECT_DATA_MEMBER_SPEC)
    8378           15 :     return (TREE_VEC_ELT (lhs, 0) == TREE_VEC_ELT (rhs, 0)
    8379           14 :             && TREE_VEC_ELT (lhs, 1) == TREE_VEC_ELT (rhs, 1)
    8380           10 :             && tree_int_cst_equal (TREE_VEC_ELT (lhs, 2),
    8381           10 :                                    TREE_VEC_ELT (rhs, 2))
    8382            9 :             && tree_int_cst_equal (TREE_VEC_ELT (lhs, 3),
    8383            9 :                                    TREE_VEC_ELT (rhs, 3))
    8384           23 :             && TREE_VEC_ELT (lhs, 4) == TREE_VEC_ELT (rhs, 4));
    8385         1737 :   else if (lkind == REFLECT_ANNOTATION)
    8386           11 :     return TREE_VALUE (lhs) == TREE_VALUE (rhs);
    8387         1726 :   else if (TYPE_P (lhs) && TYPE_P (rhs))
    8388              :     {
    8389              :       /* Given "using A = int;", "^^int != ^^A" should hold.  */
    8390         1124 :       if (typedef_variant_p (lhs) != typedef_variant_p (rhs))
    8391              :         return false;
    8392              :       /* This is for comparing function types.  E.g.,
    8393              :           auto fn() -> int; type_of(^^fn) == ^^auto()->int;  */
    8394         1112 :       return same_type_p (lhs, rhs);
    8395              :     }
    8396              : 
    8397          603 :   return cp_tree_equal (lhs, rhs);
    8398              : }
    8399              : 
    8400              : /* Return true if T is a valid splice-type-specifier.
    8401              :    [dcl.type.splice]: For a splice-type-specifier of the form
    8402              :    "typename[opt] splice-specifier", the splice-specifier shall designate
    8403              :    a type, a class template, or an alias template.
    8404              :    For a splice-type-specifier of the form
    8405              :    "typename[opt] splice-specialization-specifier", the splice-specifier
    8406              :    of the splice-specialization-specifier shall designate a template T
    8407              :    that is either a class template or an alias template.  */
    8408              : 
    8409              : bool
    8410          266 : valid_splice_type_p (const_tree t)
    8411              : {
    8412          266 :   return TYPE_P (t);
    8413              : }
    8414              : 
    8415              : /* Return true if T is a valid splice-scope-specifier.
    8416              :    [basic.lookup.qual.general]: If a splice-scope-specifier is followed
    8417              :    by a ::, it shall either be a dependent splice-scope-specifier or it
    8418              :    shall designate a namespace, class, enumeration, or dependent type.  */
    8419              : 
    8420              : bool
    8421          136 : valid_splice_scope_p (const_tree t)
    8422              : {
    8423           52 :   return (CLASS_TYPE_P (t)
    8424           84 :           || TREE_CODE (t) == ENUMERAL_TYPE
    8425          220 :           || TREE_CODE (t) == NAMESPACE_DECL);
    8426              : }
    8427              : 
    8428              : /* Check a function DECL for CWG 3115: Every function of consteval-only
    8429              :    type shall be an immediate function.  */
    8430              : 
    8431              : void
    8432    190352684 : check_consteval_only_fn (tree decl)
    8433              : {
    8434    380705368 :   if (!DECL_IMMEDIATE_FUNCTION_P (decl)
    8435    188150780 :       && consteval_only_p (decl)
    8436              :       /* But if the function can be escalated, merrily we roll along.  */
    8437    190353232 :       && !immediate_escalating_function_p (decl))
    8438           22 :     error_at (DECL_SOURCE_LOCATION (decl),
    8439              :               "function of consteval-only type must be declared %qs",
    8440              :               "consteval");
    8441    190352684 : }
    8442              : 
    8443              : /* Check if T is a valid result of splice-expression.  ADDRESS_P is true if
    8444              :    we are taking the address of the splice.  MEMBER_ACCESS_P is true if this
    8445              :    splice is used in foo.[: bar :] or foo->[: bar :] context.  COMPLAIN_P is
    8446              :    true if any errors should be emitted.  Returns true is no problems are
    8447              :    found, false otherwise.  */
    8448              : 
    8449              : bool
    8450         1949 : check_splice_expr (location_t loc, location_t start_loc, tree t,
    8451              :                    bool address_p, bool member_access_p, bool complain_p)
    8452              : {
    8453              :   /* We may not have gotten an expression.  */
    8454         1949 :   if (TREE_CODE (t) == TYPE_DECL
    8455         1944 :       || TREE_CODE (t) == NAMESPACE_DECL
    8456         1935 :       || TYPE_P (t))
    8457              :     {
    8458           67 :       if (complain_p)
    8459              :         {
    8460           55 :           if (TYPE_P (t))
    8461              :             {
    8462           43 :               auto_diagnostic_group d;
    8463           43 :               error_at (loc, "expected a reflection of an expression");
    8464           43 :               inform_tree_category (t);
    8465           43 :               if (start_loc != UNKNOWN_LOCATION)
    8466              :                 {
    8467           35 :                   rich_location richloc (line_table, start_loc);
    8468           35 :                   richloc.add_fixit_insert_before (start_loc, "typename");
    8469           35 :                   inform (&richloc, "add %<typename%> to denote a type "
    8470              :                           "outside a type-only context");
    8471           35 :                 }
    8472              :               else
    8473            8 :                 inform (loc, "add %<typename%> to denote a type outside "
    8474              :                         "a type-only context");
    8475           43 :             }
    8476              :           else
    8477              :             {
    8478           12 :               auto_diagnostic_group d;
    8479           12 :               error_at (loc, "expected a reflection of an expression");
    8480           12 :               inform_tree_category (t);
    8481           12 :             }
    8482              :         }
    8483           67 :       return false;
    8484              :     }
    8485              :   /* [expr.prim.splice]/2 For a splice-expression of the form
    8486              :      splice-specifier, the expression is ill-formed if it is:  */
    8487              :   /* -- a constructor or a destructor  */
    8488         1882 :   if (TREE_CODE (t) == FUNCTION_DECL
    8489         2423 :       && (DECL_CONSTRUCTOR_P (t) || DECL_DESTRUCTOR_P (t)))
    8490              :     {
    8491            5 :       if (complain_p)
    8492            5 :         error_at (loc, "cannot use constructor or destructor %qD in a splice "
    8493              :                   "expression", t);
    8494            5 :       return false;
    8495              :     }
    8496              :   /* -- an unnamed bit-field  */
    8497         1877 :   if (TREE_CODE (t) == FIELD_DECL && DECL_UNNAMED_BIT_FIELD (t))
    8498              :     {
    8499            1 :       if (complain_p)
    8500            1 :         error_at (loc, "cannot use an unnamed bit-field %qD in a splice "
    8501              :                   "expression", t);
    8502            1 :       return false;
    8503              :     }
    8504              :   /* Class members may not be implicitly referenced through a splice.
    8505              :      But taking the address is fine, and so is class member access a la
    8506              :      foo.[: ^^S::bar :].  */
    8507         1876 :   if (!address_p
    8508              :       && !member_access_p
    8509          630 :       && DECL_P (t)
    8510         2290 :       && DECL_NONSTATIC_MEMBER_P (t))
    8511              :     {
    8512           26 :       if (complain_p)
    8513           20 :         error_at (loc, "cannot implicitly reference a class member %qD "
    8514              :                   "through a splice", t);
    8515           26 :       return false;
    8516              :     }
    8517              :   /* [expr.unary.op]/3.1 "If the operand [of unary &] is a qualified-id or
    8518              :      splice-expression designating a non-static member m, other than an
    8519              :      explicit object member function, m shall be a direct member of some
    8520              :      class C that is not an anonymous union."  */
    8521         1850 :   if (address_p
    8522           73 :       && TREE_CODE (t) == FIELD_DECL
    8523           21 :       && ANON_UNION_TYPE_P (DECL_CONTEXT (t))
    8524         1857 :       && !TYPE_P (context_for_name_lookup (t)))
    8525              :     {
    8526            5 :       if (complain_p)
    8527            5 :         error_at (loc, "unary %<&%> applied to an anonymous union member "
    8528              :                        "%qD that is not a direct member of a named class", t);
    8529            5 :       return false;
    8530              :     }
    8531              : 
    8532              :   /* [expr.prim.splice]/2: "The expression is ill-formed if S [the construct
    8533              :      designated by splice-specifier] is
    8534              :      -- a local entity such that there is a lambda scope that intervenes
    8535              :      between the expression and the point at which S was introduced"
    8536              :      This also checks ODR violations (reflect/odr1.C).  */
    8537         1845 :   if (outer_automatic_var_p (t))
    8538           26 :     if (tree r = process_outer_var_ref (t, tf_none))
    8539           26 :       if (r == error_mark_node || is_capture_proxy (r))
    8540              :         {
    8541              :           /* Not letting process_outer_var_ref emit the error so that we can
    8542              :              say "in a splice expression".  */
    8543           11 :           if (complain_p)
    8544              :             {
    8545           11 :               auto_diagnostic_group d;
    8546           11 :               error_at (loc, "use of local variable with automatic storage "
    8547              :                         "from containing function in a splice expression");
    8548           11 :               inform (DECL_SOURCE_LOCATION (t), "%q#D declared here", t);
    8549           11 :             }
    8550           11 :           return false;
    8551              :         }
    8552              : 
    8553              :   /* If we had a reflect_kind here, we could just check for
    8554              :      REFLECT_ANNOTATION and be done with it.  But we don't have it yet (TODO),
    8555              :      so do it the suboptimal way.  */
    8556         1834 :   if (TREE_CODE (t) == TREE_LIST && annotation_p (t))
    8557              :     {
    8558            1 :       if (complain_p)
    8559            1 :         error_at (loc, "cannot use an annotation %qE in a splice expression",
    8560              :                   t);
    8561            1 :       return false;
    8562              :     }
    8563              : 
    8564              :   /* Same, but with REFLECT_DATA_MEMBER_SPEC.  */
    8565         1833 :   if (TREE_CODE (t) == TREE_VEC)
    8566              :     {
    8567            1 :       if (complain_p)
    8568            1 :         error_at (loc, "cannot use a data member specification in a "
    8569              :                   "splice expression");
    8570            1 :       return false;
    8571              :     }
    8572              : 
    8573              :   return true;
    8574              : }
    8575              : 
    8576              : /* Create a new SPLICE_SCOPE tree.  EXPR is its SPLICE_SCOPE_EXPR, and
    8577              :    TYPE_P says if it should have SPLICE_SCOPE_TYPE_P set.  */
    8578              : 
    8579              : tree
    8580          145 : make_splice_scope (tree expr, bool type_p)
    8581              : {
    8582          145 :   tree t = cxx_make_type (SPLICE_SCOPE);
    8583          145 :   SPLICE_SCOPE_EXPR (t) = expr;
    8584          145 :   SPLICE_SCOPE_TYPE_P (t) = type_p;
    8585          145 :   return t;
    8586              : }
    8587              : 
    8588              : /* Return true if T is a splice expression; that is, it is either [:T:] or
    8589              :    [:T:]<arg>.  */
    8590              : 
    8591              : bool
    8592    127768825 : dependent_splice_p (const_tree t)
    8593              : {
    8594    127768825 :   return (TREE_CODE (t) == SPLICE_EXPR
    8595    127768825 :           || (TREE_CODE (t) == TEMPLATE_ID_EXPR
    8596       467047 :               && TREE_CODE (TREE_OPERAND (t, 0)) == SPLICE_EXPR));
    8597              : }
    8598              : 
    8599              : /* Annotation index for mangling.  */
    8600              : 
    8601              : static GTY(()) int annotation_idx;
    8602              : 
    8603              : /* Helper function for mangle.cc (write_reflection).
    8604              :    Determine 2 letter mangling prefix and store it into prefix.
    8605              :    Additionally return the reflection handle possibly adjusted so that
    8606              :    write_reflection can mangle the operands of it if any are needed.  */
    8607              : 
    8608              : tree
    8609          593 : reflection_mangle_prefix (tree refl, char prefix[3])
    8610              : {
    8611          593 :   tree h = REFLECT_EXPR_HANDLE (refl);
    8612          593 :   reflect_kind kind = REFLECT_EXPR_KIND (refl);
    8613          593 :   if (h == unknown_type_node)
    8614              :     {
    8615            3 :       strcpy (prefix, "nu");
    8616            3 :       return NULL_TREE;
    8617              :     }
    8618         1180 :   if (eval_is_value (kind) == boolean_true_node)
    8619              :     {
    8620            3 :       strcpy (prefix, "vl");
    8621            3 :       if (VAR_P (h) && DECL_NTTP_OBJECT_P (h))
    8622            0 :         h = tparm_object_argument (h);
    8623            3 :       return h;
    8624              :     }
    8625         1170 :   if (eval_is_object (kind) == boolean_true_node)
    8626              :     {
    8627            4 :       strcpy (prefix, "ob");
    8628            4 :       return h;
    8629              :     }
    8630          583 :   if (eval_is_variable (h, kind) == boolean_true_node)
    8631              :     {
    8632           92 :       strcpy (prefix, "vr");
    8633           92 :       return h;
    8634              :     }
    8635          491 :   if (eval_is_structured_binding (h, kind) == boolean_true_node)
    8636              :     {
    8637            2 :       strcpy (prefix, "sb");
    8638            2 :       return h;
    8639              :     }
    8640          489 :   if (eval_is_function (h) == boolean_true_node)
    8641              :     {
    8642           49 :       strcpy (prefix, "fn");
    8643           49 :       return maybe_get_first_fn (h);
    8644              :     }
    8645          440 :   if (eval_is_function_parameter (h, kind) == boolean_true_node)
    8646              :     {
    8647           16 :       strcpy (prefix, "pa");
    8648           16 :       return maybe_update_function_parm (h);
    8649              :     }
    8650          837 :   if (eval_is_enumerator (h) == boolean_true_node)
    8651              :     {
    8652           11 :       strcpy (prefix, "en");
    8653           11 :       return h;
    8654              :     }
    8655          413 :   if (eval_is_annotation (h, kind) == boolean_true_node)
    8656              :     {
    8657            5 :       strcpy (prefix, "an");
    8658            5 :       if (TREE_PURPOSE (TREE_VALUE (h)) == NULL_TREE)
    8659            4 :         TREE_PURPOSE (TREE_VALUE (h))
    8660            8 :           = build_int_cst (integer_type_node, annotation_idx++);
    8661            5 :       return TREE_PURPOSE (TREE_VALUE (h));
    8662              :     }
    8663          408 :   if (eval_is_type_alias (h) == boolean_true_node)
    8664              :     {
    8665            6 :       strcpy (prefix, "ta");
    8666            6 :       return h;
    8667              :     }
    8668          402 :   if (eval_is_type (h) == boolean_true_node)
    8669              :     {
    8670          127 :       strcpy (prefix, "ty");
    8671          127 :       return h;
    8672              :     }
    8673          275 :   if (eval_is_nonstatic_data_member (h) == boolean_true_node)
    8674              :     {
    8675           91 :       strcpy (prefix, "dm");
    8676           91 :       return h;
    8677              :     }
    8678          184 :   if (TREE_CODE (h) == FIELD_DECL && DECL_UNNAMED_BIT_FIELD (h))
    8679              :     {
    8680            4 :       strcpy (prefix, "un");
    8681            4 :       return h;
    8682              :     }
    8683          180 :   if (eval_is_class_template (h) == boolean_true_node)
    8684              :     {
    8685           15 :       strcpy (prefix, "ct");
    8686           15 :       return h;
    8687              :     }
    8688          165 :   if (eval_is_function_template (h) == boolean_true_node)
    8689              :     {
    8690           14 :       strcpy (prefix, "ft");
    8691           14 :       h = maybe_get_first_fn (h);
    8692           14 :       return h;
    8693              :     }
    8694          151 :   if (eval_is_variable_template (h) == boolean_true_node)
    8695              :     {
    8696            7 :       strcpy (prefix, "vt");
    8697            7 :       return h;
    8698              :     }
    8699          144 :   if (eval_is_alias_template (h) == boolean_true_node)
    8700              :     {
    8701            8 :       strcpy (prefix, "at");
    8702            8 :       return h;
    8703              :     }
    8704          272 :   if (eval_is_concept (h) == boolean_true_node)
    8705              :     {
    8706            6 :       strcpy (prefix, "co");
    8707            6 :       return h;
    8708              :     }
    8709          130 :   if (eval_is_namespace_alias (h) == boolean_true_node)
    8710              :     {
    8711            4 :       strcpy (prefix, "na");
    8712            4 :       return h;
    8713              :     }
    8714          177 :   if (eval_is_namespace (h) == boolean_true_node)
    8715              :     {
    8716           75 :       if (h == global_namespace)
    8717              :         {
    8718           12 :           strcpy (prefix, "ng");
    8719           12 :           return NULL_TREE;
    8720              :         }
    8721           63 :       strcpy (prefix, "ns");
    8722           63 :       return h;
    8723              :     }
    8724           51 :   if (eval_is_base (h, kind) == boolean_true_node)
    8725              :     {
    8726           10 :       strcpy (prefix, "ba");
    8727           10 :       return h;
    8728              :     }
    8729           41 :   if (eval_is_data_member_spec (h, kind) == boolean_true_node)
    8730              :     {
    8731           41 :       strcpy (prefix, "ds");
    8732           41 :       return h;
    8733              :     }
    8734            0 :   gcc_unreachable ();
    8735              : }
    8736              : 
    8737              : #include "gt-cp-reflect.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.