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