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