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