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