LCOV - code coverage report
Current view: top level - gcc/cp - reflect.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 4487 4131
Test Date: 2026-04-20 14:57:17 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          579 : 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          579 :   meta_info_type_node = make_node (META_TYPE);
      63              :   /* Make it a complete type.  */
      64         1158 :   TYPE_SIZE (meta_info_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
      65         1158 :   TYPE_SIZE_UNIT (meta_info_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
      66              :   /* Name it.  */
      67          579 :   record_builtin_type (RID_MAX, "decltype(^^int)", meta_info_type_node);
      68              : 
      69              :   /* Create the `std::meta' namespace.  */
      70          579 :   push_namespace (get_identifier ("std"));
      71          579 :   push_namespace (get_identifier ("meta"), /*inline*/false);
      72          579 :   std_meta_node = current_namespace;
      73          579 :   pop_namespace ();
      74          579 :   pop_namespace ();
      75          579 : }
      76              : 
      77              : /* Create a REFLECT_EXPR expression of kind KIND around T.  */
      78              : 
      79              : static tree
      80        70213 : get_reflection_raw (location_t loc, tree t, reflect_kind kind = REFLECT_UNDEF)
      81              : {
      82        70213 :   t = build1_loc (loc, REFLECT_EXPR, meta_info_type_node, t);
      83        70213 :   SET_REFLECT_EXPR_KIND (t, kind);
      84        70213 :   TREE_CONSTANT (t) = true;
      85        70213 :   TREE_READONLY (t) = true;
      86        70213 :   TREE_SIDE_EFFECTS (t) = false;
      87        70213 :   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        25248 : get_reflection (location_t loc, tree t, reflect_kind kind/*=REFLECT_UNDEF*/)
     123              : {
     124        25248 :   STRIP_ANY_LOCATION_WRAPPER (t);
     125              : 
     126              :   /* Constant template parameters and pack-index-expressions cannot
     127              :      appear as operands of the reflection operator.  */
     128        25248 :   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        25247 :   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        25241 :   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        25239 :   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        25238 :   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        25238 :            && ((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        25231 :   else if (TREE_CODE (t) == USING_DECL
     174        25231 :            || (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        25227 :   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        25226 :   tree r = MAYBE_BASELINK_FUNCTIONS (t);
     196        25226 :   if (OVL_P (r))
     197              :     {
     198         1875 :       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        23351 :   else if (!processing_template_decl && t != unknown_type_node)
     208              :     {
     209              :       /* Resolve all TEMPLATE_ID_EXPRs here.  */
     210        21106 :       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        21106 :       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        21098 :       if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
     218         2091 :         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        25202 :   if (RECORD_OR_UNION_TYPE_P (t)
     224         6445 :       && TYPE_NAME (t)
     225        31586 :       && 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        25202 :   if (TREE_CODE (t) == BIT_NOT_EXPR
     231           48 :       && CLASS_TYPE_P (TREE_OPERAND (t, 0))
     232        25250 :       && 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        25202 :         t = dtor;
     239              :     }
     240              : 
     241              :   /* Look through block scope externs.  */
     242        25202 :   if (VAR_OR_FUNCTION_DECL_P (t) && DECL_LOCAL_DECL_P (t))
     243           14 :     t = DECL_LOCAL_DECL_ALIAS (t);
     244              : 
     245        25202 :   if (t == error_mark_node)
     246              :     return error_mark_node;
     247              : 
     248        25202 :   return get_reflection_raw (loc, t, kind);
     249              : }
     250              : 
     251              : /* Null reflection shared tree.  */
     252              : 
     253              : static GTY(()) tree null_reflection;
     254              : 
     255              : /* Return a null reflection value.  */
     256              : 
     257              : tree
     258         9653 : get_null_reflection ()
     259              : {
     260         9653 :   if (!null_reflection)
     261          499 :     null_reflection = get_reflection_raw (UNKNOWN_LOCATION, unknown_type_node);
     262         9653 :   return null_reflection;
     263              : }
     264              : 
     265              : /* Do strip_typedefs on T, but only for types.  */
     266              : 
     267              : static tree
     268         3695 : maybe_strip_typedefs (tree t)
     269              : {
     270         3695 :   if (TYPE_P (t))
     271         3532 :     return strip_typedefs (t);
     272              :   return t;
     273              : }
     274              : 
     275              : /* If PARM_DECL comes from an earlier reflection of a function parameter
     276              :    and function definition is seen after that, DECL_ARGUMENTS is
     277              :    overwritten and so the old PARM_DECL is no longer present in the
     278              :    DECL_ARGUMENTS (DECL_CONTEXT (parm)) chain.  Return corresponding
     279              :    PARM_DECL which is in the chain.  */
     280              : 
     281              : static tree
     282          363 : maybe_update_function_parm (tree parm)
     283              : {
     284          363 :   if (!OLD_PARM_DECL_P (parm))
     285              :     return parm;
     286           93 :   tree fn = DECL_CONTEXT (parm);
     287           93 :   int oldlen = list_length (parm);
     288           93 :   int newlen = list_length (DECL_ARGUMENTS (fn));
     289           93 :   gcc_assert (newlen >= oldlen);
     290           93 :   tree ret = DECL_ARGUMENTS (fn);
     291           93 :   int n = newlen - oldlen;
     292          243 :   while (n)
     293              :     {
     294          150 :       ret = DECL_CHAIN (ret);
     295          150 :       --n;
     296              :     }
     297              :   return ret;
     298              : }
     299              : 
     300              : /* Return true if DECL comes from std::meta.  */
     301              : 
     302              : static bool
     303       593755 : decl_in_std_meta_p (tree decl)
     304              : {
     305            0 :   return decl_namespace_context (decl) == std_meta_node;
     306              : }
     307              : 
     308              : /* True if CTX is an instance of std::meta::NAME class.  */
     309              : 
     310              : static bool
     311         4523 : is_std_meta_class (tree ctx, const char *name)
     312              : {
     313         4523 :   if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
     314              :     return false;
     315              : 
     316         4514 :   tree decl = TYPE_MAIN_DECL (ctx);
     317         4514 :   tree dname = DECL_NAME (decl);
     318         4514 :   if (dname == NULL_TREE || !id_equal (dname, name))
     319              :     return false;
     320              : 
     321         4514 :   return decl_in_std_meta_p (decl);
     322              : }
     323              : 
     324              : /* Returns true if FNDECL, a FUNCTION_DECL, is a call to a metafunction
     325              :    declared in namespace std::meta.  */
     326              : 
     327              : bool
     328    133567752 : metafunction_p (tree fndecl)
     329              : {
     330    133567752 :   if (!flag_reflection)
     331              :     return false;
     332              : 
     333              :   /* Metafunctions are expected to be marked consteval.  */
     334      4479592 :   if (!DECL_IMMEDIATE_FUNCTION_P (fndecl))
     335              :     return false;
     336              : 
     337       669447 :   if (special_function_p (fndecl))
     338              :     return false;
     339              : 
     340       589241 :   if (!decl_in_std_meta_p (fndecl))
     341              :     return false;
     342              : 
     343              :   /* They should be user provided and not defined.  */
     344        42874 :   if (!user_provided_p (fndecl)
     345        42874 :       || (DECL_NAMESPACE_SCOPE_P (fndecl) && DECL_DELETED_FN (fndecl)))
     346              :     return false;
     347        42874 :   if (DECL_INITIAL (fndecl))
     348              :     return false;
     349              : 
     350              :   return true;
     351              : }
     352              : 
     353              : /* Extract the N-th reflection argument from a metafunction call CALL.  */
     354              : 
     355              : static tree
     356        24350 : get_info (location_t loc, const constexpr_ctx *ctx, tree call, int n,
     357              :           bool *non_constant_p, bool *overflow_p, tree *jump_target)
     358              : {
     359        24350 :   gcc_checking_assert (call_expr_nargs (call) > n);
     360        24350 :   tree info = get_nth_callarg (call, n);
     361        24350 :   if (!REFLECTION_TYPE_P (TREE_TYPE (info)))
     362              :     {
     363            6 :       error_at (loc, "incorrect %qT type of argument %d, expected %qT",
     364            6 :                 TREE_TYPE (info), n + 1, meta_info_type_node);
     365            6 :       *non_constant_p = true;
     366            6 :       return NULL_TREE;
     367              :     }
     368        24344 :   info = cxx_eval_constant_expression (ctx, info, vc_prvalue,
     369              :                                        non_constant_p, overflow_p,
     370              :                                        jump_target);
     371        24344 :   if (*jump_target)
     372              :     return NULL_TREE;
     373        24338 :   if (!REFLECT_EXPR_P (info))
     374              :     {
     375           22 :       *non_constant_p = true;
     376           22 :       return NULL_TREE;
     377              :     }
     378              :   return info;
     379              : }
     380              : 
     381              : /* Helper function for get_range_elts, called through cp_walk_tree.  */
     382              : 
     383              : static tree
     384        81673 : replace_parm_r (tree *tp, int *walk_subtrees, void *data)
     385              : {
     386        81673 :   tree *p = (tree *) data;
     387        81673 :   if (*tp == p[0])
     388         7373 :     *tp = p[1];
     389        74300 :   else if (TYPE_P (*tp))
     390            0 :     *walk_subtrees = 0;
     391        81673 :   return NULL_TREE;
     392              : }
     393              : 
     394              : static tree throw_exception (location_t, const constexpr_ctx *, const char *,
     395              :                              tree, bool *, tree *);
     396              : 
     397              : /* Helper function for get_range_elts, handle adjustment of ARRAY_TYPE elts
     398              :    of a retvec.  */
     399              : 
     400              : static tree
     401         1311 : adjust_array_elt (location_t loc, const constexpr_ctx *ctx, tree valuet,
     402              :                   tree expr, tree fun, bool *non_constant_p, tree *jump_target)
     403              : {
     404         1311 :   if (TREE_CODE (valuet) == ARRAY_TYPE)
     405              :     {
     406          408 :       if (TREE_CODE (expr) != CONSTRUCTOR
     407          408 :           || TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
     408            0 :         return throw_exception (loc, ctx, "reflect_constant_array failed",
     409            0 :                                 fun, non_constant_p, jump_target);
     410              :       unsigned int i;
     411              :       tree val;
     412         1608 :       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, val)
     413              :         {
     414         1200 :           CONSTRUCTOR_ELT (expr, i)->value
     415         1200 :             = adjust_array_elt (loc, ctx, TREE_TYPE (valuet), val, fun,
     416              :                                 non_constant_p, jump_target);
     417         1200 :           if (*jump_target || *non_constant_p)
     418              :             return NULL_TREE;
     419              :         }
     420              :       return expr;
     421              :     }
     422          903 :   expr = convert_reflect_constant_arg (valuet, expr);
     423          903 :   if (expr == error_mark_node)
     424            0 :     return throw_exception (loc, ctx, "reflect_constant failed",
     425            0 :                             fun, non_constant_p, jump_target);
     426          903 :   if (VAR_P (expr))
     427            0 :     expr = DECL_INITIAL (expr);
     428              :   return expr;
     429              : }
     430              : 
     431              : /* Kinds for get_range_elts.  */
     432              : 
     433              : enum get_range_elts_kind {
     434              :   GET_INFO_VEC,
     435              :   REFLECT_CONSTANT_STRING,
     436              :   REFLECT_CONSTANT_ARRAY
     437              : };
     438              : 
     439              : /* Extract the N-th input_range argument from a metafunction call CALL
     440              :    and return it as TREE_VEC or STRING_CST or CONSTRUCTOR.  Helper function
     441              :    for get_info_vec, eval_reflect_constant_string and
     442              :    eval_reflect_constant_array.  For GET_INFO_VEC kind, <meta> ensures
     443              :    the argument is reference to reflection_range concept and so both
     444              :    range_value_t is info and range_refernce_t is cv info or cv info & or
     445              :    cv info &&.  If N is negative, CALL is the expression to extract
     446              :    values from rather than N-th argument from CALL.  */
     447              : 
     448              : static tree
     449         3980 : get_range_elts (location_t loc, const constexpr_ctx *ctx, tree call, int n,
     450              :                 bool *non_constant_p, bool *overflow_p, tree *jump_target,
     451              :                 get_range_elts_kind kind, tree fun)
     452              : {
     453         3980 :   tree arg, parm;
     454         3980 :   if (n < 0)
     455              :     arg = parm = call;
     456              :   else
     457              :     {
     458         3694 :       gcc_checking_assert (call_expr_nargs (call) > n);
     459         3694 :       arg = get_nth_callarg (call, n);
     460         3694 :       parm = DECL_ARGUMENTS (cp_get_callee_fndecl_nofold (call));
     461         5287 :       for (int i = 0; i < n; ++i)
     462         1593 :         parm = DECL_CHAIN (parm);
     463              :     }
     464         3980 :   tree type = TREE_TYPE (arg);
     465         3980 :   gcc_checking_assert (TYPE_REF_P (type));
     466         3980 :   arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue, non_constant_p,
     467              :                                       overflow_p, jump_target);
     468         3980 :   if (*jump_target || *non_constant_p)
     469              :     return NULL_TREE;
     470         3979 :   tree map[2] = { parm, arg };
     471              :   /* To speed things up, check
     472              :      if constexpr (std::ranges::contiguous_range <_R>).  */
     473         3979 :   tree ranges_ns = lookup_qualified_name (std_node, "ranges");
     474         3979 :   if (TREE_CODE (ranges_ns) != NAMESPACE_DECL)
     475              :     {
     476            0 :       error_at (loc, "%<std::ranges%> is not a namespace");
     477            0 :       *non_constant_p = true;
     478            0 :       return NULL_TREE;
     479              :     }
     480         3979 :   tree contiguous_range
     481         3979 :     = lookup_qualified_name (ranges_ns, "contiguous_range");
     482         3979 :   if (TREE_CODE (contiguous_range) != TEMPLATE_DECL
     483         3979 :       || !concept_definition_p (contiguous_range))
     484              :     contiguous_range = NULL_TREE;
     485              :   else
     486              :     {
     487         3979 :       tree args = make_tree_vec (1);
     488         3979 :       TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
     489         3979 :       contiguous_range = build2_loc (loc, TEMPLATE_ID_EXPR, boolean_type_node,
     490              :                                      contiguous_range, args);
     491         3979 :       if (!integer_nonzerop (maybe_constant_value (contiguous_range)))
     492           82 :         contiguous_range = NULL_TREE;
     493              :     }
     494         3979 :   tree valuet = meta_info_type_node;
     495         3979 :   tree ret = NULL_TREE;
     496         3979 :   if (kind != GET_INFO_VEC)
     497              :     {
     498         2087 :       tree args = make_tree_vec (1);
     499         2087 :       TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
     500         2087 :       tree inst = lookup_template_class (get_identifier ("range_value_t"),
     501              :                                          args, /*in_decl*/NULL_TREE,
     502              :                                          /*context*/ranges_ns,
     503              :                                          tf_warning_or_error);
     504         2087 :       inst = complete_type (inst);
     505         2087 :       if (inst == error_mark_node)
     506              :         {
     507            0 :           *non_constant_p = true;
     508            0 :           return NULL_TREE;
     509              :         }
     510         2087 :       valuet = TYPE_MAIN_VARIANT (inst);
     511         2087 :       if (kind == REFLECT_CONSTANT_STRING
     512         1739 :           && valuet != char_type_node
     513          102 :           && valuet != wchar_type_node
     514           91 :           && valuet != char8_type_node
     515           35 :           && valuet != char16_type_node
     516           24 :           && valuet != char32_type_node)
     517              :         {
     518            9 :           if (!cxx_constexpr_quiet_p (ctx))
     519            3 :             error_at (loc, "%<reflect_constant_string%> called with %qT "
     520              :                            "rather than %<char%>, %<wchar_t%>, %<char8_t%>, "
     521              :                            "%<char16_t%> or %<char32_t%>", inst);
     522            9 :           *non_constant_p = true;
     523            9 :           return NULL_TREE;
     524              :         }
     525              :       /* Check for the reflect_object_string special-case, where r
     526              :          refers to a string literal.  In that case CharT() should not
     527              :          be appended.  */
     528         1730 :       if (kind == REFLECT_CONSTANT_STRING
     529         1730 :           && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE
     530           82 :           && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) == valuet
     531           82 :           && TYPE_DOMAIN (TREE_TYPE (type)))
     532              :         {
     533           82 :           tree a = arg;
     534           82 :           tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (type)));
     535           82 :           STRIP_NOPS (a);
     536           82 :           tree at;
     537           82 :           if (TREE_CODE (a) == ADDR_EXPR
     538           82 :               && TREE_CODE (TREE_OPERAND (a, 0)) == STRING_CST
     539           80 :               && tree_fits_uhwi_p (maxv)
     540           80 :               && ((unsigned) TREE_STRING_LENGTH (TREE_OPERAND (a, 0))
     541           80 :                   == ((tree_to_uhwi (maxv) + 1)
     542           80 :                        * tree_to_uhwi (TYPE_SIZE_UNIT (valuet))))
     543           80 :               && (at = TREE_TYPE (TREE_OPERAND (a, 0)))
     544          162 :               && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type),
     545              :                                                             at))
     546           80 :             return TREE_OPERAND (a, 0);
     547              :         }
     548         1998 :       if (kind == REFLECT_CONSTANT_ARRAY)
     549              :         {
     550          348 :           tree valuete = strip_array_types (valuet);
     551          348 :           if (!structural_type_p (valuete))
     552              :             {
     553            6 :               if (!cxx_constexpr_quiet_p (ctx))
     554              :                 {
     555            2 :                   auto_diagnostic_group d;
     556            2 :                   error_at (loc, "%<reflect_constant_array%> argument with "
     557              :                                  "%qT which is not a structural type", inst);
     558            2 :                   structural_type_p (valuete, true);
     559            2 :                 }
     560            6 :               *non_constant_p = true;
     561            6 :               return NULL_TREE;
     562              :             }
     563          342 :           TREE_VEC_ELT (args, 0)
     564          342 :             = build_stub_type (valuete,
     565          342 :                                cp_type_quals (valuete) | TYPE_QUAL_CONST,
     566              :                                false);
     567          342 :           if (!is_xible (INIT_EXPR, valuete, args))
     568              :             {
     569            6 :               if (!cxx_constexpr_quiet_p (ctx))
     570            2 :                 error_at (loc, "%<reflect_constant_array%> argument with %qT "
     571              :                                "which is not copy constructible", inst);
     572            6 :               *non_constant_p = true;
     573            6 :               return NULL_TREE;
     574              :             }
     575          336 :           TREE_VEC_ELT (args, 0) = TREE_TYPE (type);
     576          336 :           tree instr
     577          336 :             = lookup_template_class (get_identifier ("range_reference_t"),
     578              :                                      args, /*in_decl*/NULL_TREE,
     579              :                                      /*context*/ranges_ns,
     580              :                                      tf_warning_or_error);
     581          336 :           instr = complete_type (instr);
     582          336 :           if (instr == error_mark_node)
     583              :             {
     584            0 :               *non_constant_p = true;
     585            0 :               return NULL_TREE;
     586              :             }
     587          336 :           tree referencet = TYPE_MAIN_VARIANT (instr);
     588          336 :           TREE_VEC_ELT (args, 0) = referencet;
     589          336 :           if (valuete != valuet)
     590              :             {
     591           37 :               tree rt = non_reference (referencet);
     592           37 :               if (!same_type_ignoring_top_level_qualifiers_p (valuet, rt))
     593              :                 {
     594            0 :                   if (!cxx_constexpr_quiet_p (ctx))
     595            0 :                     error_at (loc, "%<reflect_constant_array%> argument with "
     596              :                                    "%qT which is not compatible with %qT "
     597              :                                    "%<std::ranges::range_reference_t%>",
     598              :                               inst, referencet);
     599            0 :                   *non_constant_p = true;
     600            0 :                   return NULL_TREE;
     601              :                 }
     602              :             }
     603          299 :           else if (!is_xible (INIT_EXPR, valuet, args))
     604              :             {
     605            0 :               if (!cxx_constexpr_quiet_p (ctx))
     606            0 :                 error_at (loc, "%<reflect_constant_array%> argument with %qT "
     607              :                                "which is not constructible from %qT "
     608              :                                "%<std::ranges::range_reference_t%>",
     609              :                           inst, referencet);
     610            0 :               *non_constant_p = true;
     611            0 :               return NULL_TREE;
     612              :             }
     613              :         }
     614              :     }
     615         3878 :   auto_vec<tree, 32> retvec;
     616         3878 :   tree p = convert_from_reference (parm);
     617        11840 :   auto obj_call = [=, &map] (tree obj, tsubst_flags_t complain) {
     618         7962 :     releasing_vec args;
     619         7962 :     vec_safe_push (args, p);
     620         7962 :     tree call = finish_call_expr (obj, &args, true, false, complain);
     621         7962 :     if (call == error_mark_node)
     622              :       return call;
     623         7945 :     if (n >= 0)
     624         7373 :       cp_walk_tree (&call, replace_parm_r, map, NULL);
     625         7945 :     if (complain != tf_none)
     626          370 :       return call;
     627         7575 :     call = cxx_eval_constant_expression (ctx, call, vc_prvalue, non_constant_p,
     628              :                                          overflow_p, jump_target);
     629         7575 :     if (*jump_target || *non_constant_p)
     630            0 :       return NULL_TREE;
     631              :     return call;
     632        11840 :   };
     633         4137 :   auto ret_retvec = [=, &retvec] () {
     634          259 :     unsigned HOST_WIDE_INT sz = retvec.length ();
     635         1276 :     for (size_t i = 0; i < sz; ++i)
     636              :       {
     637         1017 :         if (INTEGRAL_TYPE_P (valuet))
     638              :           {
     639          746 :             if (TREE_CODE (retvec[i]) != INTEGER_CST)
     640            0 :               return throw_exception (loc, ctx,
     641              :                                       "array element not a constant integer",
     642            0 :                                       fun, non_constant_p, jump_target);
     643              :           }
     644              :         else
     645              :           {
     646          271 :             gcc_assert (kind == REFLECT_CONSTANT_ARRAY);
     647          271 :             if (TREE_CODE (valuet) == ARRAY_TYPE)
     648              :               {
     649          111 :                 retvec[i]
     650          111 :                   = adjust_array_elt (loc, ctx, valuet,
     651          111 :                                       unshare_expr (retvec[i]), fun,
     652              :                                       non_constant_p, jump_target);
     653          111 :                 if (*jump_target || *non_constant_p)
     654              :                   return NULL_TREE;
     655          111 :                 continue;
     656              :               }
     657          160 :             tree expr = convert_reflect_constant_arg (valuet, retvec[i]);
     658          160 :             if (expr == error_mark_node)
     659            0 :               return throw_exception (loc, ctx, "reflect_constant failed",
     660            0 :                                       fun, non_constant_p, jump_target);
     661          160 :             if (VAR_P (expr))
     662           77 :               expr = DECL_INITIAL (expr);
     663          160 :             retvec[i] = expr;
     664              :           }
     665              :       }
     666          259 :     if (kind == REFLECT_CONSTANT_ARRAY && sz == 0)
     667              :       {
     668              :         /* Return std::array <valuet, 0> {}.  */
     669            5 :         tree args = make_tree_vec (2);
     670            5 :         TREE_VEC_ELT (args, 0) = valuet;
     671            5 :         TREE_VEC_ELT (args, 1) = size_zero_node;
     672            5 :         tree inst = lookup_template_class (get_identifier ("array"), args,
     673              :                                            /*in_decl*/NULL_TREE,
     674              :                                            /*context*/std_node,
     675              :                                            tf_warning_or_error);
     676            5 :         tree type = complete_type (inst);
     677            5 :         if (type == error_mark_node)
     678              :           {
     679            0 :             *non_constant_p = true;
     680            0 :             return NULL_TREE;
     681              :           }
     682            5 :         tree ctor = build_constructor (init_list_type_node, nullptr);
     683            5 :         CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
     684            5 :         TREE_CONSTANT (ctor) = true;
     685            5 :         TREE_STATIC (ctor) = true;
     686            5 :         tree r = finish_compound_literal (type, ctor, tf_warning_or_error,
     687              :                                           fcl_functional);
     688              :         /* Here, we're evaluating an AGGR_INIT_EXPR, which is already
     689              :            embedded in a TARGET_EXPR, so we don't want to add another
     690              :            TARGET_EXPR inside it.  Note that SIMPLE_TARGET_EXPR_P would
     691              :            always be false because the TARGET_EXPR_INITIAL is an
     692              :            AGGR_INIT_EXPR with void type.  */
     693            5 :         if (TREE_CODE (r) == TARGET_EXPR)
     694            5 :           r = TARGET_EXPR_INITIAL (r);
     695            5 :         return r;
     696              :       }
     697          254 :     unsigned esz = tree_to_uhwi (TYPE_SIZE_UNIT (valuet));
     698          254 :     unsigned last = kind == REFLECT_CONSTANT_STRING ? esz : 0;
     699          254 :     tree index = build_index_type (size_int (last ? sz : sz - 1));
     700          254 :     tree at = build_array_type (valuet, index);
     701          254 :     at = cp_build_qualified_type (at, TYPE_QUAL_CONST);
     702          254 :     if (kind == REFLECT_CONSTANT_STRING
     703          254 :         || ((valuet == char_type_node
     704          223 :              || valuet == wchar_type_node
     705          223 :              || valuet == char8_type_node
     706          223 :              || valuet == char16_type_node
     707          223 :              || valuet == char32_type_node)
     708           20 :             && integer_zerop (retvec.last ())))
     709              :       {
     710           27 :         unsigned HOST_WIDE_INT szt = sz * esz;
     711           27 :         char *p;
     712           27 :         if (szt < 4096)
     713           27 :           p = XALLOCAVEC (char, szt + last);
     714              :         else
     715            0 :           p = XNEWVEC (char, szt + last);
     716          276 :         for (size_t i = 0; i < sz; ++i)
     717          249 :           native_encode_expr (retvec[i], (unsigned char *) p + i * esz,
     718              :                               esz, 0);
     719           27 :         if (last)
     720           21 :           memset (p + szt, '\0', last);
     721           27 :         tree ret = build_string (szt + last, p);
     722           27 :         TREE_TYPE (ret) = at;
     723           27 :         TREE_CONSTANT (ret) = 1;
     724           27 :         TREE_READONLY (ret) = 1;
     725           27 :         TREE_STATIC (ret) = 1;
     726           27 :         if (szt >= 4096)
     727            0 :           XDELETEVEC (p);
     728           27 :         return ret;
     729              :       }
     730          227 :     vec<constructor_elt, va_gc> *elts = nullptr;
     731          995 :     for (unsigned i = 0; i < sz; ++i)
     732          768 :       CONSTRUCTOR_APPEND_ELT (elts, bitsize_int (i), retvec[i]);
     733          227 :     return build_constructor (at, elts);
     734         3878 :   };
     735              :   /* If true, call std::ranges::data (p) and std::ranges::size (p)
     736              :      and if that works out and what the former returns can be handled,
     737              :      grab the elements from the initializer of the decl pointed by the
     738              :      first expression.  p has to be convert_from_reference (PARM_DECL)
     739              :      rather than its value, otherwise it is not considered lvalue.  */
     740         3878 :   if (contiguous_range)
     741              :     {
     742         3796 :       tree data = lookup_qualified_name (ranges_ns, "data");
     743         3796 :       tree size = lookup_qualified_name (ranges_ns, "size");
     744         3796 :       if (TREE_CODE (data) != VAR_DECL || TREE_CODE (size) != VAR_DECL)
     745              :         {
     746            0 :           error_at (loc, "%<std::ranges::data%> or %<std::ranges::size%> "
     747              :                          "are not customization point objects");
     748            0 :           *non_constant_p = true;
     749            0 :           return NULL_TREE;
     750              :         }
     751         3796 :       data = obj_call (data, tf_none);
     752         3796 :       if (error_operand_p (data))
     753            0 :         goto non_contiguous;
     754         3796 :       if (data == NULL_TREE)
     755              :         return NULL_TREE;
     756         3796 :       size = obj_call (size, tf_none);
     757         3796 :       if (error_operand_p (size))
     758           17 :         goto non_contiguous;
     759         3779 :       if (size == NULL_TREE)
     760              :         return NULL_TREE;
     761         3779 :       if (!tree_fits_uhwi_p (size) || tree_to_uhwi (size) > INT_MAX)
     762            0 :         goto non_contiguous;
     763         3779 :       if (integer_zerop (size))
     764              :         {
     765          623 :           if (kind == GET_INFO_VEC)
     766          618 :             return make_tree_vec (0);
     767            5 :           return ret_retvec ();
     768              :         }
     769         3156 :       STRIP_NOPS (data);
     770         3156 :       unsigned HOST_WIDE_INT minidx = 0, pplus = 0;
     771         3156 :       if (TREE_CODE (data) == POINTER_PLUS_EXPR
     772           12 :           && tree_fits_uhwi_p (TREE_OPERAND (data, 1))
     773         3168 :           && !wi::neg_p (wi::to_wide (TREE_OPERAND (data, 1))))
     774              :         {
     775           12 :           pplus = tree_to_uhwi (TREE_OPERAND (data, 1));
     776           12 :           data = TREE_OPERAND (data, 0);
     777           12 :           STRIP_NOPS (data);
     778              :         }
     779         3156 :       if (TREE_CODE (data) != ADDR_EXPR)
     780            0 :         goto non_contiguous;
     781         3156 :       data = TREE_OPERAND (data, 0);
     782         3156 :       if (TREE_CODE (data) == ARRAY_REF
     783         3156 :           && tree_fits_uhwi_p (TREE_OPERAND (data, 1)))
     784              :         {
     785           13 :           minidx = tree_to_uhwi (TREE_OPERAND (data, 1));
     786           13 :           data = TREE_OPERAND (data, 0);
     787              :         }
     788         3156 :       data = cxx_eval_constant_expression (ctx, data, vc_prvalue,
     789              :                                            non_constant_p, overflow_p,
     790              :                                            jump_target);
     791         3156 :       if (*jump_target || *non_constant_p)
     792              :         return NULL_TREE;
     793         3156 :       if (TREE_CODE (TREE_TYPE (data)) != ARRAY_TYPE
     794         3156 :           || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (data))) != valuet)
     795            8 :         goto non_contiguous;
     796         3148 :       if (pplus
     797         3148 :           && (pplus % tree_to_uhwi (TYPE_SIZE_UNIT (valuet))) != 0)
     798            0 :         goto non_contiguous;
     799         3148 :       minidx += pplus / tree_to_uhwi (TYPE_SIZE_UNIT (valuet));
     800         3148 :       if (kind != GET_INFO_VEC && TREE_CODE (data) == STRING_CST)
     801              :         {
     802         1729 :           unsigned esz = tree_to_uhwi (TYPE_SIZE_UNIT (valuet));
     803         1729 :           unsigned HOST_WIDE_INT sz = tree_to_uhwi (size) * esz;
     804         1729 :           if (minidx > INT_MAX
     805         1729 :               || (unsigned) TREE_STRING_LENGTH (data) < sz + minidx * esz)
     806            0 :             goto non_contiguous;
     807         1729 :           if (kind == REFLECT_CONSTANT_ARRAY && sz == 0)
     808            0 :             return ret_retvec ();
     809         1729 :           tree index
     810         3358 :             = build_index_type (size_int ((kind == REFLECT_CONSTANT_ARRAY
     811              :                                            ? -1 : 0) + tree_to_uhwi (size)));
     812         1729 :           tree at = build_array_type (valuet, index);
     813         1729 :           at = cp_build_qualified_type (at, TYPE_QUAL_CONST);
     814         1729 :           const unsigned char *q
     815         1729 :             = (const unsigned char *) TREE_STRING_POINTER (data);
     816         1729 :           q += minidx * esz;
     817         1729 :           if (kind == REFLECT_CONSTANT_ARRAY)
     818              :             {
     819              :               unsigned HOST_WIDE_INT i;
     820          265 :               for (i = 0; i < esz; ++i)
     821          167 :                 if (q[sz - esz + i])
     822              :                   break;
     823          100 :               if (i != esz)
     824              :                 {
     825              :                   /* Not a NUL terminated string.  Build a CONSTRUCTOR
     826              :                      instead.  */
     827           10 :                   for (i = 0; i < sz; i += esz)
     828              :                     {
     829            8 :                       tree t = native_interpret_expr (valuet, q + i, sz);
     830            8 :                       retvec.safe_push (t);
     831              :                     }
     832            2 :                   return ret_retvec ();
     833              :                 }
     834              :             }
     835         1727 :           char *p;
     836         1727 :           if (sz < 4096)
     837         1727 :             p = XALLOCAVEC (char, sz + esz);
     838              :           else
     839            0 :             p = XNEWVEC (char, sz + esz);
     840         1727 :           memcpy (p, q, sz);
     841         1727 :           memset (p + sz, '\0', esz);
     842         1825 :           ret = build_string (sz + (kind == REFLECT_CONSTANT_ARRAY
     843              :                                     ? 0 : esz), p);
     844         1727 :           TREE_TYPE (ret) = at;
     845         1727 :           TREE_CONSTANT (ret) = 1;
     846         1727 :           TREE_READONLY (ret) = 1;
     847         1727 :           TREE_STATIC (ret) = 1;
     848         1727 :           if (sz >= 4096)
     849            0 :             XDELETEVEC (p);
     850         1727 :           return ret;
     851              :         }
     852         1419 :       if (TREE_CODE (data) != CONSTRUCTOR)
     853            0 :         goto non_contiguous;
     854         1419 :       unsigned sz = tree_to_uhwi (size), i;
     855         1419 :       unsigned HOST_WIDE_INT j = 0;
     856         1419 :       tree *r, null = NULL_TREE;
     857         1419 :       if (kind == GET_INFO_VEC)
     858              :         {
     859         1212 :           ret = make_tree_vec (sz);
     860         1212 :           r = TREE_VEC_BEGIN (ret);
     861         1212 :           null = get_null_reflection ();
     862              :         }
     863              :       else
     864              :         {
     865          207 :           retvec.safe_grow (sz, true);
     866          207 :           r = retvec.address ();
     867              :         }
     868         4047 :       for (i = 0; i < sz; ++i)
     869         2628 :         r[i] = null;
     870              :       tree field, value;
     871         4074 :       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (data), i, field, value)
     872         2655 :         if (field == NULL_TREE)
     873              :           {
     874            0 :             if (j >= minidx && j - minidx < sz)
     875            0 :               r[j - minidx] = value;
     876            0 :             ++j;
     877              :           }
     878         2655 :         else if (TREE_CODE (field) == RANGE_EXPR)
     879              :           {
     880            0 :             tree lo = TREE_OPERAND (field, 0);
     881            0 :             tree hi = TREE_OPERAND (field, 1);
     882            0 :             if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
     883            0 :               goto non_contiguous;
     884            0 :             unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
     885            0 :             for (j = tree_to_uhwi (lo); j <= m; ++j)
     886            0 :               if (j >= minidx && j - minidx < sz)
     887            0 :                 r[j - minidx] = value;
     888              :           }
     889         2655 :         else if (tree_fits_uhwi_p (field))
     890              :           {
     891         2655 :             j = tree_to_uhwi (field);
     892         2655 :             if (j >= minidx && j - minidx < sz)
     893         2604 :               r[j - minidx] = value;
     894         2655 :             ++j;
     895              :           }
     896              :         else
     897            0 :           goto non_contiguous;
     898         1419 :       if (kind == GET_INFO_VEC)
     899              :         return ret;
     900          790 :       for (i = 0; i < sz; ++i)
     901          661 :         if (r[i] == NULL_TREE || !tree_fits_shwi_p (r[i]))
     902           78 :           goto non_contiguous;
     903          129 :       return ret_retvec ();
     904              :     }
     905           82 :  non_contiguous:
     906              :   /* Otherwise, do it the slower way.  Initialize two temporaries,
     907              :      one to std::ranges::base (p) and another to std::ranges::end (p)
     908              :      and use a loop.  */
     909          185 :   tree begin = lookup_qualified_name (ranges_ns, "begin");
     910          185 :   tree end = lookup_qualified_name (ranges_ns, "end");
     911          185 :   if (TREE_CODE (begin) != VAR_DECL || TREE_CODE (end) != VAR_DECL)
     912              :     {
     913            0 :       error_at (loc, "missing %<std::ranges::begin%> or %<std::ranges::end%>");
     914            0 :       *non_constant_p = true;
     915            0 :       return NULL_TREE;
     916              :     }
     917          185 :   begin = obj_call (begin, tf_warning_or_error);
     918          185 :   if (error_operand_p (begin))
     919              :     {
     920            0 :       *non_constant_p = true;
     921            0 :       return NULL_TREE;
     922              :     }
     923          185 :   end = obj_call (end, tf_warning_or_error);
     924          185 :   if (error_operand_p (end))
     925              :     {
     926            0 :       *non_constant_p = true;
     927            0 :       return NULL_TREE;
     928              :     }
     929          185 :   if (!CLASS_TYPE_P (TREE_TYPE (begin)) && !POINTER_TYPE_P (TREE_TYPE (begin)))
     930              :     {
     931            0 :       error_at (loc, "incorrect type %qT of %<std::ranges::begin(arg)%>",
     932            0 :                 TREE_TYPE (begin));
     933            0 :       *non_constant_p = true;
     934            0 :       return NULL_TREE;
     935              :     }
     936          185 :   if (VOID_TYPE_P (TREE_TYPE (end)))
     937              :     {
     938            0 :       error_at (loc, "incorrect type %qT of %<std::ranges::end(arg)%>",
     939            0 :                 TREE_TYPE (end));
     940            0 :       *non_constant_p = true;
     941            0 :       return NULL_TREE;
     942              :     }
     943          185 :   begin = get_target_expr (begin);
     944          185 :   end = get_target_expr (end);
     945          185 :   begin = cxx_eval_constant_expression (ctx, begin, vc_glvalue, non_constant_p,
     946              :                                         overflow_p, jump_target);
     947          185 :   if (*jump_target || *non_constant_p)
     948              :     return NULL_TREE;
     949          185 :   end = cxx_eval_constant_expression (ctx, end, vc_glvalue, non_constant_p,
     950              :                                       overflow_p, jump_target);
     951          185 :   if (*jump_target || *non_constant_p)
     952              :     return NULL_TREE;
     953          185 :   tree cmp = build_new_op (loc, NE_EXPR, LOOKUP_NORMAL, begin, end,
     954              :                            tf_warning_or_error);
     955          185 :   tree deref = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, begin,
     956              :                              NULL_TREE, tf_warning_or_error);
     957          185 :   tree inc = build_new_op (loc, PREINCREMENT_EXPR, LOOKUP_NORMAL, begin,
     958              :                            NULL_TREE, tf_warning_or_error);
     959          185 :   cmp = condition_conversion (cmp);
     960          185 :   if (error_operand_p (cmp)
     961          185 :       || error_operand_p (deref)
     962          370 :       || error_operand_p (inc))
     963              :     {
     964            0 :       *non_constant_p = true;
     965            0 :       return NULL_TREE;
     966              :     }
     967          185 :   if (TYPE_MAIN_VARIANT (TREE_TYPE (deref)) != valuet)
     968              :     {
     969            3 :       deref = perform_implicit_conversion (valuet, deref, tf_warning_or_error);
     970            3 :       if (error_operand_p (deref))
     971              :         {
     972            0 :           *non_constant_p = true;
     973            0 :           return NULL_TREE;
     974              :         }
     975            3 :       if (CLASS_TYPE_P (valuet))
     976              :         {
     977            1 :           deref = force_target_expr (valuet, deref, tf_warning_or_error);
     978            1 :           if (error_operand_p (deref))
     979              :             {
     980            0 :               *non_constant_p = true;
     981            0 :               return NULL_TREE;
     982              :             }
     983              :         }
     984              :     }
     985          185 :   deref = fold_build_cleanup_point_expr (TREE_TYPE (deref), deref);
     986          185 :   inc = fold_build_cleanup_point_expr (void_type_node, inc);
     987          185 :   retvec.truncate (0);
     988              :   /* while (begin != end) { push (*begin); ++begin; }  */
     989         1549 :   do
     990              :     {
     991          867 :       tree t = cxx_eval_constant_expression (ctx, cmp, vc_prvalue,
     992              :                                              non_constant_p, overflow_p,
     993              :                                              jump_target);
     994          867 :       if (*jump_target || *non_constant_p)
     995            0 :         return NULL_TREE;
     996          867 :       if (integer_zerop (t))
     997              :         break;
     998          682 :       t = cxx_eval_constant_expression (ctx, deref, vc_prvalue, non_constant_p,
     999              :                                         overflow_p, jump_target);
    1000          682 :       if (*jump_target || *non_constant_p)
    1001              :         return NULL_TREE;
    1002          682 :       retvec.safe_push (t);
    1003          682 :       cxx_eval_constant_expression (ctx, inc, vc_discard, non_constant_p,
    1004              :                                     overflow_p, jump_target);
    1005          682 :       if (*jump_target || *non_constant_p)
    1006              :         return NULL_TREE;
    1007          682 :     }
    1008              :   while (true);
    1009          185 :   if (kind != GET_INFO_VEC)
    1010          123 :     return ret_retvec ();
    1011           62 :   ret = make_tree_vec (retvec.length ());
    1012           62 :   tree v;
    1013           62 :   unsigned int i;
    1014         4258 :   FOR_EACH_VEC_ELT (retvec, i, v)
    1015          256 :     TREE_VEC_ELT (ret, i) = v;
    1016              :   return ret;
    1017         3878 : }
    1018              : 
    1019              : /* Extract the N-th reflection_range argument from a metafunction call CALL
    1020              :    and return it as TREE_VEC.  */
    1021              : 
    1022              : static tree
    1023         1893 : get_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
    1024              :               bool *non_constant_p, bool *overflow_p, tree *jump_target,
    1025              :               tree fun)
    1026              : {
    1027            0 :   return get_range_elts (loc, ctx, call, n, non_constant_p, overflow_p,
    1028            0 :                          jump_target, GET_INFO_VEC, fun);
    1029              : }
    1030              : 
    1031              : /* Create std::meta::exception{ what, from }.  WHAT is the string for what(),
    1032              :    and FROM is the info for from().  */
    1033              : 
    1034              : static tree
    1035         1573 : get_meta_exception_object (location_t loc, const constexpr_ctx *ctx,
    1036              :                            const char *what, tree from, bool *non_constant_p)
    1037              : {
    1038              :   /* Don't throw in a template.  */
    1039         1573 :   if (processing_template_decl)
    1040              :     {
    1041            2 :       *non_constant_p = true;
    1042            2 :       return NULL_TREE;
    1043              :     }
    1044              : 
    1045              :   /* Don't try to throw exceptions with -fno-exceptions.  */
    1046         1571 :   if (!flag_exceptions)
    1047              :     {
    1048            4 :       if (!cxx_constexpr_quiet_p (ctx))
    1049              :         {
    1050            1 :           auto_diagnostic_group d;
    1051            1 :           error_at (loc, "%qD should throw %qs; %<what()%>: %qs",
    1052              :                     from, "std::meta::exception", _(what));
    1053            1 :           inform (loc, "exceptions are disabled, treating as non-constant");
    1054            1 :         }
    1055            4 :       *non_constant_p = true;
    1056            4 :       return NULL_TREE;
    1057              :     }
    1058              : 
    1059         1567 :   tree type = lookup_qualified_name (std_meta_node, "exception",
    1060              :                                      LOOK_want::TYPE, /*complain*/true);
    1061         1567 :   if (TREE_CODE (type) != TYPE_DECL || !CLASS_TYPE_P (TREE_TYPE (type)))
    1062              :     {
    1063            0 :       error_at (loc, "couldn%'t throw %qs", "std::meta::exception");
    1064            0 :       return NULL_TREE;
    1065              :     }
    1066         1567 :   type = TREE_TYPE (type);
    1067         1567 :   vec<constructor_elt, va_gc> *elts = nullptr;
    1068         1567 :   what = _(what);
    1069              :   /* Translate what from SOURCE_CHARSET to exec charset.  */
    1070         1567 :   cpp_string istr, ostr;
    1071         1567 :   istr.len = strlen (what) + 1;
    1072         1567 :   istr.text = (const unsigned char *) what;
    1073         1567 :   if (!cpp_translate_string (parse_in, &istr, &ostr, CPP_STRING, false))
    1074              :     {
    1075            0 :       what = "";
    1076            0 :       ostr.text = NULL;
    1077              :     }
    1078              :   else
    1079         1567 :     what = (const char *) ostr.text;
    1080         1567 :   if (TREE_CODE (from) == FUNCTION_DECL && DECL_TEMPLATE_INFO (from))
    1081          438 :     from = DECL_TI_TEMPLATE (from);
    1082         1567 :   tree string_lit = build_string (strlen (what) + 1, what);
    1083         1567 :   free (const_cast <unsigned char *> (ostr.text));
    1084         1567 :   TREE_TYPE (string_lit) = char_array_type_node;
    1085         1567 :   string_lit = fix_string_type (string_lit);
    1086         1567 :   CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, string_lit);
    1087         1567 :   CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, get_reflection_raw (loc, from));
    1088         1567 :   tree ctor = build_constructor (init_list_type_node, elts);
    1089         1567 :   CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
    1090         1567 :   TREE_CONSTANT (ctor) = true;
    1091         1567 :   TREE_STATIC (ctor) = true;
    1092         1567 :   return finish_compound_literal (type, ctor, tf_warning_or_error,
    1093         1567 :                                   fcl_functional);
    1094              : }
    1095              : 
    1096              : /* Perform 'throw std::meta::exception{...}'.  MSGID is the string for what(),
    1097              :    FROM is the reflection for from().  */
    1098              : 
    1099              : static tree
    1100         1573 : throw_exception (location_t loc, const constexpr_ctx *ctx, const char *msgid,
    1101              :                  tree from, bool *non_constant_p, tree *jump_target)
    1102              : {
    1103         1573 :   if (tree obj = get_meta_exception_object (loc, ctx, msgid, from,
    1104              :                                             non_constant_p))
    1105         1567 :     *jump_target = cxa_allocate_and_throw_exception (loc, ctx, obj);
    1106         1573 :   return NULL_TREE;
    1107              : }
    1108              : 
    1109              : /* Wrapper around throw_exception to complain that the reflection does not
    1110              :    represent a type.  */
    1111              : 
    1112              : static tree
    1113          387 : throw_exception_nontype (location_t loc, const constexpr_ctx *ctx,
    1114              :                          tree from, bool *non_constant_p, tree *jump_target)
    1115              : {
    1116            0 :   return throw_exception (loc, ctx,
    1117              :                           "reflection does not represent a type",
    1118            0 :                           from, non_constant_p, jump_target);
    1119              : }
    1120              : 
    1121              : /* Wrapper around throw_exception to complain that the reflection does not
    1122              :    represent something that satisfies has_template_arguments.  */
    1123              : 
    1124              : static tree
    1125            1 : throw_exception_notargs (location_t loc, const constexpr_ctx *ctx,
    1126              :                          tree from, bool *non_constant_p, tree *jump_target)
    1127              : {
    1128            0 :   return throw_exception (loc, ctx,
    1129              :                           "reflection does not have template arguments",
    1130            0 :                           from, non_constant_p, jump_target);
    1131              : }
    1132              : 
    1133              : /* Wrapper around throw_exception to complain that the reflection does not
    1134              :    represent a function or a function type.  */
    1135              : 
    1136              : static tree
    1137            6 : throw_exception_nofn (location_t loc, const constexpr_ctx *ctx,
    1138              :                       tree from, bool *non_constant_p, tree *jump_target)
    1139              : {
    1140            0 :   return throw_exception (loc, ctx, "reflection does not represent a "
    1141              :                                     "function or function type",
    1142            0 :                           from, non_constant_p, jump_target);
    1143              : }
    1144              : 
    1145              : /* The values of std::meta::operators enumerators corresponding to
    1146              :    the ovl_op_code and IDENTIFIER_ASSIGN_OP_P pair.  */
    1147              : 
    1148              : static unsigned char meta_operators[2][OVL_OP_MAX];
    1149              : 
    1150              : /* Init the meta_operators table if not yet initialized.  */
    1151              : 
    1152              : static void
    1153          296 : maybe_init_meta_operators (location_t loc)
    1154              : {
    1155          296 :   if (meta_operators[0][OVL_OP_ERROR_MARK])
    1156          288 :     return;
    1157            8 :   meta_operators[0][OVL_OP_ERROR_MARK] = 1;
    1158            8 :   tree operators = lookup_qualified_name (std_meta_node, "operators");
    1159            8 :   if (TREE_CODE (operators) != TYPE_DECL
    1160            8 :       || TREE_CODE (TREE_TYPE (operators)) != ENUMERAL_TYPE)
    1161              :     {
    1162            0 :     fail:
    1163            0 :       error_at (loc, "unexpected %<std::meta::operators%>");
    1164            0 :       return;
    1165              :     }
    1166            8 :   char buf[sizeof "op_greater_greater_equals"];
    1167            8 :   memcpy (buf, "op_", 3);
    1168           24 :   for (int i = 0; i < 2; ++i)
    1169          928 :     for (int j = OVL_OP_ERROR_MARK + 1; j < OVL_OP_MAX; ++j)
    1170          912 :       if (ovl_op_info[i][j].meta_name)
    1171              :         {
    1172          400 :           strcpy (buf + 3, ovl_op_info[i][j].meta_name);
    1173          400 :           tree id = get_identifier (buf);
    1174          400 :           tree t = lookup_enumerator (TREE_TYPE (operators), id);
    1175          400 :           if (t == NULL_TREE || TREE_CODE (t) != CONST_DECL)
    1176            0 :             goto fail;
    1177          400 :           tree v = DECL_INITIAL (t);
    1178          400 :           if (!tree_fits_uhwi_p (v) || tree_to_uhwi (v) > UCHAR_MAX)
    1179            0 :             goto fail;
    1180          400 :           meta_operators[i][j] = tree_to_uhwi (v);
    1181              :         }
    1182              : }
    1183              : 
    1184              : /* Process std::meta::is_variable.
    1185              :    Returns: true if r represents a variable.  Otherwise, false.  */
    1186              : 
    1187              : static tree
    1188         7058 : eval_is_variable (const_tree r, reflect_kind kind)
    1189              : {
    1190              :   /* ^^param is a variable but parameters_of(parent_of(^^param))[0] is not.  */
    1191          246 :   if ((TREE_CODE (r) == PARM_DECL && kind != REFLECT_PARM)
    1192         6911 :       || (VAR_P (r)
    1193         2058 :           && kind == REFLECT_UNDEF
    1194              :           /* A structured binding is not a variable.  */
    1195         1920 :           && !(DECL_DECOMPOSITION_P (r) && !DECL_DECOMP_IS_BASE (r)))
    1196        12102 :       || (VAR_P (r)
    1197              :           /* Underlying variable of tuple using structured binding is a
    1198              :              variable.  */
    1199          191 :           && kind == REFLECT_VAR
    1200           30 :           && DECL_DECOMPOSITION_P (r)
    1201           30 :           && !DECL_DECOMP_IS_BASE (r)))
    1202         2044 :     return boolean_true_node;
    1203              :   else
    1204         5014 :     return boolean_false_node;
    1205              : }
    1206              : 
    1207              : /* Process std::meta::is_type.
    1208              :    Returns: true if r represents an entity whose underlying entity is
    1209              :    a type.  Otherwise, false.  */
    1210              : 
    1211              : static tree
    1212        10291 : eval_is_type (const_tree r)
    1213              : {
    1214              :   /* Null reflection isn't a type.  */
    1215        10291 :   if (TYPE_P (r) && r != unknown_type_node)
    1216         7837 :     return boolean_true_node;
    1217              :   else
    1218         2454 :     return boolean_false_node;
    1219              : }
    1220              : 
    1221              : /* Process std::meta::is_type_alias.
    1222              :    Returns: true if r represents a type alias.  Otherwise, false.  */
    1223              : 
    1224              : static tree
    1225         1690 : eval_is_type_alias (const_tree r)
    1226              : {
    1227         1690 :   if (TYPE_P (r) && typedef_variant_p (r))
    1228           62 :     return boolean_true_node;
    1229              :   else
    1230         1628 :     return boolean_false_node;
    1231              : }
    1232              : 
    1233              : /* Process std::meta::is_namespace.
    1234              :    Returns: true if r represents an entity whose underlying entity is
    1235              :    a namespace.  Otherwise, false.  */
    1236              : 
    1237              : static tree
    1238          741 : eval_is_namespace (const_tree r)
    1239              : {
    1240          482 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    1241           67 :     return boolean_true_node;
    1242              :   else
    1243          535 :     return boolean_false_node;
    1244              : }
    1245              : 
    1246              : /* Process std::meta::is_namespace_alias.
    1247              :    Returns: true if r represents a namespace alias.  Otherwise, false.  */
    1248              : 
    1249              : static tree
    1250          259 : eval_is_namespace_alias (const_tree r)
    1251              : {
    1252          259 :   if (TREE_CODE (r) == NAMESPACE_DECL && DECL_NAMESPACE_ALIAS (r))
    1253           11 :     return boolean_true_node;
    1254              :   else
    1255          248 :     return boolean_false_node;
    1256              : }
    1257              : 
    1258              : /* Process std::meta::is_function.
    1259              :    Returns: true if r represents a function.  Otherwise, false.  */
    1260              : 
    1261              : static tree
    1262         3696 : eval_is_function (tree r)
    1263              : {
    1264         3696 :   r = maybe_get_first_fn (r);
    1265              : 
    1266         3696 :   if (TREE_CODE (r) == FUNCTION_DECL)
    1267         1011 :     return boolean_true_node;
    1268              :   else
    1269         2685 :     return boolean_false_node;
    1270              : }
    1271              : 
    1272              : /* Process std::meta::is_function_template.
    1273              :    Returns: true if r represents a function template.  Otherwise, false.  */
    1274              : 
    1275              : static tree
    1276         2619 : eval_is_function_template (tree r)
    1277              : {
    1278         2619 :   r = maybe_get_first_fn (r);
    1279              : 
    1280         2619 :   if (DECL_FUNCTION_TEMPLATE_P (r))
    1281           84 :     return boolean_true_node;
    1282              : 
    1283         2535 :   return boolean_false_node;
    1284              : }
    1285              : 
    1286              : /* Process std::meta::is_variable_template.
    1287              :    Returns: true if r represents a variable template.  Otherwise, false.  */
    1288              : 
    1289              : static tree
    1290         2365 : eval_is_variable_template (tree r)
    1291              : {
    1292         2365 :   if (variable_template_p (r))
    1293           56 :     return boolean_true_node;
    1294              :   else
    1295         2309 :     return boolean_false_node;
    1296              : }
    1297              : 
    1298              : /* Process std::meta::is_class_template.
    1299              :    Returns: true if r represents a class template.  Otherwise, false.  */
    1300              : 
    1301              : static tree
    1302         2562 : eval_is_class_template (const_tree r)
    1303              : {
    1304         2562 :   if (DECL_CLASS_TEMPLATE_P (r))
    1305          185 :     return boolean_true_node;
    1306              :   else
    1307         2377 :     return boolean_false_node;
    1308              : }
    1309              : 
    1310              : /* Process std::meta::is_alias_template.
    1311              :    Returns: true if r represents an alias template.  Otherwise, false.  */
    1312              : 
    1313              : static tree
    1314         2311 : eval_is_alias_template (const_tree r)
    1315              : {
    1316         2311 :   if (DECL_ALIAS_TEMPLATE_P (r))
    1317           38 :     return boolean_true_node;
    1318              :   else
    1319         2273 :     return boolean_false_node;
    1320              : }
    1321              : 
    1322              : /* Process std::meta::is_concept.
    1323              :    Returns: true if r represents a concept.  Otherwise, false.  */
    1324              : 
    1325              : static tree
    1326         2339 : eval_is_concept (const_tree r)
    1327              : {
    1328         2420 :   if (concept_definition_p (r))
    1329            6 :     return boolean_true_node;
    1330              :   else
    1331         2245 :     return boolean_false_node;
    1332              : }
    1333              : 
    1334              : /* Process std::meta::is_object.
    1335              :    Returns: true if r represents an object.  Otherwise, false.  */
    1336              : 
    1337              : static tree
    1338         1569 : eval_is_object (reflect_kind kind)
    1339              : {
    1340          683 :   if (kind == REFLECT_OBJECT)
    1341           43 :     return boolean_true_node;
    1342              :   else
    1343         1406 :     return boolean_false_node;
    1344              : }
    1345              : 
    1346              : /* Process std::meta::is_value.
    1347              :    Returns: true if r represents a value.  Otherwise, false.  */
    1348              : 
    1349              : static tree
    1350         1197 : eval_is_value (reflect_kind kind)
    1351              : {
    1352          461 :   if (kind == REFLECT_VALUE)
    1353           34 :     return boolean_true_node;
    1354              :   else
    1355         1121 :     return boolean_false_node;
    1356              : }
    1357              : 
    1358              : /* Like get_info_vec, but throw exception if any of the elements aren't
    1359              :    eval_is_type reflections and change their content to the corresponding
    1360              :    REFLECT_EXPR_HANDLE.  */
    1361              : 
    1362              : static tree
    1363         1071 : get_type_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
    1364              :                    bool *non_constant_p, bool *overflow_p, tree *jump_target,
    1365              :                    tree fun)
    1366              : {
    1367         1071 :   tree vec = get_info_vec (loc, ctx, call, n, non_constant_p, overflow_p,
    1368              :                            jump_target, fun);
    1369         1071 :   if (*jump_target || *non_constant_p)
    1370              :     return NULL_TREE;
    1371         2623 :   for (int i = 0; i < TREE_VEC_LENGTH (vec); i++)
    1372              :     {
    1373         1568 :       tree type = REFLECT_EXPR_HANDLE (TREE_VEC_ELT (vec, i));
    1374         1568 :       if (eval_is_type (type) != boolean_true_node)
    1375           16 :         return throw_exception_nontype (loc, ctx, fun, non_constant_p,
    1376           16 :                                         jump_target);
    1377         1552 :       TREE_VEC_ELT (vec, i) = type;
    1378              :     }
    1379              :   return vec;
    1380              : }
    1381              : 
    1382              : /* Process std::meta::is_structured_binding.
    1383              :    Returns: true if r represents a structured binding.  Otherwise, false.  */
    1384              : 
    1385              : static tree
    1386          695 : eval_is_structured_binding (const_tree r, reflect_kind kind)
    1387              : {
    1388           52 :   if (DECL_DECOMPOSITION_P (r)
    1389           48 :       && !DECL_DECOMP_IS_BASE (r)
    1390          740 :       && kind != REFLECT_VAR)
    1391           37 :     return boolean_true_node;
    1392              :   else
    1393          658 :     return boolean_false_node;
    1394              : }
    1395              : 
    1396              : /* Process std::meta::is_class_member.
    1397              :    Returns: true if r represents a class member.  Otherwise, false.  */
    1398              : 
    1399              : static tree
    1400        38601 : eval_is_class_member (tree r)
    1401              : {
    1402        38601 :   r = maybe_get_first_fn (r);
    1403        38601 :   if (TREE_CODE (r) == CONST_DECL)
    1404              :     {
    1405              :       /* [class.mem.general]/5 - The enumerators of an unscoped enumeration
    1406              :          defined in the class are members of the class.  */
    1407           93 :       if (UNSCOPED_ENUM_P (DECL_CONTEXT (r)))
    1408           69 :         r = DECL_CONTEXT (r);
    1409              :       else
    1410           24 :         return boolean_false_node;
    1411              :     }
    1412        38508 :   else if (TYPE_P (r) && typedef_variant_p (r))
    1413         1610 :     r = TYPE_NAME (r);
    1414        38577 :   if (DECL_P (r) && DECL_CLASS_SCOPE_P (r))
    1415        35816 :     return boolean_true_node;
    1416         2761 :   else if (TYPE_P (r) && TYPE_CLASS_SCOPE_P (r))
    1417         1098 :     return boolean_true_node;
    1418              :   else
    1419         1663 :     return boolean_false_node;
    1420              : }
    1421              : 
    1422              : /* For direct base class relationship R return the binfo related
    1423              :    to the derived type.  */
    1424              : 
    1425              : static tree
    1426         1771 : direct_base_derived_binfo (tree r)
    1427              : {
    1428              :   /* Looping needed for multiple virtual inheritance.  */
    1429         3563 :   while (BINFO_INHERITANCE_CHAIN (r))
    1430              :     r = BINFO_INHERITANCE_CHAIN (r);
    1431         1771 :   return r;
    1432              : }
    1433              : 
    1434              : /* For direct base class relationship R return the derived type
    1435              :    (i.e. when R is (D, B) it returns D).  */
    1436              : 
    1437              : tree
    1438         1738 : direct_base_derived (tree r)
    1439              : {
    1440         1738 :   return BINFO_TYPE (direct_base_derived_binfo (r));
    1441              : }
    1442              : 
    1443              : /* Helper function for eval_is_{public, protected, private}.  */
    1444              : 
    1445              : static tree
    1446          219 : eval_is_expected_access (tree r, reflect_kind kind, tree expected_access)
    1447              : {
    1448          219 :   if (eval_is_class_member (r) == boolean_true_node)
    1449              :     {
    1450          193 :       r = maybe_get_first_fn (r);
    1451              : 
    1452          193 :       if (TYPE_P (r))
    1453              :         {
    1454           45 :           if (TYPE_NAME (r) == NULL_TREE || !DECL_P (TYPE_NAME (r)))
    1455            0 :             return boolean_false_node;
    1456           45 :           r = TYPE_NAME (r);
    1457              :         }
    1458              : 
    1459          193 :       bool matches = false;
    1460          193 :       if (expected_access == access_private_node)
    1461           55 :         matches = TREE_PRIVATE (r);
    1462          138 :       else if (expected_access == access_protected_node)
    1463           60 :         matches = TREE_PROTECTED (r);
    1464           78 :       else if (expected_access == access_public_node)
    1465           78 :         matches = !(TREE_PRIVATE (r) || TREE_PROTECTED (r));
    1466              :       else
    1467            0 :         gcc_unreachable ();
    1468              : 
    1469          115 :       if (matches)
    1470              :         return boolean_true_node;
    1471              :       else
    1472          106 :         return boolean_false_node;
    1473              :     }
    1474              : 
    1475           26 :   if (kind == REFLECT_BASE)
    1476              :     {
    1477            5 :       gcc_assert (TREE_CODE (r) == TREE_BINFO);
    1478            5 :       tree c = direct_base_derived_binfo (r);
    1479              : 
    1480            5 :       tree base_binfo;
    1481           15 :       for (unsigned ix = 0; BINFO_BASE_ITERATE (c, ix, base_binfo); ix++)
    1482           15 :         if (base_binfo == r)
    1483              :           {
    1484            5 :             tree access = BINFO_BASE_ACCESS (c, ix);
    1485            5 :             if (access == expected_access)
    1486              :               return boolean_true_node;
    1487              :             else
    1488            0 :               return boolean_false_node;
    1489              :           }
    1490            0 :       gcc_unreachable ();
    1491              :     }
    1492              : 
    1493           21 :   return boolean_false_node;
    1494              : }
    1495              : 
    1496              : /* Process std::meta::is_public.
    1497              :    Returns: true if r represents either:
    1498              :    - a class member or unnamed bit-field that is public or
    1499              :    - a direct base class relationship (D, B) for which
    1500              :    B is a public base class of D.
    1501              :    Otherwise, false.  */
    1502              : 
    1503              : static tree
    1504           86 : eval_is_public (tree r, reflect_kind kind)
    1505              : {
    1506            0 :   return eval_is_expected_access (r, kind, access_public_node);
    1507              : }
    1508              : 
    1509              : /* Process std::meta::is_protected.
    1510              :    Returns: true if r represents either:
    1511              :    - a class member or unnamed bit-field that is protected, or
    1512              :    - a direct base class relationship (D, B) for which
    1513              :    B is a protected base class of D.
    1514              :    Otherwise, false.  */
    1515              : 
    1516              : static tree
    1517           69 : eval_is_protected (tree r, reflect_kind kind)
    1518              : {
    1519            0 :   return eval_is_expected_access (r, kind, access_protected_node);
    1520              : }
    1521              : 
    1522              : /* Process std::meta::is_private
    1523              :    Returns: true if r represents either:
    1524              :    - a class member or unnamed bit-field that is private, or
    1525              :    - a direct base class relationship (D, B) for which
    1526              :    B is a private base class of D.
    1527              :    Otherwise, false.  */
    1528              : 
    1529              : static tree
    1530           64 : eval_is_private (tree r, reflect_kind kind)
    1531              : {
    1532            0 :   return eval_is_expected_access (r, kind, access_private_node);
    1533              : }
    1534              : 
    1535              : /* Process std::meta::is_virtual.
    1536              :    Returns: true if r represents either a virtual member function or a direct
    1537              :    base class relationship (D,B) for which B is a virtual base class of D.
    1538              :    Otherwise, false.  */
    1539              : 
    1540              : static tree
    1541           17 : eval_is_virtual (tree r, reflect_kind kind)
    1542              : {
    1543           17 :   r = maybe_get_first_fn (r);
    1544           17 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_VIRTUAL_P (r))
    1545           11 :     return boolean_true_node;
    1546              : 
    1547            8 :   if (kind == REFLECT_BASE && BINFO_VIRTUAL_P (r))
    1548            1 :     return boolean_true_node;
    1549              : 
    1550            5 :   return boolean_false_node;
    1551              : }
    1552              : 
    1553              : /* Process std::meta::is_pure_virtual.
    1554              :    Returns: true if r represents a member function that is pure virtual.
    1555              :    Otherwise, false.  */
    1556              : 
    1557              : static tree
    1558           14 : eval_is_pure_virtual (tree r)
    1559              : {
    1560           14 :   r = maybe_get_first_fn (r);
    1561           14 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (r))
    1562            3 :     return boolean_true_node;
    1563              :   else
    1564           11 :     return boolean_false_node;
    1565              : }
    1566              : 
    1567              : /* Helper function for eval_is_override, return true if FNDECL in TYPE
    1568              :    overrides another function.  */
    1569              : 
    1570              : static bool
    1571           21 : is_override (tree type, tree fndecl)
    1572              : {
    1573           21 :   tree binfo = TYPE_BINFO (type), base_binfo;
    1574              : 
    1575           22 :   for (unsigned ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    1576              :     {
    1577           10 :       tree basetype = BINFO_TYPE (base_binfo);
    1578           10 :       if (TYPE_POLYMORPHIC_P (basetype))
    1579              :         {
    1580           10 :           if (look_for_overrides_here (basetype, fndecl))
    1581              :             return true;
    1582            1 :           if (is_override (basetype, fndecl))
    1583              :             return true;
    1584              :         }
    1585              :     }
    1586              :   return false;
    1587              : }
    1588              : 
    1589              : /* Process std::meta::is_override.
    1590              :    Returns: true if r represents a member function that overrides another
    1591              :    member function.  Otherwise, false.  */
    1592              : 
    1593              : static tree
    1594           70 : eval_is_override (tree r)
    1595              : {
    1596           70 :   r = maybe_get_first_fn (r);
    1597           70 :   if (TREE_CODE (r) == FUNCTION_DECL
    1598           27 :       && DECL_VIRTUAL_P (r)
    1599           20 :       && !DECL_STATIC_FUNCTION_P (r)
    1600           90 :       && is_override (DECL_CONTEXT (r), r))
    1601            9 :     return boolean_true_node;
    1602           61 :   return boolean_false_node;
    1603              : }
    1604              : 
    1605              : /* Process std::meta::is_namespace_member.
    1606              :    Returns: true if r represents a namespace member.  Otherwise, false.  */
    1607              : 
    1608              : static tree
    1609           71 : eval_is_namespace_member (tree r)
    1610              : {
    1611           71 :   r = maybe_get_first_fn (r);
    1612           71 :   if (TREE_CODE (r) == CONST_DECL)
    1613              :     {
    1614           11 :       if (UNSCOPED_ENUM_P (DECL_CONTEXT (r)))
    1615            8 :         r = DECL_CONTEXT (r);
    1616              :       else
    1617            3 :         return boolean_false_node;
    1618              :     }
    1619           60 :   else if (TYPE_P (r) && typedef_variant_p (r))
    1620            3 :     r = TYPE_NAME (r);
    1621           68 :   if (r == global_namespace || r == unknown_type_node)
    1622            2 :     return boolean_false_node;
    1623           85 :   if (DECL_P (r) && DECL_NAMESPACE_SCOPE_P (r))
    1624           27 :     return boolean_true_node;
    1625           47 :   else if (TYPE_P (r) && TYPE_NAMESPACE_SCOPE_P (r))
    1626           10 :     return boolean_true_node;
    1627              :   else
    1628           29 :     return boolean_false_node;
    1629              : }
    1630              : 
    1631              : /* Process std::meta::is_nonstatic_data_member.
    1632              :    Returns: true if r represents a non-static data member.
    1633              :    Otherwise, false.  */
    1634              : 
    1635              : static tree
    1636         4759 : eval_is_nonstatic_data_member (const_tree r)
    1637              : {
    1638         4759 :   if (TREE_CODE (r) == FIELD_DECL && !DECL_UNNAMED_BIT_FIELD (r))
    1639          919 :     return boolean_true_node;
    1640              :   else
    1641         3840 :     return boolean_false_node;
    1642              : }
    1643              : 
    1644              : /* Process std::meta::is_static_member.
    1645              :    Returns: true if r represents a static member.
    1646              :    Otherwise, false.  */
    1647              : 
    1648              : static tree
    1649           68 : eval_is_static_member (tree r)
    1650              : {
    1651           68 :   r = maybe_get_first_fn (r);
    1652           68 :   r = STRIP_TEMPLATE (r);
    1653           68 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (r))
    1654            4 :     return boolean_true_node;
    1655           64 :   else if (VAR_P (r) && DECL_CLASS_SCOPE_P (r))
    1656            1 :     return boolean_true_node;
    1657              :   else
    1658           63 :     return boolean_false_node;
    1659              : }
    1660              : 
    1661              : /* Process std::meta::is_base.
    1662              :    Returns: true if r represents a direct base class relationship.
    1663              :    Otherwise, false.  */
    1664              : 
    1665              : static tree
    1666          112 : eval_is_base (tree r, reflect_kind kind)
    1667              : {
    1668          112 :   if (kind == REFLECT_BASE)
    1669              :     {
    1670           54 :       gcc_assert (TREE_CODE (r) == TREE_BINFO);
    1671           54 :       return boolean_true_node;
    1672              :     }
    1673              :   else
    1674           58 :     return boolean_false_node;
    1675              : }
    1676              : 
    1677              : /* Process std::meta::has_default_member_initializer.
    1678              :    Returns: true if r represents a non-static data member that has a default
    1679              :    member initializer.  Otherwise, false.  */
    1680              : 
    1681              : static tree
    1682           64 : eval_has_default_member_initializer (const_tree r)
    1683              : {
    1684           64 :   if (TREE_CODE (r) == FIELD_DECL
    1685            5 :       && !DECL_UNNAMED_BIT_FIELD (r)
    1686           69 :       && DECL_INITIAL (r) != NULL_TREE)
    1687            2 :     return boolean_true_node;
    1688              :   else
    1689           62 :     return boolean_false_node;
    1690              : }
    1691              : 
    1692              : /* Process std::meta::has_static_storage_duration.
    1693              :    Returns: true if r represents an object or variable that has static
    1694              :    storage duration.  Otherwise, false.  */
    1695              : 
    1696              : static tree
    1697          139 : eval_has_static_storage_duration (const_tree r, reflect_kind kind)
    1698              : {
    1699          139 :   if (eval_is_variable (r, kind) == boolean_true_node
    1700          139 :       && decl_storage_duration (const_cast<tree> (r)) == dk_static)
    1701           49 :     return boolean_true_node;
    1702              :   /* This includes DECL_NTTP_OBJECT_P objects.  */
    1703          180 :   else if (eval_is_object (kind) == boolean_true_node)
    1704              :     return boolean_true_node;
    1705              :   else
    1706           85 :     return boolean_false_node;
    1707              : }
    1708              : 
    1709              : /* Process std::meta::has_thread_storage_duration.
    1710              :    Returns: true if r represents an object or variable that has thread
    1711              :    storage duration.  Otherwise, false.  */
    1712              : 
    1713              : static tree
    1714           70 : eval_has_thread_storage_duration (const_tree r, reflect_kind kind)
    1715              : {
    1716           70 :   if (eval_is_variable (r, kind) == boolean_true_node
    1717           70 :       && decl_storage_duration (const_cast<tree> (r)) == dk_thread)
    1718            4 :     return boolean_true_node;
    1719              :   else
    1720           66 :     return boolean_false_node;
    1721              : }
    1722              : 
    1723              : /* Process std::meta::has_automatic_storage_duration.
    1724              :    Returns: true if r represents an object or variable that has automatic
    1725              :    storage duration.  Otherwise, false.  */
    1726              : 
    1727              : static tree
    1728           70 : eval_has_automatic_storage_duration (const_tree r, reflect_kind kind)
    1729              : {
    1730           70 :   if (eval_is_variable (r, kind) == boolean_true_node
    1731           70 :       && decl_storage_duration (const_cast<tree> (r)) == dk_auto)
    1732            4 :     return boolean_true_node;
    1733              :   else
    1734           66 :     return boolean_false_node;
    1735              : }
    1736              : 
    1737              : /* Process std::meta::is_mutable_member.
    1738              :    Returns: true if r represents a mutable non-static data member.
    1739              :    Otherwise, false.  */
    1740              : 
    1741              : static tree
    1742           64 : eval_is_mutable_member (tree r)
    1743              : {
    1744           64 :   if (TREE_CODE (r) == FIELD_DECL
    1745            6 :       && !DECL_UNNAMED_BIT_FIELD (r)
    1746           70 :       && DECL_MUTABLE_P (r))
    1747            3 :     return boolean_true_node;
    1748              :   else
    1749           61 :     return boolean_false_node;
    1750              : }
    1751              : 
    1752              : /* Process std::meta::is_template.
    1753              :    Returns: true if r represents a function template, class template, variable
    1754              :    template, alias template, or concept.  Otherwise, false.  */
    1755              : 
    1756              : static tree
    1757         2385 : eval_is_template (tree r)
    1758              : {
    1759         2385 :   if (eval_is_function_template (r) == boolean_true_node
    1760         2321 :       || eval_is_class_template (r) == boolean_true_node
    1761         2154 :       || eval_is_variable_template (r) == boolean_true_node
    1762         2109 :       || eval_is_alias_template (r) == boolean_true_node
    1763         4466 :       || eval_is_concept (r) == boolean_true_node)
    1764              :     return boolean_true_node;
    1765              :   else
    1766         2000 :     return boolean_false_node;
    1767              : }
    1768              : 
    1769              : /* Process std::meta::is_function_parameter.
    1770              :    Returns: true if r represents a function parameter.  Otherwise, false.  */
    1771              : 
    1772              : static tree
    1773         2166 : eval_is_function_parameter (const_tree r, reflect_kind kind)
    1774              : {
    1775         2166 :   if (kind == REFLECT_PARM)
    1776              :     {
    1777          374 :       gcc_checking_assert (TREE_CODE (r) == PARM_DECL);
    1778          374 :       return boolean_true_node;
    1779              :     }
    1780              :   else
    1781         1792 :     return boolean_false_node;
    1782              : }
    1783              : 
    1784              : /* Process std::meta::is_data_member_spec.
    1785              :    Returns: true if r represents a data member description.
    1786              :    Otherwise, false.  */
    1787              : 
    1788              : static tree
    1789           99 : eval_is_data_member_spec (const_tree r, reflect_kind kind)
    1790              : {
    1791           99 :   if (kind == REFLECT_DATA_MEMBER_SPEC)
    1792              :     {
    1793           50 :       gcc_checking_assert (TREE_CODE (r) == TREE_VEC);
    1794           50 :       return boolean_true_node;
    1795              :     }
    1796              :   else
    1797           49 :     return boolean_false_node;
    1798              : }
    1799              : 
    1800              : /* Process std::meta::is_explicit_object_parameter.
    1801              :    Returns: true if r represents a function parameter that is an explicit
    1802              :    object parameter.  Otherwise, false.  */
    1803              : 
    1804              : static tree
    1805           73 : eval_is_explicit_object_parameter (const_tree r, reflect_kind kind)
    1806              : {
    1807           73 :   if (eval_is_function_parameter (r, kind) == boolean_true_node
    1808            8 :       && r == DECL_ARGUMENTS (DECL_CONTEXT (r))
    1809           75 :       && DECL_XOBJ_MEMBER_FUNCTION_P (DECL_CONTEXT (r)))
    1810              :     return boolean_true_node;
    1811              :   else
    1812           71 :     return boolean_false_node;
    1813              : }
    1814              : 
    1815              : /* Process std::meta::has_default_argument.
    1816              :    Returns: If r represents a parameter P of a function F, then:
    1817              :    -- If F is a specialization of a templated function T, then true if there
    1818              :       exists a declaration D of T that precedes some point in the evaluation
    1819              :       context and D specifies a default argument for the parameter of T
    1820              :       corresponding to P.  Otherwise, false.
    1821              :    -- Otherwise, if there exists a declaration D of F that precedes some
    1822              :       point in the evaluation context and D specifies a default argument
    1823              :       for P, then true.
    1824              :    Otherwise, false.  */
    1825              : 
    1826              : static tree
    1827           79 : eval_has_default_argument (tree r, reflect_kind kind)
    1828              : {
    1829           79 :   if (eval_is_function_parameter (r, kind) == boolean_false_node)
    1830              :     return boolean_false_node;
    1831           30 :   r = maybe_update_function_parm (r);
    1832           30 :   if (DECL_HAS_DEFAULT_ARGUMENT_P (r))
    1833            4 :     return boolean_true_node;
    1834           26 :   tree fn = DECL_CONTEXT (r);
    1835           26 :   tree args = FUNCTION_FIRST_USER_PARM (fn);
    1836           26 :   tree types = FUNCTION_FIRST_USER_PARMTYPE (fn);
    1837           66 :   while (r != args)
    1838              :     {
    1839           14 :       args = DECL_CHAIN (args);
    1840           14 :       types = TREE_CHAIN (types);
    1841              :     }
    1842           26 :   if (TREE_PURPOSE (types))
    1843           17 :     return boolean_true_node;
    1844              :   else
    1845            9 :     return boolean_false_node;
    1846              : }
    1847              : 
    1848              : /* Process std::meta::is_vararg_function.
    1849              :    Returns: true if r represents a function or function type that
    1850              :    is a vararg function.  Otherwise, false.  */
    1851              : 
    1852              : static tree
    1853           72 : eval_is_vararg_function (tree r)
    1854              : {
    1855           72 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    1856           72 :   if (TREE_CODE (r) == FUNCTION_DECL)
    1857           16 :     r = TREE_TYPE (r);
    1858           72 :   if (FUNC_OR_METHOD_TYPE_P (r) && stdarg_p (r))
    1859           12 :     return boolean_true_node;
    1860              :   else
    1861           60 :     return boolean_false_node;
    1862              : }
    1863              : 
    1864              : /* Process std::meta::is_deleted.
    1865              :    Returns: true if r represents a function that is deleted.
    1866              :    Otherwise, false.  */
    1867              : 
    1868              : static tree
    1869           82 : eval_is_deleted (tree r)
    1870              : {
    1871           82 :   r = maybe_get_first_fn (r);
    1872           82 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_MAYBE_DELETED (r))
    1873              :     {
    1874            2 :       ++function_depth;
    1875            2 :       maybe_synthesize_method (r);
    1876            2 :       --function_depth;
    1877              :     }
    1878           82 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_DELETED_FN (r))
    1879           20 :     return boolean_true_node;
    1880              :   else
    1881           62 :     return boolean_false_node;
    1882              : }
    1883              : 
    1884              : /* Process std::meta::is_defaulted.
    1885              :    Returns: true if r represents a function that is defaulted.
    1886              :    Otherwise, false.  */
    1887              : 
    1888              : static tree
    1889          347 : eval_is_defaulted (tree r)
    1890              : {
    1891          347 :   r = maybe_get_first_fn (r);
    1892          347 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_DEFAULTED_FN (r))
    1893          275 :     return boolean_true_node;
    1894              :   else
    1895           72 :     return boolean_false_node;
    1896              : }
    1897              : 
    1898              : /* Process std::meta::is_user_provided.
    1899              :    Returns: true if r represents a function that is user-provided.
    1900              :    Otherwise, false.  */
    1901              : 
    1902              : static tree
    1903          106 : eval_is_user_provided (tree r)
    1904              : {
    1905          106 :   r = maybe_get_first_fn (r);
    1906          106 :   if (TREE_CODE (r) == FUNCTION_DECL && user_provided_p (r))
    1907           12 :     return boolean_true_node;
    1908              :   else
    1909           94 :     return boolean_false_node;
    1910              : }
    1911              : 
    1912              : /* Process std::meta::is_user_declared.
    1913              :    Returns: true if r represents a function that is user-declared.
    1914              :    Otherwise, false.  */
    1915              : 
    1916              : static tree
    1917          106 : eval_is_user_declared (tree r)
    1918              : {
    1919          106 :   r = maybe_get_first_fn (r);
    1920          106 :   if (TREE_CODE (r) == FUNCTION_DECL && !DECL_ARTIFICIAL (r))
    1921           40 :     return boolean_true_node;
    1922              :   else
    1923           66 :     return boolean_false_node;
    1924              : }
    1925              : 
    1926              : /* Process std::meta::is_explicit.
    1927              :    Returns: true if r represents
    1928              :    a member function that is declared explicit.
    1929              :    Otherwise, false.
    1930              :    If r represents a member function template
    1931              :    that is declared explicit, is_explicit(r)
    1932              :    is still false because in general such queries
    1933              :    for templates cannot be answered.  */
    1934              : 
    1935              : static tree
    1936           22 : eval_is_explicit (tree r)
    1937              : {
    1938           22 :   r = maybe_get_first_fn (r);
    1939              : 
    1940           22 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_NONCONVERTING_P (r))
    1941            4 :     return boolean_true_node;
    1942              :   else
    1943           18 :     return boolean_false_node;
    1944              : }
    1945              : 
    1946              : /* Process std::meta::is_bit_field.
    1947              :    Returns: true if r represents a bit-field, or if r represents a data member
    1948              :    description (T,N,A,W,NUA,ANN) for which W is not _|_.  Otherwise, false.  */
    1949              : 
    1950              : static tree
    1951          110 : eval_is_bit_field (const_tree r, reflect_kind kind)
    1952              : {
    1953          110 :   if (TREE_CODE (r) == FIELD_DECL && DECL_C_BIT_FIELD (r))
    1954           36 :     return boolean_true_node;
    1955           74 :   else if (kind == REFLECT_DATA_MEMBER_SPEC && TREE_VEC_ELT (r, 3))
    1956            2 :     return boolean_true_node;
    1957              :   else
    1958           72 :     return boolean_false_node;
    1959              : }
    1960              : 
    1961              : /* Process std::meta::is_enumerator.
    1962              :    Returns: true if r represents an enumerator.  Otherwise, false.  */
    1963              : 
    1964              : static tree
    1965         1406 : eval_is_enumerator (const_tree r)
    1966              : {
    1967              :   /* This doesn't check !DECL_TEMPLATE_PARM_P because such CONST_DECLs
    1968              :      would already have been rejected in get_reflection.  */
    1969          786 :   if (TREE_CODE (r) == CONST_DECL)
    1970            4 :     return boolean_true_node;
    1971              :   else
    1972         1327 :     return boolean_false_node;
    1973              : }
    1974              : 
    1975              : /* Get the linkage name for T, or NULL_TREE for types with no name
    1976              :    or for typedefs.  */
    1977              : 
    1978              : static tree
    1979           52 : reflection_type_linkage_name (tree t)
    1980              : {
    1981           52 :   if (OVERLOAD_TYPE_P (t) && !typedef_variant_p (t))
    1982           36 :     return TYPE_NAME (t);
    1983              :   return NULL_TREE;
    1984              : }
    1985              : 
    1986              : /* Process std::meta::has_internal_linkage.
    1987              :    Returns: true if r represents a variable, function, type, template, or
    1988              :    namespace whose name has internal linkage.  Otherwise, false.  */
    1989              : 
    1990              : static tree
    1991           63 : eval_has_internal_linkage (tree r, reflect_kind kind)
    1992              : {
    1993           63 :   if (eval_is_variable (r, kind) == boolean_false_node
    1994           44 :       && eval_is_function (r) == boolean_false_node
    1995           36 :       && eval_is_type (r) == boolean_false_node
    1996           23 :       && eval_is_template (r) == boolean_false_node
    1997           81 :       && eval_is_namespace (r) == boolean_false_node)
    1998              :     return boolean_false_node;
    1999           52 :   r = maybe_get_first_fn (r);
    2000           52 :   r = STRIP_TEMPLATE (r);
    2001           52 :   if (TYPE_P (r))
    2002              :     {
    2003           13 :       r = reflection_type_linkage_name (r);
    2004           13 :       if (!r)
    2005              :         return boolean_false_node;
    2006              :     }
    2007           48 :   if (decl_linkage (r) == lk_internal)
    2008            8 :     return boolean_true_node;
    2009              :   else
    2010           40 :     return boolean_false_node;
    2011              : }
    2012              : 
    2013              : /* Process std::meta::has_module_linkage.
    2014              :    Returns: true if r represents a variable, function, type, template, or
    2015              :    namespace whose name has module linkage.  Otherwise, false.  */
    2016              : 
    2017              : static tree
    2018           63 : eval_has_module_linkage (tree r, reflect_kind kind)
    2019              : {
    2020           63 :   if (eval_is_variable (r, kind) == boolean_false_node
    2021           44 :       && eval_is_function (r) == boolean_false_node
    2022           36 :       && eval_is_type (r) == boolean_false_node
    2023           23 :       && eval_is_template (r) == boolean_false_node
    2024           81 :       && eval_is_namespace (r) == boolean_false_node)
    2025              :     return boolean_false_node;
    2026           52 :   r = maybe_get_first_fn (r);
    2027           52 :   r = STRIP_TEMPLATE (r);
    2028           52 :   if (TYPE_P (r))
    2029              :     {
    2030           13 :       r = reflection_type_linkage_name (r);
    2031           13 :       if (!r)
    2032              :         return boolean_false_node;
    2033              :     }
    2034           48 :   if (decl_linkage (r) == lk_external
    2035           36 :       && DECL_LANG_SPECIFIC (r)
    2036           18 :       && DECL_MODULE_ATTACH_P (r)
    2037           49 :       && !DECL_MODULE_EXPORT_P (r))
    2038            1 :     return boolean_true_node;
    2039              :   else
    2040           47 :     return boolean_false_node;
    2041              : }
    2042              : 
    2043              : /* Process std::meta::has_external_linkage.
    2044              :    Returns: true if r represents a variable, function, type, template, or
    2045              :    namespace whose name has external linkage.  Otherwise, false.  */
    2046              : 
    2047              : static tree
    2048           63 : eval_has_external_linkage (tree r, reflect_kind kind)
    2049              : {
    2050           63 :   if (eval_is_variable (r, kind) == boolean_false_node
    2051           44 :       && eval_is_function (r) == boolean_false_node
    2052           36 :       && eval_is_type (r) == boolean_false_node
    2053           23 :       && eval_is_template (r) == boolean_false_node
    2054           81 :       && eval_is_namespace (r) == boolean_false_node)
    2055              :     return boolean_false_node;
    2056           52 :   r = maybe_get_first_fn (r);
    2057           52 :   r = STRIP_TEMPLATE (r);
    2058           52 :   if (TYPE_P (r))
    2059              :     {
    2060           13 :       r = reflection_type_linkage_name (r);
    2061           13 :       if (!r)
    2062              :         return boolean_false_node;
    2063              :     }
    2064           48 :   if (decl_linkage (r) == lk_external
    2065           48 :       && !(DECL_LANG_SPECIFIC (r)
    2066           18 :            && DECL_MODULE_ATTACH_P (r)
    2067            1 :            && !DECL_MODULE_EXPORT_P (r)))
    2068           35 :     return boolean_true_node;
    2069              :   else
    2070           13 :     return boolean_false_node;
    2071              : }
    2072              : 
    2073              : /* Process std::meta::has_c_language_linkage
    2074              :    Returns: true if r represents a variable, function, or function type with
    2075              :    C language linkage. Otherwise, false.  */
    2076              : 
    2077              : static tree
    2078           66 : eval_has_c_language_linkage (tree r, reflect_kind kind)
    2079              : {
    2080           66 :   if (eval_is_variable (r, kind) == boolean_false_node
    2081           48 :       && eval_is_function (r) == boolean_false_node
    2082          103 :       && eval_is_function_type (r) == boolean_false_node)
    2083              :     return boolean_false_node;
    2084           29 :   r = maybe_get_first_fn (r);
    2085           29 :   r = STRIP_TEMPLATE (r);
    2086           29 :   if (TYPE_P (r))
    2087              :     {
    2088            0 :       r = reflection_type_linkage_name (r);
    2089            0 :       if (!r)
    2090              :         return boolean_false_node;
    2091              :     }
    2092           29 :   if (decl_linkage (r) != lk_none && DECL_LANGUAGE (r) == lang_c)
    2093            4 :     return boolean_true_node;
    2094              :   else
    2095           25 :     return boolean_false_node;
    2096              : }
    2097              : 
    2098              : /* Process std::meta::has_linkage.
    2099              :    Returns: true if r represents a variable, function, type, template, or
    2100              :    namespace whose name has any linkage.  Otherwise, false.  */
    2101              : 
    2102              : static tree
    2103           62 : eval_has_linkage (tree r, reflect_kind kind)
    2104              : {
    2105           62 :   if (eval_is_variable (r, kind) == boolean_false_node
    2106           44 :       && eval_is_function (r) == boolean_false_node
    2107           36 :       && eval_is_type (r) == boolean_false_node
    2108           23 :       && eval_is_template (r) == boolean_false_node
    2109           80 :       && eval_is_namespace (r) == boolean_false_node)
    2110              :     return boolean_false_node;
    2111           51 :   r = maybe_get_first_fn (r);
    2112           51 :   r = STRIP_TEMPLATE (r);
    2113           51 :   if (TYPE_P (r))
    2114              :     {
    2115           13 :       r = reflection_type_linkage_name (r);
    2116           13 :       if (!r)
    2117              :         return boolean_false_node;
    2118              :     }
    2119           47 :   if (decl_linkage (r) != lk_none)
    2120           43 :     return boolean_true_node;
    2121              :   else
    2122            4 :     return boolean_false_node;
    2123              : }
    2124              : 
    2125              : /* Process std::meta::is_complete_type.
    2126              :    Returns: true if is_type(r) is true and there is some point in the
    2127              :    evaluation context from which the type represented by dealias(r) is
    2128              :    not an incomplete type.  Otherwise, false.  */
    2129              : 
    2130              : static tree
    2131          197 : eval_is_complete_type (const_tree r)
    2132              : {
    2133          197 :   if (eval_is_type (r) == boolean_true_node)
    2134              :     {
    2135          161 :       complete_type (const_cast<tree> (r));
    2136          161 :       if (COMPLETE_TYPE_P (r))
    2137          131 :         return boolean_true_node;
    2138              :     }
    2139           66 :   return boolean_false_node;
    2140              : }
    2141              : 
    2142              : /* Process std::meta::is_enumerable_type.
    2143              :    A type T is enumerable from a point P if either
    2144              :    -- T is a class type complete at point P or
    2145              :    -- T is an enumeration type defined by a declaration D such that D is
    2146              :       reachable from P but P does not occur within an enum-specifier of D.
    2147              :   Returns: true if dealias(r) represents a type that is enumerable from some
    2148              :   point in the evaluation context.  Otherwise, false.  */
    2149              : 
    2150              : static tree
    2151          188 : eval_is_enumerable_type (const_tree r)
    2152              : {
    2153          188 :   if (CLASS_TYPE_P (r))
    2154              :     {
    2155            7 :       complete_type (const_cast<tree> (r));
    2156            7 :       if (COMPLETE_TYPE_P (r))
    2157            5 :         return boolean_true_node;
    2158              :      }
    2159          181 :   else if (TREE_CODE (r) == ENUMERAL_TYPE)
    2160              :     {
    2161          175 :       r = TYPE_MAIN_VARIANT (r);
    2162          175 :       if (!ENUM_IS_OPAQUE (r) && !ENUM_BEING_DEFINED_P (r))
    2163          109 :         return boolean_true_node;
    2164              :     }
    2165           74 :   return boolean_false_node;
    2166              : }
    2167              : 
    2168              : /* Process std::meta::is_annotation.
    2169              :    Returns: true if r represents an annotation.  Otherwise, false.  */
    2170              : 
    2171              : static tree
    2172         3328 : eval_is_annotation (const_tree r, reflect_kind kind)
    2173              : {
    2174         3328 :   if (kind == REFLECT_ANNOTATION)
    2175              :     {
    2176          539 :       gcc_assert (TREE_CODE (r) == TREE_LIST);
    2177          539 :       return boolean_true_node;
    2178              :     }
    2179              :   else
    2180         2789 :     return boolean_false_node;
    2181              : }
    2182              : 
    2183              : /* Process std::meta::is_conversion_function.
    2184              :    Returns: true if r represents a function that is a conversion function.
    2185              :    Otherwise, false.  */
    2186              : 
    2187              : static tree
    2188          291 : eval_is_conversion_function (tree r)
    2189              : {
    2190          291 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2191          291 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_CONV_FN_P (r))
    2192            5 :     return boolean_true_node;
    2193              :   else
    2194          286 :     return boolean_false_node;
    2195              : }
    2196              : 
    2197              : /* Process std::meta::is_operator_function.
    2198              :    Returns: true if r represents a function that is an operator function.
    2199              :    Otherwise, false.  */
    2200              : 
    2201              : static tree
    2202          682 : eval_is_operator_function (tree r)
    2203              : {
    2204          682 :   r = maybe_get_first_fn (r);
    2205              : 
    2206          682 :   if (TREE_CODE (r) == FUNCTION_DECL
    2207          543 :       && DECL_OVERLOADED_OPERATOR_P (r)
    2208          858 :       && !DECL_CONV_FN_P (r))
    2209          171 :     return boolean_true_node;
    2210              :   else
    2211          511 :     return boolean_false_node;
    2212              : }
    2213              : 
    2214              : /* Process std::meta::is_literal_operator.
    2215              :    Returns: true if r represents a function that is a literal operator.
    2216              :    Otherwise, false.  */
    2217              : 
    2218              : static tree
    2219           15 : eval_is_literal_operator (const_tree r)
    2220              : {
    2221              :   /* No MAYBE_BASELINK_FUNCTIONS here because a literal operator
    2222              :      must be a non-member function.  */
    2223           15 :   if (TREE_CODE (r) == FUNCTION_DECL && UDLIT_OPER_P (DECL_NAME (r)))
    2224            1 :     return boolean_true_node;
    2225              :   else
    2226           14 :     return boolean_false_node;
    2227              : }
    2228              : 
    2229              : /* Process std::meta::is_special_member_function.
    2230              :    Returns: true if r represents a function that is a special member function.
    2231              :    Otherwise, false.  */
    2232              : 
    2233              : static tree
    2234          810 : eval_is_special_member_function (tree r)
    2235              : {
    2236          810 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2237          810 :   if (TREE_CODE (r) == FUNCTION_DECL && special_memfn_p (r) != sfk_none)
    2238          331 :     return boolean_true_node;
    2239              :   else
    2240          479 :     return boolean_false_node;
    2241              : }
    2242              : 
    2243              : /* Process std::meta::is_constructor.
    2244              :    Returns: true if r represents a function that is a constructor.
    2245              :    Otherwise, false.  */
    2246              : 
    2247              : static tree
    2248         1210 : eval_is_constructor (tree r)
    2249              : {
    2250         1210 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2251         2062 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (r))
    2252          156 :     return boolean_true_node;
    2253              :   else
    2254         1054 :     return boolean_false_node;
    2255              : }
    2256              : 
    2257              : /* Process std::meta::is_default_constructor.
    2258              :    Returns: true if r represents a function that is a default constructor.
    2259              :    Otherwise, false.  */
    2260              : 
    2261              : static tree
    2262          371 : eval_is_default_constructor (tree r)
    2263              : {
    2264          371 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2265          371 :   if (TREE_CODE (r) == FUNCTION_DECL && default_ctor_p (r))
    2266           41 :     return boolean_true_node;
    2267              :   else
    2268          330 :     return boolean_false_node;
    2269              : }
    2270              : 
    2271              : /* Process std::meta::is_copy_constructor.
    2272              :    Returns: true if r represents a function that is a copy constructor.
    2273              :    Otherwise, false.  */
    2274              : 
    2275              : static tree
    2276          380 : eval_is_copy_constructor (tree r)
    2277              : {
    2278          380 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2279          640 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_COPY_CONSTRUCTOR_P (r))
    2280           43 :     return boolean_true_node;
    2281              :   else
    2282          337 :     return boolean_false_node;
    2283              : }
    2284              : 
    2285              : /* Process std::meta::is_move_constructor.
    2286              :    Returns: true if r represents a function that is a move constructor.
    2287              :    Otherwise, false.  */
    2288              : 
    2289              : static tree
    2290          359 : eval_is_move_constructor (tree r)
    2291              : {
    2292          359 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2293          600 :   if (TREE_CODE (r) == FUNCTION_DECL && DECL_MOVE_CONSTRUCTOR_P (r))
    2294           36 :     return boolean_true_node;
    2295              :   else
    2296          323 :     return boolean_false_node;
    2297              : }
    2298              : 
    2299              : /* Process std::meta::is_assignment.
    2300              :    Returns: true if r represents a function that is an assignment operator.
    2301              :    Otherwise, false.  */
    2302              : 
    2303              : static tree
    2304           10 : eval_is_assignment (tree r)
    2305              : {
    2306           10 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2307           10 :   if (TREE_CODE (r) == FUNCTION_DECL
    2308            7 :       && DECL_ASSIGNMENT_OPERATOR_P (r)
    2309           15 :       && DECL_OVERLOADED_OPERATOR_IS (r, NOP_EXPR))
    2310            3 :     return boolean_true_node;
    2311              :   else
    2312            7 :     return boolean_false_node;
    2313              : }
    2314              : 
    2315              : /* Process std::meta::is_copy_assignment.
    2316              :    Returns: true if r represents a function that is a copy assignment
    2317              :    operator.  Otherwise, false.  */
    2318              : 
    2319              : static tree
    2320          382 : eval_is_copy_assignment (tree r)
    2321              : {
    2322          382 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2323          382 :   if (TREE_CODE (r) == FUNCTION_DECL
    2324          382 :       && special_function_p (r) == sfk_copy_assignment)
    2325           43 :     return boolean_true_node;
    2326              :   else
    2327          339 :     return boolean_false_node;
    2328              : }
    2329              : 
    2330              : /* Process std::meta::is_move_assignment.
    2331              :    Returns: true if r represents a function that is a move assignment
    2332              :    operator.  Otherwise, false.  */
    2333              : 
    2334              : static tree
    2335          376 : eval_is_move_assignment (tree r)
    2336              : {
    2337          376 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2338          376 :   if (TREE_CODE (r) == FUNCTION_DECL
    2339          376 :       && special_function_p (r) == sfk_move_assignment)
    2340           36 :     return boolean_true_node;
    2341              :   else
    2342          340 :     return boolean_false_node;
    2343              : }
    2344              : 
    2345              : /* Process std::meta::is_destructor.
    2346              :    Returns: true if r represents a function that is a destructor.
    2347              :    Otherwise, false.  */
    2348              : 
    2349              : static tree
    2350         1615 : eval_is_destructor (tree r)
    2351              : {
    2352         1615 :   r = maybe_get_first_fn (r);
    2353         1615 :   if (TREE_CODE (r) == FUNCTION_DECL
    2354         1615 :       && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (r))
    2355           97 :     return boolean_true_node;
    2356              :   else
    2357         1518 :     return boolean_false_node;
    2358              : }
    2359              : 
    2360              : /* Process std::meta::is_conversion_function_template.
    2361              :    Returns: true if r represents a conversion function template.
    2362              :    Otherwise, false.  */
    2363              : 
    2364              : static tree
    2365           46 : eval_is_conversion_function_template (tree r)
    2366              : {
    2367           46 :   r = maybe_get_first_fn (r);
    2368              : 
    2369           46 :   if (DECL_FUNCTION_TEMPLATE_P (r) && DECL_CONV_FN_P (r))
    2370            4 :     return boolean_true_node;
    2371              :   else
    2372           42 :     return boolean_false_node;
    2373              : }
    2374              : 
    2375              : /* Process std::meta::is_operator_function_template.
    2376              :    Returns: true if r represents an operator function template.
    2377              :    Otherwise, false.  */
    2378              : 
    2379              : static tree
    2380          188 : eval_is_operator_function_template (tree r)
    2381              : {
    2382          188 :   r = maybe_get_first_fn (r);
    2383              : 
    2384          188 :   if (DECL_FUNCTION_TEMPLATE_P (r))
    2385              :     {
    2386           76 :       r = STRIP_TEMPLATE (r);
    2387           76 :       if (DECL_OVERLOADED_OPERATOR_P (r) && !DECL_CONV_FN_P (r))
    2388           58 :         return boolean_true_node;
    2389              :     }
    2390              : 
    2391          130 :   return boolean_false_node;
    2392              : }
    2393              : 
    2394              : /* Process std::meta::is_literal_operator_template.
    2395              :    Returns: true if r represents a literal operator template.
    2396              :    Otherwise, false.  */
    2397              : 
    2398              : static tree
    2399           15 : eval_is_literal_operator_template (tree r)
    2400              : {
    2401              :   /* No MAYBE_BASELINK_FUNCTIONS here because a literal operator
    2402              :      template must be a non-member function template.  */
    2403           15 :   r = OVL_FIRST (r);
    2404              : 
    2405           15 :   if (DECL_FUNCTION_TEMPLATE_P (r) && UDLIT_OPER_P (DECL_NAME (r)))
    2406            1 :     return boolean_true_node;
    2407              :   else
    2408           14 :     return boolean_false_node;
    2409              : }
    2410              : 
    2411              : /* Process std::meta::is_constructor_template.
    2412              :    Returns: true if r represents a function that is an operator function
    2413              :    template.  Otherwise, false.  */
    2414              : 
    2415              : static tree
    2416           46 : eval_is_constructor_template (tree r)
    2417              : {
    2418           46 :   r = maybe_get_first_fn (r);
    2419              : 
    2420           46 :   if (DECL_FUNCTION_TEMPLATE_P (r) && DECL_CONSTRUCTOR_P (r))
    2421            4 :     return boolean_true_node;
    2422              :   else
    2423           42 :     return boolean_false_node;
    2424              : }
    2425              : 
    2426              : /* Process std::meta::operator_of.
    2427              :    Returns: The value of the enumerator from the operators whose corresponding
    2428              :    operator-function-id is the unqualified name of the entity represented by
    2429              :    r.
    2430              :    Throws: meta::exception unless r represents an operator function or
    2431              :    operator function template.  */
    2432              : 
    2433              : static tree
    2434          240 : eval_operator_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2435              :                   bool *non_constant_p, tree *jump_target, tree ret_type,
    2436              :                   tree fun)
    2437              : {
    2438          240 :   if (eval_is_operator_function (r) == boolean_false_node
    2439          240 :       && eval_is_operator_function_template (r) == boolean_false_node)
    2440           90 :     return throw_exception (loc, ctx,
    2441              :                             "reflection does not represent an operator "
    2442              :                             "function or operator function template",
    2443           90 :                             fun, non_constant_p, jump_target);
    2444          150 :   r = maybe_get_first_fn (r);
    2445          150 :   r = STRIP_TEMPLATE (r);
    2446          150 :   maybe_init_meta_operators (loc);
    2447          150 :   int i = IDENTIFIER_ASSIGN_OP_P (DECL_NAME (r)) ? 1 : 0;
    2448          150 :   int j = IDENTIFIER_CP_INDEX (DECL_NAME (r));
    2449          150 :   return build_int_cst (ret_type, meta_operators[i][j]);
    2450              : }
    2451              : 
    2452              : /* Helper to build a string literal containing '\0' terminated NAME.
    2453              :    ELT_TYPE must be either char_type_node or char8_type_node, and the
    2454              :    function takes care of converting the name from SOURCE_CHARSET
    2455              :    to ordinary literal charset resp. UTF-8.  Returns the string
    2456              :    literal, or NULL_TREE if the conversion failed.  */
    2457              : 
    2458              : static tree
    2459         2450 : get_string_literal (const char *name, tree elt_type)
    2460              : {
    2461         2450 :   cpp_string istr, ostr;
    2462         2450 :   istr.len = strlen (name) + 1;
    2463         2450 :   istr.text = (const unsigned char *) name;
    2464         2450 :   if (!cpp_translate_string (parse_in, &istr, &ostr,
    2465         2450 :                              elt_type == char_type_node
    2466              :                              ? CPP_STRING : CPP_UTF8STRING, false))
    2467              :     return NULL_TREE;
    2468         2448 :   name = (const char *) ostr.text;
    2469         2448 :   tree ret = build_string_literal (strlen (name) + 1, name, elt_type);
    2470         2448 :   free (const_cast <char *> (name));
    2471         2448 :   return ret;
    2472              : }
    2473              : 
    2474              : /* Process std::meta::{,u8}symbol_of.
    2475              :    Returns: A string_view or u8string_view containing the characters of the
    2476              :    operator symbol name corresponding to op, respectively encoded with the
    2477              :    ordinary literal encoding or with UTF-8.
    2478              :    Throws: meta::exception unless the value of op corresponds to one of the
    2479              :    enumerators in operators.  */
    2480              : 
    2481              : static tree
    2482          146 : eval_symbol_of (location_t loc, const constexpr_ctx *ctx, tree expr,
    2483              :                 bool *non_constant_p, tree *jump_target, tree elt_type,
    2484              :                 tree ret_type, tree fun)
    2485              : {
    2486          146 :   maybe_init_meta_operators (loc);
    2487          146 :   if (!tree_fits_uhwi_p (expr))
    2488              :     {
    2489            0 :     fail:
    2490            6 :       return throw_exception (loc, ctx,
    2491              :                               "operators argument is not a valid operator",
    2492            6 :                               fun, non_constant_p, jump_target);
    2493              :     }
    2494          146 :   unsigned HOST_WIDE_INT val = tree_to_uhwi (expr);
    2495          195 :   for (int i = 0; i < 2; ++i)
    2496         6014 :     for (int j = OVL_OP_ERROR_MARK + 1; j < OVL_OP_MAX; ++j)
    2497         5965 :       if (ovl_op_info[i][j].meta_name && meta_operators[i][j] == val)
    2498              :         {
    2499          140 :           const char *name = ovl_op_info[i][j].name;
    2500          140 :           char buf[64];
    2501          140 :           if (const char *sp = strchr (name, ' '))
    2502              :             {
    2503            6 :               memcpy (buf, name, sp - name);
    2504            6 :               strcpy (buf + (sp - name), sp + 1);
    2505            6 :               name = buf;
    2506              :             }
    2507          140 :           tree str = get_string_literal (name, elt_type);
    2508              :           /* Basic character set ought to be better convertible
    2509              :              into ordinary literal character set and must be always
    2510              :              convertible into UTF-8.  */
    2511          140 :           gcc_checking_assert (str);
    2512          140 :           releasing_vec args (make_tree_vector_single (str));
    2513          140 :           tree r = build_special_member_call (NULL_TREE,
    2514              :                                               complete_ctor_identifier,
    2515              :                                               &args, ret_type, LOOKUP_NORMAL,
    2516              :                                               tf_warning_or_error);
    2517          140 :           return build_cplus_new (ret_type, r, tf_warning_or_error);
    2518          140 :         }
    2519            6 :   goto fail;
    2520              : }
    2521              : 
    2522              : /* has-type (exposition only).
    2523              :    Returns: true if r represents a value, annotation, object, variable,
    2524              :    function whose type does not contain an undeduced placeholder type and
    2525              :    that is not a constructor or destructor, enumerator, non-static data
    2526              :    member, unnamed bit-field, direct base class relationship, data member
    2527              :    description, or function parameter.  Otherwise, false.  */
    2528              : 
    2529              : static bool
    2530         1713 : has_type (tree r, reflect_kind kind)
    2531              : {
    2532         1713 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2533         1713 :   if (TREE_CODE (r) == FUNCTION_DECL)
    2534              :     {
    2535          131 :       if (DECL_CONSTRUCTOR_P (r) || DECL_DESTRUCTOR_P (r))
    2536              :         return false;
    2537          113 :       if (undeduced_auto_decl (r))
    2538              :         return false;
    2539              :       return true;
    2540              :     }
    2541         1582 :   if (CONSTANT_CLASS_P (r)
    2542         1319 :       || eval_is_variable (r, kind) == boolean_true_node
    2543          743 :       || eval_is_enumerator (r) == boolean_true_node
    2544          687 :       || TREE_CODE (r) == FIELD_DECL
    2545          616 :       || eval_is_annotation (r, kind) == boolean_true_node
    2546          421 :       || eval_is_function_parameter (r, kind) == boolean_true_node
    2547          380 :       || eval_is_object (kind) == boolean_true_node
    2548          298 :       || eval_is_value (kind) == boolean_true_node
    2549              :       || kind == REFLECT_BASE
    2550         1842 :       || kind == REFLECT_DATA_MEMBER_SPEC)
    2551              :     return true;
    2552              :   return false;
    2553              : }
    2554              : 
    2555              : /* Helper function for eval_type_of.  Assuming has_type is true, return
    2556              :    the std::meta::type_of type (rather than reflection thereof).  */
    2557              : 
    2558              : static tree
    2559         1461 : type_of (tree r, reflect_kind kind)
    2560              : {
    2561         1461 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2562         1461 :   if (TREE_CODE (r) == PARM_DECL && kind == REFLECT_PARM)
    2563              :     {
    2564           41 :       r = maybe_update_function_parm (r);
    2565           41 :       tree fn = DECL_CONTEXT (r);
    2566           41 :       tree args = FUNCTION_FIRST_USER_PARM (fn);
    2567           41 :       tree type = FUNCTION_FIRST_USER_PARMTYPE (fn);
    2568          137 :       while (r != args)
    2569              :         {
    2570           55 :           args = DECL_CHAIN (args);
    2571           55 :           type = TREE_CHAIN (type);
    2572              :         }
    2573           41 :       r = TREE_VALUE (type);
    2574           41 :     }
    2575         1420 :   else if (kind == REFLECT_BASE)
    2576          112 :     r = BINFO_TYPE (r);
    2577         1308 :   else if (kind == REFLECT_DATA_MEMBER_SPEC)
    2578           22 :     r = TREE_VEC_ELT (r, 0);
    2579         1286 :   else if (eval_is_annotation (r, kind) == boolean_true_node)
    2580              :     {
    2581          195 :       r = TREE_TYPE (TREE_VALUE (TREE_VALUE (r)));
    2582          195 :       if (CLASS_TYPE_P (r))
    2583              :         {
    2584           17 :           int quals = cp_type_quals (r);
    2585           17 :           quals |= TYPE_QUAL_CONST;
    2586           17 :           r = cp_build_qualified_type (r, quals);
    2587              :         }
    2588              :     }
    2589         1091 :   else if (TREE_CODE (r) == FIELD_DECL && DECL_BIT_FIELD_TYPE (r))
    2590              :     r = DECL_BIT_FIELD_TYPE (r);
    2591         1070 :   else if (TREE_CODE (r) == FUNCTION_DECL)
    2592           97 :     r = static_fn_type (r);
    2593              :   else
    2594          973 :     r = TREE_TYPE (r);
    2595         1461 :   return strip_typedefs (r);
    2596              : }
    2597              : 
    2598              : /* Process std::meta::type_of.  Returns:
    2599              :    -- If r represents the ith parameter of a function F, then the ith type
    2600              :       in the parameter-type-list of F.
    2601              :    -- Otherwise, if r represents a value, object, variable, function,
    2602              :       non-static data member, or unnamed bit-field, then the type of what is
    2603              :       represented by r.
    2604              :    -- Otherwise, if r represents an annotation, then type_of(constant_of(r)).
    2605              :    -- Otherwise, if r represents an enumerator N of an enumeration E, then:
    2606              :       -- If E is defined by a declaration D that precedes a point P in the
    2607              :          evaluation context and P does not occur within an enum-specifier of
    2608              :          D, then a reflection of E.
    2609              :       -- Otherwise, a reflection of the type of N prior to the closing brace
    2610              :          of the enum-specifier as specified in [dcl.enum].
    2611              :    -- Otherwise, if r represents a direct base class relationship (D,B), then
    2612              :       a reflection of B.
    2613              :    -- Otherwise, for a data member description (T,N,A,W,NUA,ANN), a reflection
    2614              :       of the type T.  */
    2615              : 
    2616              : static tree
    2617          642 : eval_type_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2618              :               reflect_kind kind, bool *non_constant_p, tree *jump_target,
    2619              :               tree fun)
    2620              : {
    2621          642 :   if (!has_type (r, kind))
    2622           26 :     return throw_exception (loc, ctx, "reflection does not have a type",
    2623           26 :                             fun, non_constant_p, jump_target);
    2624          616 :   return get_reflection_raw (loc, type_of (r, kind));
    2625              : }
    2626              : 
    2627              : /* Process std::meta::source_location_of.
    2628              :    Returns: If r represents a value, a type other than a class type or an
    2629              :    enumeration type, the global namespace, or a data member description,
    2630              :    then source_location{}.  Otherwise, an implementation-defined
    2631              :    source_location value.  */
    2632              : 
    2633              : static tree
    2634           58 : eval_source_location_of (location_t loc, tree r, reflect_kind kind,
    2635              :                          tree std_source_location)
    2636              : {
    2637           58 :   if (!NON_UNION_CLASS_TYPE_P (std_source_location))
    2638              :     {
    2639            0 :       error_at (loc, "%qT is not a class type", std_source_location);
    2640            0 :       return error_mark_node;
    2641              :     }
    2642           58 :   location_t rloc = UNKNOWN_LOCATION;
    2643           58 :   if (kind == REFLECT_BASE)
    2644              :     /* We don't track location_t of the base specifiers, so at least
    2645              :        for now use location_t of the base parent (i.e. the derived
    2646              :        class).  */
    2647            4 :     r = direct_base_derived (r);
    2648           58 :   if (OVERLOAD_TYPE_P (r) || (TYPE_P (r) && typedef_variant_p (r)))
    2649           10 :     rloc = DECL_SOURCE_LOCATION (TYPE_NAME (r));
    2650           48 :   else if (DECL_P (r) && r != global_namespace)
    2651           30 :     rloc = DECL_SOURCE_LOCATION (r);
    2652           18 :   else if (eval_is_annotation (r, kind) == boolean_true_node)
    2653           13 :     rloc = EXPR_LOCATION (TREE_VALUE (TREE_VALUE (r)));
    2654           58 :   tree decl = NULL_TREE, field = NULL_TREE;
    2655           51 :   if (rloc != UNKNOWN_LOCATION)
    2656              :     {
    2657              :       /* Make sure __builtin_source_location (which depends on
    2658              :          std::source_location::__impl) will work without errors.  */
    2659           51 :       tree name = get_identifier ("__impl");
    2660           51 :       decl = lookup_qualified_name (std_source_location, name);
    2661           51 :       if (TREE_CODE (decl) != TYPE_DECL)
    2662              :         decl = NULL_TREE;
    2663              :       else
    2664              :         {
    2665           51 :           name = get_identifier ("__builtin_source_location");
    2666           51 :           decl = lookup_qualified_name (global_namespace, name);
    2667           51 :           if (TREE_CODE (decl) != FUNCTION_DECL
    2668           51 :               || !fndecl_built_in_p (decl, BUILT_IN_FRONTEND)
    2669           51 :               || DECL_FE_FUNCTION_CODE (decl) != CP_BUILT_IN_SOURCE_LOCATION
    2670          102 :               || !require_deduced_type (decl, tf_warning_or_error))
    2671              :             decl = NULL_TREE;
    2672              :         }
    2673              :     }
    2674           51 :   if (decl)
    2675              :     {
    2676           51 :       field = TYPE_FIELDS (std_source_location);
    2677           51 :       field = next_aggregate_field (field);
    2678              :       /* Make sure std::source_location has exactly a single non-static
    2679              :          data member (_M_impl in libstdc++, __ptr_ in libc++) with pointer
    2680              :          type.  Return {._M_impl = &*.Lsrc_locN}.  */
    2681           51 :       if (field != NULL_TREE
    2682           51 :           && POINTER_TYPE_P (TREE_TYPE (field))
    2683          102 :           && !next_aggregate_field (DECL_CHAIN (field)))
    2684              :         {
    2685           51 :           tree call = build_call_nary (TREE_TYPE (TREE_TYPE (decl)), decl, 0);
    2686           51 :           SET_EXPR_LOCATION (call, rloc);
    2687           51 :           call = fold_builtin_source_location (call);
    2688           51 :           return build_constructor_single (std_source_location, field, call);
    2689              :         }
    2690              :     }
    2691            7 :   return build_constructor (std_source_location, nullptr);
    2692              : }
    2693              : 
    2694              : /* If R is (const T &) &foo, get foo.  */
    2695              : 
    2696              : static tree
    2697          428 : maybe_get_reference_referent (tree r)
    2698              : {
    2699          428 :   if (TREE_CODE (r) == NOP_EXPR
    2700          192 :       && TYPE_REF_P (TREE_TYPE (r))
    2701          618 :       && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
    2702              :     {
    2703          190 :       STRIP_NOPS (r);
    2704          190 :       r = TREE_OPERAND (r, 0);
    2705              :     }
    2706          428 :   return r;
    2707              : }
    2708              : 
    2709              : /* Process std::meta::object_of.
    2710              :    Returns:
    2711              :    -- If r represents an object, then r.
    2712              :    -- Otherwise, if r represents a reference, then a reflection of the object
    2713              :       referred to by that reference.
    2714              :    -- Otherwise, r represents a variable; a reflection of the object declared
    2715              :       by that variable.
    2716              :    Throws: meta::exception unless r is a reflection representing either
    2717              :    -- an object with static storage duration, or
    2718              :    -- a variable that either declares or refers to such an object, and if that
    2719              :       variable is a reference R, then either
    2720              :       -- R is usable in constant expressions, or
    2721              :       -- the lifetime of R began within the core constant expression currently
    2722              :          under evaluation.  */
    2723              : 
    2724              : static tree
    2725           67 : eval_object_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2726              :                 reflect_kind kind, bool *non_constant_p, bool *overflow_p,
    2727              :                 tree *jump_target, tree fun)
    2728              : {
    2729           67 :   tree orig = r;
    2730           67 :   tree type = TREE_TYPE (r);
    2731           67 :   if (type && TYPE_REF_P (type))
    2732           14 :     r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p,
    2733              :                                       overflow_p, jump_target);
    2734           67 :   r = maybe_get_reference_referent (r);
    2735           67 :   if (eval_has_static_storage_duration (orig, kind) == boolean_false_node
    2736           67 :       && (orig == r
    2737            2 :           || eval_has_static_storage_duration (r, kind) == boolean_false_node))
    2738           33 :     return throw_exception (loc, ctx, "reflection does not represent an"
    2739              :                                       " object with static storage duration,"
    2740              :                                       " or a reference to such an object",
    2741           33 :                             fun, non_constant_p, jump_target);
    2742           34 :   return get_reflection_raw (loc, r, REFLECT_OBJECT);
    2743              : }
    2744              : 
    2745              : /* Process std::meta::constant_of.
    2746              :    Let R be a constant expression of type info such that R == r is true.
    2747              :    If r represents an annotation, then let C be its underlying constant.
    2748              :    Effects: Equivalent to:
    2749              :      if constexpr (is_annotation(R)) {
    2750              :        return C;
    2751              :      } else if constexpr (is_array_type(type_of(R)) {
    2752              :        return reflect_constant_array([: R :]);
    2753              :      } else if constexpr (is_function_type(type_of(R)) {
    2754              :        return reflect_function([: R :]);
    2755              :      } else {
    2756              :        return reflect_constant([: R :]);
    2757              :      }
    2758              :    Throws: meta::exception unless either r represents an annotation or
    2759              :    [: R :] is a valid splice-expression.  */
    2760              : 
    2761              : static tree
    2762          604 : eval_constant_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2763              :                   reflect_kind kind, bool *non_constant_p, bool *overflow_p,
    2764              :                   tree *jump_target, tree fun)
    2765              : {
    2766          604 :   tree type;
    2767          604 :   if (has_type (r, kind))
    2768          586 :     type = type_of (r, kind);
    2769              :   else
    2770           18 :     type = maybe_strip_typedefs (r);
    2771              : 
    2772              :   /* So that outer_automatic_var_p works below in check_splice_expr.  */
    2773          604 :   temp_override<tree> ovr (current_function_decl);
    2774          604 :   current_function_decl = cxx_constexpr_caller (ctx);
    2775              : 
    2776          604 :   if (eval_is_annotation (r, kind) == boolean_true_node)
    2777          116 :     r = tree_strip_any_location_wrapper (TREE_VALUE (TREE_VALUE (r)));
    2778          976 :   else if (eval_is_array_type (loc, type) == boolean_true_node)
    2779              :     {
    2780          189 :       const tsubst_flags_t complain = complain_flags (ctx);
    2781              :       /* Create a call to reflect_constant_array so that we can simply
    2782              :          let eval_reflect_constant_array do its job.  */
    2783          189 :       tree name = get_identifier ("reflect_constant_array");
    2784          189 :       tree call = lookup_qualified_name (std_meta_node, name);
    2785          189 :       if (error_operand_p (call) || !is_overloaded_fn (call))
    2786              :         {
    2787            0 :           if (complain)
    2788            0 :             error_at (loc, "couldn%'t look up %<%D::%D%>", std_meta_node, name);
    2789            0 :           *non_constant_p = true;
    2790            0 :           return NULL_TREE;
    2791              :         }
    2792              :       /* We want the argument to be a CONSTRUCTOR or a STRING_CST.  */
    2793          189 :       r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p,
    2794              :                                         overflow_p, jump_target);
    2795          189 :       if (*jump_target || *non_constant_p)
    2796              :         return NULL_TREE;
    2797          189 :       releasing_vec args (make_tree_vector_single (r));
    2798          189 :       call = finish_call_expr (call, &args, /*disallow_virtual=*/true,
    2799              :                                /*koenig_p=*/false, complain);
    2800          189 :       if (call == error_mark_node)
    2801              :         {
    2802            0 :           *non_constant_p = true;
    2803            0 :           return NULL_TREE;
    2804              :         }
    2805          189 :       return eval_reflect_constant_array (loc, ctx, call, non_constant_p,
    2806          189 :                                           overflow_p, jump_target, fun);
    2807          189 :     }
    2808          299 :   else if (eval_is_function_type (type) == boolean_true_node)
    2809            2 :     return eval_reflect_function (loc, ctx, type, r, non_constant_p,
    2810            2 :                                   jump_target, fun);
    2811          297 :   else if (!check_splice_expr (loc, UNKNOWN_LOCATION, r,
    2812              :                                /*address_p=*/false,
    2813              :                                /*member_access_p=*/false,
    2814              :                                /*template_p=*/false,
    2815              :                                /*targs_p=*/false,
    2816              :                                /*complain_p=*/false)
    2817              :            /* One cannot query the value of a function template.
    2818              :               ??? But if [:^^X:] where X is a template is OK, should we
    2819              :               really throw?  We need an LWG issue.  */
    2820          297 :            || eval_is_template (r) == boolean_true_node)
    2821           24 :     return throw_exception (loc, ctx, "reflection does not represent an "
    2822              :                                       "annotation or a valid argument to "
    2823              :                                       "a splice-expression",
    2824           24 :                             fun, non_constant_p, jump_target);
    2825              : 
    2826          389 :   r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p,
    2827              :                                     overflow_p, jump_target);
    2828          389 :   if (*jump_target || *non_constant_p)
    2829              :     return NULL_TREE;
    2830              :   /* Figure out the type for reflect_constant.  */
    2831          382 :   type = TREE_TYPE (convert_from_reference (r));
    2832          382 :   type = type_decays_to (type);
    2833          382 :   type = cv_unqualified (type);
    2834              : 
    2835          382 :   return eval_reflect_constant (loc, ctx, type, r, non_constant_p, jump_target,
    2836          382 :                                 fun);
    2837          604 : }
    2838              : 
    2839              : /* Process std::meta::dealias.
    2840              :    Returns: If r represents an entity, then a reflection representing the
    2841              :    underlying entity of what r represents.  Otherwise, r.
    2842              :    This implements LWG 4427 so we do not throw.  */
    2843              : 
    2844              : static tree
    2845           94 : eval_dealias (location_t loc, tree r, reflect_kind kind)
    2846              : {
    2847           94 :   r = maybe_strip_typedefs (r);
    2848           94 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    2849            4 :     r = ORIGINAL_NAMESPACE (r);
    2850           94 :   return get_reflection_raw (loc, r, kind);
    2851              : }
    2852              : 
    2853              : /* Process std::meta::is_noexcept.
    2854              :    Returns: true if r represents a noexcept function type or a function
    2855              :    with a non-throwing exception specification ([except.spec]).
    2856              :    Otherwise, false.
    2857              :    Note: If r represents a function template that is declared noexcept,
    2858              :    is_noexcept (r) is still false because in general such queries
    2859              :    for templates cannot be answered.  */
    2860              : 
    2861              : static tree
    2862          171 : eval_is_noexcept (tree r)
    2863              : {
    2864          171 :   if (eval_is_function (r) == boolean_true_node)
    2865              :     {
    2866           73 :       r = maybe_get_first_fn (r);
    2867           73 :       maybe_instantiate_noexcept (r);
    2868           73 :       if (TYPE_NOTHROW_P (TREE_TYPE (r)))
    2869           41 :         return boolean_true_node;
    2870              :       else
    2871           32 :         return boolean_false_node;
    2872              :     }
    2873              : 
    2874          196 :   if (eval_is_function_type (r) == boolean_true_node
    2875           98 :       && TYPE_NOTHROW_P (r))
    2876            8 :     return boolean_true_node;
    2877              : 
    2878           90 :   return boolean_false_node;
    2879              : }
    2880              : 
    2881              : /* Process std::meta::is_const.
    2882              :    Let T be type_of(r) if has-type(r) is true.  Otherwise, let T be dealias(r).
    2883              :    Returns: true if T represents a const type, or a const-qualified function
    2884              :    type.  Otherwise, false.  */
    2885              : 
    2886              : static tree
    2887          111 : eval_is_const (tree r, reflect_kind kind)
    2888              : {
    2889          111 :   if (has_type (r, kind))
    2890           50 :     r = type_of (r, kind);
    2891              :   else
    2892           61 :     r = maybe_strip_typedefs (r);
    2893          111 :   r = strip_array_types (r);
    2894          111 :   if (TREE_CODE (r) == METHOD_TYPE)
    2895              :     {
    2896            0 :       if (type_memfn_quals (r) & TYPE_QUAL_CONST)
    2897            0 :         return boolean_true_node;
    2898              :     }
    2899          111 :   else if (TYPE_P (r) && TYPE_READONLY (r))
    2900           28 :     return boolean_true_node;
    2901           83 :   return boolean_false_node;
    2902              : }
    2903              : 
    2904              : /* Process std::meta::is_volatile.
    2905              :    Let T be type_of(r) if has-type(r) is true.  Otherwise, let T be dealias(r).
    2906              :    Returns: true if T represents a volatile type, or a volatile-qualified
    2907              :    function type.  Otherwise, false.  */
    2908              : 
    2909              : static tree
    2910           87 : eval_is_volatile (tree r, reflect_kind kind)
    2911              : {
    2912           87 :   if (has_type (r, kind))
    2913           32 :     r = type_of (r, kind);
    2914              :   else
    2915           55 :     r = maybe_strip_typedefs (r);
    2916           87 :   r = strip_array_types (r);
    2917           87 :   if (TREE_CODE (r) == METHOD_TYPE)
    2918              :     {
    2919            0 :       if (type_memfn_quals (r) & TYPE_QUAL_VOLATILE)
    2920            0 :         return boolean_true_node;
    2921              :     }
    2922           87 :   else if (TYPE_P (r) && TYPE_VOLATILE (r))
    2923           19 :     return boolean_true_node;
    2924           68 :   return boolean_false_node;
    2925              : }
    2926              : 
    2927              : /* Process std::meta::has_template_arguments.
    2928              :    Returns: true if r represents a specialization of a function template,
    2929              :    variable template, class template, or an alias template.  Otherwise,
    2930              :    false.  */
    2931              : 
    2932              : static tree
    2933          815 : eval_has_template_arguments (tree r)
    2934              : {
    2935          815 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2936              :   /* For
    2937              :        typedef cls_tmpl<int> TYPE;
    2938              :      'has_template_arguments (^^TYPE)' should be false.  */
    2939          815 :   if (TYPE_P (r) && typedef_variant_p (r))
    2940           59 :     return (alias_template_specialization_p (r, nt_opaque)
    2941           59 :             ? boolean_true_node : boolean_false_node);
    2942          756 :   if (primary_template_specialization_p (r)
    2943          756 :       || variable_template_specialization_p (r))
    2944          152 :     return boolean_true_node;
    2945              :   else
    2946          604 :     return boolean_false_node;
    2947              : }
    2948              : 
    2949              : /* Process std::meta::template_of.
    2950              :    Returns: A reflection of the template of the specialization represented
    2951              :    by r.
    2952              :    Throws: meta::exception unless has_template_arguments(r) is true.  */
    2953              : 
    2954              : static tree
    2955           39 : eval_template_of (location_t loc, const constexpr_ctx *ctx, tree r,
    2956              :                   bool *non_constant_p, tree *jump_target, tree fun)
    2957              : {
    2958           39 :   if (eval_has_template_arguments (r) != boolean_true_node)
    2959            1 :     return throw_exception_notargs (loc, ctx, fun, non_constant_p, jump_target);
    2960              : 
    2961           38 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    2962           38 :   if (TYPE_P (r) && typedef_variant_p (r))
    2963           14 :     r = TI_TEMPLATE (TYPE_ALIAS_TEMPLATE_INFO (r));
    2964           31 :   else if (CLASS_TYPE_P (r) && CLASSTYPE_TEMPLATE_INFO (r))
    2965           23 :     r = CLASSTYPE_TI_TEMPLATE (r);
    2966            8 :   else if (VAR_OR_FUNCTION_DECL_P (r) && DECL_TEMPLATE_INFO (r))
    2967            8 :     r = DECL_TI_TEMPLATE (r);
    2968              :   else
    2969            0 :     gcc_unreachable ();
    2970              : 
    2971           38 :   gcc_assert (TREE_CODE (r) == TEMPLATE_DECL);
    2972           38 :   return get_reflection_raw (loc, r);
    2973              : }
    2974              : 
    2975              : /* Process std::meta::has_parent
    2976              :    Returns:
    2977              :    -- If r represents the global namespace, then false.
    2978              :    -- Otherwise, if r represents an entity that has C language linkage,
    2979              :       then false.
    2980              :    -- Otherwise, if r represents an entity that has a language linkage
    2981              :       other than C++ language linkage, then an implementation-defined value.
    2982              :    -- Otherwise, if r represents a type that is neither a class nor enumeration
    2983              :       type, then false.
    2984              :    -- Otherwise, if r represents an entity or direct base class relationship,
    2985              :       then true.
    2986              :    -- Otherwise, false.  */
    2987              : 
    2988              : static tree
    2989          478 : eval_has_parent (tree r, reflect_kind kind)
    2990              : {
    2991          478 :   if (kind == REFLECT_OBJECT
    2992          478 :       || CONSTANT_CLASS_P (r)
    2993          472 :       || r == global_namespace
    2994          469 :       || kind == REFLECT_DATA_MEMBER_SPEC)
    2995           12 :     return boolean_false_node;
    2996          466 :   if (TYPE_P (r))
    2997              :     {
    2998           48 :       if (TYPE_NAME (r)
    2999           48 :           && DECL_P (TYPE_NAME (r))
    3000           96 :           && DECL_LANGUAGE (TYPE_NAME (r)) == lang_c)
    3001            0 :         return boolean_false_node;
    3002           48 :       else if (OVERLOAD_TYPE_P (r) || typedef_variant_p (r))
    3003           43 :         return boolean_true_node;
    3004              :       else
    3005            5 :         return boolean_false_node;
    3006              :     }
    3007          418 :   r = maybe_get_first_fn (r);
    3008          418 :   if (kind == REFLECT_BASE)
    3009           46 :     return boolean_true_node;
    3010          372 :   if (!DECL_P (r))
    3011            0 :     return boolean_false_node;
    3012          372 :   if (TREE_CODE (r) != NAMESPACE_DECL && DECL_LANGUAGE (r) == lang_c)
    3013            9 :     return boolean_false_node;
    3014          363 :   return boolean_true_node;
    3015              : }
    3016              : 
    3017              : /* Process std::meta::parent_of.
    3018              :    Returns:
    3019              :    -- If r represents a non-static data member that is a direct member of an
    3020              :       anonymous union, or an unnamed bit-field declared within the
    3021              :       member-specification of such a union, then a reflection representing the
    3022              :       innermost enclosing anonymous union.
    3023              :    -- Otherwise, if r represents an enumerator, then a reflection representing
    3024              :       the corresponding enumeration type.
    3025              :    -- Otherwise, if r represents a direct base class relationship (D,B), then
    3026              :       a reflection representing D.
    3027              :    -- Otherwise, let E be a class, function, or namespace whose class scope,
    3028              :       function parameter scope, or namespace scope, respectively, is the
    3029              :       innermost such scope that either is, or encloses, the target scope of a
    3030              :       declaration of what is represented by r.
    3031              :       -- If E is the function call operator of a closure type for a
    3032              :          consteval-block-declaration, then parent_of(parent_of(^^E)).
    3033              :       -- Otherwise, ^^E.  */
    3034              : 
    3035              : static tree
    3036          421 : eval_parent_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3037              :                 reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3038              :                 tree fun)
    3039              : {
    3040          421 :   if (eval_has_parent (r, kind) != boolean_true_node)
    3041           17 :     return throw_exception (loc, ctx, "reflection does not represent an "
    3042              :                                       "entity with parent",
    3043           17 :                             fun, non_constant_p, jump_target);
    3044          404 :   tree c;
    3045          404 :   r = maybe_get_first_fn (r);
    3046          404 :   if (TYPE_P (r))
    3047              :     {
    3048           32 :       if (TYPE_NAME (r) && DECL_P (TYPE_NAME (r)))
    3049           32 :         c = CP_DECL_CONTEXT (TYPE_NAME (r));
    3050              :       else
    3051            0 :         c = CP_TYPE_CONTEXT (r);
    3052              :     }
    3053          372 :   else if (kind == REFLECT_BASE)
    3054           45 :     c = direct_base_derived (r);
    3055              :   else
    3056          327 :     c = CP_DECL_CONTEXT (r);
    3057              :   tree lam;
    3058          452 :   while (LAMBDA_FUNCTION_P (c)
    3059           30 :          && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (c)))
    3060          452 :          && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
    3061           18 :     c = CP_TYPE_CONTEXT (CP_DECL_CONTEXT (c));
    3062          404 :   return get_reflection_raw (loc, c);
    3063              : }
    3064              : 
    3065              : /* Return std::vector<info>.  */
    3066              : 
    3067              : static tree
    3068         4155 : get_vector_info ()
    3069              : {
    3070         4155 :   tree args = make_tree_vec (1);
    3071         4155 :   TREE_VEC_ELT (args, 0) = meta_info_type_node;
    3072         4155 :   tree inst = lookup_template_class (get_identifier ("vector"), args,
    3073              :                                      /*in_decl*/NULL_TREE,
    3074              :                                      /*context*/std_node, tf_none);
    3075         4155 :   inst = complete_type (inst);
    3076         4155 :   if (inst == error_mark_node || !COMPLETE_TYPE_P (inst))
    3077              :     {
    3078            0 :       error ("couldn%'t look up %qs", "std::vector");
    3079            0 :       return NULL_TREE;
    3080              :     }
    3081              : 
    3082              :   return inst;
    3083              : }
    3084              : 
    3085              : /* Build std::vector<info>{ ELTS }.  */
    3086              : 
    3087              : static tree
    3088         4155 : get_vector_of_info_elts (vec<constructor_elt, va_gc> *elts)
    3089              : {
    3090         4155 :   tree ctor = build_constructor (init_list_type_node, elts);
    3091         4155 :   CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
    3092         4155 :   TREE_CONSTANT (ctor) = true;
    3093         4155 :   TREE_STATIC (ctor) = true;
    3094         4155 :   tree type = get_vector_info ();
    3095         4155 :   if (!type)
    3096            0 :     return error_mark_node;
    3097         4155 :   tree r = finish_compound_literal (type, ctor, tf_warning_or_error,
    3098              :                                     fcl_functional);
    3099              :   /* Here, we're evaluating an AGGR_INIT_EXPR, which is already
    3100              :      embedded in a TARGET_EXPR, so we don't want to add another
    3101              :      TARGET_EXPR inside it.  Note that SIMPLE_TARGET_EXPR_P would
    3102              :      always be false because the TARGET_EXPR_INITIAL is an
    3103              :      AGGR_INIT_EXPR with void type.  */
    3104         4155 :   if (TREE_CODE (r) == TARGET_EXPR)
    3105         4155 :     r = TARGET_EXPR_INITIAL (r);
    3106              :   return r;
    3107              : }
    3108              : 
    3109              : /* Process std::meta::parameters_of.
    3110              :    Returns:
    3111              :    -- If r represents a function F, then a vector containing reflections of
    3112              :       the parameters of F, in the order in which they appear in a declaration
    3113              :       of F.
    3114              :    -- Otherwise, r represents a function type T; a vector containing
    3115              :       reflections of the types in parameter-type-list of T, in the order in
    3116              :       which they appear in the parameter-type-list.
    3117              : 
    3118              :    Throws: meta::exception unless r represents a function or a function
    3119              :    type.  */
    3120              : 
    3121              : static tree
    3122          348 : eval_parameters_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3123              :                     bool *non_constant_p, tree *jump_target, tree fun)
    3124              : {
    3125          348 :   if (eval_is_function (r) != boolean_true_node
    3126          378 :       && eval_is_function_type (r) != boolean_true_node)
    3127            6 :     return throw_exception_nofn (loc, ctx, fun, non_constant_p, jump_target);
    3128              : 
    3129          342 :   r = maybe_get_first_fn (r);
    3130          342 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3131          342 :   if (TREE_CODE (r) == FUNCTION_DECL)
    3132         1398 :     for (tree arg = FUNCTION_FIRST_USER_PARM (r); arg; arg = DECL_CHAIN (arg))
    3133         1080 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3134              :                               get_reflection_raw (loc, arg, REFLECT_PARM));
    3135              :   else
    3136           95 :     for (tree arg = TYPE_ARG_TYPES (r); arg && arg != void_list_node;
    3137           71 :          arg = TREE_CHAIN (arg))
    3138              :       {
    3139           71 :         tree type = maybe_strip_typedefs (TREE_VALUE (arg));
    3140           71 :         CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3141              :                                 get_reflection_raw (loc, type));
    3142              :       }
    3143          342 :   return get_vector_of_info_elts (elts);
    3144              : }
    3145              : 
    3146              : /* Process std::meta::variable_of.
    3147              :    Returns: The reflection of the parameter variable corresponding to r.
    3148              : 
    3149              :    Throws: meta::exception unless
    3150              :    -- r represents a parameter of a function F and
    3151              :    -- there is a point P in the evaluation context for which the innermost
    3152              :       non-block scope enclosing P is the function parameter scope associated
    3153              :       with F.  */
    3154              : 
    3155              : static tree
    3156          120 : eval_variable_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3157              :                   reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3158              :                   tree fun)
    3159              : {
    3160          120 :   if (eval_is_function_parameter (r, kind) == boolean_false_node
    3161              :       /* This doesn't consider the points corresponding to injected
    3162              :          declarations, but that doesn't seem needed.  */
    3163          120 :       || DECL_CONTEXT (r) != current_function_decl)
    3164           58 :     return throw_exception (loc, ctx, "reflection does not represent "
    3165              :                                       "parameter of current function",
    3166           58 :                             fun, non_constant_p, jump_target);
    3167           62 :   r = maybe_update_function_parm (r);
    3168           62 :   return get_reflection_raw (loc, r, REFLECT_UNDEF);
    3169              : }
    3170              : 
    3171              : /* Process std::meta::return_type_of.
    3172              :    Returns: The reflection of the return type of the function or function type
    3173              :    represented by r.
    3174              : 
    3175              :    Throws: meta::exception unless either r represents a function and
    3176              :    has-type(r) is true or r represents a function type.  */
    3177              : 
    3178              : static tree
    3179           63 : eval_return_type_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3180              :                      reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3181              :                      tree fun)
    3182              : {
    3183           24 :   if ((eval_is_function (r) != boolean_true_node || !has_type (r, kind))
    3184          118 :       && eval_is_function_type (r) != boolean_true_node)
    3185           50 :     return throw_exception (loc, ctx, "reflection does not represent a "
    3186              :                             "function or function type with a return type",
    3187           50 :                             fun, non_constant_p, jump_target);
    3188              : 
    3189           13 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    3190           13 :   if (TREE_CODE (r) == FUNCTION_DECL)
    3191            8 :     r = TREE_TYPE (r);
    3192           13 :   r = TREE_TYPE (r);
    3193           13 :   return get_reflection_raw (loc, r, REFLECT_UNDEF);
    3194              : }
    3195              : 
    3196              : /* Process std::meta::offset_of.
    3197              :    Let V be the offset in bits from the beginning of a complete object of the
    3198              :    type represented by parent_of(r) to the subobject associated with the
    3199              :    entity represented by r.
    3200              :    Returns: {V / CHAR_BIT, V % CHAR_BIT}.
    3201              :    Throws: meta::exception unless r represents a non-static data member,
    3202              :    unnamed bit-field, or direct base class relationship (D,B) for which either
    3203              :    B is not a virtual base class or D is not an abstract class.  */
    3204              : 
    3205              : static tree
    3206          123 : eval_offset_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3207              :                 reflect_kind kind, tree member_offset, bool *non_constant_p,
    3208              :                 tree *jump_target, tree fun)
    3209              : {
    3210          123 :   tree byte_off = NULL_TREE, bit_off = NULL_TREE;
    3211          123 :   if (kind == REFLECT_BASE)
    3212              :     {
    3213           44 :       tree d = direct_base_derived (r);
    3214           44 :       if (BINFO_VIRTUAL_P (r) && ABSTRACT_CLASS_TYPE_P (d))
    3215            0 :         return throw_exception (loc, ctx,
    3216              :                                 "reflection of virtual direct base "
    3217              :                                 "relationship with abstract derived "
    3218            0 :                                 "class", fun, non_constant_p, jump_target);
    3219           44 :       byte_off = BINFO_OFFSET (r);
    3220              :     }
    3221           79 :   else if (TREE_CODE (r) != FIELD_DECL)
    3222           46 :     return throw_exception (loc, ctx, "reflection unsuitable for offset_of",
    3223           46 :                             fun, non_constant_p, jump_target);
    3224              :   else
    3225           33 :     bit_off = bit_position (r);
    3226           77 :   if (TREE_CODE (bit_off ? bit_off : byte_off) != INTEGER_CST)
    3227            0 :     return throw_exception (loc, ctx, "non-constant offset for offset_of",
    3228            0 :                             fun, non_constant_p, jump_target);
    3229           77 :   if (TREE_CODE (member_offset) != RECORD_TYPE)
    3230              :     {
    3231            0 :     fail:
    3232            0 :       error_at (loc, "unexpected return type of %qs", "std::meta::offset_of");
    3233            0 :       return build_zero_cst (member_offset);
    3234              :     }
    3235           77 :   tree bytes = next_aggregate_field (TYPE_FIELDS (member_offset));
    3236           77 :   if (!bytes || !INTEGRAL_TYPE_P (TREE_TYPE (bytes)))
    3237            0 :     goto fail;
    3238           77 :   tree bits = next_aggregate_field (DECL_CHAIN (bytes));
    3239           77 :   if (!bits || !INTEGRAL_TYPE_P (TREE_TYPE (bits)))
    3240            0 :     goto fail;
    3241           77 :   if (next_aggregate_field (DECL_CHAIN (bits)))
    3242            0 :     goto fail;
    3243           77 :   tree bytesv;
    3244           77 :   if (byte_off)
    3245              :     bytesv = byte_off;
    3246              :   else
    3247           33 :     bytesv = size_binop (TRUNC_DIV_EXPR, bit_off, bitsize_unit_node);
    3248           77 :   bytesv = fold_convert (TREE_TYPE (bytes), bytesv);
    3249           77 :   tree bitsv;
    3250           77 :   if (byte_off)
    3251           44 :     bitsv = build_zero_cst (TREE_TYPE (bits));
    3252              :   else
    3253              :     {
    3254           33 :       bitsv = size_binop (TRUNC_MOD_EXPR, bit_off, bitsize_unit_node);
    3255           33 :       bitsv = fold_convert (TREE_TYPE (bits), bitsv);
    3256              :     }
    3257           77 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3258           77 :   CONSTRUCTOR_APPEND_ELT (elts, bytes, bytesv);
    3259           77 :   CONSTRUCTOR_APPEND_ELT (elts, bits, bitsv);
    3260           77 :   return build_constructor (member_offset, elts);
    3261              : }
    3262              : 
    3263              : /* Process std::meta::size_of.
    3264              :    Returns: If
    3265              :      -- r represents a non-static data member of type T or a data member
    3266              :         description (T,N,A,W,NUA,ANN) or
    3267              :      -- dealias(r) represents a type T,
    3268              :    then sizeof(T) if T is not a reference type and size_of(add_pointer(^^T))
    3269              :    otherwise.  Otherwise, size_of(type_of(r)).
    3270              : 
    3271              :    Throws: meta::exception unless all of the following conditions are met:
    3272              :      -- dealias(r) is a reflection of a type, object, value, variable of
    3273              :         non-reference type, non-static data member that is not a bit-field,
    3274              :         direct base class relationship, or data member description
    3275              :         (T,N,A,W,NUA,ANN) where W is not _|_.
    3276              :      -- If dealias(r) represents a type, then is_complete_type(r) is true.  */
    3277              : 
    3278              : static tree
    3279           99 : eval_size_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3280              :               reflect_kind kind, tree ret_type, bool *non_constant_p,
    3281              :               tree *jump_target, tree fun)
    3282              : {
    3283           99 :   if (eval_is_type (r) != boolean_true_node
    3284           80 :       && eval_is_object (kind) != boolean_true_node
    3285           78 :       && eval_is_value (kind) != boolean_true_node
    3286           76 :       && (eval_is_variable (r, kind) != boolean_true_node
    3287           18 :           || TYPE_REF_P (TREE_TYPE (r)))
    3288           62 :       && (TREE_CODE (r) != FIELD_DECL || DECL_C_BIT_FIELD (r))
    3289           57 :       && kind != REFLECT_BASE
    3290          139 :       && (kind != REFLECT_DATA_MEMBER_SPEC || TREE_VEC_ELT (r, 3)))
    3291           38 :     return throw_exception (loc, ctx, "reflection not suitable for size_of",
    3292           38 :                             fun, non_constant_p, jump_target);
    3293           61 :   if (!INTEGRAL_TYPE_P (ret_type))
    3294              :     {
    3295            0 :       error_at (loc, "unexpected return type of %qs", "std::meta::size_of");
    3296            0 :       return build_zero_cst (ret_type);
    3297              :     }
    3298           61 :   tree type;
    3299           61 :   if (TYPE_P (r))
    3300              :     type = r;
    3301              :   else
    3302           42 :     type = type_of (r, kind);
    3303           61 :   tree ret;
    3304           61 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, tf_none)
    3305              :       /* No special casing of references needed, c_sizeof_or_alignof_type
    3306              :          returns the same size for POINTER_TYPE and REFERENCE_TYPE.  */
    3307           61 :       || ((ret = c_sizeof_or_alignof_type (loc, type, true, false, 0))
    3308           59 :           == error_mark_node))
    3309            4 :     return throw_exception (loc, ctx,
    3310              :                             "reflection with incomplete type in size_of",
    3311            4 :                             fun, non_constant_p, jump_target);
    3312           57 :   return fold_convert (ret_type, ret);
    3313              : }
    3314              : 
    3315              : /* Process std::meta::alignment_of.
    3316              :    Returns:
    3317              :    -- If dealias(r) represents a type T, then alignment_of(add_pointer(r)) if
    3318              :       T is a reference type and the alignment requirement of T otherwise.
    3319              :    -- Otherwise, if dealias(r) represents a variable or object, then the
    3320              :       alignment requirement of the variable or object.
    3321              :    -- Otherwise, if r represents a direct base class relationship, then
    3322              :       alignment_of(type_of(r)).
    3323              :    -- Otherwise, if r represents a non-static data member M of a class C,
    3324              :       then the alignment of the direct member subobject corresponding to M of a
    3325              :       complete object of type C.
    3326              :    -- Otherwise, r represents a data member description (T,N,A,W,NUA,ANN).
    3327              :       If A is not _|_, then the value A.  Otherwise, alignment_of(^^T).
    3328              :    Throws: meta::exception unless all of the following conditions are met:
    3329              :    -- dealias(r) is a reflection of a type, object, variable of non-reference
    3330              :       type, non-static data member that is not a bit-field, direct base class
    3331              :       relationship, or data member description (T,N,A,W,NUA,ANN) where W is
    3332              :       _|_.
    3333              :    -- If dealias(r) represents a type, then is_complete_type(r) is true.  */
    3334              : 
    3335              : static tree
    3336          105 : eval_alignment_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3337              :                    reflect_kind kind, tree ret_type, bool *non_constant_p,
    3338              :                    tree *jump_target, tree fun)
    3339              : {
    3340          105 :   if (eval_is_type (r) != boolean_true_node
    3341           89 :       && eval_is_object (kind) != boolean_true_node
    3342           83 :       && (eval_is_variable (r, kind) != boolean_true_node
    3343           25 :           || TYPE_REF_P (TREE_TYPE (r)))
    3344           62 :       && (TREE_CODE (r) != FIELD_DECL || DECL_C_BIT_FIELD (r))
    3345           44 :       && kind != REFLECT_BASE
    3346          147 :       && (kind != REFLECT_DATA_MEMBER_SPEC || TREE_VEC_ELT (r, 3)))
    3347           40 :     return throw_exception (loc, ctx, "reflection not suitable for alignment_of",
    3348           40 :                             fun, non_constant_p, jump_target);
    3349           65 :   if (!INTEGRAL_TYPE_P (ret_type))
    3350              :     {
    3351            0 :       error_at (loc, "unexpected return type of %qs", "std::meta::alignment_of");
    3352            0 :       return build_zero_cst (ret_type);
    3353              :     }
    3354           65 :   tree type;
    3355           65 :   if (kind == REFLECT_DATA_MEMBER_SPEC)
    3356              :     {
    3357            2 :       if (TREE_VEC_ELT (r, 2))
    3358            0 :         return fold_convert (ret_type, TREE_VEC_ELT (r, 2));
    3359              :       else
    3360            2 :         type = TREE_VEC_ELT (r, 0);
    3361              :     }
    3362           63 :   else if (kind == REFLECT_BASE)
    3363            2 :     type = BINFO_TYPE (r);
    3364           61 :   else if (TREE_CODE (r) == FIELD_DECL
    3365           43 :            || eval_is_variable (r, kind) == boolean_true_node
    3366           83 :            || (eval_is_object (kind) == boolean_true_node
    3367            6 :                && ((DECL_P (r) && TREE_CODE (r) != FUNCTION_DECL)
    3368            4 :                    || TREE_CODE (r) == COMPONENT_REF)))
    3369              :     {
    3370           43 :       if (TREE_CODE (r) == COMPONENT_REF)
    3371            2 :         r = TREE_OPERAND (r, 1);
    3372           43 :       return build_int_cst (ret_type, MAX (DECL_ALIGN_UNIT (r), 1));
    3373              :     }
    3374           18 :   else if (TYPE_P (r))
    3375              :     type = r;
    3376            2 :   else if (eval_is_object (kind) == boolean_true_node)
    3377            2 :     type = TREE_TYPE (r);
    3378              :   else
    3379            0 :     gcc_unreachable ();
    3380           22 :   if (TYPE_REF_P (type))
    3381            4 :     type = ptr_type_node;
    3382           22 :   if (FUNC_OR_METHOD_TYPE_P (type))
    3383            2 :     return throw_exception (loc, ctx, "alignment_of on function type",
    3384            2 :                             fun, non_constant_p, jump_target);
    3385           20 :   tree ret;
    3386           20 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, tf_none)
    3387              :       /* No special casing of references needed, c_sizeof_or_alignof_type
    3388              :          returns the same alignment for POINTER_TYPE and REFERENCE_TYPE.  */
    3389           20 :       || ((ret = c_sizeof_or_alignof_type (loc, type, false, true, 0))
    3390           20 :           == error_mark_node))
    3391            0 :     return throw_exception (loc, ctx,
    3392              :                             "reflection with incomplete type in alignment_of",
    3393            0 :                             fun, non_constant_p, jump_target);
    3394           20 :   return fold_convert (ret_type, ret);
    3395              : }
    3396              : 
    3397              : /* Process std::meta::bit_size_of.
    3398              :    Returns:
    3399              :      -- If r represents an unnamed bit-field or a non-static data member that
    3400              :         is a bit-field with width W, then W.
    3401              :      -- Otherwise, if r represents a data member description (T,N,A,W,NUA,ANN)
    3402              :         and W is not _|_, then W.
    3403              :      -- Otherwise, CHAR_BIT * size_of(r).
    3404              : 
    3405              :    Throws: meta::exception unless all of the following conditions are met:
    3406              : 
    3407              :      -- dealias(r) is a reflection of a type, object, value, variable of
    3408              :         non-reference type, non-static data member, unnamed bit-field, direct
    3409              :         base class relationship, or data member description.
    3410              :      -- If dealias(r) represents a type T, there is a point within the
    3411              :         evaluation context from which T is not incomplete.  */
    3412              : 
    3413              : static tree
    3414          100 : eval_bit_size_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3415              :                   reflect_kind kind, tree ret_type, bool *non_constant_p,
    3416              :                   tree *jump_target, tree fun)
    3417              : {
    3418          100 :   if (eval_is_type (r) != boolean_true_node
    3419           86 :       && eval_is_object (kind) != boolean_true_node
    3420           85 :       && eval_is_value (kind) != boolean_true_node
    3421           83 :       && (eval_is_variable (r, kind) != boolean_true_node
    3422           18 :           || TYPE_REF_P (TREE_TYPE (r)))
    3423           69 :       && TREE_CODE (r) != FIELD_DECL
    3424              :       && kind != REFLECT_BASE
    3425          136 :       && kind != REFLECT_DATA_MEMBER_SPEC)
    3426           30 :     return throw_exception (loc, ctx,
    3427              :                             "reflection not suitable for bit_size_of",
    3428           30 :                             fun, non_constant_p, jump_target);
    3429           70 :   if (!INTEGRAL_TYPE_P (ret_type))
    3430              :     {
    3431            0 :       error_at (loc, "unexpected return type of %qs",
    3432              :                 "std::meta::bit_size_of");
    3433            0 :       return build_zero_cst (ret_type);
    3434              :     }
    3435           70 :   tree type;
    3436           70 :   if (TREE_CODE (r) == FIELD_DECL && DECL_C_BIT_FIELD (r))
    3437           28 :     return fold_convert (ret_type, DECL_SIZE (r));
    3438           42 :   else if (TYPE_P (r))
    3439              :     type = r;
    3440           28 :   else if (kind == REFLECT_DATA_MEMBER_SPEC && TREE_VEC_ELT (r, 3))
    3441            2 :     return fold_convert (ret_type, TREE_VEC_ELT (r, 3));
    3442              :   else
    3443           26 :     type = type_of (r, kind);
    3444           40 :   tree ret;
    3445           40 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, tf_none)
    3446              :       /* No special casing of references needed, c_sizeof_or_alignof_type
    3447              :          returns the same size for POINTER_TYPE and REFERENCE_TYPE.  */
    3448           40 :       || ((ret = c_sizeof_or_alignof_type (loc, type, true, false, 0))
    3449           38 :           == error_mark_node))
    3450            4 :     return throw_exception (loc, ctx,
    3451              :                             "reflection with incomplete type in bit_size_of",
    3452            4 :                             fun, non_constant_p, jump_target);
    3453           36 :   ret = size_binop (MULT_EXPR, ret, size_int (BITS_PER_UNIT));
    3454           36 :   return fold_convert (ret_type, ret);
    3455              : }
    3456              : 
    3457              : /* Process std::meta::has_identifier.
    3458              :    Returns:
    3459              :    -- If r represents an entity that has a typedef name for linkage purposes,
    3460              :       then true.
    3461              :    -- Otherwise, if r represents an unnamed entity, then false.
    3462              :    -- Otherwise, if r represents a type alias, then !has_template_arguments(r).
    3463              :    -- Otherwise, if r represents a type, then true if
    3464              :       -- r represents a cv-unqualified class type and has_template_arguments(r)
    3465              :          is false, or
    3466              :       -- r represents a cv-unqualified enumeration type.
    3467              :       Otherwise, false.
    3468              :    -- Otherwise, if r represents a class type, then !has_template_arguments(r).
    3469              :    -- Otherwise, if r represents a function, then true if
    3470              :       has_template_arguments(r) is false and the function is not a constructor,
    3471              :       destructor, operator function, or conversion function.  Otherwise, false.
    3472              :    -- Otherwise, if r represents a template, then true if r does not represent
    3473              :       a constructor template, operator function template, or conversion
    3474              :       function template.  Otherwise, false.
    3475              :    -- Otherwise, if r represents the ith parameter of a function F that is an
    3476              :       (implicit or explicit) specialization of a templated function T and the
    3477              :       ith parameter of the instantiated declaration of T whose template
    3478              :       arguments are those of F would be instantiated from a pack, then false.
    3479              :    -- Otherwise, if r represents the parameter P of a function F, then let S
    3480              :       be the set of declarations, ignoring any explicit instantiations, that
    3481              :       precede some point in the evaluation context and that declare either F
    3482              :       or a templated function of which F is a specialization; true if
    3483              :       -- there is a declaration D in S that introduces a name N for either P
    3484              :          or the parameter corresponding to P in the templated function that
    3485              :          D declares and
    3486              :       -- no declaration in S does so using any name other than N.
    3487              :       Otherwise, false.
    3488              :    -- Otherwise, if r represents a variable, then false if the declaration of
    3489              :       that variable was instantiated from a function parameter pack.
    3490              :       Otherwise, !has_template_arguments(r).
    3491              :    -- Otherwise, if r represents a structured binding, then false if the
    3492              :       declaration of that structured binding was instantiated from a
    3493              :       structured binding pack.  Otherwise, true.
    3494              :    -- Otherwise, if r represents an enumerator, non-static-data member,
    3495              :       namespace, or namespace alias, then true.
    3496              :    -- Otherwise, if r represents a direct base class relationship, then
    3497              :       has_identifier(type_of(r)).
    3498              :    -- Otherwise, r represents a data member description (T,N,A,W,NUA,ANN);
    3499              :       true if N is not _|_.  Otherwise, false.  */
    3500              : 
    3501              : static tree
    3502          912 : eval_has_identifier (tree r, reflect_kind kind)
    3503              : {
    3504          912 :   r = maybe_get_first_fn (r);
    3505          912 :   if (kind == REFLECT_BASE)
    3506              :     {
    3507           15 :       r = type_of (r, kind);
    3508           15 :       kind = REFLECT_UNDEF;
    3509              :     }
    3510          912 :   if (DECL_P (r)
    3511          698 :       && kind != REFLECT_PARM
    3512         1491 :       && (!DECL_NAME (r) || IDENTIFIER_ANON_P (DECL_NAME (r))))
    3513           31 :     return boolean_false_node;
    3514          881 :   if (TYPE_P (r) && (!TYPE_NAME (r)
    3515          402 :                      || (TYPE_ANON_P (r) && !typedef_variant_p (r))
    3516          192 :                      || (DECL_P (TYPE_NAME (r))
    3517          192 :                          && !DECL_NAME (TYPE_NAME (r)))))
    3518           11 :     return boolean_false_node;
    3519          870 :   if (eval_is_type_alias (r) == boolean_true_node
    3520          870 :       || (CLASS_TYPE_P (r) && !cv_qualified_p (r)))
    3521              :     {
    3522          158 :       if (eval_has_template_arguments (r) == boolean_true_node)
    3523            0 :         return boolean_false_node;
    3524              :       else
    3525              :         return boolean_true_node;
    3526              :     }
    3527          712 :   if (TYPE_P (r))
    3528              :     {
    3529           34 :       if (TREE_CODE (r) == ENUMERAL_TYPE && !cv_qualified_p (r))
    3530           18 :         return boolean_true_node;
    3531              :       else
    3532           16 :         return boolean_false_node;
    3533              :     }
    3534          678 :   if (eval_is_function (r) == boolean_true_node)
    3535              :     {
    3536          290 :       if (eval_has_template_arguments (r) == boolean_true_node
    3537          288 :           || eval_is_constructor (r) == boolean_true_node
    3538          284 :           || eval_is_destructor (r) == boolean_true_node
    3539          283 :           || eval_is_operator_function (r) == boolean_true_node
    3540          566 :           || eval_is_conversion_function (r) == boolean_true_node)
    3541           18 :         return boolean_false_node;
    3542              :       else
    3543              :         return boolean_true_node;
    3544              :     }
    3545          388 :   if (eval_is_template (r) == boolean_true_node)
    3546              :     {
    3547           28 :       if (eval_is_constructor_template (r) == boolean_true_node
    3548           28 :           || eval_is_operator_function_template (r) == boolean_true_node
    3549           55 :           || eval_is_conversion_function_template (r) == boolean_true_node)
    3550            1 :         return boolean_false_node;
    3551              :       else
    3552              :         return boolean_true_node;
    3553              :     }
    3554          360 :   if (eval_is_function_parameter (r, kind) == boolean_true_node)
    3555              :     {
    3556          119 :       r = maybe_update_function_parm (r);
    3557          119 :       if (MULTIPLE_NAMES_PARM_P (r))
    3558           16 :         return boolean_false_node;
    3559          103 :       if (DECL_NAME (r))
    3560              :         {
    3561           59 :           if (strchr (IDENTIFIER_POINTER (DECL_NAME (r)), '#'))
    3562            1 :             return boolean_false_node;
    3563              :           else
    3564           58 :             return boolean_true_node;
    3565              :         }
    3566           44 :       if (lookup_attribute ("old parm name", DECL_ATTRIBUTES (r)))
    3567           26 :         return boolean_true_node;
    3568              :       else
    3569           18 :         return boolean_false_node;
    3570              :     }
    3571          241 :   if (eval_is_variable (r, kind) == boolean_true_node)
    3572              :     {
    3573          131 :       if (strchr (IDENTIFIER_POINTER (DECL_NAME (r)), '#'))
    3574            0 :         return boolean_false_node;
    3575          131 :       if (eval_has_template_arguments (r) == boolean_true_node)
    3576            0 :         return boolean_false_node;
    3577              :       else
    3578              :         return boolean_true_node;
    3579              :     }
    3580          110 :   if (eval_is_structured_binding (r, kind) == boolean_true_node)
    3581              :     {
    3582           12 :       if (strchr (IDENTIFIER_POINTER (DECL_NAME (r)), '#'))
    3583            0 :         return boolean_false_node;
    3584              :       else
    3585              :         return boolean_true_node;
    3586              :     }
    3587           98 :   if (eval_is_enumerator (r) == boolean_true_node
    3588           94 :       || TREE_CODE (r) == FIELD_DECL
    3589          131 :       || (TREE_CODE (r) == NAMESPACE_DECL && r != global_namespace))
    3590              :     return boolean_true_node;
    3591           13 :   if (kind == REFLECT_DATA_MEMBER_SPEC && TREE_VEC_ELT (r, 1))
    3592              :     return boolean_true_node;
    3593            5 :   return boolean_false_node;
    3594              : }
    3595              : 
    3596              : /* Process std::meta::{,u8}identifier_of.
    3597              :    Let E be UTF-8 for u8identifier_of, and otherwise the ordinary literal
    3598              :    encoding.
    3599              :    Returns: An NTMBS, encoded with E, determined as follows:
    3600              :    -- If r represents an entity with a typedef name for linkage purposes,
    3601              :       then that name.
    3602              :    -- Otherwise, if r represents a literal operator or literal operator
    3603              :       template, then the ud-suffix of the operator or operator template.
    3604              :    -- Otherwise, if r represents the parameter P of a function F, then let S
    3605              :       be the set of declarations, ignoring any explicit instantiations, that
    3606              :       precede some point in the evaluation context and that declare either F
    3607              :       or a templated function of which F is a specialization; the name that
    3608              :       was introduced by a declaration in S for the parameter corresponding
    3609              :       to P.
    3610              :    -- Otherwise, if r represents an entity, then the identifier introduced by
    3611              :       the declaration of that entity.
    3612              :    -- Otherwise, if r represents a direct base class relationship, then
    3613              :       identifier_of(type_of(r)) or u8identifier_of(type_of(r)), respectively.
    3614              :    -- Otherwise, r represents a data member description (T,N,A,W,NUA,ANN);
    3615              :       a string_view or u8string_view, respectively, containing the identifier
    3616              :       N.
    3617              :    Throws: meta::exception unless has_identifier(r) is true and the identifier
    3618              :    that would be returned (see above) is representable by E.  */
    3619              : 
    3620              : static tree
    3621          492 : eval_identifier_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3622              :                     reflect_kind kind, bool *non_constant_p, tree *jump_target,
    3623              :                     tree elt_type, tree ret_type, tree fun)
    3624              : {
    3625          492 :   if (eval_has_identifier (r, kind) == boolean_false_node)
    3626            6 :     return throw_exception (loc, ctx,
    3627              :                             "reflection with has_identifier false",
    3628            6 :                             fun, non_constant_p, jump_target);
    3629          486 :   r = maybe_get_first_fn (r);
    3630          486 :   const char *name = NULL;
    3631          486 :   if (kind == REFLECT_BASE)
    3632              :     {
    3633           15 :       r = type_of (r, kind);
    3634           15 :       kind = REFLECT_UNDEF;
    3635              :     }
    3636          486 :   if (eval_is_function_parameter (r, kind) == boolean_true_node)
    3637              :     {
    3638           57 :       r = maybe_update_function_parm (r);
    3639           57 :       if (DECL_NAME (r))
    3640           41 :         name = IDENTIFIER_POINTER (DECL_NAME (r));
    3641              :       else
    3642              :         {
    3643           16 :           tree opn = lookup_attribute ("old parm name", DECL_ATTRIBUTES (r));
    3644           16 :           opn = TREE_VALUE (TREE_VALUE (opn));
    3645           16 :           name = IDENTIFIER_POINTER (opn);
    3646              :         }
    3647              :     }
    3648          429 :   else if (DECL_P (r) && UDLIT_OPER_P (DECL_NAME (r)))
    3649            3 :     name = UDLIT_OP_SUFFIX (DECL_NAME (r));
    3650          426 :   else if (DECL_P (r))
    3651          313 :     name = IDENTIFIER_POINTER (DECL_NAME (r));
    3652          113 :   else if (TYPE_P (r))
    3653              :     {
    3654          107 :       if (DECL_P (TYPE_NAME (r)))
    3655          107 :         name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (r)));
    3656              :       else
    3657            0 :         name = IDENTIFIER_POINTER (TYPE_NAME (r));
    3658              :     }
    3659            6 :   else if (kind == REFLECT_DATA_MEMBER_SPEC)
    3660            6 :     name = IDENTIFIER_POINTER (TREE_VEC_ELT (r, 1));
    3661              :   else
    3662            0 :     gcc_unreachable ();
    3663          486 :   tree str = get_string_literal (name, elt_type);
    3664          486 :   if (str == NULL_TREE)
    3665              :     {
    3666            0 :       if (elt_type == char_type_node)
    3667            0 :         return throw_exception (loc, ctx, "identifier_of not representable"
    3668              :                                           " in ordinary literal encoding",
    3669            0 :                                 fun, non_constant_p, jump_target);
    3670              :       else
    3671            0 :         return throw_exception (loc, ctx, "u8identifier_of not representable"
    3672              :                                           " in UTF-8",
    3673            0 :                                 fun, non_constant_p, jump_target);
    3674              :     }
    3675          486 :   releasing_vec args (make_tree_vector_single (str));
    3676          486 :   tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    3677              :                                         &args, ret_type, LOOKUP_NORMAL,
    3678              :                                         tf_warning_or_error);
    3679          486 :   return build_cplus_new (ret_type, ret, tf_warning_or_error);
    3680          486 : }
    3681              : 
    3682              : /* Display R, which is a data member description.  */
    3683              : 
    3684              : void
    3685           11 : dump_data_member_spec (pretty_printer *pp, tree r)
    3686              : {
    3687              : #if __GNUC__ >= 10
    3688           11 : #pragma GCC diagnostic push
    3689           11 : #pragma GCC diagnostic ignored "-Wformat"
    3690           11 : #pragma GCC diagnostic ignored "-Wformat-diag"
    3691              : #endif
    3692           11 :   pp_printf (pp, "(%T, %E, %E, %E, %s, {", TREE_VEC_ELT (r, 0),
    3693           11 :              TREE_VEC_ELT (r, 1), TREE_VEC_ELT (r, 2), TREE_VEC_ELT (r, 3),
    3694           11 :              TREE_VEC_ELT (r, 4) == boolean_true_node
    3695              :              ? "true" : "false");
    3696           15 :   for (int i = 5; i < TREE_VEC_LENGTH (r); ++i)
    3697            6 :     pp_printf (pp, "%s%E", i == 5 ? "" : ", ",
    3698            4 :                REFLECT_EXPR_HANDLE (TREE_VEC_ELT (r, i)));
    3699           11 :   pp_printf (pp, "})");
    3700              : #if __GNUC__ >= 10
    3701           11 : #pragma GCC diagnostic pop
    3702              : #endif
    3703           11 : }
    3704              : 
    3705              : /* Process std::meta::{,u8}display_string_of.
    3706              :    Returns: An implementation-defined string_view or u8string_view,
    3707              :    respectively.
    3708              :    Recommended practice: Where possible, implementations should return a
    3709              :    string suitable for identifying the represented construct.  */
    3710              : 
    3711              : static tree
    3712          223 : eval_display_string_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3713              :                         reflect_kind kind, bool *non_constant_p,
    3714              :                         tree *jump_target, tree elt_type, tree ret_type,
    3715              :                         tree fun)
    3716              : {
    3717              : #if __GNUC__ >= 10
    3718          223 : #pragma GCC diagnostic push
    3719          223 : #pragma GCC diagnostic ignored "-Wformat"
    3720          223 : #pragma GCC diagnostic ignored "-Wformat-diag"
    3721              : #endif
    3722          223 :   r = maybe_get_first_fn (r);
    3723          223 :   pretty_printer pp, *refpp = global_dc->get_reference_printer ();
    3724          223 :   pp_format_decoder (&pp) = pp_format_decoder (refpp);
    3725          223 :   pp.set_format_postprocessor (pp_format_postprocessor (refpp)->clone ());
    3726          223 :   if (r == unknown_type_node)
    3727            2 :     pp_printf (&pp, "<null reflection>");
    3728          221 :   else if (TYPE_P (r))
    3729           35 :     pp_printf (&pp, "%T", r);
    3730          186 :   else if (kind == REFLECT_PARM)
    3731              :     {
    3732           36 :       r = maybe_update_function_parm (r);
    3733           36 :       tree fn = DECL_CONTEXT (r);
    3734           36 :       if (DECL_NAME (r))
    3735           28 :         pp_printf (&pp, "<parameter %D of %D>", r, fn);
    3736              :       else
    3737              :         {
    3738            8 :           int idx = 1;
    3739            8 :           for (tree args = FUNCTION_FIRST_USER_PARM (fn);
    3740           20 :                r != args; args = DECL_CHAIN (args))
    3741           12 :             ++idx;
    3742            8 :           pp_printf (&pp, "<unnamed parameter %d of %D>", idx, fn);
    3743              :         }
    3744              :     }
    3745          150 :   else if (kind == REFLECT_VALUE || kind == REFLECT_OBJECT)
    3746            8 :     pp_printf (&pp, "%E", r);
    3747          142 :   else if (DECL_P (r) && (DECL_NAME (r) || TREE_CODE (r) == NAMESPACE_DECL))
    3748          112 :     pp_printf (&pp, "%D", r);
    3749           30 :   else if (TREE_CODE (r) == FIELD_DECL)
    3750              :     {
    3751            8 :       if (DECL_UNNAMED_BIT_FIELD (r))
    3752            4 :         pp_printf (&pp, "%T::<unnamed bit-field>", DECL_CONTEXT (r));
    3753            4 :       else if (ANON_UNION_TYPE_P (TREE_TYPE (r)))
    3754            4 :         pp_printf (&pp, "%T::<anonymous union>", DECL_CONTEXT (r));
    3755              :       else
    3756            0 :         pp_printf (&pp, "%T::<unnamed member>", DECL_CONTEXT (r));
    3757              :     }
    3758           22 :   else if (kind == REFLECT_BASE)
    3759              :     {
    3760            4 :       tree d = direct_base_derived (r);
    3761            4 :       pp_printf (&pp, "%T: %T", d, BINFO_TYPE (r));
    3762              :     }
    3763           18 :   else if (kind == REFLECT_DATA_MEMBER_SPEC)
    3764           10 :     dump_data_member_spec (&pp, r);
    3765            8 :   else if (eval_is_annotation (r, kind) == boolean_true_node)
    3766           16 :     pp_printf (&pp, "[[=%E]]",
    3767            8 :                tree_strip_any_location_wrapper (TREE_VALUE (TREE_VALUE (r))));
    3768              :   else
    3769            0 :     pp_string (&pp, "<unsupported reflection>");
    3770              : #if __GNUC__ >= 10
    3771          223 : #pragma GCC diagnostic pop
    3772              : #endif
    3773          223 :   tree str = get_string_literal (pp_formatted_text (&pp), elt_type);
    3774          223 :   if (str == NULL_TREE)
    3775              :     {
    3776            0 :       if (elt_type == char_type_node)
    3777            0 :         return throw_exception (loc, ctx, "display_string_of not representable"
    3778              :                                           " in ordinary literal encoding",
    3779            0 :                                 fun, non_constant_p, jump_target);
    3780              :       else
    3781            0 :         return throw_exception (loc, ctx,
    3782              :                                 "u8display_string_of not representable"
    3783              :                                 " in UTF-8",
    3784            0 :                                 fun, non_constant_p, jump_target);
    3785              :     }
    3786          223 :   releasing_vec args (make_tree_vector_single (str));
    3787          223 :   tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    3788              :                                         &args, ret_type, LOOKUP_NORMAL,
    3789              :                                         tf_warning_or_error);
    3790          223 :   return build_cplus_new (ret_type, ret, tf_warning_or_error);
    3791          223 : }
    3792              : 
    3793              : /* Determine the reflection kind for R.  */
    3794              : 
    3795              : static reflect_kind
    3796         1059 : get_reflection_kind (tree r)
    3797              : {
    3798         1059 :   if (eval_is_type (r) == boolean_true_node
    3799          991 :       || eval_is_template (r) == boolean_true_node
    3800         2017 :       || eval_is_function (r) == boolean_true_node)
    3801              :     return REFLECT_UNDEF;
    3802          955 :   return obvalue_p (r) ? REFLECT_OBJECT : REFLECT_VALUE;
    3803              : }
    3804              : 
    3805              : /* Get the reflection of template argument ARG as per
    3806              :    std::meta::template_arguments_of.  */
    3807              : 
    3808              : static tree
    3809          207 : get_reflection_of_targ (tree arg)
    3810              : {
    3811          207 :   const location_t loc = location_of (arg);
    3812              :   /* canonicalize_type_argument already strip_typedefs.  */
    3813          207 :   arg = STRIP_REFERENCE_REF (arg);
    3814          207 :   arg = maybe_get_reference_referent (arg);
    3815          207 :   return get_reflection_raw (loc, arg, get_reflection_kind (arg));
    3816              : }
    3817              : 
    3818              : /* Process std::meta::template_arguments_of.
    3819              :    Returns: A vector containing reflections of the template arguments of the
    3820              :    template specialization represented by r, in the order in which they appear
    3821              :    in the corresponding template argument list.
    3822              :    For a given template argument A, its corresponding reflection R is
    3823              :    determined as follows:
    3824              : 
    3825              :    -- If A denotes a type or type alias, then R is a reflection representing
    3826              :       the underlying entity of A.
    3827              :    -- Otherwise, if A denotes a class template, variable template, concept,
    3828              :       or alias template, then R is a reflection representing A.
    3829              :    -- Otherwise, A is a constant template argument.  Let P be the
    3830              :       corresponding template parameter.
    3831              :       -- If P has reference type, then R is a reflection representing the
    3832              :          object or function referred to by A.
    3833              :       -- Otherwise, if P has class type, then R represents the corresponding
    3834              :          template parameter object.
    3835              :       -- Otherwise, R is a reflection representing the value of A.
    3836              : 
    3837              :    Throws: meta::exception unless has_template_arguments(r) is true.  */
    3838              : 
    3839              : static tree
    3840          101 : eval_template_arguments_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3841              :                             bool *non_constant_p, tree *jump_target, tree fun)
    3842              : {
    3843          101 :   if (eval_has_template_arguments (r) != boolean_true_node)
    3844            0 :     return throw_exception_notargs (loc, ctx, fun, non_constant_p, jump_target);
    3845              : 
    3846          101 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3847          101 :   tree args = NULL_TREE;
    3848          101 :   if (TYPE_P (r) && typedef_variant_p (r))
    3849              :     {
    3850           12 :       if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (r))
    3851           12 :         args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo));
    3852              :     }
    3853              :   else
    3854           89 :     args = get_template_innermost_arguments (r);
    3855          101 :   gcc_assert (args);
    3856          302 :   for (tree arg : tree_vec_range (args))
    3857              :     {
    3858          201 :       if (ARGUMENT_PACK_P (arg))
    3859              :         {
    3860           11 :           tree pargs = ARGUMENT_PACK_ARGS (arg);
    3861           28 :           for (tree a : tree_vec_range (pargs))
    3862           17 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3863              :                                     get_reflection_of_targ (a));
    3864              :         }
    3865              :       else
    3866          391 :         CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, get_reflection_of_targ (arg));
    3867              :     }
    3868          101 :   return get_vector_of_info_elts (elts);
    3869              : }
    3870              : 
    3871              : /* Helper for eval_remove_const to build non-const type.  */
    3872              : 
    3873              : static tree
    3874           94 : remove_const (tree type)
    3875              : {
    3876           94 :   return cp_build_qualified_type (type,
    3877           94 :                                   cp_type_quals (type) & ~TYPE_QUAL_CONST);
    3878              : }
    3879              : 
    3880              : /* Process std::meta::annotations_of and annotations_of_with_type.
    3881              :    For a function F, let S(F) be the set of declarations, ignoring any explicit
    3882              :    instantiations, that declare either F or a templated function of which F is
    3883              :    a specialization.
    3884              :    Returns: A vector containing all of the reflections R representing each
    3885              :    annotation applying to:
    3886              :    -- if item represents a function parameter P of a function F, then the
    3887              :       declaration of P in each declaration of F in S(F),
    3888              :    -- otherwise, if item represents a function F, then each declaration of F
    3889              :       in S(F),
    3890              :    -- otherwise, if item represents a direct base class relationship (D,B),
    3891              :       then the corresponding base-specifier in the definition of D,
    3892              :    -- otherwise, each declaration of the entity represented by item,
    3893              :    such that precedes either some point in the evaluation context or a point
    3894              :    immediately following the class-specifier of the outermost class for which
    3895              :    such a point is in a complete-class context.
    3896              :    For any two reflections R1 and R2 in the returned vector, if the annotation
    3897              :    represented by R1 precedes the annotation represented by R2, then R1
    3898              :    appears before R2.
    3899              :    If R1 and R2 represent annotations from the same translation unit T, any
    3900              :    element in the returned vector between R1 and R2 represents an annotation
    3901              :    from T.
    3902              : 
    3903              :    Throws: meta::exception unless item represents a type, type alias,
    3904              :    variable, function, function parameter, namespace, enumerator, direct base
    3905              :    class relationship, or non-static data member.  */
    3906              : 
    3907              : static tree
    3908          322 : eval_annotations_of (location_t loc, const constexpr_ctx *ctx, tree r,
    3909              :                      reflect_kind kind, tree type, bool *non_constant_p,
    3910              :                      tree *jump_target, tree fun)
    3911              : {
    3912          335 :   if (!(eval_is_type (r) == boolean_true_node
    3913          281 :         || eval_is_type_alias (r) == boolean_true_node
    3914          281 :         || eval_is_variable (r, kind) == boolean_true_node
    3915          152 :         || eval_is_function (r) == boolean_true_node
    3916           80 :         || eval_is_function_parameter (r, kind) == boolean_true_node
    3917           59 :         || eval_is_namespace (r) == boolean_true_node
    3918           43 :         || eval_is_enumerator (r) == boolean_true_node
    3919           41 :         || eval_is_base (r, kind) == boolean_true_node
    3920           13 :         || eval_is_nonstatic_data_member (r) == boolean_true_node))
    3921            0 :     return throw_exception (loc, ctx,
    3922              :                             "reflection does not represent a type,"
    3923              :                             " type alias, variable, function, function"
    3924              :                             " parameter, namespace, enumerator,"
    3925              :                             " direct base class relationship,"
    3926              :                             " or non-static data member",
    3927            0 :                             fun, non_constant_p, jump_target);
    3928              : 
    3929          322 :   if (type)
    3930              :     {
    3931           14 :       type = maybe_strip_typedefs (type);
    3932           14 :       if (!TYPE_P (type)
    3933           14 :           || !complete_type_or_maybe_complain (type, NULL_TREE, tf_none))
    3934            0 :         return throw_exception (loc, ctx,
    3935              :                                 "reflection does not represent a complete"
    3936              :                                 " type or type alias", fun, non_constant_p,
    3937            0 :                                 jump_target);
    3938           14 :       type = remove_const (type);
    3939              :     }
    3940              : 
    3941          322 :   r = maybe_get_first_fn (r);
    3942          322 :   bool var_of = false;
    3943          322 :   if (kind == REFLECT_BASE)
    3944              :     {
    3945           28 :       gcc_assert (TREE_CODE (r) == TREE_BINFO);
    3946           28 :       tree c = direct_base_derived_binfo (r), binfo = r, base_binfo;
    3947              : 
    3948           28 :       r = NULL_TREE;
    3949           72 :       for (unsigned ix = 0; BINFO_BASE_ITERATE (c, ix, base_binfo); ix++)
    3950           72 :         if (base_binfo == binfo)
    3951              :           {
    3952           56 :             if (ix + BINFO_BASE_BINFOS (c)->length ()
    3953           28 :                 < vec_safe_length (BINFO_BASE_ACCESSES (c)))
    3954           26 :               r = BINFO_BASE_ACCESS (c, ix + BINFO_BASE_BINFOS (c)->length ());
    3955              :             break;
    3956              :           }
    3957              :     }
    3958          294 :   else if (TYPE_P (r))
    3959              :     {
    3960           41 :       complete_type (r);
    3961           41 :       if (typedef_variant_p (r))
    3962            4 :         r = DECL_ATTRIBUTES (TYPE_NAME (r));
    3963              :       else
    3964           37 :         r = TYPE_ATTRIBUTES (r);
    3965              :     }
    3966          253 :   else if (DECL_P (r))
    3967              :     {
    3968          253 :       if (TREE_CODE (r) == PARM_DECL && kind != REFLECT_PARM)
    3969          253 :         var_of = true;
    3970          253 :       r = DECL_ATTRIBUTES (r);
    3971              :     }
    3972              :   else
    3973            0 :     gcc_unreachable ();
    3974          322 :   vec<constructor_elt, va_gc> *elts = nullptr;
    3975         1549 :   for (tree a = r; (a = lookup_attribute ("internal ", "annotation ", a));
    3976         1227 :        a = TREE_CHAIN (a))
    3977              :     {
    3978         1227 :       gcc_checking_assert (TREE_CODE (TREE_VALUE (a)) == TREE_LIST);
    3979         1227 :       tree val = TREE_VALUE (TREE_VALUE (a));
    3980         1227 :       tree purpose = TREE_PURPOSE (TREE_VALUE (a));
    3981         1266 :       if (var_of
    3982         1227 :           && (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         1188 :       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         2346 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    3997              :                               get_reflection_raw (loc, a, REFLECT_ANNOTATION));
    3998              :     }
    3999          322 :   if (elts)
    4000              :     {
    4001              :       /* Reverse the order.  */
    4002          309 :       unsigned l = elts->length ();
    4003          309 :       constructor_elt *ptr = elts->address ();
    4004              : 
    4005          794 :       for (unsigned i = 0; i < l / 2; i++)
    4006          485 :         std::swap (ptr[i], ptr[l - i - 1]);
    4007              :     }
    4008          322 :   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          871 : 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          871 :   if (!structural_type_p (type)
    4029          867 :       || CP_TYPE_VOLATILE_P (type)
    4030          867 :       || CP_TYPE_CONST_P (type)
    4031         1738 :       || 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          867 :   expr = convert_reflect_constant_arg (type, convert_from_reference (expr));
    4038          867 :   if (expr == error_mark_node)
    4039           15 :     return throw_exception (loc, ctx, "reflect_constant failed", fun,
    4040           15 :                             non_constant_p, jump_target);
    4041          852 :   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          122 : 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          244 :   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          122 :   type = cp_build_reference_type (type, /*rval=*/false);
    4061          122 :   tree e = convert_reflect_constant_arg (type, convert_from_reference (expr));
    4062          122 :   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          118 :   expr = maybe_get_reference_referent (expr);
    4068          118 :   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         2752 : eval_type_trait (location_t loc, tree type1, tree type2, cp_trait_kind kind)
    4112              : {
    4113         2752 :   tree r = finish_trait_expr (loc, kind, type1, type2);
    4114         2752 :   gcc_checking_assert (r != error_mark_node);
    4115         2752 :   STRIP_ANY_LOCATION_WRAPPER (r);
    4116         2752 :   return r;
    4117              : }
    4118              : 
    4119              : /* Like above, but for type traits that take only one type.  */
    4120              : 
    4121              : static tree
    4122         2045 : 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          590 : eval_is_function_type (tree type)
    4131              : {
    4132          550 :   if (FUNC_OR_METHOD_TYPE_P (type))
    4133           46 :     return boolean_true_node;
    4134              :   else
    4135          460 :     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          640 : eval_is_array_type (location_t loc, tree type)
    4186              : {
    4187          488 :   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          537 : 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          207 : eval_is_object_type (location_t loc, tree type)
    4294              : {
    4295          179 :   return eval_type_trait (loc, type, CPTK_IS_OBJECT);
    4296              : }
    4297              : 
    4298              : /* Process std::meta::is_scalar_type.  */
    4299              : 
    4300              : static tree
    4301           28 : eval_is_scalar_type (tree type)
    4302              : {
    4303           28 :   if (SCALAR_TYPE_P (type))
    4304           13 :     return boolean_true_node;
    4305              :   else
    4306           15 :     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          438 : 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          438 :   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          609 :   for (int i = 0; i < TREE_VEC_LENGTH (rvec); ++i)
    5476              :     {
    5477          359 :       tree ra = TREE_VEC_ELT (rvec, i);
    5478          359 :       tree a = REFLECT_EXPR_HANDLE (ra);
    5479          359 :       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          359 :       if (a == unknown_type_node
    5484          355 :           || kind == REFLECT_PARM
    5485          351 :           || eval_is_namespace (a) == boolean_true_node
    5486          337 :           || eval_is_constructor (a) == boolean_true_node
    5487          337 :           || eval_is_destructor (a) == boolean_true_node
    5488          333 :           || eval_is_annotation (a, kind) == boolean_true_node
    5489          329 :           || (TREE_CODE (a) == FIELD_DECL && !DECL_UNNAMED_BIT_FIELD (a))
    5490              :           || kind == REFLECT_DATA_MEMBER_SPEC
    5491          329 :           || kind == REFLECT_BASE
    5492          688 :           || (!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          329 :       a = convert_from_reference (a);
    5499          329 :       TREE_VEC_ELT (rvec, i) = a;
    5500              :     }
    5501          250 :   if (DECL_TYPE_TEMPLATE_P (r) || DECL_TEMPLATE_TEMPLATE_PARM_P (r))
    5502              :     {
    5503          106 :       tree type = lookup_template_class (r, rvec, NULL_TREE, NULL_TREE,
    5504              :                                          tf_none);
    5505          106 :       if (type == error_mark_node)
    5506           48 :         return boolean_false_node;
    5507              :       else
    5508           58 :         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          292 : 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          292 :   tree cs = eval_can_substitute (loc, ctx, r, rvec, non_constant_p, jump_target,
    5554              :                                  fun);
    5555          292 :   if (*jump_target)
    5556              :     return cs;
    5557          199 :   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          138 :   tree ret = NULL_TREE;
    5561          138 :   if (DECL_TYPE_TEMPLATE_P (r) || DECL_TEMPLATE_TEMPLATE_PARM_P (r))
    5562           45 :     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           79 :   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          364 : 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          364 :   type = strip_typedefs (type);
    5693          364 :   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          360 :   opts = convert_from_reference (opts);
    5697          360 :   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          360 :   enum { m_name = 1, m_alignment, m_bit_width, m_no_unique_address,
    5705              :          m_annotations, n_args };
    5706          360 :   tree args[n_args] = { type, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
    5707          360 :                         NULL_TREE };
    5708          360 :   for (tree field = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (opts)));
    5709         2160 :        field; field = next_aggregate_field (DECL_CHAIN (field)))
    5710         1800 :     if (tree name = DECL_NAME (field))
    5711              :       {
    5712         1800 :         if (id_equal (name, "name"))
    5713          360 :           args[m_name] = field;
    5714         1440 :         else if (id_equal (name, "alignment"))
    5715          360 :           args[m_alignment] = field;
    5716         1080 :         else if (id_equal (name, "bit_width"))
    5717          360 :           args[m_bit_width] = field;
    5718          720 :         else if (id_equal (name, "no_unique_address"))
    5719          360 :           args[m_no_unique_address] = field;
    5720          360 :         else if (id_equal (name, "annotations"))
    5721          360 :           args[m_annotations] = field;
    5722              :       }
    5723         1790 :   for (int i = m_name; i < n_args; ++i)
    5724              :     {
    5725         1504 :       if (args[i] == NULL_TREE)
    5726            0 :         goto fail;
    5727         1504 :       tree opt = build3 (COMPONENT_REF, TREE_TYPE (args[i]), opts, args[i],
    5728              :                          NULL_TREE);
    5729         1504 :       if (i == m_no_unique_address)
    5730              :         {
    5731              :           /* The no_unique_address handling is simple.  */
    5732          286 :           if (TREE_CODE (TREE_TYPE (opt)) != BOOLEAN_TYPE)
    5733            0 :             goto fail;
    5734          286 :           opt = cxx_eval_constant_expression (ctx, opt, vc_prvalue,
    5735              :                                               non_constant_p, overflow_p,
    5736              :                                               jump_target);
    5737          286 :           if (*jump_target || *non_constant_p)
    5738           74 :             return NULL_TREE;
    5739          286 :           if (TREE_CODE (opt) != INTEGER_CST)
    5740            0 :             goto fail;
    5741          286 :           if (integer_zerop (opt))
    5742          271 :             args[i] = boolean_false_node;
    5743              :           else
    5744           15 :             args[i] = boolean_true_node;
    5745         1190 :           continue;
    5746              :         }
    5747         1218 :       if (i == m_annotations)
    5748              :         {
    5749              :           /* To handle annotations, read it using input range from
    5750              :              std::vector<info>.  */
    5751          286 :           tree rtype
    5752          286 :             = cp_build_reference_type (TREE_TYPE (opt), /*rval*/false);
    5753          286 :           opt = build_address (opt);
    5754          286 :           opt = fold_convert (rtype, opt);
    5755          286 :           opt = get_info_vec (loc, ctx, opt, -1, non_constant_p, overflow_p,
    5756              :                               jump_target, fun);
    5757          286 :           if (*jump_target || *non_constant_p)
    5758              :             return NULL_TREE;
    5759          286 :           args[i] = opt;
    5760          286 :           continue;
    5761          286 :         }
    5762              :       /* Otherwise the member is optional<something>.  */
    5763          932 :       if (!CLASS_TYPE_P (TREE_TYPE (opt)))
    5764            0 :         goto fail;
    5765          932 :       tree has_value = build_static_cast (loc, boolean_type_node, opt,
    5766              :                                           tf_warning_or_error);
    5767          932 :       if (error_operand_p (has_value))
    5768            0 :         goto fail;
    5769          932 :       has_value = cxx_eval_constant_expression (ctx, has_value, vc_prvalue,
    5770              :                                                 non_constant_p, overflow_p,
    5771              :                                                 jump_target);
    5772          932 :       if (*jump_target || *non_constant_p)
    5773              :         return NULL_TREE;
    5774          932 :       if (TREE_CODE (has_value) != INTEGER_CST)
    5775            0 :         goto fail;
    5776          932 :       if (integer_zerop (has_value))
    5777              :         {
    5778              :           /* If it doesn't have value, store NULL_TREE.  */
    5779          517 :           args[i] = NULL_TREE;
    5780          517 :           continue;
    5781              :         }
    5782          415 :       tree deref = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, opt,
    5783              :                                  NULL_TREE, tf_warning_or_error);
    5784          415 :       if (error_operand_p (deref))
    5785            0 :         goto fail;
    5786          415 :       if (i != m_name)
    5787              :         {
    5788              :           /* For alignment and bit_width otherwise it should be int.  */
    5789          101 :           if (TYPE_MAIN_VARIANT (TREE_TYPE (deref)) != integer_type_node)
    5790            0 :             goto fail;
    5791          101 :           deref = cxx_eval_constant_expression (ctx, deref, vc_prvalue,
    5792              :                                                 non_constant_p, overflow_p,
    5793              :                                                 jump_target);
    5794          101 :           if (*jump_target || *non_constant_p)
    5795              :             return NULL_TREE;
    5796          101 :           if (TREE_CODE (deref) != INTEGER_CST)
    5797            0 :             goto fail;
    5798          101 :           args[i] = deref;
    5799          101 :           continue;
    5800              :         }
    5801              :       /* Otherwise it is a name.  */
    5802          314 :       if (!CLASS_TYPE_P (TREE_TYPE (deref)))
    5803            0 :         goto fail;
    5804          314 :       enum { m_is_u8, m_u8s, m_s, n_fields };
    5805          314 :       tree fields[n_fields] = { NULL_TREE, NULL_TREE, NULL_TREE };
    5806          314 :       for (tree field = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (deref)));
    5807         1570 :            field; field = next_aggregate_field (DECL_CHAIN (field)))
    5808         1256 :         if (tree name = DECL_NAME (field))
    5809              :           {
    5810         1256 :             if (id_equal (name, "_M_is_u8"))
    5811          314 :               fields[m_is_u8] = field;
    5812          942 :             else if (id_equal (name, "_M_u8s"))
    5813          314 :               fields[m_u8s] = field;
    5814          628 :             else if (id_equal (name, "_M_s"))
    5815          314 :               fields[m_s] = field;
    5816              :           }
    5817         1134 :       for (int j = 0; j < n_fields; ++j)
    5818              :         {
    5819          894 :           if (fields[j] == NULL_TREE)
    5820            0 :             goto fail;
    5821          894 :           if (j != m_is_u8
    5822         1046 :               && j == (fields[m_is_u8] == boolean_true_node ? m_s : m_u8s))
    5823          580 :             continue;
    5824          628 :           tree f = build3 (COMPONENT_REF, TREE_TYPE (fields[j]), deref,
    5825              :                            fields[j], NULL_TREE);
    5826          628 :           if (j == m_is_u8)
    5827              :             {
    5828              :               /* The _M_is_u8 handling is simple.  */
    5829          314 :               if (TREE_CODE (TREE_TYPE (f)) != BOOLEAN_TYPE)
    5830            0 :                 goto fail;
    5831          314 :               f = cxx_eval_constant_expression (ctx, f, vc_prvalue,
    5832              :                                                 non_constant_p, overflow_p,
    5833              :                                                 jump_target);
    5834          314 :               if (*jump_target || *non_constant_p)
    5835           74 :                 return NULL_TREE;
    5836          314 :               if (TREE_CODE (f) != INTEGER_CST)
    5837            0 :                 goto fail;
    5838          314 :               if (integer_zerop (f))
    5839          233 :                 fields[m_is_u8] = boolean_false_node;
    5840              :               else
    5841           81 :                 fields[m_is_u8] = boolean_true_node;
    5842          314 :               continue;
    5843              :             }
    5844              :           /* _M_u8s/_M_s handling is the same except for encoding.  */
    5845          314 :           if (!CLASS_TYPE_P (TREE_TYPE (f)))
    5846            0 :             goto fail;
    5847          314 :           tree fns = lookup_qualified_name (TREE_TYPE (f),
    5848              :                                             get_identifier ("c_str"));
    5849          314 :           if (error_operand_p (fns))
    5850            0 :             goto fail;
    5851          314 :           f = build_new_method_call (f, fns, NULL, NULL_TREE, LOOKUP_NORMAL,
    5852              :                                      NULL, tf_warning_or_error);
    5853          314 :           if (error_operand_p (f))
    5854            0 :             goto fail;
    5855          314 :           f = cxx_eval_constant_expression (ctx, f, vc_prvalue,
    5856              :                                             non_constant_p, overflow_p,
    5857              :                                             jump_target);
    5858          314 :           if (*jump_target || *non_constant_p)
    5859              :             return NULL_TREE;
    5860          314 :           STRIP_NOPS (f);
    5861          314 :           if (TREE_CODE (f) != ADDR_EXPR)
    5862            0 :             goto fail;
    5863          314 :           f = TREE_OPERAND (f, 0);
    5864          314 :           f = cxx_eval_constant_expression (ctx, f, vc_prvalue,
    5865              :                                             non_constant_p, overflow_p,
    5866              :                                             jump_target);
    5867          314 :           if (*jump_target || *non_constant_p)
    5868              :             return NULL_TREE;
    5869          314 :           if (TREE_CODE (f) != CONSTRUCTOR
    5870          314 :               || TREE_CODE (TREE_TYPE (f)) != ARRAY_TYPE)
    5871            0 :             goto fail;
    5872          314 :           tree eltt = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (f)));
    5873          314 :           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         1670 :           bool ntmbs = false;
    5879         1670 :           FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (f), k, field, value)
    5880         1670 :             if (!tree_fits_shwi_p (value))
    5881            0 :               goto fail;
    5882         1670 :             else if (field == NULL_TREE)
    5883              :               {
    5884            0 :                 if (integer_zerop (value))
    5885              :                   {
    5886              :                     ntmbs = true;
    5887              :                     break;
    5888              :                   }
    5889            0 :                 ++l;
    5890              :               }
    5891         1670 :             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         1670 :             else if (tree_fits_uhwi_p (field))
    5906              :               {
    5907         1670 :                 l = tree_to_uhwi (field);
    5908         1670 :                 if (integer_zerop (value))
    5909              :                   {
    5910              :                     ntmbs = true;
    5911              :                     break;
    5912              :                   }
    5913         1356 :                 ++l;
    5914              :               }
    5915              :             else
    5916            0 :               goto fail;
    5917          314 :           if (!ntmbs || l > INT_MAX - 1)
    5918            0 :             goto fail;
    5919          314 :           char *namep;
    5920          314 :           unsigned len = l;
    5921          314 :           if (l < 64)
    5922          314 :             namep = XALLOCAVEC (char, l + 1);
    5923              :           else
    5924            0 :             namep = XNEWVEC (char, l + 1);
    5925          314 :           memset (namep, 0, l + 1);
    5926          314 :           l = 0;
    5927         1670 :           FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (f), k, field, value)
    5928         1670 :             if (integer_zerop (value))
    5929              :               break;
    5930         1356 :             else if (field == NULL_TREE)
    5931              :               {
    5932            0 :                 namep[l] = tree_to_shwi (value);
    5933            0 :                 ++l;
    5934              :               }
    5935         1356 :             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         1356 :                 l = tree_to_uhwi (field);
    5946         1356 :                 namep[l++] = tree_to_shwi (value);
    5947              :               }
    5948          314 :           namep[len] = '\0';
    5949              :           /* Convert namep from execution charset to SOURCE_CHARSET.  */
    5950          314 :           cpp_string istr, ostr;
    5951          314 :           istr.len = strlen (namep) + 1;
    5952          314 :           istr.text = (const unsigned char *) namep;
    5953          395 :           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          314 :           if (len >= 64)
    5972            0 :             XDELETEVEC (namep);
    5973          314 :           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          256 :           args[i] = get_identifier ((const char *) ostr.text);
    5978          256 :           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          240 :             default:
    5987          240 :               break;
    5988              :             }
    5989              :         }
    5990              :     }
    5991          286 :   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          280 :   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          278 :   if (args[m_bit_width])
    6000              :     {
    6001           74 :       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           72 :       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           70 :       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           68 :       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           66 :       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           64 :       if (args[m_name] == NULL_TREE)
    6023              :         {
    6024           38 :           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           32 :           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          258 :   if (args[m_alignment])
    6035              :     {
    6036           21 :       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           19 :       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           17 :       tree al = cxx_sizeof_or_alignof_type (loc, type, ALIGNOF_EXPR, true,
    6044              :                                             tf_none);
    6045           17 :       if (TREE_CODE (al) == INTEGER_CST
    6046           17 :           && 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          307 :   for (int i = 0; i < TREE_VEC_LENGTH (args[m_annotations]); ++i)
    6052              :     {
    6053           63 :       tree r = REFLECT_EXPR_HANDLE (TREE_VEC_ELT (args[m_annotations], i));
    6054           63 :       reflect_kind kind
    6055           63 :         = REFLECT_EXPR_KIND (TREE_VEC_ELT (args[m_annotations], i));
    6056           63 :       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           61 :       tree type = type_of (r, kind);
    6060           61 :       if (eval_is_array_type (loc, type) == boolean_true_node
    6061          118 :           || 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           55 :       tree cst = eval_constant_of (loc, ctx, r, kind, non_constant_p,
    6066              :                                    overflow_p, jump_target, fun);
    6067           55 :       if (cst == NULL_TREE)
    6068              :         return NULL_TREE;
    6069           55 :       TREE_VEC_ELT (args[m_annotations], i) = cst;
    6070              :     }
    6071          244 :   tree ret = make_tree_vec (m_annotations
    6072          244 :                             + TREE_VEC_LENGTH (args[m_annotations]));
    6073         1464 :   for (int i = 0; i < m_annotations; ++i)
    6074         1220 :     TREE_VEC_ELT (ret, i) = args[i];
    6075          299 :   for (int i = 0; i < TREE_VEC_LENGTH (args[m_annotations]); ++i)
    6076          110 :     TREE_VEC_ELT (ret, i + m_annotations)
    6077           55 :       = TREE_VEC_ELT (args[m_annotations], i);
    6078          244 :   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        38320 : extract_access_context (location_t loc, tree actx, tree *scope,
    6578              :                         tree *designating_class)
    6579              : {
    6580        38320 :   if (TREE_CODE (actx) != CONSTRUCTOR
    6581        38320 :       || CONSTRUCTOR_NELTS (actx) != 2
    6582        38320 :       || !REFLECT_EXPR_P (CONSTRUCTOR_ELT (actx, 0)->value)
    6583        76640 :       || !REFLECT_EXPR_P (CONSTRUCTOR_ELT (actx, 1)->value))
    6584              :     {
    6585            0 :       error_at (loc, "invalid %<access_context%> argument");
    6586            0 :       return false;
    6587              :     }
    6588        38320 :   *scope = REFLECT_EXPR_HANDLE (CONSTRUCTOR_ELT (actx, 0)->value);
    6589        38320 :   *designating_class = REFLECT_EXPR_HANDLE (CONSTRUCTOR_ELT (actx, 1)->value);
    6590        38320 :   if (*scope == unknown_type_node)
    6591        28817 :     *scope = NULL_TREE;
    6592         9503 :   else if (TREE_CODE (*scope) != FUNCTION_DECL
    6593         8881 :            && TREE_CODE (*scope) != NAMESPACE_DECL
    6594        13653 :            && !CLASS_TYPE_P (*scope))
    6595              :     {
    6596            0 :       error_at (loc, "unexpected %<access_context::scope()%>");
    6597            0 :       return false;
    6598              :     }
    6599         9503 :   else if (CLASS_TYPE_P (*scope))
    6600         4150 :     *scope = TYPE_MAIN_VARIANT (*scope);
    6601        38320 :   if (*designating_class == unknown_type_node)
    6602        34208 :     *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        38320 : 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        38320 :   tree scope = NULL_TREE, designating_class = NULL_TREE, c;
    6654        38320 :   if (!extract_access_context (loc, actx, &scope, &designating_class))
    6655              :     {
    6656            0 :       *non_constant_p = true;
    6657            0 :       return call;
    6658              :     }
    6659              : 
    6660        38320 :   if (eval_is_class_member (r) == boolean_true_node)
    6661              :     {
    6662        36702 :       r = maybe_get_first_fn (r);
    6663        36702 :       c = r;
    6664        36702 :       if (TREE_CODE (r) == CONST_DECL && UNSCOPED_ENUM_P (DECL_CONTEXT (r)))
    6665           39 :         c = DECL_CONTEXT (r);
    6666        36702 :       if (TYPE_P (c))
    6667              :         {
    6668         2630 :           if (TYPE_NAME (c) && DECL_P (TYPE_NAME (c)))
    6669         2630 :             c = CP_DECL_CONTEXT (TYPE_NAME (c));
    6670              :           else
    6671            0 :             c = CP_TYPE_CONTEXT (c);
    6672              :         }
    6673              :       else
    6674        34072 :         c = CP_DECL_CONTEXT (r);
    6675              :     }
    6676         1618 :   else if (kind == REFLECT_BASE)
    6677              :     {
    6678         1576 :       c = direct_base_derived (r);
    6679         1576 :       r = BINFO_TYPE (r);
    6680              :     }
    6681              :   else
    6682              :     return boolean_true_node;
    6683        38278 :   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        38278 :   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        38277 :   if (scope == NULL_TREE)
    6698        28817 :     return boolean_true_node;
    6699         9460 :   if (designating_class == NULL_TREE)
    6700         5349 :     designating_class = c;
    6701         9460 :   if (TREE_CODE (scope) == NAMESPACE_DECL)
    6702         4689 :     push_to_top_level ();
    6703         4771 :   else if (TYPE_P (scope))
    6704         4149 :     push_access_scope (TYPE_NAME (scope));
    6705              :   else
    6706          622 :     push_access_scope (scope);
    6707         9460 :   tree ret = boolean_false_node;
    6708         9460 :   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         9053 :       tree o = TYPE_P (r) ? TYPE_NAME (r) : r;
    6716         9053 :       if (accessible_p (TYPE_BINFO (designating_class), o,
    6717              :                         /*consider_local_p=*/true))
    6718         6642 :         ret = boolean_true_node;
    6719              :     }
    6720         9460 :   if (TREE_CODE (scope) == NAMESPACE_DECL)
    6721         4689 :     pop_from_top_level ();
    6722         4771 :   else if (TYPE_P (scope))
    6723         4149 :     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        45661 : members_of_representable_p (tree c, tree r)
    6734              : {
    6735        45661 :   if (TREE_CODE (r) == CONST_DECL)
    6736              :     return false;
    6737        87841 :   if (LAMBDA_TYPE_P (c) && !LAMBDA_FUNCTION_P (r))
    6738              :     return false;
    6739        44427 :   if (TYPE_P (r))
    6740              :     {
    6741         4472 :       if (CP_DECL_CONTEXT (TYPE_NAME (r)) != c)
    6742              :         return false;
    6743         5642 :       if (LAMBDA_TYPE_P (r))
    6744              :         return false;
    6745         4111 :       if (OVERLOAD_TYPE_P (r))
    6746              :         return true;
    6747         2094 :       if (typedef_variant_p (r))
    6748              :         return true;
    6749              :     }
    6750        39955 :   else if (DECL_P (r))
    6751              :     {
    6752        39955 :       if (CP_DECL_CONTEXT (r) != c)
    6753              :         return false;
    6754        10078 :       if (DECL_CLASS_TEMPLATE_P (r)
    6755        38926 :           || DECL_FUNCTION_TEMPLATE_P (r)
    6756        32012 :           || variable_template_p (r)
    6757        30926 :           || DECL_ALIAS_TEMPLATE_P (r)
    6758        29897 :           || concept_definition_p (r)
    6759        29877 :           || TREE_CODE (r) == FIELD_DECL
    6760        63667 :           || TREE_CODE (r) == NAMESPACE_DECL)
    6761              :         return true;
    6762        23652 :       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       351283 : members_cmp (const void *a, const void *b)
    6772              : {
    6773       351283 :   const constructor_elt *ea = (const constructor_elt *) a;
    6774       351283 :   const constructor_elt *eb = (const constructor_elt *) b;
    6775       351283 :   tree vala = REFLECT_EXPR_HANDLE (ea->value);
    6776       351283 :   tree valb = REFLECT_EXPR_HANDLE (eb->value);
    6777       351283 :   if (TYPE_P (vala))
    6778        62546 :     vala = TYPE_NAME (vala);
    6779       351283 :   if (TYPE_P (valb))
    6780        54645 :     valb = TYPE_NAME (valb);
    6781       351283 :   if (DECL_UID (vala) < DECL_UID (valb))
    6782              :     return -1;
    6783       180868 :   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         2707 : 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         2707 :   r = TYPE_MAIN_VARIANT (r);
    6906         2707 :   if (kind == METAFN_MEMBERS_OF)
    6907              :     {
    6908         2259 :       if (modules_p ())
    6909            0 :         lazy_load_pendings (TYPE_NAME (r));
    6910         2259 :       if (CLASSTYPE_LAZY_DEFAULT_CTOR (r))
    6911           76 :         lazily_declare_fn (sfk_constructor, r);
    6912         2259 :       if (CLASSTYPE_LAZY_COPY_CTOR (r))
    6913           85 :         lazily_declare_fn (sfk_copy_constructor, r);
    6914         2259 :       if (CLASSTYPE_LAZY_MOVE_CTOR (r))
    6915           72 :         lazily_declare_fn (sfk_move_constructor, r);
    6916         2259 :       if (CLASSTYPE_LAZY_DESTRUCTOR (r))
    6917           83 :         lazily_declare_fn (sfk_destructor, r);
    6918         2259 :       if (CLASSTYPE_LAZY_COPY_ASSIGN (r))
    6919           97 :         lazily_declare_fn (sfk_copy_assignment, r);
    6920         2259 :       if (CLASSTYPE_LAZY_MOVE_ASSIGN (r))
    6921           86 :         lazily_declare_fn (sfk_move_assignment, r);
    6922              :     }
    6923         2707 :   auto_vec <tree, 8> implicitly_declared;
    6924         2707 :   vec<constructor_elt, va_gc> *elts = nullptr;
    6925        70684 :   for (tree field = TYPE_FIELDS (r); field; field = DECL_CHAIN (field))
    6926              :     {
    6927        67977 :       tree m = field;
    6928        67977 :       if (TREE_CODE (field) == FIELD_DECL && DECL_ARTIFICIAL (field))
    6929        42953 :         continue; /* Ignore bases and the vptr.  */
    6930        66909 :       else if (DECL_SELF_REFERENCE_P (field))
    6931         2707 :         continue;
    6932        64202 :       else if (TREE_CODE (field) == TYPE_DECL)
    6933         4054 :         m = TREE_TYPE (field);
    6934        60148 :       else if (TREE_CODE (field) == FUNCTION_DECL)
    6935              :         {
    6936              :           /* Ignore cloned cdtors.  */
    6937        39286 :           if (DECL_CLONED_FUNCTION_P (field))
    6938        19446 :             continue;
    6939              :           /* Ignore functions with unsatisfied constraints.  */
    6940        19840 :           if (!constraints_satisfied_p (field))
    6941           20 :             continue;
    6942        19820 :           if (DECL_MAYBE_DELETED (field))
    6943              :             {
    6944           11 :               ++function_depth;
    6945           11 :               maybe_synthesize_method (field);
    6946           11 :               --function_depth;
    6947              :             }
    6948              :         }
    6949        44736 :       if (members_of_representable_p (r, m))
    6950              :         {
    6951        44948 :           if (kind == METAFN_STATIC_DATA_MEMBERS_OF
    6952        42199 :               && eval_is_variable (m, REFLECT_UNDEF) != boolean_true_node)
    6953         2749 :             continue; /* For static_data_members_of only include
    6954              :                          is_variable.  */
    6955        42542 :           else if ((kind == METAFN_NONSTATIC_DATA_MEMBERS_OF
    6956        39450 :                     || kind == METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS)
    6957        39450 :                    && 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        36358 :           tree a = eval_is_accessible (loc, ctx, m, REFLECT_UNDEF, actx, call,
    6961              :                                        non_constant_p, jump_target, fun);
    6962        36358 :           if (*jump_target || *non_constant_p)
    6963            0 :             return nullptr;
    6964        36358 :           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        34040 :           gcc_assert (a == boolean_true_node);
    6972        45556 :           if (kind == METAFN_MEMBERS_OF
    6973        32714 :               && TREE_CODE (m) == FUNCTION_DECL
    6974        51220 :               && DECL_ARTIFICIAL (m))
    6975              :             {
    6976              :               /* Implicitly-declared special members or operator== members
    6977              :                  appear after any user declared members.  */
    6978        11516 :               implicitly_declared.safe_push (m);
    6979        11516 :               continue;
    6980              :             }
    6981        22524 :           else if (kind == METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS)
    6982           37 :             continue;
    6983        22487 :           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         2707 :   if (kind == METAFN_MEMBERS_OF && elts)
    6991         2216 :     elts->qsort (members_cmp);
    6992         2259 :   if (kind == METAFN_MEMBERS_OF && !implicitly_declared.is_empty ())
    6993              :     {
    6994         2179 :       gcc_assert (implicitly_declared.length () <= 8);
    6995        12990 :       for (tree m : implicitly_declared)
    6996        11497 :         if (default_ctor_p (m))
    6997              :           {
    6998          686 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    6999              :                                     get_reflection_raw (loc, m));
    7000          686 :             break;
    7001              :           }
    7002        15174 :       for (tree m : implicitly_declared)
    7003        21622 :         if (DECL_COPY_CONSTRUCTOR_P (m))
    7004              :           {
    7005         2174 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    7006              :                                     get_reflection_raw (loc, m));
    7007         2174 :             break;
    7008              :           }
    7009         8711 :       for (tree m : implicitly_declared)
    7010         4344 :         if (special_function_p (m) == sfk_copy_assignment)
    7011              :           {
    7012         2170 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    7013              :                                     get_reflection_raw (loc, m));
    7014         2170 :             break;
    7015              :           }
    7016        13075 :       for (tree m : implicitly_declared)
    7017        17370 :         if (DECL_MOVE_CONSTRUCTOR_P (m))
    7018              :           {
    7019         2147 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    7020              :                                     get_reflection_raw (loc, m));
    7021         2147 :             break;
    7022              :           }
    7023         6636 :       for (tree m : implicitly_declared)
    7024         2246 :         if (special_function_p (m) == sfk_move_assignment)
    7025              :           {
    7026         2147 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    7027              :                                     get_reflection_raw (loc, m));
    7028         2147 :             break;
    7029              :           }
    7030        10867 :       for (tree m : implicitly_declared)
    7031         6505 :         if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (m))
    7032              :           {
    7033         2175 :             CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    7034              :                                     get_reflection_raw (loc, m));
    7035         2175 :             break;
    7036              :           }
    7037        18036 :       for (tree m : implicitly_declared)
    7038        11516 :         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         2707 :   return elts;
    7046         2707 : }
    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          702 : 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          702 :   vec<constructor_elt, va_gc> *elts = nullptr;
    7057          702 :   tree binfo = TYPE_BINFO (r), base_binfo;
    7058         2247 :   for (unsigned i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    7059              :     {
    7060         1545 :       tree a = eval_is_accessible (loc, ctx, base_binfo, REFLECT_BASE, actx,
    7061              :                                    call, non_constant_p, jump_target, fun);
    7062         1545 :       if (*jump_target || *non_constant_p)
    7063              :         return nullptr;
    7064         1545 :       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         1439 :       gcc_assert (a == boolean_true_node);
    7071         1439 :       if (kind == METAFN_HAS_INACCESSIBLE_BASES)
    7072           53 :         continue;
    7073         2931 :       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
    7074              :                               get_reflection_raw (loc, base_binfo,
    7075              :                                                   REFLECT_BASE));
    7076              :     }
    7077          702 :   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         2381 : 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         2381 :   r = maybe_strip_typedefs (r);
    7134         2381 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    7135          122 :     r = ORIGINAL_NAMESPACE (r);
    7136         2381 :   vec<constructor_elt, va_gc> *elts;
    7137         2381 :   if (TREE_CODE (r) == NAMESPACE_DECL)
    7138          122 :     elts = namespace_members_of (loc, r);
    7139         2259 :   else if (CLASS_TYPE_P (r)
    7140         4518 :            && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    7141              :     {
    7142         2259 :       elts = class_members_of (loc, ctx, r, actx, call, non_constant_p,
    7143              :                                jump_target, METAFN_MEMBERS_OF, fun);
    7144         2259 :       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         2381 :   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          495 : 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          495 :   r = maybe_strip_typedefs (r);
    7169          495 :   vec<constructor_elt, va_gc> *elts = nullptr;
    7170          495 :   if (CLASS_TYPE_P (r)
    7171          990 :       && complete_type_or_maybe_complain (r, NULL_TREE, tf_none))
    7172              :     {
    7173          495 :       elts = class_bases_of (loc, ctx, r, actx, call, non_constant_p,
    7174              :                              jump_target, METAFN_BASES_OF, fun);
    7175          495 :       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          495 :   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         1599 : 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         1599 :   tree str = get_range_elts (loc, ctx, call, 0, non_constant_p, overflow_p,
    7390              :                              jump_target, REFLECT_CONSTANT_STRING, fun);
    7391         1599 :   if (*jump_target || *non_constant_p)
    7392              :     return NULL_TREE;
    7393         1599 :   if (TREE_CODE (str) != STRING_CST
    7394         3198 :       || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)))
    7395         1599 :           != (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         1599 :   cpp_string istr, ostr;
    7407         1599 :   istr.len = TREE_STRING_LENGTH (str) + 1;
    7408         1599 :   istr.text = (const unsigned char *) TREE_STRING_POINTER (str);
    7409         1599 :   const char *name;
    7410         1626 :   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         1599 :     name = (const char *) ostr.text;
    7418              :   /* And then let get_string_literal translate from SOURCE_CHARSET to
    7419              :      {UTF-8,exec charset}.  */
    7420         1599 :   tree dchar_type = to_utf8 ? char8_type_node : char_type_node;
    7421         1599 :   str = get_string_literal (name, dchar_type);
    7422         1599 :   free (const_cast <unsigned char *> (ostr.text));
    7423         1599 :   if (str == NULL_TREE)
    7424              :     {
    7425            2 :       str = get_string_literal ("", dchar_type);
    7426            2 :       gcc_assert (str);
    7427              :     }
    7428         1599 :   releasing_vec args (make_tree_vector_single (str));
    7429         1599 :   tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    7430         1599 :                                         &args, TREE_TYPE (call), LOOKUP_NORMAL,
    7431              :                                         tf_warning_or_error);
    7432         1599 :   return build_cplus_new (TREE_TYPE (call), ret, tf_warning_or_error);
    7433         1599 : }
    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           70 : 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          194 :   auto adjust_type = [](tree type) -> tree
    7453              :     {
    7454          124 :       if (TYPE_REF_P (type))
    7455           69 :         type = TREE_TYPE (type);
    7456          124 :       type = build_cplus_array_type (type, NULL_TREE);
    7457          124 :       return build_pointer_type (type);
    7458              :     };
    7459              : 
    7460           70 :   const bool var_p = eval_is_variable (r, kind) == boolean_true_node;
    7461           96 :   if (var_p || eval_is_object (kind) == boolean_true_node)
    7462              :     {
    7463              :       /* The wording is saying that U is the type of r.  */
    7464           62 :       tree U = TREE_TYPE (r);
    7465           62 :       if (is_convertible (adjust_type (U), adjust_type (T))
    7466           62 :           && (!var_p || is_constant_expression (r)))
    7467              :         {
    7468           58 :           if (TYPE_REF_P (TREE_TYPE (r)))
    7469              :             {
    7470            7 :               r = DECL_INITIAL (r);
    7471            7 :               r = maybe_get_reference_referent (r);
    7472            7 :               gcc_checking_assert (!TYPE_REF_P (TREE_TYPE (r)));
    7473              :             }
    7474           58 :           return build_address (r);
    7475              :         }
    7476              :     }
    7477              : 
    7478           12 :   return throw_exception (loc, ctx, "value cannot be extracted", fun,
    7479           12 :                           non_constant_p, jump_target);
    7480              : }
    7481              : 
    7482              : /* Helper for extract_value.  Return true iff we can extract value of
    7483              :    type U using type T.  */
    7484              : 
    7485              : static bool
    7486          355 : can_extract_value_p (tree T, tree U)
    7487              : {
    7488          355 :   if (POINTER_TYPE_P (U)
    7489           23 :       && (similar_type_p (T, U)
    7490            8 :           || (FUNCTION_POINTER_TYPE_P (T) && FUNCTION_POINTER_TYPE_P (U)))
    7491          374 :       && is_convertible (U, T))
    7492              :     return true;
    7493          342 :   else if (same_type_ignoring_top_level_qualifiers_p (T, U))
    7494              :     return true;
    7495          266 :   else if (TREE_CODE (U) == ARRAY_TYPE
    7496          181 :            && POINTER_TYPE_P (T)
    7497          447 :            && is_convertible (U, T))
    7498              :     {
    7499              :       /* remove_extent_t<U> */
    7500          175 :       U = TREE_TYPE (U);
    7501          175 :       U = strip_typedefs (U);
    7502              :       /* remove_extent_t<U>* */
    7503          175 :       U = build_pointer_type (U);
    7504          175 :       return similar_type_p (T, U);
    7505              :     }
    7506           18 :   else if (LAMBDA_TYPE_P (U)
    7507            7 :            && FUNCTION_POINTER_TYPE_P (T)
    7508           98 :            && is_convertible (U, T))
    7509              :     return true;
    7510              :   return false;
    7511              : }
    7512              : 
    7513              : /* Helper for eval_extract, extracting a value.
    7514              :    Let U be the type of the value or object that r represents.
    7515              :    Returns: static_cast<T>([:R:]), where R is a constant expression of
    7516              :    type info such that R == r is true.
    7517              :    Throws: meta::exception unless
    7518              :    -- U is a pointer type, T and U are either similar or both function pointer
    7519              :       types, and is_convertible_v<U, T> is true,
    7520              :    -- U is not a pointer type and the cv-unqualified types of T and U are the
    7521              :       same,
    7522              :    -- U is an array type, T is a pointer type, remove_extent_t<U>* and T are
    7523              :       similar types, and the value r represents is convertible to T, or
    7524              :    -- U is a closure type, T is a function pointer type, and the value that r
    7525              :       represents is convertible to T.  */
    7526              : 
    7527              : static tree
    7528          355 : extract_value (location_t loc, const constexpr_ctx *ctx, tree T, tree r,
    7529              :                bool *non_constant_p, tree *jump_target, tree fun)
    7530              : {
    7531          355 :   if (REFLECT_EXPR_P (r))
    7532              :     {
    7533          355 :       r = REFLECT_EXPR_HANDLE (r);
    7534          355 :       if (can_extract_value_p (T, TREE_TYPE (r)))
    7535          267 :         return build_static_cast (loc, T, r, tf_none);
    7536              :     }
    7537           88 :   return throw_exception (loc, ctx, "value cannot be extracted", fun,
    7538           88 :                           non_constant_p, jump_target);
    7539              : }
    7540              : 
    7541              : /* Helper for extract_member_or_function.  Return true iff we can
    7542              :    extract an NSDM or function R of kind KIND using type T.  */
    7543              : 
    7544              : static bool
    7545           81 : can_extract_member_or_function_p (tree T, tree r, reflect_kind kind)
    7546              : {
    7547           81 :   if (eval_is_nonstatic_data_member (r) == boolean_true_node)
    7548              :     {
    7549           15 :       if (eval_is_bit_field (r, kind) == boolean_true_node)
    7550              :         return false;
    7551              :       /* static union { int m; }; extract<int>(^^m); is invalid.  */
    7552           11 :       if (TREE_CODE (r) == FIELD_DECL
    7553           11 :           && ANON_UNION_TYPE_P (DECL_CONTEXT (r)))
    7554              :         {
    7555            2 :           tree c = CP_TYPE_CONTEXT (DECL_CONTEXT (r));
    7556            2 :           while (ANON_UNION_TYPE_P (c))
    7557            0 :             c = CP_TYPE_CONTEXT (c);
    7558            2 :           if (!TYPE_P (c))
    7559              :             return false;
    7560              :         }
    7561              :       /* Create the X C::* type.  */
    7562            9 :       tree type = build_offset_type (CP_DECL_CONTEXT (r), TREE_TYPE (r));
    7563            9 :       if (similar_type_p (type, T) && is_convertible (type, T))
    7564              :         return true;
    7565            0 :       return false;
    7566              :     }
    7567           66 :   else if (DECL_IOBJ_MEMBER_FUNCTION_P (r))
    7568              :     {
    7569           43 :       tree F = TREE_TYPE (r);
    7570           43 :       F = build_pointer_type (F);
    7571           43 :       F = build_ptrmemfunc_type (F);
    7572           43 :       if (same_type_p (T, F) || fnptr_conv_p (T, F))
    7573           17 :         return true;
    7574              :       return false;
    7575              :     }
    7576           23 :   else if (TREE_CODE (r) == FUNCTION_DECL)
    7577              :     {
    7578           23 :       tree F = TREE_TYPE (r);
    7579           23 :       F = build_pointer_type (F);
    7580           23 :       if (same_type_p (T, F) || fnptr_conv_p (T, F))
    7581           15 :         return true;
    7582              :       return false;
    7583              :     }
    7584              : 
    7585              :   return false;
    7586              : }
    7587              : 
    7588              : /* Helper for eval_extract, extracting a NSDM or function.
    7589              :    Returns:
    7590              :    -- If T is a pointer type, then a pointer value pointing to the function
    7591              :       represented by r.
    7592              :    -- Otherwise, a pointer-to-member value designating the non-static data
    7593              :       member or function represented by r.
    7594              :    Throws: meta::exception unless
    7595              :    -- r represents a non-static data member with type X, that is not
    7596              :       a bit-field, that is a direct member of class C, T and X C::*
    7597              :       are similar types, and is_convertible_v<X C::*, T> is true;
    7598              :    -- r represents an implicit object member function with type F or
    7599              :       F noexcept that is a direct member of a class C, and T is F C::*; or
    7600              :    -- r represents a non-member function, static member function, or
    7601              :       explicit object member function of function type F or F noexcept, and
    7602              :       T is F*.  */
    7603              : 
    7604              : static tree
    7605           81 : extract_member_or_function (location_t loc, const constexpr_ctx *ctx,
    7606              :                             tree T, tree r, reflect_kind kind,
    7607              :                             bool *non_constant_p, tree *jump_target, tree fun)
    7608              : {
    7609           81 :   r = MAYBE_BASELINK_FUNCTIONS (r);
    7610           81 :   if (!can_extract_member_or_function_p (T, r, kind))
    7611           40 :     return throw_exception (loc, ctx, "value cannot be extracted", fun,
    7612           40 :                             non_constant_p, jump_target);
    7613              : 
    7614           41 :   const tsubst_flags_t complain = complain_flags (ctx);
    7615           41 :   if (POINTER_TYPE_P (T))
    7616              :     {
    7617           15 :       r = cp_build_addr_expr (r, complain);
    7618           15 :       return perform_implicit_conversion (T, r, complain);
    7619              :     }
    7620              :   else
    7621              :     {
    7622           26 :       if (!mark_used (r, complain))
    7623              :         {
    7624            0 :           *non_constant_p = true;
    7625            0 :           return NULL_TREE;
    7626              :         }
    7627           26 :       r = build_offset_ref (DECL_CONTEXT (r), r, /*address_p=*/true, complain);
    7628           26 :       r = cp_build_addr_expr (r, complain);
    7629           26 :       r = cp_convert (T, r, complain);
    7630           26 :       return r;
    7631              :     }
    7632              : }
    7633              : 
    7634              : /* Process std::meta::extract.
    7635              :    Let U be remove_cv_t<T>.
    7636              :    Effects: Equivalent to:
    7637              :      if constexpr (is_reference_type(^^T)) {
    7638              :        return extract-ref<T>(r);
    7639              :      } else if constexpr (is_nonstatic_data_member(r) || is_function(r)) {
    7640              :        return extract-member-or-function<U>(r);
    7641              :      } else {
    7642              :        return extract-value<U>(constant_of(r));
    7643              :      }
    7644              :   */
    7645              : 
    7646              : static tree
    7647          511 : eval_extract (location_t loc, const constexpr_ctx *ctx, tree type, tree r,
    7648              :               reflect_kind kind, bool *non_constant_p, bool *overflow_p,
    7649              :               tree *jump_target, tree fun)
    7650              : {
    7651          511 :   if (eval_is_reference_type (loc, type) == boolean_true_node)
    7652           70 :     return extract_ref (loc, ctx, type, r, kind, non_constant_p, jump_target,
    7653           70 :                         fun);
    7654          441 :   type = cv_unqualified (type);
    7655          441 :   if (eval_is_nonstatic_data_member (r) == boolean_true_node
    7656          441 :       || eval_is_function (r) == boolean_true_node)
    7657           81 :     return extract_member_or_function (loc, ctx, type, r, kind, non_constant_p,
    7658           81 :                                        jump_target, fun);
    7659              :   else
    7660              :     {
    7661          360 :       r = eval_constant_of (loc, ctx, r, kind, non_constant_p, overflow_p,
    7662              :                             jump_target, fun);
    7663          360 :       if (*jump_target || *non_constant_p)
    7664              :         return NULL_TREE;
    7665          355 :       return extract_value (loc, ctx, type, r, non_constant_p, jump_target,
    7666          355 :                             fun);
    7667              :     }
    7668              : }
    7669              : 
    7670              : /* Diagnose incorrect type of metafn argument and return true in that
    7671              :    case.  */
    7672              : 
    7673              : static bool
    7674         5083 : check_metafn_arg_type (location_t loc, metafn_kind_arg kind, int n, tree type,
    7675              :                        bool *non_constant_p)
    7676              : {
    7677         5083 :   tree expected = NULL_TREE;
    7678         5083 :   const char *expected_str = NULL;
    7679         5083 :   switch ((metafn_kind_arg) kind)
    7680              :     {
    7681              :     case METAFN_KIND_ARG_VOID:
    7682              :       break;
    7683            0 :     case METAFN_KIND_ARG_INFO:
    7684            0 :     case METAFN_KIND_ARG_TINFO:
    7685            0 :       if (!REFLECTION_TYPE_P (type))
    7686            0 :         expected = meta_info_type_node;
    7687              :       break;
    7688              :     case METAFN_KIND_ARG_REFLECTION_RANGE:
    7689              :     case METAFN_KIND_ARG_REFLECTION_RANGET:
    7690              :     case METAFN_KIND_ARG_INPUT_RANGE:
    7691              :       break;
    7692           54 :     case METAFN_KIND_ARG_SIZE_T:
    7693           54 :       if (!same_type_ignoring_top_level_qualifiers_p (type, size_type_node))
    7694         5083 :         expected_str = "std::size_t";
    7695              :       break;
    7696          114 :     case METAFN_KIND_ARG_UNSIGNED:
    7697          114 :       if (!same_type_ignoring_top_level_qualifiers_p (type,
    7698              :                                                       unsigned_type_node))
    7699            3 :         expected = unsigned_type_node;
    7700              :       break;
    7701          149 :     case METAFN_KIND_ARG_OPERATORS:
    7702          149 :       if (TREE_CODE (type) != ENUMERAL_TYPE
    7703          146 :           || TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)
    7704          295 :           || TYPE_CONTEXT (type) != std_meta_node)
    7705              :         expected_str = "std::meta::operators";
    7706              :       break;
    7707         3757 :     case METAFN_KIND_ARG_ACCESS_CONTEXT:
    7708         3757 :       if (TYPE_REF_P (type))
    7709            0 :         type = TREE_TYPE (type);
    7710         3757 :       if (!is_std_meta_class (type, "access_context"))
    7711            0 :         expected_str = "std::meta::access_context";
    7712              :       break;
    7713          367 :     case METAFN_KIND_ARG_DATA_MEMBER_OPTIONS:
    7714          367 :       if (TYPE_REF_P (type))
    7715          364 :         type = TREE_TYPE (type);
    7716          367 :       if (!is_std_meta_class (type, "data_member_options"))
    7717            3 :         expected_str = "std::meta::data_member_options";
    7718              :       break;
    7719              :     case METAFN_KIND_ARG_TEMPLATE_PARM:
    7720              :     case METAFN_KIND_ARG_TEMPLATE_PARM_REF:
    7721              :       break;
    7722              :     }
    7723         5083 :   if (expected || expected_str)
    7724              :     {
    7725           12 :       if (expected_str)
    7726            9 :         error_at (loc, "incorrect %qT type of argument %d, expected %qs",
    7727              :                   type, n + 1, expected_str);
    7728              :       else
    7729            3 :         error_at (loc, "incorrect %qT type of argument %d, expected %qT",
    7730              :                   type, n + 1, expected);
    7731           12 :       *non_constant_p = true;
    7732           12 :       return true;
    7733              :     }
    7734              :   return false;
    7735              : }
    7736              : 
    7737              : /* Diagnose incorrect return type of metafn and return true in that case.  */
    7738              : 
    7739              : static bool
    7740        26680 : check_metafn_return_type (location_t loc, metafn_kind_ret kind, tree type,
    7741              :                           bool *non_constant_p)
    7742              : {
    7743        26680 :   tree expected = NULL_TREE;
    7744        26680 :   const char *expected_str = NULL;
    7745        26680 :   switch (kind)
    7746              :     {
    7747        14056 :     case METAFN_KIND_RET_BOOL:
    7748        14056 :       if (TREE_CODE (type) != BOOLEAN_TYPE)
    7749            3 :         expected = boolean_type_node;
    7750              :       break;
    7751         4136 :     case METAFN_KIND_RET_INFO:
    7752         4136 :       if (!REFLECTION_TYPE_P (type))
    7753            1 :         expected = meta_info_type_node;
    7754              :       break;
    7755          489 :     case METAFN_KIND_RET_SIZE_T:
    7756          489 :       if (!same_type_ignoring_top_level_qualifiers_p (type, size_type_node))
    7757        26680 :         expected_str = "std::size_t";
    7758              :       break;
    7759          126 :     case METAFN_KIND_RET_MEMBER_OFFSET:
    7760          126 :       if (!is_std_meta_class (type, "member_offset"))
    7761        26680 :         expected_str = "std::meta::member_offset";
    7762              :       break;
    7763          243 :     case METAFN_KIND_RET_OPERATORS:
    7764          243 :       if (TREE_CODE (type) != ENUMERAL_TYPE
    7765          240 :           || TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)
    7766          483 :           || TYPE_CONTEXT (type) != std_meta_node)
    7767              :         expected_str = "std::meta::operators";
    7768              :       break;
    7769           61 :     case METAFN_KIND_RET_SOURCE_LOCATION:
    7770           61 :       if (!is_std_class (type, "source_location"))
    7771        26680 :         expected_str = "std::source_location";
    7772              :       break;
    7773          676 :     case METAFN_KIND_RET_STRING_VIEW:
    7774          676 :       if (!CLASS_TYPE_P (type))
    7775              :         expected_str = "std::string_view";
    7776              :       break;
    7777         1791 :     case METAFN_KIND_RET_U8STRING_VIEW:
    7778         1791 :       if (!CLASS_TYPE_P (type))
    7779              :         expected_str = "std::u8string_view";
    7780              :       break;
    7781           63 :     case METAFN_KIND_RET_STRONG_ORDERING:
    7782           63 :       if (!is_std_class (type, "strong_ordering"))
    7783        26680 :         expected_str = "std::strong_ordering";
    7784              :       break;
    7785         4255 :     case METAFN_KIND_RET_VECTOR_INFO:
    7786         4255 :       if (!CLASS_TYPE_P (type))
    7787              :         expected_str = "std::vector<std::meta::info>";
    7788              :       break;
    7789          273 :     case METAFN_KIND_RET_ACCESS_CONTEXT:
    7790          273 :       if (!is_std_meta_class (type, "access_context"))
    7791        26680 :         expected_str = "std::meta::access_context";
    7792              :       break;
    7793              :     case METAFN_KIND_RET_TEMPLATE_PARM:
    7794              :       break;
    7795              :     }
    7796        26680 :   if (expected || expected_str)
    7797              :     {
    7798           32 :       if (expected_str)
    7799           28 :         error_at (loc, "incorrect %qT return type, expected %qs",
    7800              :                   type, expected_str);
    7801              :       else
    7802            4 :         error_at (loc, "incorrect %qT return type, expected %qT",
    7803              :                   type, expected);
    7804           32 :       *non_constant_p = true;
    7805           32 :       return true;
    7806              :     }
    7807              :   return false;
    7808              : }
    7809              : 
    7810              : /* Expand a call to a metafunction FUN.  CALL is the CALL_EXPR.
    7811              :    JUMP_TARGET is set if we are throwing std::meta::exception.  */
    7812              : 
    7813              : tree
    7814        26680 : process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
    7815              :                       bool *non_constant_p, bool *overflow_p,
    7816              :                       tree *jump_target)
    7817              : {
    7818        26680 :   tree name = DECL_NAME (fun);
    7819        26680 :   const char *ident = IDENTIFIER_POINTER (name);
    7820        26680 :   const location_t loc = cp_expr_loc_or_input_loc (call);
    7821        26680 :   const metafn_info *minfo
    7822        26680 :     = metafn_lookup::find (ident, IDENTIFIER_LENGTH (name));
    7823        26680 :   if (minfo == NULL)
    7824              :     {
    7825            0 :     not_found:
    7826            0 :       error_at (loc, "unknown metafunction %qD", fun);
    7827            0 :       *non_constant_p = true;
    7828            0 :       return NULL_TREE;
    7829              :     }
    7830        26680 :   tree h = NULL_TREE, h1 = NULL_TREE, hvec = NULL_TREE, expr = NULL_TREE;
    7831        26680 :   tree type = NULL_TREE, ht, info;
    7832        26680 :   reflect_kind kind = REFLECT_UNDEF;
    7833        26680 :   tree rettype;
    7834        26680 :   if (TREE_CODE (call) == AGGR_INIT_EXPR)
    7835         4249 :     rettype = TREE_TYPE (AGGR_INIT_EXPR_SLOT (call));
    7836              :   else
    7837        22431 :     rettype = TREE_TYPE (call);
    7838        26680 :   if (check_metafn_return_type (loc, METAFN_KIND_RET (minfo), rettype,
    7839              :                                 non_constant_p))
    7840              :     return NULL_TREE;
    7841       105321 :   for (int argno = 0; argno < 3; ++argno)
    7842        79109 :     switch (METAFN_KIND_ARG (minfo, argno))
    7843              :       {
    7844              :       case METAFN_KIND_ARG_VOID:
    7845              :         break;
    7846        24350 :       case METAFN_KIND_ARG_INFO:
    7847        24350 :       case METAFN_KIND_ARG_TINFO:
    7848        24350 :         gcc_assert (argno < 2);
    7849        24350 :         info = get_info (loc, ctx, call, argno, non_constant_p, overflow_p,
    7850              :                          jump_target);
    7851        24350 :         if (*jump_target || *non_constant_p)
    7852              :           return NULL_TREE;
    7853        24316 :         ht = REFLECT_EXPR_HANDLE (info);
    7854        24316 :         if (METAFN_KIND_ARG (minfo, argno) == METAFN_KIND_ARG_TINFO
    7855        24316 :             && eval_is_type (ht) != boolean_true_node)
    7856          371 :           return throw_exception_nontype (loc, ctx, fun, non_constant_p,
    7857          371 :                                           jump_target);
    7858        23945 :         if (argno == 0)
    7859              :           {
    7860        22955 :             kind = REFLECT_EXPR_KIND (info);
    7861        22955 :             h = ht;
    7862              :           }
    7863              :         else
    7864              :           h1 = ht;
    7865              :         break;
    7866          536 :       case METAFN_KIND_ARG_REFLECTION_RANGE:
    7867          536 :         gcc_assert (argno == 1);
    7868          536 :         hvec = get_info_vec (loc, ctx, call, argno, non_constant_p,
    7869              :                              overflow_p, jump_target, fun);
    7870          536 :         if (*jump_target || *non_constant_p)
    7871              :           return NULL_TREE;
    7872              :         break;
    7873         1071 :       case METAFN_KIND_ARG_REFLECTION_RANGET:
    7874         1071 :         hvec = get_type_info_vec (loc, ctx, call, argno, non_constant_p,
    7875              :                                 overflow_p, jump_target, fun);
    7876         1071 :         if (*jump_target || *non_constant_p)
    7877              :           return NULL_TREE;
    7878              :         break;
    7879         1898 :       case METAFN_KIND_ARG_INPUT_RANGE:
    7880              :         /* Handled in eval_reflect_constant_*.  */
    7881         1898 :         gcc_assert (argno == 0);
    7882              :         break;
    7883          642 :       case METAFN_KIND_ARG_TEMPLATE_PARM:
    7884          642 :       case METAFN_KIND_ARG_TEMPLATE_PARM_REF:
    7885          642 :         type = TREE_VEC_ELT (get_template_innermost_arguments (fun), 0);
    7886              :         /* FALLTHRU */
    7887          845 :       case METAFN_KIND_ARG_SIZE_T:
    7888          845 :       case METAFN_KIND_ARG_OPERATORS:
    7889          845 :         gcc_assert (argno == 0);
    7890          845 :         expr = get_nth_callarg (call, 0);
    7891          845 :         if (check_metafn_arg_type (loc, METAFN_KIND_ARG (minfo, argno), 0,
    7892          845 :                                    TREE_TYPE (expr), non_constant_p))
    7893              :           return NULL_TREE;
    7894          839 :         expr = cxx_eval_constant_expression (ctx, expr, vc_prvalue,
    7895              :                                              non_constant_p, overflow_p,
    7896              :                                              jump_target);
    7897          839 :         if (*jump_target || *non_constant_p)
    7898              :           return NULL_TREE;
    7899              :         break;
    7900         4238 :       case METAFN_KIND_ARG_UNSIGNED:
    7901         4238 :       case METAFN_KIND_ARG_ACCESS_CONTEXT:
    7902         4238 :       case METAFN_KIND_ARG_DATA_MEMBER_OPTIONS:
    7903         4238 :         gcc_assert (argno == 1);
    7904         4238 :         expr = get_nth_callarg (call, argno);
    7905         4238 :         if (check_metafn_arg_type (loc, METAFN_KIND_ARG (minfo, argno), 1,
    7906         4238 :                                    TREE_TYPE (expr), non_constant_p))
    7907              :           return NULL_TREE;
    7908         4232 :         expr = cxx_eval_constant_expression (ctx, expr, vc_prvalue,
    7909              :                                              non_constant_p, overflow_p,
    7910              :                                              jump_target);
    7911         4232 :         if (*jump_target || *non_constant_p)
    7912              :           return NULL_TREE;
    7913              :         break;
    7914            0 :       default:
    7915            0 :         gcc_unreachable ();
    7916              :       }
    7917              : 
    7918        26212 :   switch (minfo->code)
    7919              :     {
    7920          240 :     case METAFN_OPERATOR_OF:
    7921          240 :       return eval_operator_of (loc, ctx, h, non_constant_p, jump_target,
    7922          240 :                                rettype, fun);
    7923           96 :     case METAFN_SYMBOL_OF:
    7924           96 :       return eval_symbol_of (loc, ctx, expr, non_constant_p, jump_target,
    7925           96 :                              char_type_node, rettype, fun);
    7926           50 :     case METAFN_U8SYMBOL_OF:
    7927           50 :       return eval_symbol_of (loc, ctx, expr, non_constant_p, jump_target,
    7928           50 :                              char8_type_node, rettype, fun);
    7929          420 :     case METAFN_HAS_IDENTIFIER:
    7930          420 :       return eval_has_identifier (h, kind);
    7931          433 :     case METAFN_IDENTIFIER_OF:
    7932          433 :       return eval_identifier_of (loc, ctx, h, kind, non_constant_p, jump_target,
    7933          433 :                                  char_type_node, rettype, fun);
    7934           59 :     case METAFN_U8IDENTIFIER_OF:
    7935           59 :       return eval_identifier_of (loc, ctx, h, kind, non_constant_p, jump_target,
    7936           59 :                                  char8_type_node, rettype, fun);
    7937          114 :     case METAFN_DISPLAY_STRING_OF:
    7938          114 :       return eval_display_string_of (loc, ctx, h, kind, non_constant_p,
    7939              :                                      jump_target, char_type_node,
    7940          114 :                                      rettype, fun);
    7941          109 :     case METAFN_U8DISPLAY_STRING_OF:
    7942          109 :       return eval_display_string_of (loc, ctx, h, kind, non_constant_p,
    7943              :                                      jump_target, char8_type_node,
    7944          109 :                                      rettype, fun);
    7945           58 :     case METAFN_SOURCE_LOCATION_OF:
    7946           58 :       return eval_source_location_of (loc, h, kind, rettype);
    7947          642 :     case METAFN_TYPE_OF:
    7948          642 :       return eval_type_of (loc, ctx, h, kind, non_constant_p, jump_target, fun);
    7949           67 :     case METAFN_OBJECT_OF:
    7950           67 :       return eval_object_of (loc, ctx, h, kind, non_constant_p, overflow_p,
    7951           67 :                              jump_target, fun);
    7952          189 :     case METAFN_CONSTANT_OF:
    7953          189 :       return eval_constant_of (loc, ctx, h, kind, non_constant_p, overflow_p,
    7954          189 :                                jump_target, fun);
    7955           86 :     case METAFN_IS_PUBLIC:
    7956           86 :       return eval_is_public (h, kind);
    7957           69 :     case METAFN_IS_PROTECTED:
    7958           69 :       return eval_is_protected (h, kind);
    7959           64 :     case METAFN_IS_PRIVATE:
    7960           64 :       return eval_is_private (h, kind);
    7961           17 :     case METAFN_IS_VIRTUAL:
    7962           17 :       return eval_is_virtual (h, kind);
    7963           14 :     case METAFN_IS_PURE_VIRTUAL:
    7964           14 :       return eval_is_pure_virtual (h);
    7965           70 :     case METAFN_IS_OVERRIDE:
    7966           70 :       return eval_is_override (h);
    7967           20 :     case METAFN_IS_FINAL:
    7968           20 :       return eval_is_final (h);
    7969           82 :     case METAFN_IS_DELETED:
    7970           82 :       return eval_is_deleted (h);
    7971          347 :     case METAFN_IS_DEFAULTED:
    7972          347 :       return eval_is_defaulted (h);
    7973          106 :     case METAFN_IS_USER_PROVIDED:
    7974          106 :       return eval_is_user_provided (h);
    7975          106 :     case METAFN_IS_USER_DECLARED:
    7976          106 :       return eval_is_user_declared (h);
    7977           22 :     case METAFN_IS_EXPLICIT:
    7978           22 :       return eval_is_explicit (h);
    7979          171 :     case METAFN_IS_NOEXCEPT:
    7980          171 :       return eval_is_noexcept (h);
    7981           95 :     case METAFN_IS_BIT_FIELD:
    7982           95 :       return eval_is_bit_field (h, kind);
    7983           49 :     case METAFN_IS_ENUMERATOR:
    7984           49 :       return eval_is_enumerator (h);
    7985            3 :     case METAFN_IS_ANNOTATION:
    7986            3 :       return eval_is_annotation (h, kind);
    7987           73 :     case METAFN_IS_CONST:
    7988           73 :       return eval_is_const (h, kind);
    7989           55 :     case METAFN_IS_VOLATILE:
    7990           55 :       return eval_is_volatile (h, kind);
    7991           64 :     case METAFN_IS_MUTABLE_MEMBER:
    7992           64 :       return eval_is_mutable_member (h);
    7993           24 :     case METAFN_IS_LVALUE_REFERENCE_QUALIFIED:
    7994           24 :       return eval_is_lrvalue_reference_qualified (h, kind, /*rvalue_p=*/false);
    7995           21 :     case METAFN_IS_RVALUE_REFERENCE_QUALIFIED:
    7996           21 :       return eval_is_lrvalue_reference_qualified (h, kind, /*rvalue_p=*/true);
    7997           70 :     case METAFN_HAS_STATIC_STORAGE_DURATION:
    7998           70 :       return eval_has_static_storage_duration (h, kind);
    7999           70 :     case METAFN_HAS_THREAD_STORAGE_DURATION:
    8000           70 :       return eval_has_thread_storage_duration (h, kind);
    8001           70 :     case METAFN_HAS_AUTOMATIC_STORAGE_DURATION:
    8002           70 :       return eval_has_automatic_storage_duration (h, kind);
    8003           63 :     case METAFN_HAS_INTERNAL_LINKAGE:
    8004           63 :       return eval_has_internal_linkage (h, kind);
    8005           63 :     case METAFN_HAS_MODULE_LINKAGE:
    8006           63 :       return eval_has_module_linkage (h, kind);
    8007           63 :     case METAFN_HAS_EXTERNAL_LINKAGE:
    8008           63 :       return eval_has_external_linkage (h, kind);
    8009           66 :     case METAFN_HAS_C_LANGUAGE_LINKAGE:
    8010           66 :       return eval_has_c_language_linkage (h, kind);
    8011           62 :     case METAFN_HAS_LINKAGE:
    8012           62 :       return eval_has_linkage (h, kind);
    8013          122 :     case METAFN_IS_COMPLETE_TYPE:
    8014          122 :       return eval_is_complete_type (h);
    8015           43 :     case METAFN_IS_ENUMERABLE_TYPE:
    8016           43 :       return eval_is_enumerable_type (h);
    8017          161 :     case METAFN_IS_VARIABLE:
    8018          161 :       return eval_is_variable (h, kind);
    8019          250 :     case METAFN_IS_TYPE:
    8020          250 :       return eval_is_type (h);
    8021          124 :     case METAFN_IS_NAMESPACE:
    8022          124 :       return eval_is_namespace (h);
    8023           84 :     case METAFN_IS_TYPE_ALIAS:
    8024           84 :       return eval_is_type_alias (h);
    8025          119 :     case METAFN_IS_NAMESPACE_ALIAS:
    8026          119 :       return eval_is_namespace_alias (h);
    8027          115 :     case METAFN_IS_FUNCTION:
    8028          115 :       return eval_is_function (h);
    8029           15 :     case METAFN_IS_CONVERSION_FUNCTION:
    8030           15 :       return eval_is_conversion_function (h);
    8031          159 :     case METAFN_IS_OPERATOR_FUNCTION:
    8032          159 :       return eval_is_operator_function (h);
    8033           15 :     case METAFN_IS_LITERAL_OPERATOR:
    8034           15 :       return eval_is_literal_operator (h);
    8035          810 :     case METAFN_IS_SPECIAL_MEMBER_FUNCTION:
    8036          810 :       return eval_is_special_member_function (h);
    8037          585 :     case METAFN_IS_CONSTRUCTOR:
    8038          585 :       return eval_is_constructor (h);
    8039          371 :     case METAFN_IS_DEFAULT_CONSTRUCTOR:
    8040          371 :       return eval_is_default_constructor (h);
    8041          380 :     case METAFN_IS_COPY_CONSTRUCTOR:
    8042          380 :       return eval_is_copy_constructor (h);
    8043          359 :     case METAFN_IS_MOVE_CONSTRUCTOR:
    8044          359 :       return eval_is_move_constructor (h);
    8045           10 :     case METAFN_IS_ASSIGNMENT:
    8046           10 :       return eval_is_assignment (h);
    8047          382 :     case METAFN_IS_COPY_ASSIGNMENT:
    8048          382 :       return eval_is_copy_assignment (h);
    8049          376 :     case METAFN_IS_MOVE_ASSIGNMENT:
    8050          376 :       return eval_is_move_assignment (h);
    8051          994 :     case METAFN_IS_DESTRUCTOR:
    8052          994 :       return eval_is_destructor (h);
    8053           58 :     case METAFN_IS_FUNCTION_PARAMETER:
    8054           58 :       return eval_is_function_parameter (h, kind);
    8055           73 :     case METAFN_IS_EXPLICIT_OBJECT_PARAMETER:
    8056           73 :       return eval_is_explicit_object_parameter (h, kind);
    8057           79 :     case METAFN_HAS_DEFAULT_ARGUMENT:
    8058           79 :       return eval_has_default_argument (h, kind);
    8059           72 :     case METAFN_IS_VARARG_FUNCTION:
    8060           72 :       return eval_is_vararg_function (h);
    8061           56 :     case METAFN_IS_TEMPLATE:
    8062           56 :       return eval_is_template (h);
    8063           56 :     case METAFN_IS_FUNCTION_TEMPLATE:
    8064           56 :       return eval_is_function_template (h);
    8065           47 :     case METAFN_IS_VARIABLE_TEMPLATE:
    8066           47 :       return eval_is_variable_template (h);
    8067           47 :     case METAFN_IS_CLASS_TEMPLATE:
    8068           47 :       return eval_is_class_template (h);
    8069           47 :     case METAFN_IS_ALIAS_TEMPLATE:
    8070           47 :       return eval_is_alias_template (h);
    8071           19 :     case METAFN_IS_CONVERSION_FUNCTION_TEMPLATE:
    8072           19 :       return eval_is_conversion_function_template (h);
    8073           20 :     case METAFN_IS_OPERATOR_FUNCTION_TEMPLATE:
    8074           20 :       return eval_is_operator_function_template (h);
    8075           15 :     case METAFN_IS_LITERAL_OPERATOR_TEMPLATE:
    8076           15 :       return eval_is_literal_operator_template (h);
    8077           18 :     case METAFN_IS_CONSTRUCTOR_TEMPLATE:
    8078           18 :       return eval_is_constructor_template (h);
    8079          111 :     case METAFN_IS_CONCEPT:
    8080          111 :       return eval_is_concept (h);
    8081           69 :     case METAFN_IS_VALUE:
    8082           69 :       return eval_is_value (kind);
    8083          135 :     case METAFN_IS_OBJECT:
    8084          135 :       return eval_is_object (kind);
    8085           40 :     case METAFN_IS_STRUCTURED_BINDING:
    8086           40 :       return eval_is_structured_binding (h, kind);
    8087           62 :     case METAFN_IS_CLASS_MEMBER:
    8088           62 :       return eval_is_class_member (h);
    8089           71 :     case METAFN_IS_NAMESPACE_MEMBER:
    8090           71 :       return eval_is_namespace_member (h);
    8091           62 :     case METAFN_IS_NONSTATIC_DATA_MEMBER:
    8092           62 :       return eval_is_nonstatic_data_member (h);
    8093           68 :     case METAFN_IS_STATIC_MEMBER:
    8094           68 :       return eval_is_static_member (h);
    8095           15 :     case METAFN_IS_BASE:
    8096           15 :       return eval_is_base (h, kind);
    8097           64 :     case METAFN_HAS_DEFAULT_MEMBER_INITIALIZER:
    8098           64 :       return eval_has_default_member_initializer (h);
    8099           57 :     case METAFN_HAS_PARENT:
    8100           57 :       return eval_has_parent (h, kind);
    8101          421 :     case METAFN_PARENT_OF:
    8102          421 :       return eval_parent_of (loc, ctx, h, kind, non_constant_p, jump_target,
    8103          421 :                              fun);
    8104           94 :     case METAFN_DEALIAS:
    8105           94 :       return eval_dealias (loc, h, kind);
    8106           96 :     case METAFN_HAS_TEMPLATE_ARGUMENTS:
    8107           96 :       return eval_has_template_arguments (h);
    8108           39 :     case METAFN_TEMPLATE_OF:
    8109           39 :       return eval_template_of (loc, ctx, h, non_constant_p, jump_target, fun);
    8110          101 :     case METAFN_TEMPLATE_ARGUMENTS_OF:
    8111          101 :       return eval_template_arguments_of (loc, ctx, h, non_constant_p,
    8112          101 :                                          jump_target, fun);
    8113          348 :     case METAFN_PARAMETERS_OF:
    8114          348 :       return eval_parameters_of (loc, ctx, h, non_constant_p, jump_target,
    8115          348 :                                  fun);
    8116          120 :     case METAFN_VARIABLE_OF:
    8117          120 :       return eval_variable_of (loc, ctx, h, kind, non_constant_p, jump_target,
    8118          120 :                                fun);
    8119           63 :     case METAFN_RETURN_TYPE_OF:
    8120           63 :       return eval_return_type_of (loc, ctx, h, kind, non_constant_p,
    8121           63 :                                   jump_target, fun);
    8122          417 :     case METAFN_IS_ACCESSIBLE:
    8123          417 :       return eval_is_accessible (loc, ctx, h, kind, expr, call,
    8124          417 :                                  non_constant_p, jump_target, fun);
    8125           15 :     case METAFN_HAS_INACCESSIBLE_NONSTATIC_DATA_MEMBERS:
    8126           15 :       return eval_has_inaccessible_nonstatic_data_members (loc, ctx, h, expr,
    8127              :                                                            call,
    8128              :                                                            non_constant_p,
    8129           15 :                                                            jump_target, fun);
    8130           12 :     case METAFN_HAS_INACCESSIBLE_BASES:
    8131           12 :       return eval_has_inaccessible_bases (loc, ctx, h, expr, call,
    8132           12 :                                           non_constant_p, jump_target, fun);
    8133           19 :     case METAFN_HAS_INACCESSIBLE_SUBOBJECTS:
    8134           19 :       return eval_has_inaccessible_subobjects (loc, ctx, h, expr, call,
    8135              :                                                non_constant_p, jump_target,
    8136           19 :                                                fun);
    8137           64 :     case METAFN_CURRENT_FUNCTION:
    8138           64 :       return eval_current_function (loc, ctx, call, non_constant_p,
    8139           64 :                                     jump_target, fun);
    8140           68 :     case METAFN_CURRENT_CLASS:
    8141           68 :       return eval_current_class (loc, ctx, call, non_constant_p,
    8142           68 :                                  jump_target, fun);
    8143           34 :     case METAFN_CURRENT_NAMESPACE:
    8144           34 :       return eval_current_namespace (loc, ctx, call, non_constant_p);
    8145         2381 :     case METAFN_MEMBERS_OF:
    8146         2381 :       return eval_members_of (loc, ctx, h, expr, call, non_constant_p,
    8147         2381 :                               jump_target, fun);
    8148          495 :     case METAFN_BASES_OF:
    8149          495 :       return eval_bases_of (loc, ctx, h, expr, call, non_constant_p,
    8150          495 :                             jump_target, fun);
    8151           80 :     case METAFN_STATIC_DATA_MEMBERS_OF:
    8152           80 :       return eval_static_data_members_of (loc, ctx, h, expr, call,
    8153              :                                           non_constant_p, jump_target,
    8154           80 :                                           fun);
    8155          162 :     case METAFN_NONSTATIC_DATA_MEMBERS_OF:
    8156          162 :       return eval_nonstatic_data_members_of (loc, ctx, h, expr, call,
    8157              :                                              non_constant_p, jump_target,
    8158          162 :                                              fun);
    8159          176 :     case METAFN_SUBOBJECTS_OF:
    8160          176 :       return eval_subobjects_of (loc, ctx, h, expr, call, non_constant_p,
    8161          176 :                                  jump_target, fun);
    8162          169 :     case METAFN_ENUMERATORS_OF:
    8163          169 :       return eval_enumerators_of (loc, ctx, h, non_constant_p, jump_target,
    8164          169 :                                   fun);
    8165          123 :     case METAFN_OFFSET_OF:
    8166          123 :       return eval_offset_of (loc, ctx, h, kind, rettype,
    8167          123 :                              non_constant_p, jump_target, fun);
    8168           99 :     case METAFN_SIZE_OF:
    8169           99 :       return eval_size_of (loc, ctx, h, kind, rettype, non_constant_p,
    8170           99 :                            jump_target, fun);
    8171          105 :     case METAFN_ALIGNMENT_OF:
    8172          105 :       return eval_alignment_of (loc, ctx, h, kind, rettype,
    8173          105 :                                 non_constant_p, jump_target, fun);
    8174          100 :     case METAFN_BIT_SIZE_OF:
    8175          100 :       return eval_bit_size_of (loc, ctx, h, kind, rettype,
    8176          100 :                                non_constant_p, jump_target, fun);
    8177          511 :     case METAFN_EXTRACT:
    8178          511 :       {
    8179          511 :         type = TREE_VEC_ELT (get_template_innermost_arguments (fun), 0);
    8180          511 :         return eval_extract (loc, ctx, type, h, kind, non_constant_p,
    8181          511 :                              overflow_p, jump_target, fun);
    8182              :       }
    8183          146 :     case METAFN_CAN_SUBSTITUTE:
    8184          146 :       return eval_can_substitute (loc, ctx, h, hvec, non_constant_p,
    8185          146 :                                   jump_target, fun);
    8186          292 :     case METAFN_SUBSTITUTE:
    8187          292 :       return eval_substitute (loc, ctx, h, hvec, non_constant_p, jump_target,
    8188          292 :                               fun);
    8189          489 :     case METAFN_REFLECT_CONSTANT:
    8190          489 :       return eval_reflect_constant (loc, ctx, type, expr, non_constant_p,
    8191          489 :                                     jump_target, fun);
    8192          122 :     case METAFN_REFLECT_OBJECT:
    8193          122 :       return eval_reflect_object (loc, ctx, type, expr, non_constant_p,
    8194          122 :                                   jump_target, fun);
    8195           29 :     case METAFN_REFLECT_FUNCTION:
    8196           29 :       return eval_reflect_function (loc, ctx, type, expr, non_constant_p,
    8197           29 :                                     jump_target, fun);
    8198          140 :     case METAFN_REFLECT_CONSTANT_STRING:
    8199          140 :       return eval_reflect_constant_string (loc, ctx, call, non_constant_p,
    8200          140 :                                            overflow_p, jump_target, fun);
    8201          159 :     case METAFN_REFLECT_CONSTANT_ARRAY:
    8202          159 :       return eval_reflect_constant_array (loc, ctx, call, non_constant_p,
    8203          159 :                                           overflow_p, jump_target, fun);
    8204          364 :     case METAFN_DATA_MEMBER_SPEC:
    8205          364 :       return eval_data_member_spec (loc, ctx, h, expr, non_constant_p,
    8206          364 :                                     overflow_p, jump_target, fun);
    8207           54 :     case METAFN_IS_DATA_MEMBER_SPEC:
    8208           54 :       return eval_is_data_member_spec (h, kind);
    8209           97 :     case METAFN_DEFINE_AGGREGATE:
    8210           97 :       return eval_define_aggregate (loc, ctx, h, hvec, call, non_constant_p);
    8211           29 :     case METAFN_IS_VOID_TYPE:
    8212           29 :       return eval_is_void_type (h);
    8213           26 :     case METAFN_IS_NULL_POINTER_TYPE:
    8214           26 :       return eval_is_null_pointer_type (h);
    8215          130 :     case METAFN_IS_INTEGRAL_TYPE:
    8216          130 :       return eval_is_integral_type (h);
    8217           28 :     case METAFN_IS_FLOATING_POINT_TYPE:
    8218           28 :       return eval_is_floating_point_type (h);
    8219           91 :     case METAFN_IS_ARRAY_TYPE:
    8220           91 :       return eval_is_array_type (loc, h);
    8221           28 :     case METAFN_IS_POINTER_TYPE:
    8222           28 :       return eval_is_pointer_type (loc, h);
    8223           26 :     case METAFN_IS_LVALUE_REFERENCE_TYPE:
    8224           26 :       return eval_is_lvalue_reference_type (h);
    8225           26 :     case METAFN_IS_RVALUE_REFERENCE_TYPE:
    8226           26 :       return eval_is_rvalue_reference_type (h);
    8227           26 :     case METAFN_IS_MEMBER_OBJECT_POINTER_TYPE:
    8228           26 :       return eval_is_member_object_pointer_type (loc, h);
    8229           26 :     case METAFN_IS_MEMBER_FUNCTION_POINTER_TYPE:
    8230           26 :       return eval_is_member_function_pointer_type (loc, h);
    8231           26 :     case METAFN_IS_ENUM_TYPE:
    8232           26 :       return eval_is_enum_type (loc, h);
    8233           43 :     case METAFN_IS_UNION_TYPE:
    8234           43 :       return eval_is_union_type (loc, h);
    8235          150 :     case METAFN_IS_CLASS_TYPE:
    8236          150 :       return eval_is_class_type (loc, h);
    8237           40 :     case METAFN_IS_FUNCTION_TYPE:
    8238           40 :       return eval_is_function_type (h);
    8239           26 :     case METAFN_IS_REFLECTION_TYPE:
    8240           26 :       return eval_is_reflection_type (h);
    8241           26 :     case METAFN_IS_REFERENCE_TYPE:
    8242           26 :       return eval_is_reference_type (loc, h);
    8243           28 :     case METAFN_IS_ARITHMETIC_TYPE:
    8244           28 :       return eval_is_arithmetic_type (h);
    8245           28 :     case METAFN_IS_FUNDAMENTAL_TYPE:
    8246           28 :       return eval_is_fundamental_type (h);
    8247           28 :     case METAFN_IS_OBJECT_TYPE:
    8248           28 :       return eval_is_object_type (loc, h);
    8249           28 :     case METAFN_IS_SCALAR_TYPE:
    8250           28 :       return eval_is_scalar_type (h);
    8251           28 :     case METAFN_IS_COMPOUND_TYPE:
    8252           28 :       return eval_is_compound_type (h);
    8253           28 :     case METAFN_IS_MEMBER_POINTER_TYPE:
    8254           28 :       return eval_is_member_pointer_type (loc, h);
    8255            8 :     case METAFN_IS_CONST_TYPE:
    8256            8 :       return eval_is_const_type (h);
    8257            8 :     case METAFN_IS_VOLATILE_TYPE:
    8258            8 :       return eval_is_volatile_type (h);
    8259           39 :     case METAFN_IS_TRIVIALLY_COPYABLE_TYPE:
    8260           39 :       return eval_is_trivially_copyable_type (h);
    8261            4 :     case METAFN_IS_STANDARD_LAYOUT_TYPE:
    8262            4 :       return eval_is_standard_layout_type (h);
    8263           15 :     case METAFN_IS_EMPTY_TYPE:
    8264           15 :       return eval_is_empty_type (loc, h);
    8265           10 :     case METAFN_IS_POLYMORPHIC_TYPE:
    8266           10 :       return eval_is_polymorphic_type (loc, h);
    8267            5 :     case METAFN_IS_ABSTRACT_TYPE:
    8268            5 :       return eval_is_abstract_type (h);
    8269            3 :     case METAFN_IS_FINAL_TYPE:
    8270            3 :       return eval_is_final_type (loc, h);
    8271           24 :     case METAFN_IS_AGGREGATE_TYPE:
    8272           24 :       return eval_is_aggregate_type (h);
    8273           30 :     case METAFN_IS_STRUCTURAL_TYPE:
    8274           30 :       return eval_is_structural_type (loc, h);
    8275           17 :     case METAFN_IS_SIGNED_TYPE:
    8276           17 :       return eval_is_signed_type (h);
    8277           17 :     case METAFN_IS_UNSIGNED_TYPE:
    8278           17 :       return eval_is_unsigned_type (h);
    8279           18 :     case METAFN_IS_BOUNDED_ARRAY_TYPE:
    8280           18 :       return eval_is_bounded_array_type (loc, h);
    8281           21 :     case METAFN_IS_UNBOUNDED_ARRAY_TYPE:
    8282           21 :       return eval_is_unbounded_array_type (h);
    8283           18 :     case METAFN_IS_SCOPED_ENUM_TYPE:
    8284           18 :       return eval_is_scoped_enum_type (h);
    8285          622 :     case METAFN_IS_CONSTRUCTIBLE_TYPE:
    8286          622 :       return eval_is_constructible_type (h, hvec);
    8287          104 :     case METAFN_IS_DEFAULT_CONSTRUCTIBLE_TYPE:
    8288          104 :       return eval_is_default_constructible_type (h);
    8289           25 :     case METAFN_IS_COPY_CONSTRUCTIBLE_TYPE:
    8290           25 :       return eval_is_copy_constructible_type (h);
    8291           25 :     case METAFN_IS_MOVE_CONSTRUCTIBLE_TYPE:
    8292           25 :       return eval_is_move_constructible_type (h);
    8293          497 :     case METAFN_IS_ASSIGNABLE_TYPE:
    8294          497 :       return eval_is_assignable_type (loc, h, h1);
    8295           25 :     case METAFN_IS_COPY_ASSIGNABLE_TYPE:
    8296           25 :       return eval_is_copy_assignable_type (h);
    8297           25 :     case METAFN_IS_MOVE_ASSIGNABLE_TYPE:
    8298           25 :       return eval_is_move_assignable_type (h);
    8299           21 :     case METAFN_IS_SWAPPABLE_WITH_TYPE:
    8300           21 :       return eval_is_swappable_with_type (loc, ctx, h, h1, call,
    8301              :                                           non_constant_p, jump_target, fun,
    8302           21 :                                           "is_swappable_with");
    8303           95 :     case METAFN_IS_SWAPPABLE_TYPE:
    8304           95 :       return eval_is_swappable_type (loc, ctx, h, call, non_constant_p,
    8305           95 :                                      jump_target, fun, "is_swappable");
    8306           72 :     case METAFN_IS_DESTRUCTIBLE_TYPE:
    8307           72 :       return eval_is_destructible_type (loc, h);
    8308           73 :     case METAFN_IS_TRIVIALLY_CONSTRUCTIBLE_TYPE:
    8309           73 :       return eval_is_trivially_constructible_type (h, hvec);
    8310           17 :     case METAFN_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_TYPE:
    8311           17 :       return eval_is_trivially_default_constructible_type (h);
    8312           20 :     case METAFN_IS_TRIVIALLY_COPY_CONSTRUCTIBLE_TYPE:
    8313           20 :       return eval_is_trivially_copy_constructible_type (h);
    8314           20 :     case METAFN_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE_TYPE:
    8315           20 :       return eval_is_trivially_move_constructible_type (h);
    8316           54 :     case METAFN_IS_TRIVIALLY_ASSIGNABLE_TYPE:
    8317           54 :       return eval_is_trivially_assignable_type (loc, h, h1);
    8318           23 :     case METAFN_IS_TRIVIALLY_COPY_ASSIGNABLE_TYPE:
    8319           23 :       return eval_is_trivially_copy_assignable_type (h);
    8320           23 :     case METAFN_IS_TRIVIALLY_MOVE_ASSIGNABLE_TYPE:
    8321           23 :       return eval_is_trivially_move_assignable_type (h);
    8322            5 :     case METAFN_IS_TRIVIALLY_DESTRUCTIBLE_TYPE:
    8323            5 :       return eval_is_trivially_destructible_type (loc, h);
    8324           50 :     case METAFN_IS_NOTHROW_CONSTRUCTIBLE_TYPE:
    8325           50 :       return eval_is_nothrow_constructible_type (h, hvec);
    8326           20 :     case METAFN_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE_TYPE:
    8327           20 :       return eval_is_nothrow_default_constructible_type (h);
    8328           25 :     case METAFN_IS_NOTHROW_COPY_CONSTRUCTIBLE_TYPE:
    8329           25 :       return eval_is_nothrow_copy_constructible_type (h);
    8330           25 :     case METAFN_IS_NOTHROW_MOVE_CONSTRUCTIBLE_TYPE:
    8331           25 :       return eval_is_nothrow_move_constructible_type (h);
    8332           10 :     case METAFN_IS_NOTHROW_ASSIGNABLE_TYPE:
    8333           10 :       return eval_is_nothrow_assignable_type (loc, h, h1);
    8334           25 :     case METAFN_IS_NOTHROW_COPY_ASSIGNABLE_TYPE:
    8335           25 :       return eval_is_nothrow_copy_assignable_type (h);
    8336           25 :     case METAFN_IS_NOTHROW_MOVE_ASSIGNABLE_TYPE:
    8337           25 :       return eval_is_nothrow_move_assignable_type (h);
    8338           27 :     case METAFN_IS_NOTHROW_SWAPPABLE_WITH_TYPE:
    8339           27 :       return eval_is_swappable_with_type (loc, ctx, h, h1, call,
    8340              :                                           non_constant_p, jump_target, fun,
    8341           27 :                                           "is_nothrow_swappable_with");
    8342           90 :     case METAFN_IS_NOTHROW_SWAPPABLE_TYPE:
    8343           90 :       return eval_is_swappable_type (loc, ctx, h, call, non_constant_p,
    8344           90 :                                      jump_target, fun, "is_nothrow_swappable");
    8345           83 :     case METAFN_IS_NOTHROW_DESTRUCTIBLE_TYPE:
    8346           83 :       return eval_is_nothrow_destructible_type (loc, h);
    8347           74 :     case METAFN_IS_IMPLICIT_LIFETIME_TYPE:
    8348           74 :       return eval_is_implicit_lifetime_type (h);
    8349           10 :     case METAFN_HAS_VIRTUAL_DESTRUCTOR:
    8350           10 :       return eval_has_virtual_destructor (h);
    8351           31 :     case METAFN_HAS_UNIQUE_OBJECT_REPRESENTATIONS:
    8352           31 :       return eval_has_unique_object_representations (h);
    8353           31 :     case METAFN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY:
    8354           31 :       return eval_reference_constructs_from_temporary (loc, h, h1);
    8355           31 :     case METAFN_REFERENCE_CONVERTS_FROM_TEMPORARY:
    8356           31 :       return eval_reference_converts_from_temporary (loc, h, h1);
    8357           15 :     case METAFN_RANK:
    8358           15 :       return eval_rank (h);
    8359          111 :     case METAFN_EXTENT:
    8360          111 :       return eval_extent (loc, h, expr);
    8361           10 :     case METAFN_IS_SAME_TYPE:
    8362           10 :       return eval_is_same_type (loc, h, h1);
    8363            9 :     case METAFN_IS_BASE_OF_TYPE:
    8364            9 :       return eval_is_base_of_type (loc, h, h1);
    8365           19 :     case METAFN_IS_VIRTUAL_BASE_OF_TYPE:
    8366           19 :       return eval_is_virtual_base_of_type (loc, h, h1);
    8367            5 :     case METAFN_IS_CONVERTIBLE_TYPE:
    8368            5 :       return eval_is_convertible_type (loc, h, h1);
    8369            7 :     case METAFN_IS_NOTHROW_CONVERTIBLE_TYPE:
    8370            7 :       return eval_is_nothrow_convertible_type (loc, h, h1);
    8371           18 :     case METAFN_IS_LAYOUT_COMPATIBLE_TYPE:
    8372           18 :       return eval_is_layout_compatible_type (loc, h, h1);
    8373           16 :     case METAFN_IS_POINTER_INTERCONVERTIBLE_BASE_OF_TYPE:
    8374           16 :       return eval_is_pointer_interconvertible_base_of_type (loc, h, h1);
    8375           38 :     case METAFN_IS_INVOCABLE_TYPE:
    8376           38 :       return eval_is_invocable_type (loc, h, hvec);
    8377           71 :     case METAFN_IS_INVOCABLE_R_TYPE:
    8378           71 :       return eval_is_invocable_r_type (loc, ctx, h, h1, hvec, call,
    8379              :                                        non_constant_p, jump_target, fun,
    8380           71 :                                        "is_invocable_r");
    8381           28 :     case METAFN_IS_NOTHROW_INVOCABLE_TYPE:
    8382           28 :       return eval_is_nothrow_invocable_type (loc, h, hvec);
    8383           42 :     case METAFN_IS_NOTHROW_INVOCABLE_R_TYPE:
    8384           42 :       return eval_is_invocable_r_type (loc, ctx, h, h1, hvec, call,
    8385              :                                        non_constant_p, jump_target, fun,
    8386           42 :                                        "is_nothrow_invocable_r");
    8387           11 :     case METAFN_REMOVE_CONST:
    8388           11 :       return eval_remove_const (loc, h);
    8389           12 :     case METAFN_REMOVE_VOLATILE:
    8390           12 :       return eval_remove_volatile (loc, h);
    8391           11 :     case METAFN_REMOVE_CV:
    8392           11 :       return eval_remove_cv (loc, h);
    8393           13 :     case METAFN_ADD_CONST:
    8394           13 :       return eval_add_const (loc, h);
    8395           13 :     case METAFN_ADD_VOLATILE:
    8396           13 :       return eval_add_volatile (loc, h);
    8397           13 :     case METAFN_ADD_CV:
    8398           13 :       return eval_add_cv (loc, h);
    8399           18 :     case METAFN_REMOVE_REFERENCE:
    8400           18 :       return eval_remove_reference (loc, h);
    8401           16 :     case METAFN_ADD_LVALUE_REFERENCE:
    8402           16 :       return eval_add_lvalue_reference (loc, h);
    8403           15 :     case METAFN_ADD_RVALUE_REFERENCE:
    8404           15 :       return eval_add_rvalue_reference (loc, h);
    8405           25 :     case METAFN_MAKE_SIGNED:
    8406           25 :       return eval_make_signed (loc, ctx, h, false, non_constant_p, jump_target,
    8407           25 :                                fun);
    8408           25 :     case METAFN_MAKE_UNSIGNED:
    8409           25 :       return eval_make_signed (loc, ctx, h, true, non_constant_p, jump_target,
    8410           25 :                                fun);
    8411           12 :     case METAFN_REMOVE_EXTENT:
    8412           12 :       return eval_remove_extent (loc, h);
    8413           11 :     case METAFN_REMOVE_ALL_EXTENTS:
    8414           11 :       return eval_remove_all_extents (loc, h);
    8415           13 :     case METAFN_REMOVE_POINTER:
    8416           13 :       return eval_remove_pointer (loc, h);
    8417           17 :     case METAFN_ADD_POINTER:
    8418           17 :       return eval_add_pointer (loc, h);
    8419           17 :     case METAFN_REMOVE_CVREF:
    8420           17 :       return eval_remove_cvref (loc, h);
    8421           21 :     case METAFN_DECAY:
    8422           21 :       return eval_decay (loc, h);
    8423           89 :     case METAFN_COMMON_TYPE:
    8424           89 :       return eval_common_type (loc, ctx, hvec, call, non_constant_p,
    8425           89 :                                jump_target, fun, ident);
    8426           32 :     case METAFN_COMMON_REFERENCE:
    8427           32 :       return eval_common_type (loc, ctx, hvec, call, non_constant_p,
    8428           32 :                                jump_target, fun, ident);
    8429           12 :     case METAFN_UNDERLYING_TYPE:
    8430           12 :       return eval_underlying_type (loc, ctx, h, non_constant_p, jump_target,
    8431           12 :                                    fun);
    8432           10 :     case METAFN_INVOKE_RESULT:
    8433           10 :       return eval_invoke_result (loc, ctx, h, hvec, call, non_constant_p,
    8434           10 :                                  jump_target, fun);
    8435           14 :     case METAFN_UNWRAP_REFERENCE:
    8436           14 :       return eval_unwrap_reference (loc, ctx, h, call, non_constant_p,
    8437           14 :                                     jump_target, fun, ident);
    8438           12 :     case METAFN_UNWRAP_REF_DECAY:
    8439           12 :       return eval_unwrap_reference (loc, ctx, h, call, non_constant_p,
    8440           12 :                                     jump_target, fun, ident);
    8441           28 :     case METAFN_TUPLE_SIZE:
    8442           28 :       return eval_tuple_size (loc, ctx, h, call, non_constant_p, jump_target,
    8443           28 :                               fun);
    8444           31 :     case METAFN_TUPLE_ELEMENT:
    8445           31 :       return eval_tuple_element (loc, ctx, expr, h1, call,
    8446           31 :                                  non_constant_p, jump_target, fun);
    8447           10 :     case METAFN_VARIANT_SIZE:
    8448           10 :       return eval_variant_size (loc, ctx, h, call, non_constant_p,
    8449           10 :                                 jump_target, fun);
    8450           17 :     case METAFN_VARIANT_ALTERNATIVE:
    8451           17 :       return eval_variant_alternative (loc, ctx, expr, h1, call,
    8452           17 :                                        non_constant_p, jump_target, fun);
    8453           58 :     case METAFN_TYPE_ORDER:
    8454           58 :       return eval_type_order (h, h1);
    8455          308 :     case METAFN_ANNOTATIONS_OF:
    8456          308 :       return eval_annotations_of (loc, ctx, h, kind, NULL_TREE, non_constant_p,
    8457          308 :                                   jump_target, fun);
    8458           14 :     case METAFN_ANNOTATIONS_OF_WITH_TYPE:
    8459           14 :       return eval_annotations_of (loc, ctx, h, kind, h1, non_constant_p,
    8460           14 :                                   jump_target, fun);
    8461              :     /* Special metafunctions.  */
    8462          270 :     case METAFN_ACCESS_CONTEXT_CURRENT:
    8463          540 :       if (DECL_CLASS_SCOPE_P (fun)
    8464          270 :           && TYPE_NAME (DECL_CONTEXT (fun))
    8465          270 :           && TREE_CODE (TYPE_NAME (DECL_CONTEXT (fun))) == TYPE_DECL
    8466          270 :           && DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun)))
    8467          540 :           && id_equal (DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun))),
    8468              :                        "access_context"))
    8469          270 :         return eval_access_context_current (loc, ctx, call, non_constant_p);
    8470            0 :       goto not_found;
    8471         1599 :     case METAFN_EXCEPTION__S_EXCEPTION_CVT_TO_UTF8:
    8472         1599 :     case METAFN_EXCEPTION__S_EXCEPTION_CVT_FROM_UTF8:
    8473         3198 :       if (DECL_CLASS_SCOPE_P (fun)
    8474         1599 :           && TYPE_NAME (DECL_CONTEXT (fun))
    8475         1599 :           && TREE_CODE (TYPE_NAME (DECL_CONTEXT (fun))) == TYPE_DECL
    8476         1599 :           && DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun)))
    8477         3198 :           && id_equal (DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun))),
    8478              :                        "exception"))
    8479              :         {
    8480         1599 :           bool to_utf8
    8481              :             = minfo->code == METAFN_EXCEPTION__S_EXCEPTION_CVT_TO_UTF8;
    8482         1599 :           return eval_exception__S_exception_cvt_tofrom_utf8 (loc, ctx, call,
    8483              :                                                               non_constant_p,
    8484              :                                                               overflow_p,
    8485              :                                                               jump_target,
    8486         1599 :                                                               fun, to_utf8);
    8487              :         }
    8488            0 :       goto not_found;
    8489              :     }
    8490            0 :   goto not_found;
    8491              : }
    8492              : 
    8493              : /* Splice reflection REFL; i.e., return its entity.  */
    8494              : 
    8495              : tree
    8496         2976 : splice (tree refl)
    8497              : {
    8498         2976 :   if (refl == error_mark_node)
    8499              :     return error_mark_node;
    8500              : 
    8501              :   /* Who in the world am I?  That's the great puzzle and we have to wait
    8502              :      until instantiation to find out.  */
    8503         2963 :   if (instantiation_dependent_expression_p (refl))
    8504          669 :     return build_nt (SPLICE_EXPR, refl);
    8505              : 
    8506              :   /* [basic.splice] "The constant-expression of a splice-specifier shall
    8507              :      be a converted constant expression of type std::meta::info."  */
    8508         2294 :   refl = build_converted_constant_expr (meta_info_type_node, refl,
    8509              :                                         tf_warning_or_error);
    8510              : 
    8511         2294 :   if (processing_template_decl)
    8512          437 :     refl = fold_non_dependent_expr (refl, tf_warning_or_error, true);
    8513              :   else
    8514         1857 :     refl = cxx_constant_value (refl);
    8515         2294 :   if (refl == error_mark_node)
    8516              :     {
    8517            7 :       gcc_checking_assert (seen_error ());
    8518            7 :       return error_mark_node;
    8519              :     }
    8520         2287 :   location_t loc = cp_expr_loc_or_input_loc (refl);
    8521         2287 :   if (!REFLECT_EXPR_P (refl))
    8522              :     {
    8523            1 :       error_at (loc, "splice argument must be an "
    8524              :                 "expression of type %qs", "std::meta::info");
    8525            1 :       return error_mark_node;
    8526              :     }
    8527              : 
    8528         2286 :   if (compare_reflections (refl, get_null_reflection ()))
    8529              :     {
    8530            3 :       error_at (loc, "cannot splice a null reflection");
    8531            3 :       return error_mark_node;
    8532              :     }
    8533              : 
    8534              :   /* This isn't checked in check_splice_expr, because reflect_kind isn't
    8535              :      available there and variable_of (parameters_of (...)[...]) can be
    8536              :      spliced.  */
    8537         2283 :   if (REFLECT_EXPR_KIND (refl) == REFLECT_PARM)
    8538              :     {
    8539            3 :       auto_diagnostic_group d;
    8540            6 :       error_at (loc, "cannot use %qD function parameter reflection in a "
    8541            3 :                 "splice expression", REFLECT_EXPR_HANDLE (refl));
    8542            3 :       if (DECL_CONTEXT (REFLECT_EXPR_HANDLE (refl)) == current_function_decl)
    8543            1 :         inform (loc,
    8544              :                 "apply %<std::meta::variable_of%> on it before splicing");
    8545            3 :       return error_mark_node;
    8546            3 :     }
    8547              : 
    8548              :   /* We are bringing some entity from the unevaluated expressions world
    8549              :      to possibly outside of that, mark it used.  */
    8550         2280 :   if (!mark_used (REFLECT_EXPR_HANDLE (refl)))
    8551            0 :     return error_mark_node;
    8552              : 
    8553         2280 :   refl = REFLECT_EXPR_HANDLE (refl);
    8554              :   /* Function templates are wrapped in OVERLOAD from name lookup
    8555              :      and a lot of places assume that.  Furthermore, if reflection comes
    8556              :      from ^^fntmpl, it is wrapped with OVERLOAD already, only when
    8557              :      it comes from e.g. members_of it is not.  */
    8558         2280 :   if (DECL_FUNCTION_TEMPLATE_P (refl))
    8559          542 :     refl = ovl_make (refl, NULL_TREE);
    8560              : 
    8561              :   return refl;
    8562              : }
    8563              : 
    8564              : /* A walker for consteval_only_p.  It cannot be a lambda, because we
    8565              :    have to call this recursively, sigh.  */
    8566              : 
    8567              : static tree
    8568    174144194 : consteval_only_type_r (tree *tp, int *walk_subtrees, void *data)
    8569              : {
    8570    174144194 :   tree t = *tp;
    8571              :   /* Types can contain themselves recursively, hence this.  */
    8572    174144194 :   auto visited = static_cast<hash_set<tree> *>(data);
    8573              : 
    8574    174144194 :   if (!TYPE_P (t))
    8575              :     return NULL_TREE;
    8576              : 
    8577    112957047 :   if (REFLECTION_TYPE_P (t))
    8578              :     return t;
    8579              : 
    8580    112930758 :   if (typedef_variant_p (t))
    8581              :     /* Tell cp_walk_subtrees to look through typedefs.  */
    8582     16394426 :     *walk_subtrees = 2;
    8583              : 
    8584    112930758 :   if (RECORD_OR_UNION_TYPE_P (t))
    8585              :     {
    8586              :       /* Don't walk template arguments; A<info>::type isn't a consteval-only
    8587              :          type.  */
    8588     29090957 :       *walk_subtrees = 0;
    8589              :       /* So we have to walk the fields manually.  */
    8590     29090957 :       for (tree member = TYPE_FIELDS (t);
    8591   1396286661 :            member; member = DECL_CHAIN (member))
    8592   1367232312 :         if (TREE_CODE (member) == FIELD_DECL)
    8593     48555346 :           if (tree r = cp_walk_tree (&TREE_TYPE (member),
    8594              :                                      consteval_only_type_r, visited, visited))
    8595              :             return r;
    8596              :     }
    8597              : 
    8598              :   return NULL_TREE;
    8599              : }
    8600              : 
    8601              : /* True if T is a consteval-only type as per [basic.types.general]:
    8602              :    "A type is consteval-only if it is either std::meta::info or a type
    8603              :    compounded from a consteval-only type", or something that has
    8604              :    a consteval-only type.  */
    8605              : 
    8606              : bool
    8607    355662655 : consteval_only_p (tree t)
    8608              : {
    8609    355662655 :   if (!flag_reflection)
    8610              :     return false;
    8611              : 
    8612     28547386 :   if (!TYPE_P (t))
    8613     28536119 :     t = TREE_TYPE (t);
    8614              : 
    8615     28547386 :   if (!t)
    8616              :     return false;
    8617              : 
    8618     28425717 :   if (TREE_CODE (t) == TREE_VEC)
    8619              :     {
    8620            4 :       for (tree arg : tree_vec_range (t))
    8621            3 :         if (arg && consteval_only_p (arg))
    8622            0 :           return true;
    8623            1 :       return false;
    8624              :     }
    8625              : 
    8626              :   /* We need the complete type otherwise we'd have no fields for class
    8627              :      templates and thus come up with zilch for things like
    8628              :        template<typename T>
    8629              :        struct X : T { };
    8630              :      which could be consteval-only, depending on T.  */
    8631     28425716 :   t = complete_type (t);
    8632              : 
    8633              :   /* Classes with std::meta::info members are also consteval-only.  */
    8634     28425716 :   hash_set<tree> visited;
    8635     28425716 :   return !!cp_walk_tree (&t, consteval_only_type_r, &visited, &visited);
    8636     28425716 : }
    8637              : 
    8638              : /* A walker for check_out_of_consteval_use_r.  It cannot be a lambda, because
    8639              :    we have to call this recursively.  */
    8640              : 
    8641              : static tree
    8642     25607868 : check_out_of_consteval_use_r (tree *tp, int *walk_subtrees, void *pset)
    8643              : {
    8644     25607868 :   tree t = *tp;
    8645              : 
    8646              :   /* No need to look into types or unevaluated operands.  */
    8647     25607868 :   if (TYPE_P (t)
    8648     25522636 :       || (unevaluated_p (TREE_CODE (t)) && !REFLECT_EXPR_P (t))
    8649              :       /* Don't walk INIT_EXPRs, because we'd emit bogus errors about
    8650              :          member initializers.  */
    8651     25489920 :       || TREE_CODE (t) == INIT_EXPR
    8652              :       /* And don't recurse on DECL_EXPRs.  */
    8653     25002428 :       || TREE_CODE (t) == DECL_EXPR
    8654              :       /* Blocks can appear in the TREE_VEC operand of OpenMP
    8655              :          depend/affinity/map/to/from OMP_CLAUSEs when using iterators.  */
    8656     50372725 :       || TREE_CODE (t) == BLOCK)
    8657              :     {
    8658       843012 :       *walk_subtrees = false;
    8659       843012 :       return NULL_TREE;
    8660              :     }
    8661              : 
    8662              :   /* A subexpression of a manifestly constant-evaluated expression is
    8663              :      an immediate function context.  For example,
    8664              : 
    8665              :       consteval void foo (std::meta::info) { }
    8666              :       void g() { foo (^^void); }
    8667              : 
    8668              :       is all good.  */
    8669     24764856 :   if (tree decl = cp_get_callee_fndecl_nofold (t))
    8670      1367810 :     if (immediate_invocation_p (decl))
    8671              :       {
    8672        10953 :         *walk_subtrees = false;
    8673        10953 :         return NULL_TREE;
    8674              :       }
    8675              : 
    8676     24753903 :   if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
    8677              :     {
    8678        38977 :       tree vexpr = DECL_VALUE_EXPR (t);
    8679        38977 :       if (tree ret = cp_walk_tree (&vexpr, check_out_of_consteval_use_r, pset,
    8680              :                                    (hash_set<tree> *) pset))
    8681            2 :         return ret;
    8682              :     }
    8683              : 
    8684     24753901 :   if (TREE_CODE (t) == BIND_EXPR)
    8685              :     {
    8686        66043 :       if (tree r = cp_walk_tree (&BIND_EXPR_BODY (t),
    8687              :                                  check_out_of_consteval_use_r, pset,
    8688              :                                  static_cast<hash_set<tree> *>(pset)))
    8689              :         return r;
    8690              :       /* Don't walk BIND_EXPR_VARS.  */
    8691        66043 :       *walk_subtrees = false;
    8692        66043 :       return NULL_TREE;
    8693              :     }
    8694              : 
    8695     24687858 :   if (TREE_CODE (t) == IF_STMT)
    8696              :     {
    8697       253574 :       if (IF_STMT_CONSTEVAL_P (t))
    8698              :         {
    8699         2800 :           if (tree r = cp_walk_tree (&ELSE_CLAUSE (t),
    8700              :                                      check_out_of_consteval_use_r, pset,
    8701              :                                      static_cast<hash_set<tree> *>(pset)))
    8702              :             return r;
    8703              :           /* Don't walk the consteval branch.  */
    8704         2796 :           *walk_subtrees = false;
    8705         2796 :           return NULL_TREE;
    8706              :         }
    8707       250774 :       else if (IF_STMT_CONSTEXPR_P (t))
    8708              :         {
    8709        22261 :           if (tree r = cp_walk_tree (&THEN_CLAUSE (t),
    8710              :                                      check_out_of_consteval_use_r, pset,
    8711              :                                      static_cast<hash_set<tree> *>(pset)))
    8712              :             return r;
    8713        22261 :           if (tree r = cp_walk_tree (&ELSE_CLAUSE (t),
    8714              :                                      check_out_of_consteval_use_r, pset,
    8715              :                                      static_cast<hash_set<tree> *>(pset)))
    8716              :             return r;
    8717              :           /* Don't walk the condition -- it's a manifestly constant-evaluated
    8718              :              context.  */
    8719        22261 :           *walk_subtrees = false;
    8720        22261 :           return NULL_TREE;
    8721              :         }
    8722              :     }
    8723              : 
    8724              :   /* Don't diagnose RETURN_EXPRs in cdtors on cdtor_returns_this
    8725              :      target.  Those don't exist on other targets.  */
    8726     24662797 :   if (TREE_CODE (t) == RETURN_EXPR
    8727       288632 :       && targetm.cxx.cdtor_returns_this ()
    8728     24662797 :       && (DECL_CONSTRUCTOR_P (current_function_decl)
    8729            0 :           || DECL_DESTRUCTOR_P (current_function_decl)))
    8730              :     {
    8731            0 :       *walk_subtrees = false;
    8732            0 :       return NULL_TREE;
    8733              :     }
    8734              : 
    8735              :   /* Now check the type to see if we are dealing with a consteval-only
    8736              :      expression.  */
    8737     24662797 :   if (!consteval_only_p (t))
    8738              :     return NULL_TREE;
    8739              : 
    8740              :   /* Already escalated?  */
    8741        20425 :   if (current_function_decl
    8742        40817 :       && DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
    8743              :     {
    8744         5764 :       *walk_subtrees = false;
    8745         5764 :       return NULL_TREE;
    8746              :     }
    8747              : 
    8748              :   /* We might have to escalate if we are in an immediate-escalating
    8749              :      function.  */
    8750        14661 :   if (immediate_escalating_function_p (current_function_decl))
    8751              :     {
    8752        14567 :       promote_function_to_consteval (current_function_decl);
    8753        14567 :       *walk_subtrees = false;
    8754        14567 :       return NULL_TREE;
    8755              :     }
    8756              : 
    8757           94 :   *walk_subtrees = false;
    8758           94 :   return t;
    8759              : }
    8760              : 
    8761              : /* Detect if a consteval-only expression EXPR or a consteval-only
    8762              :    variable EXPR not declared constexpr is used outside
    8763              :    a manifestly constant-evaluated context.  E.g.:
    8764              : 
    8765              :      void f() {
    8766              :        constexpr auto r = ^^int;  // OK
    8767              :        [: r :] i = 42;  // still OK
    8768              :        auto z = r;  // bad
    8769              :      }
    8770              : 
    8771              :    But
    8772              : 
    8773              :      consteval void g() {
    8774              :        constexpr auto r = ^^int;
    8775              :        auto z = r;
    8776              :      }
    8777              : 
    8778              :    is OK.  If COMPLAIN, emit an error; otherwise we're in the search-only
    8779              :    mode.  Return true if we found a problematic expression.  */
    8780              : 
    8781              : bool
    8782    231596100 : check_out_of_consteval_use (tree expr, bool complain/*=true*/)
    8783              : {
    8784    231596100 :   if (!flag_reflection || in_immediate_context () || expr == NULL_TREE)
    8785    228437891 :     return false;
    8786              : 
    8787      3158209 :   if (VAR_P (expr) && DECL_DECLARED_CONSTEXPR_P (expr))
    8788              :     return false;
    8789              : 
    8790      2633883 :   hash_set<tree> pset;
    8791      2633883 :   if (tree t = cp_walk_tree (&expr, check_out_of_consteval_use_r, &pset, &pset))
    8792              :     {
    8793           94 :       if (complain)
    8794              :         {
    8795           79 :           if (VAR_P (t) && !DECL_DECLARED_CONSTEXPR_P (t))
    8796              :             {
    8797           42 :               auto_diagnostic_group d;
    8798           84 :               error_at (cp_expr_loc_or_input_loc (t),
    8799              :                         "consteval-only variable %qD not declared %<constexpr%> "
    8800              :                         "used outside a constant-evaluated context", t);
    8801           42 :               inform (DECL_SOURCE_LOCATION (t), "add %<constexpr%>");
    8802           42 :             }
    8803              :           else
    8804           40 :             error_at (cp_expr_loc_or_input_loc (t),
    8805              :                       "consteval-only expressions are only allowed in "
    8806              :                       "a constant-evaluated context");
    8807              :         }
    8808           94 :       return true;
    8809              :     }
    8810              : 
    8811              :   return false;
    8812      2633883 : }
    8813              : 
    8814              : /* Return true if the reflections LHS and RHS are equal.  */
    8815              : 
    8816              : bool
    8817         4230 : compare_reflections (tree lhs, tree rhs)
    8818              : {
    8819         4231 :   reflect_kind lkind;
    8820         4231 :   do
    8821              :     {
    8822         4231 :       lkind = REFLECT_EXPR_KIND (lhs);
    8823         4231 :       if (lkind != REFLECT_EXPR_KIND (rhs))
    8824              :         return false;
    8825         4025 :       lhs = REFLECT_EXPR_HANDLE (lhs);
    8826         4025 :       rhs = REFLECT_EXPR_HANDLE (rhs);
    8827              :     }
    8828         4025 :   while (REFLECT_EXPR_P (lhs) && REFLECT_EXPR_P (rhs));
    8829              : 
    8830         4024 :   lhs = resolve_nondeduced_context (lhs, tf_warning_or_error);
    8831         4024 :   rhs = resolve_nondeduced_context (rhs, tf_warning_or_error);
    8832              : 
    8833              :   /* TEMPLATE_DECLs are wrapped in an OVERLOAD.  When we have
    8834              : 
    8835              :        template_of (^^fun_tmpl<int>) == ^^fun_tmpl
    8836              : 
    8837              :      the RHS will be OVERLOAD<TEMPLATE_DECL> but the LHS will
    8838              :      only be TEMPLATE_DECL.  They should compare equal, though.  */
    8839              :   // ??? Can we do something better?
    8840         4024 :   lhs = maybe_get_first_fn (lhs);
    8841         4024 :   rhs = maybe_get_first_fn (rhs);
    8842              : 
    8843              :   /* First handle reflection-specific comparisons, then fall back to
    8844              :      cp_tree_equal.  */
    8845         4024 :   if (lkind == REFLECT_PARM)
    8846              :     {
    8847            1 :       lhs = maybe_update_function_parm (lhs);
    8848            1 :       rhs = maybe_update_function_parm (rhs);
    8849              :     }
    8850         4023 :   else if (lkind == REFLECT_DATA_MEMBER_SPEC)
    8851              :     {
    8852           23 :       if (typedef_variant_p (TREE_VEC_ELT (lhs, 0))
    8853           23 :           != typedef_variant_p (TREE_VEC_ELT (rhs, 0))
    8854           23 :           || !same_type_p (TREE_VEC_ELT (lhs, 0), TREE_VEC_ELT (rhs, 0))
    8855           22 :           || TREE_VEC_ELT (lhs, 1) != TREE_VEC_ELT (rhs, 1)
    8856           18 :           || !tree_int_cst_equal (TREE_VEC_ELT (lhs, 2),
    8857           18 :                                   TREE_VEC_ELT (rhs, 2))
    8858           17 :           || !tree_int_cst_equal (TREE_VEC_ELT (lhs, 3),
    8859           17 :                                   TREE_VEC_ELT (rhs, 3))
    8860           16 :           || TREE_VEC_ELT (lhs, 4) != TREE_VEC_ELT (rhs, 4)
    8861           37 :           || TREE_VEC_LENGTH (lhs) != TREE_VEC_LENGTH (rhs))
    8862           10 :         return false;
    8863           31 :       for (int i = 5; i < TREE_VEC_LENGTH (lhs); ++i)
    8864           24 :         if (!compare_reflections (TREE_VEC_ELT (lhs, i),
    8865           24 :                                   TREE_VEC_ELT (rhs, i)))
    8866              :           return false;
    8867              :       return true;
    8868              :     }
    8869         4000 :   else if (lkind == REFLECT_ANNOTATION)
    8870           16 :     return TREE_VALUE (lhs) == TREE_VALUE (rhs);
    8871         3984 :   else if (TYPE_P (lhs) && TYPE_P (rhs))
    8872              :     {
    8873              :       /* Given "using A = int;", "^^int != ^^A" should hold.  */
    8874         1517 :       if (typedef_variant_p (lhs) != typedef_variant_p (rhs))
    8875              :         return false;
    8876              :       /* This is for comparing function types.  E.g.,
    8877              :           auto fn() -> int; type_of(^^fn) == ^^auto()->int;  */
    8878         1462 :       return same_type_p (lhs, rhs);
    8879              :     }
    8880              : 
    8881         2468 :   return cp_tree_equal (lhs, rhs);
    8882              : }
    8883              : 
    8884              : /* Return true if T is a valid splice-type-specifier.
    8885              :    [dcl.type.splice]: For a splice-type-specifier of the form
    8886              :    "typename[opt] splice-specifier", the splice-specifier shall designate
    8887              :    a type, a class template, or an alias template.
    8888              :    For a splice-type-specifier of the form
    8889              :    "typename[opt] splice-specialization-specifier", the splice-specifier
    8890              :    of the splice-specialization-specifier shall designate a template T
    8891              :    that is either a class template or an alias template.  */
    8892              : 
    8893              : bool
    8894          308 : valid_splice_type_p (const_tree t)
    8895              : {
    8896          308 :   return TYPE_P (t);
    8897              : }
    8898              : 
    8899              : /* Return true if T is a valid splice-scope-specifier.
    8900              :    [basic.lookup.qual.general]: If a splice-scope-specifier is followed
    8901              :    by a ::, it shall either be a dependent splice-scope-specifier or it
    8902              :    shall designate a namespace, class, enumeration, or dependent type.  */
    8903              : 
    8904              : bool
    8905          149 : valid_splice_scope_p (const_tree t)
    8906              : {
    8907           55 :   return (CLASS_TYPE_P (t)
    8908           94 :           || TREE_CODE (t) == ENUMERAL_TYPE
    8909          243 :           || TREE_CODE (t) == NAMESPACE_DECL);
    8910              : }
    8911              : 
    8912              : /* Return true if T is a valid result of the splice in a class member access,
    8913              :    as in obj.[:R:].  If DECLS_ONLY_P, only certain decls are OK.  */
    8914              : 
    8915              : bool
    8916         5033 : valid_splice_for_member_access_p (const_tree t, bool decls_only_p/*=true*/)
    8917              : {
    8918         5033 :   if (TREE_CODE (t) == FIELD_DECL
    8919              :       || VAR_P (t)
    8920         5033 :       || TREE_CODE (t) == CONST_DECL
    8921         4271 :       || TREE_CODE (t) == FUNCTION_DECL
    8922         2704 :       || reflection_function_template_p (t)
    8923         5820 :       || variable_template_p (const_cast<tree> (t)))
    8924              :     return true;
    8925              : 
    8926          622 :   if (decls_only_p)
    8927              :     return false;
    8928              : 
    8929          391 :   return (BASELINK_P (t)
    8930          246 :           || TREE_CODE (t) == TEMPLATE_ID_EXPR
    8931          493 :           || TREE_CODE (t) == TREE_BINFO);
    8932              : }
    8933              : 
    8934              : /* Check a function DECL for CWG 3115: Every function of consteval-only
    8935              :    type shall be an immediate function.  */
    8936              : 
    8937              : void
    8938    186909426 : check_consteval_only_fn (tree decl)
    8939              : {
    8940    373818852 :   if (!DECL_IMMEDIATE_FUNCTION_P (decl)
    8941    185141520 :       && consteval_only_p (decl)
    8942              :       /* But if the function can be escalated, merrily we roll along.  */
    8943    186910118 :       && !immediate_escalating_function_p (decl))
    8944           22 :     error_at (DECL_SOURCE_LOCATION (decl),
    8945              :               "function of consteval-only type must be declared %qs",
    8946              :               "consteval");
    8947    186909426 : }
    8948              : 
    8949              : /* Check if T is a valid result of splice-expression.  ADDRESS_P is true if
    8950              :    we are taking the address of the splice.  MEMBER_ACCESS_P is true if this
    8951              :    splice is used in foo.[: bar :] or foo->[: bar :] context.  TEMPLATE_P is
    8952              :    true if the splice-expression was preceded by 'template'.  TARGS_P is true
    8953              :    if there were template arguments.  COMPLAIN_P is true if any errors should
    8954              :    be emitted.  Returns true is no problems are found, false otherwise.  */
    8955              : 
    8956              : bool
    8957         2104 : check_splice_expr (location_t loc, location_t start_loc, tree t,
    8958              :                    bool address_p, bool member_access_p, bool template_p,
    8959              :                    bool targs_p, bool complain_p)
    8960              : {
    8961              :   /* We may not have gotten an expression.  */
    8962         2104 :   if (TREE_CODE (t) == TYPE_DECL
    8963         2099 :       || TREE_CODE (t) == NAMESPACE_DECL
    8964         2090 :       || TYPE_P (t))
    8965              :     {
    8966           67 :       if (complain_p)
    8967              :         {
    8968           55 :           if (TYPE_P (t))
    8969              :             {
    8970           43 :               auto_diagnostic_group d;
    8971           43 :               error_at (loc, "expected a reflection of an expression");
    8972           43 :               inform_tree_category (t);
    8973           43 :               if (start_loc != UNKNOWN_LOCATION)
    8974              :                 {
    8975           35 :                   rich_location richloc (line_table, start_loc);
    8976           35 :                   richloc.add_fixit_insert_before (start_loc, "typename");
    8977           35 :                   inform (&richloc, "add %<typename%> to denote a type "
    8978              :                           "outside a type-only context");
    8979           35 :                 }
    8980              :               else
    8981            8 :                 inform (loc, "add %<typename%> to denote a type outside "
    8982              :                         "a type-only context");
    8983           43 :             }
    8984              :           else
    8985              :             {
    8986           12 :               auto_diagnostic_group d;
    8987           12 :               error_at (loc, "expected a reflection of an expression");
    8988           12 :               inform_tree_category (t);
    8989           12 :             }
    8990              :         }
    8991           67 :       return false;
    8992              :     }
    8993              :   /* [expr.prim.splice]/2 For a splice-expression of the form
    8994              :      splice-specifier, the expression is ill-formed if it is:  */
    8995              :   /* -- a constructor or a destructor  */
    8996         2037 :   if (TREE_CODE (t) == FUNCTION_DECL
    8997         2596 :       && (DECL_CONSTRUCTOR_P (t) || DECL_DESTRUCTOR_P (t)))
    8998              :     {
    8999            5 :       if (complain_p)
    9000            5 :         error_at (loc, "cannot use constructor or destructor %qD in a splice "
    9001              :                   "expression", t);
    9002            5 :       return false;
    9003              :     }
    9004              :   /* -- an unnamed bit-field  */
    9005         2032 :   if (TREE_CODE (t) == FIELD_DECL && DECL_UNNAMED_BIT_FIELD (t))
    9006              :     {
    9007            1 :       if (complain_p)
    9008            1 :         error_at (loc, "cannot use an unnamed bit-field %qD in a splice "
    9009              :                   "expression", t);
    9010            1 :       return false;
    9011              :     }
    9012              :   /* Class members may not be implicitly referenced through a splice.
    9013              :      But taking the address is fine, and so is class member access a la
    9014              :      foo.[: ^^S::bar :].  */
    9015         2031 :   if (!address_p
    9016              :       && !member_access_p
    9017          750 :       && DECL_P (t)
    9018         2507 :       && DECL_NONSTATIC_MEMBER_P (t))
    9019              :     {
    9020           26 :       if (complain_p)
    9021           20 :         error_at (loc, "cannot implicitly reference a class member %qD "
    9022              :                   "through a splice", t);
    9023           26 :       return false;
    9024              :     }
    9025              : 
    9026              :   /* One can't access a class template or alias template with . or ->.  */
    9027         2005 :   if (member_access_p && DECL_TYPE_TEMPLATE_P (t))
    9028              :     {
    9029            5 :       if (complain_p)
    9030            5 :         error_at (loc, "invalid class member access of type template %qE", t);
    9031            5 :       return false;
    9032              :     }
    9033              : 
    9034         2000 :   if (member_access_p
    9035         1193 :       && !valid_splice_for_member_access_p (t, /*decls_only_p=*/false))
    9036              :     {
    9037           10 :       if (complain_p)
    9038           10 :         error_at (loc, "cannot use %qE to access a class member", t);
    9039           10 :       return false;
    9040              :     }
    9041              : 
    9042              :   /* [expr.unary.op]/3.1 "If the operand [of unary &] is a qualified-id or
    9043              :      splice-expression designating a non-static member m, other than an
    9044              :      explicit object member function, m shall be a direct member of some
    9045              :      class C that is not an anonymous union."  */
    9046         1990 :   if (address_p
    9047           83 :       && TREE_CODE (t) == FIELD_DECL
    9048           22 :       && ANON_UNION_TYPE_P (DECL_CONTEXT (t))
    9049         1997 :       && !TYPE_P (context_for_name_lookup (t)))
    9050              :     {
    9051            5 :       if (complain_p)
    9052            5 :         error_at (loc, "unary %<&%> applied to an anonymous union member "
    9053              :                        "%qD that is not a direct member of a named class", t);
    9054            5 :       return false;
    9055              :     }
    9056              : 
    9057              :   /* [expr.prim.splice]/2: "The expression is ill-formed if S [the construct
    9058              :      designated by splice-specifier] is
    9059              :      -- a local entity such that there is a lambda scope that intervenes
    9060              :      between the expression and the point at which S was introduced"
    9061              :      This also checks ODR violations (reflect/odr1.C).  */
    9062         1985 :   if (outer_automatic_var_p (t))
    9063           31 :     if (tree r = process_outer_var_ref (t, tf_none))
    9064           31 :       if (r == error_mark_node || is_capture_proxy (r))
    9065              :         {
    9066              :           /* Not letting process_outer_var_ref emit the error so that we can
    9067              :              say "in a splice expression".  */
    9068           15 :           if (complain_p)
    9069              :             {
    9070           15 :               auto_diagnostic_group d;
    9071           15 :               error_at (loc, "use of local variable with automatic storage "
    9072              :                         "from containing function in a splice expression");
    9073           15 :               inform (DECL_SOURCE_LOCATION (t), "%q#D declared here", t);
    9074           15 :             }
    9075           15 :           return false;
    9076              :         }
    9077              : 
    9078              :   /* If we had a reflect_kind here, we could just check for
    9079              :      REFLECT_ANNOTATION and be done with it.  But we don't have it yet (TODO),
    9080              :      so do it the suboptimal way.  */
    9081         1970 :   if (TREE_CODE (t) == TREE_LIST && annotation_p (t))
    9082              :     {
    9083            1 :       if (complain_p)
    9084            1 :         error_at (loc, "cannot use an annotation %qE in a splice expression",
    9085              :                   t);
    9086            1 :       return false;
    9087              :     }
    9088              : 
    9089              :   /* Same, but with REFLECT_DATA_MEMBER_SPEC.  */
    9090         1969 :   if (TREE_CODE (t) == TREE_VEC)
    9091              :     {
    9092            1 :       if (complain_p)
    9093            1 :         error_at (loc, "cannot use a data member specification in a "
    9094              :                   "splice expression");
    9095            1 :       return false;
    9096              :     }
    9097              : 
    9098         1968 :   if (template_p)
    9099              :     {
    9100              :       /* [expr.prim.splice] For a splice-expression of the form template
    9101              :          splice-specifier, the splice-specifier shall designate a function
    9102              :          template.  */
    9103          673 :       if (!targs_p)
    9104              :         {
    9105          317 :           if (!reflection_function_template_p (t) && !dependent_splice_p (t))
    9106              :             {
    9107           18 :               if (complain_p)
    9108              :                 {
    9109           18 :                   auto_diagnostic_group d;
    9110           18 :                   error_at (loc, "expected a reflection of a function "
    9111              :                             "template");
    9112           18 :                   inform_tree_category (t);
    9113           18 :                 }
    9114           18 :               return false;
    9115              :             }
    9116              :         }
    9117              :       /* [expr.prim.splice] For a splice-expression of the form
    9118              :          template splice-specialization-specifier, the splice-specifier of the
    9119              :          splice-specialization-specifier shall designate a template.  The
    9120              :          template should be a function template or a variable template.  */
    9121          356 :       else if (DECL_TYPE_TEMPLATE_P (t))
    9122              :         {
    9123            2 :           if (complain_p)
    9124              :             {
    9125            2 :               auto_diagnostic_group d;
    9126            2 :               error_at (loc, "expected a reflection of a function or variable "
    9127              :                         "template");
    9128            2 :               inform_tree_category (t);
    9129            2 :             }
    9130            2 :           return false;
    9131              :         }
    9132          653 :       gcc_checking_assert (reflection_function_template_p (t)
    9133              :                            || get_template_info (t)
    9134              :                            || TREE_CODE (t) == TEMPLATE_ID_EXPR
    9135              :                            || variable_template_p (t)
    9136              :                            || dependent_splice_p (t));
    9137              :     }
    9138              : 
    9139              :   return true;
    9140              : }
    9141              : 
    9142              : /* Create a new SPLICE_SCOPE tree.  EXPR is its SPLICE_SCOPE_EXPR, and
    9143              :    TYPE_P says if it should have SPLICE_SCOPE_TYPE_P set.  */
    9144              : 
    9145              : tree
    9146          169 : make_splice_scope (tree expr, bool type_p)
    9147              : {
    9148          169 :   tree t = cxx_make_type (SPLICE_SCOPE);
    9149          169 :   SPLICE_SCOPE_EXPR (t) = expr;
    9150          169 :   SPLICE_SCOPE_TYPE_P (t) = type_p;
    9151          169 :   return t;
    9152              : }
    9153              : 
    9154              : /* Return true if T is a splice expression; that is, it is either [:T:] or
    9155              :    [:T:]<arg>.  */
    9156              : 
    9157              : bool
    9158    109882487 : dependent_splice_p (const_tree t)
    9159              : {
    9160    109882487 :   return (TREE_CODE (t) == SPLICE_EXPR
    9161    109882487 :           || (TREE_CODE (t) == TEMPLATE_ID_EXPR
    9162      4071235 :               && TREE_CODE (TREE_OPERAND (t, 0)) == SPLICE_EXPR));
    9163              : }
    9164              : 
    9165              : /* Annotation index for mangling.  */
    9166              : 
    9167              : static GTY(()) int annotation_idx;
    9168              : 
    9169              : /* Helper function for mangle.cc (write_reflection).
    9170              :    Determine 2 letter mangling prefix and store it into prefix.
    9171              :    Additionally return the reflection handle possibly adjusted so that
    9172              :    write_reflection can mangle the operands of it if any are needed.  */
    9173              : 
    9174              : tree
    9175          670 : reflection_mangle_prefix (tree refl, char prefix[3])
    9176              : {
    9177          670 :   tree h = REFLECT_EXPR_HANDLE (refl);
    9178          670 :   reflect_kind kind = REFLECT_EXPR_KIND (refl);
    9179          670 :   if (h == unknown_type_node)
    9180              :     {
    9181            3 :       strcpy (prefix, "nu");
    9182            3 :       return NULL_TREE;
    9183              :     }
    9184         1334 :   if (eval_is_value (kind) == boolean_true_node)
    9185              :     {
    9186            6 :       strcpy (prefix, "vl");
    9187            6 :       if (VAR_P (h) && DECL_NTTP_OBJECT_P (h))
    9188            0 :         h = tparm_object_argument (h);
    9189            6 :       return h;
    9190              :     }
    9191         1317 :   if (eval_is_object (kind) == boolean_true_node)
    9192              :     {
    9193            5 :       strcpy (prefix, "ob");
    9194            5 :       return h;
    9195              :     }
    9196          656 :   if (eval_is_variable (h, kind) == boolean_true_node)
    9197              :     {
    9198          111 :       strcpy (prefix, "vr");
    9199          111 :       return h;
    9200              :     }
    9201          545 :   if (eval_is_structured_binding (h, kind) == boolean_true_node)
    9202              :     {
    9203            4 :       strcpy (prefix, "sb");
    9204            4 :       return h;
    9205              :     }
    9206          541 :   if (eval_is_function (h) == boolean_true_node)
    9207              :     {
    9208           52 :       strcpy (prefix, "fn");
    9209           52 :       return maybe_get_first_fn (h);
    9210              :     }
    9211          489 :   if (eval_is_function_parameter (h, kind) == boolean_true_node)
    9212              :     {
    9213           16 :       strcpy (prefix, "pa");
    9214           16 :       return maybe_update_function_parm (h);
    9215              :     }
    9216          933 :   if (eval_is_enumerator (h) == boolean_true_node)
    9217              :     {
    9218           13 :       strcpy (prefix, "en");
    9219           13 :       return h;
    9220              :     }
    9221          460 :   if (eval_is_annotation (h, kind) == boolean_true_node)
    9222              :     {
    9223            5 :       strcpy (prefix, "an");
    9224            5 :       if (TREE_PURPOSE (TREE_VALUE (h)) == NULL_TREE)
    9225            4 :         TREE_PURPOSE (TREE_VALUE (h))
    9226            8 :           = bitsize_int (annotation_idx++);
    9227              :       /* TREE_PURPOSE void_node or INTEGER_CST with signed type
    9228              :          means it is annotation which should appear in
    9229              :          variable_of list.  */
    9230            1 :       else if (TREE_PURPOSE (TREE_VALUE (h)) == void_node)
    9231            0 :         TREE_PURPOSE (TREE_VALUE (h))
    9232            0 :           = sbitsize_int (annotation_idx++);
    9233            5 :       return TREE_PURPOSE (TREE_VALUE (h));
    9234              :     }
    9235          455 :   if (eval_is_type_alias (h) == boolean_true_node)
    9236              :     {
    9237           12 :       strcpy (prefix, "ta");
    9238           12 :       return h;
    9239              :     }
    9240          443 :   if (eval_is_type (h) == boolean_true_node)
    9241              :     {
    9242          146 :       strcpy (prefix, "ty");
    9243          146 :       return h;
    9244              :     }
    9245          297 :   if (eval_is_nonstatic_data_member (h) == boolean_true_node)
    9246              :     {
    9247           99 :       strcpy (prefix, "dm");
    9248           99 :       return h;
    9249              :     }
    9250          198 :   if (TREE_CODE (h) == FIELD_DECL && DECL_UNNAMED_BIT_FIELD (h))
    9251              :     {
    9252            4 :       strcpy (prefix, "un");
    9253            4 :       return h;
    9254              :     }
    9255          194 :   if (eval_is_class_template (h) == boolean_true_node)
    9256              :     {
    9257           16 :       strcpy (prefix, "ct");
    9258           16 :       return h;
    9259              :     }
    9260          178 :   if (eval_is_function_template (h) == boolean_true_node)
    9261              :     {
    9262           14 :       strcpy (prefix, "ft");
    9263           14 :       h = maybe_get_first_fn (h);
    9264           14 :       return h;
    9265              :     }
    9266          164 :   if (eval_is_variable_template (h) == boolean_true_node)
    9267              :     {
    9268            9 :       strcpy (prefix, "vt");
    9269            9 :       return h;
    9270              :     }
    9271          155 :   if (eval_is_alias_template (h) == boolean_true_node)
    9272              :     {
    9273            8 :       strcpy (prefix, "at");
    9274            8 :       return h;
    9275              :     }
    9276          294 :   if (eval_is_concept (h) == boolean_true_node)
    9277              :     {
    9278            7 :       strcpy (prefix, "co");
    9279            7 :       return h;
    9280              :     }
    9281          140 :   if (eval_is_namespace_alias (h) == boolean_true_node)
    9282              :     {
    9283            5 :       strcpy (prefix, "na");
    9284            5 :       return h;
    9285              :     }
    9286          191 :   if (eval_is_namespace (h) == boolean_true_node)
    9287              :     {
    9288           79 :       if (h == global_namespace)
    9289              :         {
    9290           13 :           strcpy (prefix, "gs");
    9291           13 :           return NULL_TREE;
    9292              :         }
    9293           66 :       strcpy (prefix, "ns");
    9294           66 :       return h;
    9295              :     }
    9296           56 :   if (eval_is_base (h, kind) == boolean_true_node)
    9297              :     {
    9298           11 :       strcpy (prefix, "ba");
    9299           11 :       return h;
    9300              :     }
    9301           45 :   if (eval_is_data_member_spec (h, kind) == boolean_true_node)
    9302              :     {
    9303           42 :       strcpy (prefix, "ds");
    9304           42 :       return h;
    9305              :     }
    9306              :   /* We don't have a metafunction for template template parameters.  */
    9307            3 :   if (DECL_TEMPLATE_TEMPLATE_PARM_P (h))
    9308              :     {
    9309            1 :       strcpy (prefix, "tt");
    9310            1 :       return h;
    9311              :     }
    9312              :   /* For ^^T::x, we can't say what the reflection is going to be.  Just say
    9313              :      it's something dependent.  This is at the end rather than the beginning
    9314              :      because potential_constant_expression_1 doesn't handle codes like
    9315              :      TREE_BINFO.  */
    9316            2 :   if (uses_template_parms (h))
    9317              :     {
    9318            2 :       strcpy (prefix, "de");
    9319            2 :       return h;
    9320              :     }
    9321            0 :   gcc_unreachable ();
    9322              : }
    9323              : 
    9324              : /* Returns true iff X is a reflection of a function template.  */
    9325              : 
    9326              : bool
    9327         4398 : reflection_function_template_p (const_tree x)
    9328              : {
    9329        14418 :   return (DECL_FUNCTION_TEMPLATE_P
    9330         4398 :           (OVL_FIRST (MAYBE_BASELINK_FUNCTIONS (const_cast<tree> (x)))));
    9331              : }
    9332              : 
    9333              : #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.