LCOV - code coverage report
Current view: top level - gcc/cp - reflect.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.2 % 4536 4180
Test Date: 2026-05-30 15:37:04 Functions: 100.0 % 303 303
Legend: Lines:     hit not hit

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