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