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