LCOV - code coverage report
Current view: top level - gcc/cp - reflect.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.0 % 4599 4183
Test Date: 2026-10-03 16:17:38 Functions: 100.0 % 306 306
Legend: Lines:     hit not hit

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