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