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