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