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