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