LCOV - code coverage report
Current view: top level - gcc/cp - reflect.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.2 % 4548 4192
Test Date: 2026-06-20 15:32:29 Functions: 100.0 % 303 303
Legend: Lines:     hit not hit

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