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