111
|
1 /* Processing rules for constraints.
|
145
|
2 Copyright (C) 2013-2020 Free Software Foundation, Inc.
|
111
|
3 Contributed by Andrew Sutton (andrew.n.sutton@gmail.com)
|
|
4
|
|
5 This file is part of GCC.
|
|
6
|
|
7 GCC is free software; you can redistribute it and/or modify
|
|
8 it under the terms of the GNU General Public License as published by
|
|
9 the Free Software Foundation; either version 3, or (at your option)
|
|
10 any later version.
|
|
11
|
|
12 GCC is distributed in the hope that it will be useful,
|
|
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 GNU General Public License for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GCC; see the file COPYING3. If not see
|
|
19 <http://www.gnu.org/licenses/>. */
|
|
20
|
|
21 #include "config.h"
|
|
22 #include "system.h"
|
|
23 #include "coretypes.h"
|
|
24 #include "tm.h"
|
|
25 #include "timevar.h"
|
|
26 #include "hash-set.h"
|
|
27 #include "machmode.h"
|
|
28 #include "vec.h"
|
|
29 #include "double-int.h"
|
|
30 #include "input.h"
|
|
31 #include "alias.h"
|
|
32 #include "symtab.h"
|
|
33 #include "wide-int.h"
|
|
34 #include "inchash.h"
|
|
35 #include "tree.h"
|
|
36 #include "stringpool.h"
|
|
37 #include "attribs.h"
|
|
38 #include "intl.h"
|
|
39 #include "flags.h"
|
|
40 #include "cp-tree.h"
|
|
41 #include "c-family/c-common.h"
|
|
42 #include "c-family/c-objc.h"
|
|
43 #include "cp-objcp-common.h"
|
|
44 #include "tree-inline.h"
|
|
45 #include "decl.h"
|
|
46 #include "toplev.h"
|
|
47 #include "type-utils.h"
|
|
48
|
145
|
49 static tree satisfaction_value (tree t);
|
|
50
|
|
51 /* When we're parsing or substuting a constraint expression, we have slightly
|
|
52 different expression semantics. In particular, we don't want to reduce a
|
|
53 concept-id to a satisfaction value. */
|
|
54
|
|
55 processing_constraint_expression_sentinel::
|
|
56 processing_constraint_expression_sentinel ()
|
|
57 {
|
|
58 ++scope_chain->x_processing_constraint;
|
|
59 }
|
|
60
|
|
61 processing_constraint_expression_sentinel::
|
|
62 ~processing_constraint_expression_sentinel ()
|
|
63 {
|
|
64 --scope_chain->x_processing_constraint;
|
|
65 }
|
|
66
|
|
67 bool
|
|
68 processing_constraint_expression_p ()
|
|
69 {
|
|
70 return scope_chain->x_processing_constraint != 0;
|
|
71 }
|
|
72
|
111
|
73 /*---------------------------------------------------------------------------
|
145
|
74 Constraint expressions
|
111
|
75 ---------------------------------------------------------------------------*/
|
|
76
|
145
|
77 /* Information provided to substitution. */
|
|
78
|
|
79 struct subst_info
|
|
80 {
|
|
81 subst_info (tsubst_flags_t cmp, tree in)
|
|
82 : complain (cmp), in_decl (in)
|
|
83 { }
|
|
84
|
|
85 /* True if we should not diagnose errors. */
|
|
86 bool quiet() const
|
|
87 {
|
|
88 return complain == tf_none;
|
|
89 }
|
|
90
|
|
91 /* True if we should diagnose errors. */
|
|
92 bool noisy() const
|
|
93 {
|
|
94 return !quiet ();
|
|
95 }
|
|
96
|
|
97 tsubst_flags_t complain;
|
|
98 tree in_decl;
|
|
99 };
|
|
100
|
|
101 static tree satisfy_constraint (tree, tree, subst_info);
|
|
102
|
|
103 /* True if T is known to be some type other than bool. Note that this
|
|
104 is false for dependent types and errors. */
|
111
|
105
|
|
106 static inline bool
|
145
|
107 known_non_bool_p (tree t)
|
111
|
108 {
|
145
|
109 return (t && !WILDCARD_TYPE_P (t) && TREE_CODE (t) != BOOLEAN_TYPE);
|
111
|
110 }
|
|
111
|
145
|
112 static bool
|
|
113 check_constraint_atom (cp_expr expr)
|
|
114 {
|
|
115 if (known_non_bool_p (TREE_TYPE (expr)))
|
|
116 {
|
|
117 error_at (expr.get_location (),
|
|
118 "constraint expression does not have type %<bool%>");
|
|
119 return false;
|
|
120 }
|
|
121
|
|
122 /* Check that we're using function concepts correctly. */
|
|
123 if (concept_check_p (expr))
|
|
124 {
|
|
125 tree id = unpack_concept_check (expr);
|
|
126 tree tmpl = TREE_OPERAND (id, 0);
|
|
127 if (OVL_P (tmpl) && TREE_CODE (expr) == TEMPLATE_ID_EXPR)
|
|
128 {
|
|
129 error_at (EXPR_LOC_OR_LOC (expr, input_location),
|
|
130 "function concept must be called");
|
|
131 return false;
|
|
132 }
|
|
133 }
|
|
134
|
|
135 return true;
|
|
136 }
|
|
137
|
|
138 static bool
|
|
139 check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
|
111
|
140 {
|
145
|
141 return check_constraint_atom (lhs) && check_constraint_atom (rhs);
|
111
|
142 }
|
|
143
|
145
|
144 /* Validate the semantic properties of the constraint expression. */
|
|
145
|
|
146 static cp_expr
|
|
147 finish_constraint_binary_op (location_t loc,
|
|
148 tree_code code,
|
|
149 cp_expr lhs,
|
|
150 cp_expr rhs)
|
|
151 {
|
|
152 gcc_assert (processing_constraint_expression_p ());
|
|
153 if (lhs == error_mark_node || rhs == error_mark_node)
|
|
154 return error_mark_node;
|
|
155 if (!check_constraint_operands (loc, lhs, rhs))
|
|
156 return error_mark_node;
|
|
157 tree overload;
|
|
158 tree expr = build_x_binary_op (loc, code,
|
|
159 lhs, TREE_CODE (lhs),
|
|
160 rhs, TREE_CODE (rhs),
|
|
161 &overload, tf_none);
|
|
162 /* When either operand is dependent, the overload set may be non-empty. */
|
|
163 if (expr == error_mark_node)
|
|
164 return error_mark_node;
|
|
165 SET_EXPR_LOCATION (expr, loc);
|
|
166 return expr;
|
|
167 }
|
|
168
|
|
169 cp_expr
|
|
170 finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
|
|
171 {
|
|
172 return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
|
|
173 }
|
|
174
|
|
175 cp_expr
|
|
176 finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
|
|
177 {
|
|
178 return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
|
|
179 }
|
|
180
|
|
181 cp_expr
|
|
182 finish_constraint_primary_expr (cp_expr expr)
|
|
183 {
|
|
184 if (expr == error_mark_node)
|
|
185 return error_mark_node;
|
|
186 if (!check_constraint_atom (expr))
|
|
187 return cp_expr (error_mark_node, expr.get_location ());
|
|
188 return expr;
|
|
189 }
|
|
190
|
|
191 /* Combine two constraint-expressions with a logical-and. */
|
111
|
192
|
|
193 tree
|
145
|
194 combine_constraint_expressions (tree lhs, tree rhs)
|
111
|
195 {
|
145
|
196 processing_constraint_expression_sentinel pce;
|
|
197 if (!lhs)
|
|
198 return rhs;
|
|
199 if (!rhs)
|
|
200 return lhs;
|
|
201 return finish_constraint_and_expr (input_location, lhs, rhs);
|
111
|
202 }
|
|
203
|
145
|
204 /* Extract the template-id from a concept check. For standard and variable
|
|
205 checks, this is simply T. For function concept checks, this is the
|
|
206 called function. */
|
111
|
207
|
|
208 tree
|
145
|
209 unpack_concept_check (tree t)
|
111
|
210 {
|
145
|
211 gcc_assert (concept_check_p (t));
|
|
212
|
|
213 if (TREE_CODE (t) == CALL_EXPR)
|
|
214 t = CALL_EXPR_FN (t);
|
|
215
|
|
216 gcc_assert (TREE_CODE (t) == TEMPLATE_ID_EXPR);
|
|
217 return t;
|
111
|
218 }
|
|
219
|
145
|
220 /* Extract the TEMPLATE_DECL from a concept check. */
|
|
221
|
|
222 tree
|
|
223 get_concept_check_template (tree t)
|
|
224 {
|
|
225 tree id = unpack_concept_check (t);
|
|
226 tree tmpl = TREE_OPERAND (id, 0);
|
|
227 if (OVL_P (tmpl))
|
|
228 tmpl = OVL_FIRST (tmpl);
|
|
229 return tmpl;
|
|
230 }
|
|
231
|
|
232 /* Returns true if any of the arguments in the template argument list is
|
|
233 a wildcard or wildcard pack. */
|
111
|
234
|
|
235 bool
|
|
236 contains_wildcard_p (tree args)
|
|
237 {
|
|
238 for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
|
|
239 {
|
|
240 tree arg = TREE_VEC_ELT (args, i);
|
|
241 if (TREE_CODE (arg) == WILDCARD_DECL)
|
|
242 return true;
|
|
243 }
|
|
244 return false;
|
|
245 }
|
|
246
|
|
247 /*---------------------------------------------------------------------------
|
|
248 Resolution of qualified concept names
|
|
249 ---------------------------------------------------------------------------*/
|
|
250
|
145
|
251 /* This facility is used to resolve constraint checks from requirement
|
|
252 expressions. A constraint check is a call to a function template declared
|
|
253 with the keyword 'concept'.
|
|
254
|
|
255 The result of resolution is a pair (a TREE_LIST) whose value is the
|
|
256 matched declaration, and whose purpose contains the coerced template
|
|
257 arguments that can be substituted into the call. */
|
|
258
|
|
259 /* Given an overload set OVL, try to find a unique definition that can be
|
|
260 instantiated by the template arguments ARGS.
|
|
261
|
|
262 This function is not called for arbitrary call expressions. In particular,
|
|
263 the call expression must be written with explicit template arguments
|
|
264 and no function arguments. For example:
|
|
265
|
|
266 f<T, U>()
|
|
267
|
|
268 If a single match is found, this returns a TREE_LIST whose VALUE
|
|
269 is the constraint function (not the template), and its PURPOSE is
|
|
270 the complete set of arguments substituted into the parameter list. */
|
|
271
|
111
|
272 static tree
|
145
|
273 resolve_function_concept_overload (tree ovl, tree args)
|
111
|
274 {
|
|
275 int nerrs = 0;
|
|
276 tree cands = NULL_TREE;
|
|
277 for (lkp_iterator iter (ovl); iter; ++iter)
|
|
278 {
|
|
279 tree tmpl = *iter;
|
|
280 if (TREE_CODE (tmpl) != TEMPLATE_DECL)
|
|
281 continue;
|
|
282
|
145
|
283 /* Don't try to deduce checks for non-concepts. We often end up trying
|
|
284 to resolve constraints in functional casts as part of a
|
|
285 postfix-expression. We can save time and headaches by not
|
|
286 instantiating those declarations.
|
|
287
|
|
288 NOTE: This masks a potential error, caused by instantiating
|
|
289 non-deduced contexts using placeholder arguments. */
|
111
|
290 tree fn = DECL_TEMPLATE_RESULT (tmpl);
|
|
291 if (DECL_ARGUMENTS (fn))
|
|
292 continue;
|
|
293 if (!DECL_DECLARED_CONCEPT_P (fn))
|
|
294 continue;
|
|
295
|
145
|
296 /* Remember the candidate if we can deduce a substitution. */
|
111
|
297 ++processing_template_decl;
|
|
298 tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
|
|
299 if (tree subst = coerce_template_parms (parms, args, tmpl))
|
|
300 {
|
|
301 if (subst == error_mark_node)
|
|
302 ++nerrs;
|
|
303 else
|
|
304 cands = tree_cons (subst, fn, cands);
|
|
305 }
|
|
306 --processing_template_decl;
|
|
307 }
|
|
308
|
|
309 if (!cands)
|
|
310 /* We either had no candidates or failed deductions. */
|
|
311 return nerrs ? error_mark_node : NULL_TREE;
|
|
312 else if (TREE_CHAIN (cands))
|
|
313 /* There are multiple candidates. */
|
|
314 return error_mark_node;
|
|
315
|
|
316 return cands;
|
|
317 }
|
|
318
|
145
|
319 /* Determine if the the call expression CALL is a constraint check, and
|
|
320 return the concept declaration and arguments being checked. If CALL
|
|
321 does not denote a constraint check, return NULL. */
|
|
322
|
111
|
323 tree
|
145
|
324 resolve_function_concept_check (tree call)
|
111
|
325 {
|
|
326 gcc_assert (TREE_CODE (call) == CALL_EXPR);
|
|
327
|
145
|
328 /* A constraint check must be only a template-id expression.
|
|
329 If it's a call to a base-link, its function(s) should be a
|
|
330 template-id expression. If this is not a template-id, then
|
|
331 it cannot be a concept-check. */
|
111
|
332 tree target = CALL_EXPR_FN (call);
|
|
333 if (BASELINK_P (target))
|
|
334 target = BASELINK_FUNCTIONS (target);
|
|
335 if (TREE_CODE (target) != TEMPLATE_ID_EXPR)
|
|
336 return NULL_TREE;
|
|
337
|
145
|
338 /* Get the overload set and template arguments and try to
|
|
339 resolve the target. */
|
111
|
340 tree ovl = TREE_OPERAND (target, 0);
|
|
341
|
145
|
342 /* This is a function call of a variable concept... ill-formed. */
|
111
|
343 if (TREE_CODE (ovl) == TEMPLATE_DECL)
|
|
344 {
|
|
345 error_at (location_of (call),
|
|
346 "function call of variable concept %qE", call);
|
|
347 return error_mark_node;
|
|
348 }
|
|
349
|
|
350 tree args = TREE_OPERAND (target, 1);
|
145
|
351 return resolve_function_concept_overload (ovl, args);
|
111
|
352 }
|
|
353
|
145
|
354 /* Returns a pair containing the checked concept and its associated
|
|
355 prototype parameter. The result is a TREE_LIST whose TREE_VALUE
|
|
356 is the concept (non-template) and whose TREE_PURPOSE contains
|
|
357 the converted template arguments, including the deduced prototype
|
|
358 parameter (in position 0). */
|
111
|
359
|
|
360 tree
|
145
|
361 resolve_concept_check (tree check)
|
111
|
362 {
|
145
|
363 gcc_assert (concept_check_p (check));
|
|
364 tree id = unpack_concept_check (check);
|
111
|
365 tree tmpl = TREE_OPERAND (id, 0);
|
145
|
366
|
|
367 /* If this is an overloaded function concept, perform overload
|
|
368 resolution (this only happens when deducing prototype parameters
|
|
369 and template introductions). */
|
|
370 if (TREE_CODE (tmpl) == OVERLOAD)
|
|
371 {
|
|
372 if (OVL_CHAIN (tmpl))
|
|
373 return resolve_function_concept_check (check);
|
|
374 tmpl = OVL_FIRST (tmpl);
|
|
375 }
|
|
376
|
111
|
377 tree args = TREE_OPERAND (id, 1);
|
|
378 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
|
|
379 ++processing_template_decl;
|
|
380 tree result = coerce_template_parms (parms, args, tmpl);
|
|
381 --processing_template_decl;
|
145
|
382 if (result == error_mark_node)
|
111
|
383 return error_mark_node;
|
145
|
384 return build_tree_list (result, DECL_TEMPLATE_RESULT (tmpl));
|
111
|
385 }
|
|
386
|
145
|
387 /* Given a call expression or template-id expression to a concept EXPR
|
|
388 possibly including a wildcard, deduce the concept being checked and
|
|
389 the prototype parameter. Returns true if the constraint and prototype
|
|
390 can be deduced and false otherwise. Note that the CHECK and PROTO
|
|
391 arguments are set to NULL_TREE if this returns false. */
|
111
|
392
|
|
393 bool
|
|
394 deduce_constrained_parameter (tree expr, tree& check, tree& proto)
|
|
395 {
|
145
|
396 tree info = resolve_concept_check (expr);
|
111
|
397 if (info && info != error_mark_node)
|
|
398 {
|
|
399 check = TREE_VALUE (info);
|
|
400 tree arg = TREE_VEC_ELT (TREE_PURPOSE (info), 0);
|
|
401 if (ARGUMENT_PACK_P (arg))
|
|
402 arg = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0);
|
|
403 proto = TREE_TYPE (arg);
|
|
404 return true;
|
|
405 }
|
145
|
406
|
111
|
407 check = proto = NULL_TREE;
|
|
408 return false;
|
|
409 }
|
|
410
|
145
|
411 /* Given a call expression or template-id expression to a concept, EXPR,
|
|
412 deduce the concept being checked and return the template arguments.
|
|
413 Returns NULL_TREE if deduction fails. */
|
111
|
414 static tree
|
145
|
415 deduce_concept_introduction (tree check)
|
111
|
416 {
|
145
|
417 tree info = resolve_concept_check (check);
|
111
|
418 if (info && info != error_mark_node)
|
|
419 return TREE_PURPOSE (info);
|
|
420 return NULL_TREE;
|
|
421 }
|
|
422
|
145
|
423 /* Build a constrained placeholder type where SPEC is a type-constraint.
|
|
424 SPEC can be anything were concept_definition_p is true.
|
|
425
|
|
426 If DECLTYPE_P is true, then the placeholder is decltype(auto).
|
|
427
|
|
428 Returns a pair whose FIRST is the concept being checked and whose
|
|
429 SECOND is the prototype parameter. */
|
|
430
|
|
431 tree_pair
|
|
432 finish_type_constraints (tree spec, tree args, tsubst_flags_t complain)
|
111
|
433 {
|
145
|
434 gcc_assert (concept_definition_p (spec));
|
|
435
|
|
436 /* Build an initial concept check. */
|
|
437 tree check = build_type_constraint (spec, args, complain);
|
|
438 if (check == error_mark_node)
|
|
439 return std::make_pair (error_mark_node, NULL_TREE);
|
|
440
|
|
441 /* Extract the concept and prototype parameter from the check. */
|
|
442 tree con;
|
|
443 tree proto;
|
|
444 if (!deduce_constrained_parameter (check, con, proto))
|
|
445 return std::make_pair (error_mark_node, NULL_TREE);
|
|
446
|
|
447 return std::make_pair (con, proto);
|
111
|
448 }
|
|
449
|
|
450 /*---------------------------------------------------------------------------
|
|
451 Expansion of concept definitions
|
|
452 ---------------------------------------------------------------------------*/
|
|
453
|
|
454 /* Returns the expression of a function concept. */
|
|
455
|
145
|
456 static tree
|
111
|
457 get_returned_expression (tree fn)
|
|
458 {
|
|
459 /* Extract the body of the function minus the return expression. */
|
|
460 tree body = DECL_SAVED_TREE (fn);
|
|
461 if (!body)
|
|
462 return error_mark_node;
|
|
463 if (TREE_CODE (body) == BIND_EXPR)
|
|
464 body = BIND_EXPR_BODY (body);
|
|
465 if (TREE_CODE (body) != RETURN_EXPR)
|
|
466 return error_mark_node;
|
|
467
|
|
468 return TREE_OPERAND (body, 0);
|
|
469 }
|
|
470
|
|
471 /* Returns the initializer of a variable concept. */
|
|
472
|
145
|
473 static tree
|
111
|
474 get_variable_initializer (tree var)
|
|
475 {
|
|
476 tree init = DECL_INITIAL (var);
|
|
477 if (!init)
|
|
478 return error_mark_node;
|
145
|
479 if (BRACE_ENCLOSED_INITIALIZER_P (init)
|
|
480 && CONSTRUCTOR_NELTS (init) == 1)
|
|
481 init = CONSTRUCTOR_ELT (init, 0)->value;
|
111
|
482 return init;
|
|
483 }
|
|
484
|
|
485 /* Returns the definition of a variable or function concept. */
|
|
486
|
145
|
487 static tree
|
111
|
488 get_concept_definition (tree decl)
|
|
489 {
|
145
|
490 if (TREE_CODE (decl) == OVERLOAD)
|
|
491 decl = OVL_FIRST (decl);
|
|
492
|
|
493 if (TREE_CODE (decl) == TEMPLATE_DECL)
|
|
494 decl = DECL_TEMPLATE_RESULT (decl);
|
|
495
|
|
496 if (TREE_CODE (decl) == CONCEPT_DECL)
|
|
497 return DECL_INITIAL (decl);
|
111
|
498 if (VAR_P (decl))
|
|
499 return get_variable_initializer (decl);
|
145
|
500 if (TREE_CODE (decl) == FUNCTION_DECL)
|
111
|
501 return get_returned_expression (decl);
|
|
502 gcc_unreachable ();
|
|
503 }
|
|
504
|
|
505 /*---------------------------------------------------------------------------
|
145
|
506 Normalization of expressions
|
111
|
507
|
|
508 This set of functions will transform an expression into a constraint
|
145
|
509 in a sequence of steps.
|
111
|
510 ---------------------------------------------------------------------------*/
|
|
511
|
145
|
512 void
|
|
513 debug_parameter_mapping (tree map)
|
|
514 {
|
|
515 for (tree p = map; p; p = TREE_CHAIN (p))
|
|
516 {
|
|
517 tree parm = TREE_VALUE (p);
|
|
518 tree arg = TREE_PURPOSE (p);
|
|
519 if (TYPE_P (parm))
|
|
520 verbatim ("MAP %qD TO %qT", TEMPLATE_TYPE_DECL (parm), arg);
|
|
521 else
|
|
522 verbatim ("MAP %qD TO %qE", TEMPLATE_PARM_DECL (parm), arg);
|
|
523 // debug_tree (parm);
|
|
524 // debug_tree (arg);
|
|
525 }
|
|
526 }
|
|
527
|
|
528 void
|
|
529 debug_argument_list (tree args)
|
|
530 {
|
|
531 for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
|
|
532 {
|
|
533 tree arg = TREE_VEC_ELT (args, i);
|
|
534 if (TYPE_P (arg))
|
|
535 verbatim ("ARG %qT", arg);
|
|
536 else
|
|
537 verbatim ("ARG %qE", arg);
|
|
538 }
|
|
539 }
|
|
540
|
|
541 /* Associate each parameter in PARMS with its corresponding template
|
|
542 argument in ARGS. */
|
|
543
|
|
544 static tree
|
|
545 map_arguments (tree parms, tree args)
|
|
546 {
|
|
547 for (tree p = parms; p; p = TREE_CHAIN (p))
|
|
548 {
|
|
549 int level;
|
|
550 int index;
|
|
551 template_parm_level_and_index (TREE_VALUE (p), &level, &index);
|
|
552 TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
|
|
553 }
|
|
554 return parms;
|
|
555 }
|
|
556
|
|
557 /* Build the parameter mapping for EXPR using ARGS. */
|
|
558
|
|
559 static tree
|
|
560 build_parameter_mapping (tree expr, tree args, tree decl)
|
|
561 {
|
|
562 tree ctx_parms = NULL_TREE;
|
|
563 if (decl)
|
|
564 {
|
|
565 gcc_assert (TREE_CODE (decl) == TEMPLATE_DECL);
|
|
566 ctx_parms = DECL_TEMPLATE_PARMS (decl);
|
|
567 }
|
|
568 else if (current_template_parms)
|
|
569 {
|
|
570 /* TODO: This should probably be the only case, but because the
|
|
571 point of declaration of concepts is currently set after the
|
|
572 initializer, the template parameter lists are not available
|
|
573 when normalizing concept definitions, hence the case above. */
|
|
574 ctx_parms = current_template_parms;
|
|
575 }
|
|
576
|
|
577 tree parms = find_template_parameters (expr, ctx_parms);
|
|
578 tree map = map_arguments (parms, args);
|
|
579 return map;
|
|
580 }
|
|
581
|
|
582 /* True if the parameter mappings of two atomic constraints are equivalent. */
|
|
583
|
|
584 static bool
|
|
585 parameter_mapping_equivalent_p (tree t1, tree t2)
|
|
586 {
|
|
587 tree map1 = ATOMIC_CONSTR_MAP (t1);
|
|
588 tree map2 = ATOMIC_CONSTR_MAP (t2);
|
|
589 while (map1 && map2)
|
|
590 {
|
|
591 tree arg1 = TREE_PURPOSE (map1);
|
|
592 tree arg2 = TREE_PURPOSE (map2);
|
|
593 if (!template_args_equal (arg1, arg2))
|
|
594 return false;
|
|
595 map1 = TREE_CHAIN (map1);
|
|
596 map2 = TREE_CHAIN (map2);
|
|
597 }
|
|
598 return true;
|
|
599 }
|
|
600
|
|
601 /* Provides additional context for normalization. */
|
|
602
|
|
603 struct norm_info : subst_info
|
|
604 {
|
|
605 explicit norm_info (tsubst_flags_t complain)
|
|
606 : subst_info (tf_warning_or_error | complain, NULL_TREE),
|
|
607 context()
|
|
608 {}
|
|
609
|
|
610 /* Construct a top-level context for DECL. */
|
|
611
|
|
612 norm_info (tree in_decl, tsubst_flags_t complain)
|
|
613 : subst_info (tf_warning_or_error | complain, in_decl),
|
|
614 context (make_context (in_decl))
|
|
615 {}
|
|
616
|
|
617 bool generate_diagnostics() const
|
|
618 {
|
|
619 return complain & tf_norm;
|
|
620 }
|
|
621
|
|
622 tree make_context(tree in_decl)
|
|
623 {
|
|
624 if (generate_diagnostics ())
|
|
625 return build_tree_list (NULL_TREE, in_decl);
|
|
626 return NULL_TREE;
|
|
627 }
|
|
628
|
|
629 void update_context(tree expr, tree args)
|
|
630 {
|
|
631 if (generate_diagnostics ())
|
|
632 {
|
|
633 tree map = build_parameter_mapping (expr, args, in_decl);
|
|
634 context = tree_cons (map, expr, context);
|
|
635 }
|
|
636 in_decl = get_concept_check_template (expr);
|
|
637 }
|
|
638
|
|
639 /* Provides information about the source of a constraint. This is a
|
|
640 TREE_LIST whose VALUE is either a concept check or a constrained
|
|
641 declaration. The PURPOSE, for concept checks is a parameter mapping
|
|
642 for that check. */
|
|
643
|
|
644 tree context;
|
|
645 };
|
|
646
|
|
647 static tree normalize_expression (tree, tree, norm_info);
|
|
648
|
111
|
649 /* Transform a logical-or or logical-and expression into either
|
|
650 a conjunction or disjunction. */
|
|
651
|
145
|
652 static tree
|
|
653 normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
|
111
|
654 {
|
145
|
655 tree t0 = normalize_expression (TREE_OPERAND (t, 0), args, info);
|
|
656 tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);
|
|
657
|
|
658 /* Build a new info object for the constraint. */
|
|
659 tree ci = info.generate_diagnostics()
|
|
660 ? build_tree_list (t, info.context)
|
|
661 : NULL_TREE;
|
|
662
|
|
663 return build2 (c, ci, t0, t1);
|
111
|
664 }
|
|
665
|
145
|
666 static tree
|
|
667 normalize_concept_check (tree check, tree args, norm_info info)
|
111
|
668 {
|
145
|
669 tree id = unpack_concept_check (check);
|
|
670 tree tmpl = TREE_OPERAND (id, 0);
|
|
671 tree targs = TREE_OPERAND (id, 1);
|
|
672
|
|
673 /* A function concept is wrapped in an overload. */
|
|
674 if (TREE_CODE (tmpl) == OVERLOAD)
|
111
|
675 {
|
145
|
676 /* TODO: Can we diagnose this error during parsing? */
|
|
677 if (TREE_CODE (check) == TEMPLATE_ID_EXPR)
|
|
678 error_at (EXPR_LOC_OR_LOC (check, input_location),
|
|
679 "function concept must be called");
|
|
680 tmpl = OVL_FIRST (tmpl);
|
111
|
681 }
|
|
682
|
145
|
683 /* Substitute through the arguments of the concept check. */
|
|
684 targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
|
|
685 if (targs == error_mark_node)
|
|
686 return error_mark_node;
|
|
687
|
|
688 /* Build the substitution for the concept definition. */
|
|
689 tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
|
|
690 /* Turn on template processing; coercing non-type template arguments
|
|
691 will automatically assume they're non-dependent. */
|
|
692 ++processing_template_decl;
|
|
693 tree subst = coerce_template_parms (parms, targs, tmpl);
|
|
694 --processing_template_decl;
|
|
695 if (subst == error_mark_node)
|
|
696 return error_mark_node;
|
|
697
|
|
698 /* The concept may have been ill-formed. */
|
|
699 tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
|
|
700 if (def == error_mark_node)
|
|
701 return error_mark_node;
|
|
702
|
|
703 info.update_context (check, args);
|
|
704 return normalize_expression (def, subst, info);
|
111
|
705 }
|
|
706
|
|
707 /* The normal form of an atom depends on the expression. The normal
|
|
708 form of a function call to a function concept is a check constraint
|
|
709 for that concept. The normal form of a reference to a variable
|
|
710 concept is a check constraint for that concept. Otherwise, the
|
|
711 constraint is a predicate constraint. */
|
|
712
|
145
|
713 static tree
|
|
714 normalize_atom (tree t, tree args, norm_info info)
|
111
|
715 {
|
145
|
716 /* Concept checks are not atomic. */
|
|
717 if (concept_check_p (t))
|
|
718 return normalize_concept_check (t, args, info);
|
|
719
|
|
720 /* Build the parameter mapping for the atom. */
|
|
721 tree map = build_parameter_mapping (t, args, info.in_decl);
|
|
722
|
|
723 /* Build a new info object for the atom. */
|
|
724 tree ci = build_tree_list (t, info.context);
|
|
725
|
|
726 return build1 (ATOMIC_CONSTR, ci, map);
|
111
|
727 }
|
|
728
|
145
|
729 /* Returns the normal form of an expression. */
|
|
730
|
|
731 static tree
|
|
732 normalize_expression (tree t, tree args, norm_info info)
|
111
|
733 {
|
|
734 if (!t)
|
|
735 return NULL_TREE;
|
|
736
|
|
737 if (t == error_mark_node)
|
|
738 return error_mark_node;
|
|
739
|
|
740 switch (TREE_CODE (t))
|
|
741 {
|
145
|
742 case TRUTH_ANDIF_EXPR:
|
|
743 return normalize_logical_operation (t, args, CONJ_CONSTR, info);
|
|
744 case TRUTH_ORIF_EXPR:
|
|
745 return normalize_logical_operation (t, args, DISJ_CONSTR, info);
|
|
746 default:
|
|
747 return normalize_atom (t, args, info);
|
|
748 }
|
|
749 }
|
|
750
|
|
751 /* Cache of the normalized form of constraints. Marked as deletable because it
|
|
752 can all be recalculated. */
|
|
753 static GTY((deletable)) hash_map<tree,tree> *normalized_map;
|
|
754
|
|
755 static tree
|
|
756 get_normalized_constraints (tree t, tree args, norm_info info)
|
|
757 {
|
|
758 auto_timevar time (TV_CONSTRAINT_NORM);
|
|
759 return normalize_expression (t, args, info);
|
|
760 }
|
|
761
|
|
762 /* Returns the normalized constraints from a constraint-info object
|
|
763 or NULL_TREE if the constraints are null. ARGS provide the initial
|
|
764 arguments for normalization and IN_DECL provides the declaration
|
|
765 to which the constraints belong. */
|
|
766
|
|
767 static tree
|
|
768 get_normalized_constraints_from_info (tree ci, tree args, tree in_decl,
|
|
769 bool diag = false)
|
|
770 {
|
|
771 if (ci == NULL_TREE)
|
|
772 return NULL_TREE;
|
|
773
|
|
774 /* Substitution errors during normalization are fatal. */
|
|
775 ++processing_template_decl;
|
|
776 norm_info info (in_decl, diag ? tf_norm : tf_none);
|
|
777 tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci),
|
|
778 args, info);
|
|
779 --processing_template_decl;
|
|
780
|
|
781 return t;
|
|
782 }
|
|
783
|
|
784 /* Returns the normalized constraints for the declaration D. */
|
|
785
|
|
786 static tree
|
|
787 get_normalized_constraints_from_decl (tree d, bool diag = false)
|
|
788 {
|
|
789 tree tmpl;
|
|
790 tree decl;
|
|
791
|
|
792 /* For inherited constructors, consider the original declaration;
|
|
793 it has the correct template information attached. */
|
|
794 d = strip_inheriting_ctors (d);
|
|
795
|
|
796 if (TREE_CODE (d) == TEMPLATE_DECL)
|
|
797 {
|
|
798 tmpl = d;
|
|
799 decl = DECL_TEMPLATE_RESULT (tmpl);
|
|
800 }
|
|
801 else
|
|
802 {
|
|
803 if (tree ti = DECL_TEMPLATE_INFO (d))
|
|
804 tmpl = TI_TEMPLATE (ti);
|
|
805 else
|
|
806 tmpl = NULL_TREE;
|
|
807 decl = d;
|
111
|
808 }
|
145
|
809
|
|
810 /* Get the most general template for the declaration, and compute
|
|
811 arguments from that. This ensures that the arguments used for
|
|
812 normalization are always template parameters and not arguments
|
|
813 used for outer specializations. For example:
|
|
814
|
|
815 template<typename T>
|
|
816 struct S {
|
|
817 template<typename U> requires C<T, U> void f(U);
|
|
818 };
|
|
819
|
|
820 S<int>::f(0);
|
|
821
|
|
822 When we normalize the requirements for S<int>::f, we want the
|
|
823 arguments to be {T, U}, not {int, U}. One reason for this is that
|
|
824 accepting the latter causes the template parameter level of U
|
|
825 to be reduced in a way that makes it overly difficult substitute
|
|
826 concrete arguments (i.e., eventually {int, int} during satisfaction. */
|
|
827 if (tmpl)
|
|
828 {
|
|
829 if (DECL_LANG_SPECIFIC(tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
|
|
830 tmpl = most_general_template (tmpl);
|
|
831 }
|
|
832
|
|
833 /* If we're not diagnosing errors, use cached constraints, if any. */
|
|
834 if (!diag)
|
|
835 if (tree *p = hash_map_safe_get (normalized_map, tmpl))
|
|
836 return *p;
|
|
837
|
|
838 tree args = generic_targs_for (tmpl);
|
|
839 tree ci = get_constraints (decl);
|
|
840 tree norm = get_normalized_constraints_from_info (ci, args, tmpl, diag);
|
|
841
|
|
842 if (!diag)
|
|
843 hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);
|
|
844
|
|
845 return norm;
|
|
846 }
|
|
847
|
|
848 /* Returns the normal form of TMPL's definition. */
|
|
849
|
|
850 static tree
|
|
851 normalize_concept_definition (tree tmpl, bool diag = false)
|
|
852 {
|
|
853 if (!diag)
|
|
854 if (tree *p = hash_map_safe_get (normalized_map, tmpl))
|
|
855 return *p;
|
|
856
|
|
857 gcc_assert (concept_definition_p (tmpl));
|
|
858 if (OVL_P (tmpl))
|
|
859 tmpl = OVL_FIRST (tmpl);
|
|
860 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
|
|
861 tree args = generic_targs_for (tmpl);
|
|
862 tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
|
|
863 ++processing_template_decl;
|
|
864 norm_info info (tmpl, diag ? tf_norm : tf_none);
|
|
865 tree norm = get_normalized_constraints (def, args, info);
|
|
866 --processing_template_decl;
|
|
867
|
|
868 if (!diag)
|
|
869 hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);
|
|
870
|
|
871 return norm;
|
|
872 }
|
|
873
|
|
874 /* Returns the normal form of TMPL's requirements. */
|
|
875
|
|
876 static tree
|
|
877 normalize_template_requirements (tree tmpl, bool diag = false)
|
|
878 {
|
|
879 return get_normalized_constraints_from_decl (tmpl, diag);
|
|
880 }
|
|
881
|
|
882 /* Returns the normal form of TMPL's requirements. */
|
|
883
|
|
884 static tree
|
|
885 normalize_nontemplate_requirements (tree decl, bool diag = false)
|
|
886 {
|
|
887 return get_normalized_constraints_from_decl (decl, diag);
|
|
888 }
|
|
889
|
|
890 /* Normalize an EXPR as a constraint using ARGS. */
|
|
891
|
|
892 static tree
|
|
893 normalize_constraint_expression (tree expr, tree args, bool diag = false)
|
|
894 {
|
|
895 if (!expr || expr == error_mark_node)
|
|
896 return expr;
|
|
897 ++processing_template_decl;
|
|
898 norm_info info (diag ? tf_norm : tf_none);
|
|
899 tree norm = get_normalized_constraints (expr, args, info);
|
|
900 --processing_template_decl;
|
|
901 return norm;
|
111
|
902 }
|
|
903
|
145
|
904 /* Normalize an EXPR as a constraint. */
|
|
905
|
|
906 static tree
|
|
907 normalize_constraint_expression (tree expr, bool diag = false)
|
|
908 {
|
|
909 if (!expr || expr == error_mark_node)
|
|
910 return expr;
|
|
911
|
|
912 /* For concept checks, use the supplied template arguments as those used
|
|
913 for normalization. Otherwise, there are no template arguments. */
|
|
914 tree args;
|
|
915 if (concept_check_p (expr))
|
|
916 {
|
|
917 tree id = unpack_concept_check (expr);
|
|
918 args = TREE_OPERAND (id, 1);
|
|
919 }
|
|
920 else
|
|
921 args = NULL_TREE;
|
|
922
|
|
923 return normalize_constraint_expression (expr, args, diag);
|
|
924 }
|
|
925
|
|
926 /* 17.4.1.2p2. Two constraints are identical if they are formed
|
|
927 from the same expression and the targets of the parameter mapping
|
|
928 are equivalent. */
|
|
929
|
|
930 bool
|
|
931 atomic_constraints_identical_p (tree t1, tree t2)
|
|
932 {
|
|
933 gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR);
|
|
934 gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR);
|
|
935
|
|
936 if (ATOMIC_CONSTR_EXPR (t1) != ATOMIC_CONSTR_EXPR (t2))
|
|
937 return false;
|
|
938
|
|
939 if (!parameter_mapping_equivalent_p (t1, t2))
|
|
940 return false;
|
|
941
|
|
942 return true;
|
|
943 }
|
|
944
|
|
945 /* True if T1 and T2 are equivalent, meaning they have the same syntactic
|
|
946 structure and all corresponding constraints are identical. */
|
|
947
|
|
948 bool
|
|
949 constraints_equivalent_p (tree t1, tree t2)
|
|
950 {
|
|
951 gcc_assert (CONSTR_P (t1));
|
|
952 gcc_assert (CONSTR_P (t2));
|
|
953
|
|
954 if (TREE_CODE (t1) != TREE_CODE (t2))
|
|
955 return false;
|
|
956
|
|
957 switch (TREE_CODE (t1))
|
|
958 {
|
|
959 case CONJ_CONSTR:
|
|
960 case DISJ_CONSTR:
|
|
961 if (!constraints_equivalent_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
|
|
962 return false;
|
|
963 if (!constraints_equivalent_p (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)))
|
|
964 return false;
|
|
965 break;
|
|
966 case ATOMIC_CONSTR:
|
|
967 if (!atomic_constraints_identical_p(t1, t2))
|
|
968 return false;
|
|
969 break;
|
|
970 default:
|
|
971 gcc_unreachable ();
|
|
972 }
|
|
973 return true;
|
|
974 }
|
|
975
|
|
976 /* Compute the hash value for T. */
|
|
977
|
|
978 hashval_t
|
|
979 hash_atomic_constraint (tree t)
|
|
980 {
|
|
981 gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);
|
|
982
|
|
983 /* Hash the identity of the expression. */
|
|
984 hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t));
|
|
985
|
|
986 /* Hash the targets of the parameter map. */
|
|
987 tree p = ATOMIC_CONSTR_MAP (t);
|
|
988 while (p)
|
|
989 {
|
|
990 val = iterative_hash_template_arg (TREE_PURPOSE (p), val);
|
|
991 p = TREE_CHAIN (p);
|
|
992 }
|
|
993
|
|
994 return val;
|
|
995 }
|
|
996
|
|
997 namespace inchash
|
|
998 {
|
|
999
|
|
1000 static void
|
|
1001 add_constraint (tree t, hash& h)
|
|
1002 {
|
|
1003 h.add_int(TREE_CODE (t));
|
|
1004 switch (TREE_CODE (t))
|
|
1005 {
|
|
1006 case CONJ_CONSTR:
|
|
1007 case DISJ_CONSTR:
|
|
1008 add_constraint (TREE_OPERAND (t, 0), h);
|
|
1009 add_constraint (TREE_OPERAND (t, 1), h);
|
|
1010 break;
|
|
1011 case ATOMIC_CONSTR:
|
|
1012 h.merge_hash (hash_atomic_constraint (t));
|
|
1013 break;
|
|
1014 default:
|
|
1015 gcc_unreachable ();
|
|
1016 }
|
|
1017 }
|
|
1018
|
|
1019 }
|
|
1020
|
|
1021 /* Computes a hash code for the constraint T. */
|
|
1022
|
|
1023 hashval_t
|
|
1024 iterative_hash_constraint (tree t, hashval_t val)
|
|
1025 {
|
|
1026 gcc_assert (CONSTR_P (t));
|
|
1027 inchash::hash h (val);
|
|
1028 inchash::add_constraint (t, h);
|
|
1029 return h.end ();
|
|
1030 }
|
111
|
1031
|
|
1032 // -------------------------------------------------------------------------- //
|
|
1033 // Constraint Semantic Processing
|
|
1034 //
|
|
1035 // The following functions are called by the parser and substitution rules
|
|
1036 // to create and evaluate constraint-related nodes.
|
|
1037
|
|
1038 // The constraints associated with the current template parameters.
|
|
1039 tree
|
|
1040 current_template_constraints (void)
|
|
1041 {
|
|
1042 if (!current_template_parms)
|
|
1043 return NULL_TREE;
|
145
|
1044 tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
|
111
|
1045 return build_constraints (tmpl_constr, NULL_TREE);
|
|
1046 }
|
|
1047
|
145
|
1048 /* If the recently parsed TYPE declares or defines a template or
|
|
1049 template specialization, get its corresponding constraints from the
|
|
1050 current template parameters and bind them to TYPE's declaration. */
|
|
1051
|
111
|
1052 tree
|
|
1053 associate_classtype_constraints (tree type)
|
|
1054 {
|
145
|
1055 if (!type || type == error_mark_node || !CLASS_TYPE_P (type))
|
111
|
1056 return type;
|
|
1057
|
145
|
1058 /* An explicit class template specialization has no template parameters. */
|
111
|
1059 if (!current_template_parms)
|
|
1060 return type;
|
|
1061
|
|
1062 if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
|
|
1063 {
|
|
1064 tree decl = TYPE_STUB_DECL (type);
|
|
1065 tree ci = current_template_constraints ();
|
|
1066
|
145
|
1067 /* An implicitly instantiated member template declaration already
|
|
1068 has associated constraints. If it is defined outside of its
|
|
1069 class, then we need match these constraints against those of
|
|
1070 original declaration. */
|
111
|
1071 if (tree orig_ci = get_constraints (decl))
|
|
1072 {
|
|
1073 if (!equivalent_constraints (ci, orig_ci))
|
|
1074 {
|
145
|
1075 error ("%qT does not match original declaration", type);
|
|
1076 tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
|
|
1077 location_t loc = DECL_SOURCE_LOCATION (tmpl);
|
|
1078 inform (loc, "original template declaration here");
|
|
1079 /* Fall through, so that we define the type anyway. */
|
111
|
1080 }
|
|
1081 return type;
|
|
1082 }
|
|
1083 set_constraints (decl, ci);
|
|
1084 }
|
|
1085 return type;
|
|
1086 }
|
|
1087
|
145
|
1088 /* Create an empty constraint info block. */
|
|
1089
|
|
1090 static inline tree_constraint_info*
|
111
|
1091 build_constraint_info ()
|
|
1092 {
|
|
1093 return (tree_constraint_info *)make_node (CONSTRAINT_INFO);
|
|
1094 }
|
|
1095
|
|
1096 /* Build a constraint-info object that contains the associated constraints
|
|
1097 of a declaration. This also includes the declaration's template
|
|
1098 requirements (TREQS) and any trailing requirements for a function
|
|
1099 declarator (DREQS). Note that both TREQS and DREQS must be constraints.
|
|
1100
|
|
1101 If the declaration has neither template nor declaration requirements
|
|
1102 this returns NULL_TREE, indicating an unconstrained declaration. */
|
|
1103
|
|
1104 tree
|
145
|
1105 build_constraints (tree tr, tree dr)
|
111
|
1106 {
|
145
|
1107 if (!tr && !dr)
|
111
|
1108 return NULL_TREE;
|
|
1109
|
|
1110 tree_constraint_info* ci = build_constraint_info ();
|
145
|
1111 ci->template_reqs = tr;
|
|
1112 ci->declarator_reqs = dr;
|
|
1113 ci->associated_constr = combine_constraint_expressions (tr, dr);
|
111
|
1114
|
|
1115 return (tree)ci;
|
|
1116 }
|
|
1117
|
145
|
1118 /* Add constraint RHS to the end of CONSTRAINT_INFO ci. */
|
|
1119
|
|
1120 tree
|
|
1121 append_constraint (tree ci, tree rhs)
|
|
1122 {
|
|
1123 tree tr = ci ? CI_TEMPLATE_REQS (ci) : NULL_TREE;
|
|
1124 tree dr = ci ? CI_DECLARATOR_REQS (ci) : NULL_TREE;
|
|
1125 dr = combine_constraint_expressions (dr, rhs);
|
|
1126 if (ci)
|
|
1127 {
|
|
1128 CI_DECLARATOR_REQS (ci) = dr;
|
|
1129 tree ac = combine_constraint_expressions (tr, dr);
|
|
1130 CI_ASSOCIATED_CONSTRAINTS (ci) = ac;
|
|
1131 }
|
|
1132 else
|
|
1133 ci = build_constraints (tr, dr);
|
|
1134 return ci;
|
|
1135 }
|
|
1136
|
|
1137 /* A mapping from declarations to constraint information. */
|
|
1138
|
|
1139 static GTY ((cache)) decl_tree_cache_map *decl_constraints;
|
|
1140
|
|
1141 /* Returns the template constraints of declaration T. If T is not
|
|
1142 constrained, return NULL_TREE. Note that T must be non-null. */
|
|
1143
|
|
1144 tree
|
|
1145 get_constraints (const_tree t)
|
|
1146 {
|
|
1147 if (!flag_concepts)
|
|
1148 return NULL_TREE;
|
|
1149 if (!decl_constraints)
|
|
1150 return NULL_TREE;
|
|
1151
|
|
1152 gcc_assert (DECL_P (t));
|
|
1153 if (TREE_CODE (t) == TEMPLATE_DECL)
|
|
1154 t = DECL_TEMPLATE_RESULT (t);
|
|
1155 tree* found = decl_constraints->get (CONST_CAST_TREE (t));
|
|
1156 if (found)
|
|
1157 return *found;
|
|
1158 else
|
|
1159 return NULL_TREE;
|
|
1160 }
|
|
1161
|
|
1162 /* Associate the given constraint information CI with the declaration
|
|
1163 T. If T is a template, then the constraints are associated with
|
|
1164 its underlying declaration. Don't build associations if CI is
|
|
1165 NULL_TREE. */
|
|
1166
|
|
1167 void
|
|
1168 set_constraints (tree t, tree ci)
|
|
1169 {
|
|
1170 if (!ci)
|
|
1171 return;
|
|
1172 gcc_assert (t && flag_concepts);
|
|
1173 if (TREE_CODE (t) == TEMPLATE_DECL)
|
|
1174 t = DECL_TEMPLATE_RESULT (t);
|
|
1175 bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
|
|
1176 gcc_assert (!found);
|
|
1177 }
|
|
1178
|
|
1179 /* Remove the associated constraints of the declaration T. */
|
|
1180
|
|
1181 void
|
|
1182 remove_constraints (tree t)
|
|
1183 {
|
|
1184 gcc_assert (DECL_P (t));
|
|
1185 if (TREE_CODE (t) == TEMPLATE_DECL)
|
|
1186 t = DECL_TEMPLATE_RESULT (t);
|
|
1187
|
|
1188 if (decl_constraints)
|
|
1189 decl_constraints->remove (t);
|
|
1190 }
|
|
1191
|
|
1192 /* If DECL is a friend, substitute into REQS to produce requirements suitable
|
|
1193 for declaration matching. */
|
|
1194
|
|
1195 tree
|
|
1196 maybe_substitute_reqs_for (tree reqs, const_tree decl_)
|
|
1197 {
|
|
1198 if (reqs == NULL_TREE)
|
|
1199 return NULL_TREE;
|
|
1200 tree decl = CONST_CAST_TREE (decl_);
|
|
1201 tree result = STRIP_TEMPLATE (decl);
|
|
1202 if (DECL_FRIEND_P (result))
|
|
1203 {
|
|
1204 tree tmpl = decl == result ? DECL_TI_TEMPLATE (result) : decl;
|
|
1205 tree gargs = generic_targs_for (tmpl);
|
|
1206 processing_template_decl_sentinel s;
|
|
1207 if (uses_template_parms (gargs))
|
|
1208 ++processing_template_decl;
|
|
1209 reqs = tsubst_constraint (reqs, gargs,
|
|
1210 tf_warning_or_error, NULL_TREE);
|
|
1211 }
|
|
1212 return reqs;
|
|
1213 }
|
|
1214
|
|
1215 /* Returns the template-head requires clause for the template
|
|
1216 declaration T or NULL_TREE if none. */
|
|
1217
|
|
1218 tree
|
|
1219 get_template_head_requirements (tree t)
|
|
1220 {
|
|
1221 tree ci = get_constraints (t);
|
|
1222 if (!ci)
|
|
1223 return NULL_TREE;
|
|
1224 return CI_TEMPLATE_REQS (ci);
|
|
1225 }
|
|
1226
|
|
1227 /* Returns the trailing requires clause of the declarator of
|
|
1228 a template declaration T or NULL_TREE if none. */
|
|
1229
|
|
1230 tree
|
|
1231 get_trailing_function_requirements (tree t)
|
|
1232 {
|
|
1233 tree ci = get_constraints (t);
|
|
1234 if (!ci)
|
|
1235 return NULL_TREE;
|
|
1236 return CI_DECLARATOR_REQS (ci);
|
|
1237 }
|
111
|
1238
|
|
1239 /* Construct a sequence of template arguments by prepending
|
|
1240 ARG to REST. Either ARG or REST may be null. */
|
145
|
1241 static tree
|
111
|
1242 build_concept_check_arguments (tree arg, tree rest)
|
|
1243 {
|
|
1244 gcc_assert (rest ? TREE_CODE (rest) == TREE_VEC : true);
|
|
1245 tree args;
|
|
1246 if (arg)
|
|
1247 {
|
|
1248 int n = rest ? TREE_VEC_LENGTH (rest) : 0;
|
|
1249 args = make_tree_vec (n + 1);
|
|
1250 TREE_VEC_ELT (args, 0) = arg;
|
|
1251 if (rest)
|
|
1252 for (int i = 0; i < n; ++i)
|
|
1253 TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i);
|
|
1254 int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0;
|
|
1255 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
|
|
1256 }
|
|
1257 else
|
|
1258 {
|
|
1259 gcc_assert (rest != NULL_TREE);
|
|
1260 args = rest;
|
|
1261 }
|
|
1262 return args;
|
|
1263 }
|
|
1264
|
145
|
1265 /* Builds an id-expression of the form `C<Args...>()` where C is a function
|
|
1266 concept. */
|
|
1267
|
|
1268 static tree
|
|
1269 build_function_check (tree tmpl, tree args, tsubst_flags_t /*complain*/)
|
|
1270 {
|
|
1271 if (TREE_CODE (tmpl) == TEMPLATE_DECL)
|
|
1272 {
|
|
1273 /* If we just got a template, wrap it in an overload so it looks like any
|
|
1274 other template-id. */
|
|
1275 tmpl = ovl_make (tmpl);
|
|
1276 TREE_TYPE (tmpl) = boolean_type_node;
|
|
1277 }
|
|
1278
|
|
1279 /* Perform function concept resolution now so we always have a single
|
|
1280 function of the overload set (even if we started with only one; the
|
|
1281 resolution function converts template arguments). Note that we still
|
|
1282 wrap this in an overload set so we don't upset other parts of the
|
|
1283 compiler that expect template-ids referring to function concepts
|
|
1284 to have an overload set. */
|
|
1285 tree info = resolve_function_concept_overload (tmpl, args);
|
|
1286 if (info == error_mark_node)
|
|
1287 return error_mark_node;
|
|
1288 if (!info)
|
|
1289 {
|
|
1290 error ("no matching concepts for %qE", tmpl);
|
|
1291 return error_mark_node;
|
|
1292 }
|
|
1293 args = TREE_PURPOSE (info);
|
|
1294 tmpl = DECL_TI_TEMPLATE (TREE_VALUE (info));
|
|
1295
|
|
1296 /* Rebuild the singleton overload set; mark the type bool. */
|
|
1297 tmpl = ovl_make (tmpl, NULL_TREE);
|
|
1298 TREE_TYPE (tmpl) = boolean_type_node;
|
|
1299
|
|
1300 /* Build the id-expression around the overload set. */
|
|
1301 tree id = build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
|
|
1302
|
|
1303 /* Finally, build the call expression around the overload. */
|
|
1304 ++processing_template_decl;
|
|
1305 vec<tree, va_gc> *fargs = make_tree_vector ();
|
|
1306 tree call = build_min_nt_call_vec (id, fargs);
|
|
1307 TREE_TYPE (call) = boolean_type_node;
|
|
1308 release_tree_vector (fargs);
|
|
1309 --processing_template_decl;
|
|
1310
|
|
1311 return call;
|
|
1312 }
|
|
1313
|
|
1314 /* Builds an id-expression of the form `C<Args...>` where C is a variable
|
|
1315 concept. */
|
|
1316
|
|
1317 static tree
|
|
1318 build_variable_check (tree tmpl, tree args, tsubst_flags_t complain)
|
|
1319 {
|
|
1320 gcc_assert (variable_concept_p (tmpl));
|
|
1321 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
|
|
1322 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
|
|
1323 args = coerce_template_parms (parms, args, tmpl, complain);
|
|
1324 if (args == error_mark_node)
|
|
1325 return error_mark_node;
|
|
1326 return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
|
|
1327 }
|
|
1328
|
|
1329 /* Builds an id-expression of the form `C<Args...>` where C is a standard
|
|
1330 concept. */
|
|
1331
|
|
1332 static tree
|
|
1333 build_standard_check (tree tmpl, tree args, tsubst_flags_t complain)
|
|
1334 {
|
|
1335 gcc_assert (standard_concept_p (tmpl));
|
|
1336 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
|
|
1337 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
|
|
1338 args = coerce_template_parms (parms, args, tmpl, complain);
|
|
1339 if (args == error_mark_node)
|
|
1340 return error_mark_node;
|
|
1341 return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
|
|
1342 }
|
|
1343
|
|
1344 /* Construct an expression that checks TARGET using ARGS. */
|
|
1345
|
111
|
1346 tree
|
145
|
1347 build_concept_check (tree target, tree args, tsubst_flags_t complain)
|
111
|
1348 {
|
145
|
1349 return build_concept_check (target, NULL_TREE, args, complain);
|
|
1350 }
|
|
1351
|
|
1352 /* Construct an expression that checks the concept given by DECL. If
|
|
1353 concept_definition_p (DECL) is false, this returns null. */
|
|
1354
|
|
1355 tree
|
|
1356 build_concept_check (tree decl, tree arg, tree rest, tsubst_flags_t complain)
|
|
1357 {
|
|
1358 if (arg == NULL_TREE && rest == NULL_TREE)
|
|
1359 {
|
|
1360 tree id = build_nt (TEMPLATE_ID_EXPR, decl, rest);
|
|
1361 error ("invalid use concept %qE", id);
|
|
1362 return error_mark_node;
|
|
1363 }
|
|
1364
|
111
|
1365 tree args = build_concept_check_arguments (arg, rest);
|
145
|
1366
|
|
1367 if (standard_concept_p (decl))
|
|
1368 return build_standard_check (decl, args, complain);
|
|
1369 if (variable_concept_p (decl))
|
|
1370 return build_variable_check (decl, args, complain);
|
|
1371 if (function_concept_p (decl))
|
|
1372 return build_function_check (decl, args, complain);
|
|
1373
|
|
1374 return error_mark_node;
|
|
1375 }
|
|
1376
|
|
1377 /* Build a template-id that can participate in a concept check. */
|
|
1378
|
|
1379 static tree
|
|
1380 build_concept_id (tree decl, tree args)
|
|
1381 {
|
|
1382 tree check = build_concept_check (decl, args, tf_warning_or_error);
|
|
1383 if (check == error_mark_node)
|
|
1384 return error_mark_node;
|
|
1385 return unpack_concept_check (check);
|
111
|
1386 }
|
|
1387
|
145
|
1388 /* Build a template-id that can participate in a concept check, preserving
|
|
1389 the source location of the original template-id. */
|
|
1390
|
|
1391 tree
|
|
1392 build_concept_id (tree expr)
|
|
1393 {
|
|
1394 gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR);
|
|
1395 tree id = build_concept_id (TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
|
|
1396 protected_set_expr_location (id, cp_expr_location (expr));
|
|
1397 return id;
|
|
1398 }
|
|
1399
|
|
1400 /* Build as template-id with a placeholder that can be used as a
|
|
1401 type constraint.
|
|
1402
|
|
1403 Note that this will diagnose errors if the initial concept check
|
|
1404 cannot be built. */
|
|
1405
|
|
1406 tree
|
|
1407 build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
|
|
1408 {
|
|
1409 tree wildcard = build_nt (WILDCARD_DECL);
|
|
1410 tree check = build_concept_check (decl, wildcard, args, complain);
|
|
1411 if (check == error_mark_node)
|
|
1412 return error_mark_node;
|
|
1413 return unpack_concept_check (check);
|
|
1414 }
|
111
|
1415
|
|
1416 /* Returns a TYPE_DECL that contains sufficient information to
|
|
1417 build a template parameter of the same kind as PROTO and
|
|
1418 constrained by the concept declaration CNC. Note that PROTO
|
|
1419 is the first template parameter of CNC.
|
|
1420
|
|
1421 If specified, ARGS provides additional arguments to the
|
|
1422 constraint check. */
|
|
1423 tree
|
|
1424 build_constrained_parameter (tree cnc, tree proto, tree args)
|
|
1425 {
|
|
1426 tree name = DECL_NAME (cnc);
|
|
1427 tree type = TREE_TYPE (proto);
|
|
1428 tree decl = build_decl (input_location, TYPE_DECL, name, type);
|
|
1429 CONSTRAINED_PARM_PROTOTYPE (decl) = proto;
|
|
1430 CONSTRAINED_PARM_CONCEPT (decl) = cnc;
|
|
1431 CONSTRAINED_PARM_EXTRA_ARGS (decl) = args;
|
|
1432 return decl;
|
|
1433 }
|
|
1434
|
145
|
1435 /* Create a constraint expression for the given DECL that evaluates the
|
|
1436 requirements specified by CONSTR, a TYPE_DECL that contains all the
|
|
1437 information necessary to build the requirements (see finish_concept_name
|
|
1438 for the layout of that TYPE_DECL).
|
|
1439
|
|
1440 Note that the constraints are neither reduced nor decomposed. That is
|
|
1441 done only after the requires clause has been parsed (or not). */
|
|
1442
|
111
|
1443 tree
|
|
1444 finish_shorthand_constraint (tree decl, tree constr)
|
|
1445 {
|
|
1446 /* No requirements means no constraints. */
|
|
1447 if (!constr)
|
|
1448 return NULL_TREE;
|
|
1449
|
131
|
1450 if (error_operand_p (constr))
|
|
1451 return NULL_TREE;
|
|
1452
|
111
|
1453 tree proto = CONSTRAINED_PARM_PROTOTYPE (constr);
|
|
1454 tree con = CONSTRAINED_PARM_CONCEPT (constr);
|
|
1455 tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
|
|
1456
|
145
|
1457 /* The TS lets use shorthand to constrain a pack of arguments, but the
|
|
1458 standard does not.
|
|
1459
|
|
1460 For the TS, consider:
|
|
1461
|
|
1462 template<C... Ts> struct s;
|
|
1463
|
|
1464 If C is variadic (and because Ts is a pack), we associate the
|
|
1465 constraint C<Ts...>. In all other cases, we associate
|
|
1466 the constraint (C<Ts> && ...).
|
|
1467
|
|
1468 The standard behavior cannot be overridden by -fconcepts-ts. */
|
|
1469 bool variadic_concept_p = template_parameter_pack_p (proto);
|
|
1470 bool declared_pack_p = template_parameter_pack_p (decl);
|
|
1471 bool apply_to_each_p = (cxx_dialect >= cxx2a) ? true : !variadic_concept_p;
|
111
|
1472
|
|
1473 /* Get the argument and overload used for the requirement
|
|
1474 and adjust it if we're going to expand later. */
|
|
1475 tree arg = template_parm_to_arg (build_tree_list (NULL_TREE, decl));
|
145
|
1476 if (apply_to_each_p && declared_pack_p)
|
111
|
1477 arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0));
|
|
1478
|
145
|
1479 /* Build the concept constraint-expression. */
|
111
|
1480 tree tmpl = DECL_TI_TEMPLATE (con);
|
145
|
1481 tree check = tmpl;
|
|
1482 if (TREE_CODE (con) == FUNCTION_DECL)
|
|
1483 check = ovl_make (tmpl);
|
|
1484 check = build_concept_check (check, arg, args, tf_warning_or_error);
|
|
1485
|
|
1486 /* Make the check a fold-expression if needed. */
|
|
1487 if (apply_to_each_p && declared_pack_p)
|
|
1488 check = finish_left_unary_fold_expr (check, TRUTH_ANDIF_EXPR);
|
|
1489
|
|
1490 return check;
|
111
|
1491 }
|
|
1492
|
|
1493 /* Returns a conjunction of shorthand requirements for the template
|
|
1494 parameter list PARMS. Note that the requirements are stored in
|
|
1495 the TYPE of each tree node. */
|
145
|
1496
|
111
|
1497 tree
|
|
1498 get_shorthand_constraints (tree parms)
|
|
1499 {
|
|
1500 tree result = NULL_TREE;
|
|
1501 parms = INNERMOST_TEMPLATE_PARMS (parms);
|
|
1502 for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
|
|
1503 {
|
|
1504 tree parm = TREE_VEC_ELT (parms, i);
|
|
1505 tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
|
145
|
1506 result = combine_constraint_expressions (result, constr);
|
111
|
1507 }
|
|
1508 return result;
|
|
1509 }
|
|
1510
|
145
|
1511 /* Get the deduced wildcard from a DEDUCED placeholder. If the deduced
|
|
1512 wildcard is a pack, return the first argument of that pack. */
|
|
1513
|
111
|
1514 static tree
|
145
|
1515 get_deduced_wildcard (tree wildcard)
|
|
1516 {
|
|
1517 if (ARGUMENT_PACK_P (wildcard))
|
|
1518 wildcard = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (wildcard), 0);
|
|
1519 gcc_assert (TREE_CODE (wildcard) == WILDCARD_DECL);
|
|
1520 return wildcard;
|
|
1521 }
|
|
1522
|
|
1523 /* Returns the prototype parameter for the nth deduced wildcard. */
|
|
1524
|
|
1525 static tree
|
|
1526 get_introduction_prototype (tree wildcards, int index)
|
|
1527 {
|
|
1528 return TREE_TYPE (get_deduced_wildcard (TREE_VEC_ELT (wildcards, index)));
|
|
1529 }
|
|
1530
|
|
1531 /* Introduce a type template parameter. */
|
|
1532
|
|
1533 static tree
|
|
1534 introduce_type_template_parameter (tree wildcard, bool& non_type_p)
|
111
|
1535 {
|
145
|
1536 non_type_p = false;
|
|
1537 return finish_template_type_parm (class_type_node, DECL_NAME (wildcard));
|
|
1538 }
|
|
1539
|
|
1540 /* Introduce a template template parameter. */
|
|
1541
|
|
1542 static tree
|
|
1543 introduce_template_template_parameter (tree wildcard, bool& non_type_p)
|
|
1544 {
|
|
1545 non_type_p = false;
|
|
1546 begin_template_parm_list ();
|
|
1547 current_template_parms = DECL_TEMPLATE_PARMS (TREE_TYPE (wildcard));
|
|
1548 end_template_parm_list ();
|
|
1549 return finish_template_template_parm (class_type_node, DECL_NAME (wildcard));
|
|
1550 }
|
|
1551
|
|
1552 /* Introduce a template non-type parameter. */
|
|
1553
|
|
1554 static tree
|
|
1555 introduce_nontype_template_parameter (tree wildcard, bool& non_type_p)
|
|
1556 {
|
|
1557 non_type_p = true;
|
|
1558 tree parm = copy_decl (TREE_TYPE (wildcard));
|
|
1559 DECL_NAME (parm) = DECL_NAME (wildcard);
|
|
1560 return parm;
|
|
1561 }
|
|
1562
|
|
1563 /* Introduce a single template parameter. */
|
|
1564
|
|
1565 static tree
|
|
1566 build_introduced_template_parameter (tree wildcard, bool& non_type_p)
|
|
1567 {
|
|
1568 tree proto = TREE_TYPE (wildcard);
|
111
|
1569
|
|
1570 tree parm;
|
145
|
1571 if (TREE_CODE (proto) == TYPE_DECL)
|
|
1572 parm = introduce_type_template_parameter (wildcard, non_type_p);
|
|
1573 else if (TREE_CODE (proto) == TEMPLATE_DECL)
|
|
1574 parm = introduce_template_template_parameter (wildcard, non_type_p);
|
|
1575 else
|
|
1576 parm = introduce_nontype_template_parameter (wildcard, non_type_p);
|
|
1577
|
|
1578 /* Wrap in a TREE_LIST for process_template_parm. Note that introduced
|
|
1579 parameters do not retain the defaults from the source parameter. */
|
|
1580 return build_tree_list (NULL_TREE, parm);
|
|
1581 }
|
|
1582
|
|
1583 /* Introduce a single template parameter. */
|
|
1584
|
|
1585 static tree
|
|
1586 introduce_template_parameter (tree parms, tree wildcard)
|
|
1587 {
|
|
1588 gcc_assert (!ARGUMENT_PACK_P (wildcard));
|
|
1589 tree proto = TREE_TYPE (wildcard);
|
|
1590 location_t loc = DECL_SOURCE_LOCATION (wildcard);
|
|
1591
|
|
1592 /* Diagnose the case where we have C{...Args}. */
|
|
1593 if (WILDCARD_PACK_P (wildcard))
|
111
|
1594 {
|
145
|
1595 tree id = DECL_NAME (wildcard);
|
|
1596 error_at (loc, "%qE cannot be introduced with an ellipsis %<...%>", id);
|
|
1597 inform (DECL_SOURCE_LOCATION (proto), "prototype declared here");
|
111
|
1598 }
|
|
1599
|
145
|
1600 bool non_type_p;
|
|
1601 tree parm = build_introduced_template_parameter (wildcard, non_type_p);
|
|
1602 return process_template_parm (parms, loc, parm, non_type_p, false);
|
|
1603 }
|
|
1604
|
|
1605 /* Introduce a template parameter pack. */
|
|
1606
|
|
1607 static tree
|
|
1608 introduce_template_parameter_pack (tree parms, tree wildcard)
|
|
1609 {
|
|
1610 bool non_type_p;
|
|
1611 tree parm = build_introduced_template_parameter (wildcard, non_type_p);
|
|
1612 location_t loc = DECL_SOURCE_LOCATION (wildcard);
|
|
1613 return process_template_parm (parms, loc, parm, non_type_p, true);
|
|
1614 }
|
|
1615
|
|
1616 /* Introduce the nth template parameter. */
|
|
1617
|
|
1618 static tree
|
|
1619 introduce_template_parameter (tree parms, tree wildcards, int& index)
|
|
1620 {
|
|
1621 tree deduced = TREE_VEC_ELT (wildcards, index++);
|
|
1622 return introduce_template_parameter (parms, deduced);
|
|
1623 }
|
|
1624
|
|
1625 /* Introduce either a template parameter pack or a list of template
|
|
1626 parameters. */
|
|
1627
|
|
1628 static tree
|
|
1629 introduce_template_parameters (tree parms, tree wildcards, int& index)
|
|
1630 {
|
|
1631 /* If the prototype was a parameter, we better have deduced an
|
|
1632 argument pack, and that argument must be the last deduced value
|
|
1633 in the wildcard vector. */
|
|
1634 tree deduced = TREE_VEC_ELT (wildcards, index++);
|
|
1635 gcc_assert (ARGUMENT_PACK_P (deduced));
|
|
1636 gcc_assert (index == TREE_VEC_LENGTH (wildcards));
|
|
1637
|
|
1638 /* Introduce each element in the pack. */
|
|
1639 tree args = ARGUMENT_PACK_ARGS (deduced);
|
|
1640 for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
|
|
1641 {
|
|
1642 tree arg = TREE_VEC_ELT (args, i);
|
|
1643 if (WILDCARD_PACK_P (arg))
|
|
1644 parms = introduce_template_parameter_pack (parms, arg);
|
|
1645 else
|
|
1646 parms = introduce_template_parameter (parms, arg);
|
|
1647 }
|
|
1648
|
|
1649 return parms;
|
111
|
1650 }
|
|
1651
|
145
|
1652 /* Builds the template parameter list PARMS by chaining introduced
|
|
1653 parameters from the WILDCARD vector. INDEX is the position of
|
|
1654 the current parameter. */
|
|
1655
|
|
1656 static tree
|
|
1657 process_introduction_parms (tree parms, tree wildcards, int& index)
|
|
1658 {
|
|
1659 tree proto = get_introduction_prototype (wildcards, index);
|
|
1660 if (template_parameter_pack_p (proto))
|
|
1661 return introduce_template_parameters (parms, wildcards, index);
|
|
1662 else
|
|
1663 return introduce_template_parameter (parms, wildcards, index);
|
|
1664 }
|
|
1665
|
|
1666 /* Ensure that all template parameters have been introduced for the concept
|
|
1667 named in CHECK. If not, emit a diagnostic.
|
|
1668
|
|
1669 Note that implicitly introducing a parameter with a default argument
|
|
1670 creates a case where a parameter is declared, but unnamed, making
|
|
1671 it unusable in the definition. */
|
|
1672
|
|
1673 static bool
|
|
1674 check_introduction_list (tree intros, tree check)
|
|
1675 {
|
|
1676 check = unpack_concept_check (check);
|
|
1677 tree tmpl = TREE_OPERAND (check, 0);
|
|
1678 if (OVL_P (tmpl))
|
|
1679 tmpl = OVL_FIRST (tmpl);
|
|
1680
|
|
1681 tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
|
|
1682 if (TREE_VEC_LENGTH (intros) < TREE_VEC_LENGTH (parms))
|
|
1683 {
|
|
1684 error_at (input_location, "all template parameters of %qD must "
|
|
1685 "be introduced", tmpl);
|
|
1686 return false;
|
|
1687 }
|
|
1688
|
|
1689 return true;
|
|
1690 }
|
|
1691
|
|
1692 /* Associates a constraint check to the current template based on the
|
|
1693 introduction parameters. INTRO_LIST must be a TREE_VEC of WILDCARD_DECLs
|
|
1694 containing a chained PARM_DECL which contains the identifier as well as
|
|
1695 the source location. TMPL_DECL is the decl for the concept being used.
|
|
1696 If we take a concept, C, this will form a check in the form of
|
|
1697 C<INTRO_LIST> filling in any extra arguments needed by the defaults
|
|
1698 deduced.
|
|
1699
|
|
1700 Returns NULL_TREE if no concept could be matched and error_mark_node if
|
|
1701 an error occurred when matching. */
|
|
1702
|
111
|
1703 tree
|
145
|
1704 finish_template_introduction (tree tmpl_decl,
|
|
1705 tree intro_list,
|
|
1706 location_t intro_loc)
|
111
|
1707 {
|
145
|
1708 /* Build a concept check to deduce the actual parameters. */
|
|
1709 tree expr = build_concept_check (tmpl_decl, intro_list, tf_none);
|
111
|
1710 if (expr == error_mark_node)
|
145
|
1711 {
|
|
1712 error_at (intro_loc, "cannot deduce template parameters from "
|
|
1713 "introduction list");
|
|
1714 return error_mark_node;
|
|
1715 }
|
|
1716
|
|
1717 if (!check_introduction_list (intro_list, expr))
|
|
1718 return error_mark_node;
|
111
|
1719
|
|
1720 tree parms = deduce_concept_introduction (expr);
|
|
1721 if (!parms)
|
|
1722 return NULL_TREE;
|
|
1723
|
|
1724 /* Build template parameter scope for introduction. */
|
|
1725 tree parm_list = NULL_TREE;
|
|
1726 begin_template_parm_list ();
|
|
1727 int nargs = MIN (TREE_VEC_LENGTH (parms), TREE_VEC_LENGTH (intro_list));
|
145
|
1728 for (int n = 0; n < nargs; )
|
|
1729 parm_list = process_introduction_parms (parm_list, parms, n);
|
111
|
1730 parm_list = end_template_parm_list (parm_list);
|
145
|
1731
|
|
1732 /* Update the number of arguments to reflect the number of deduced
|
|
1733 template parameter introductions. */
|
|
1734 nargs = TREE_VEC_LENGTH (parm_list);
|
|
1735
|
|
1736 /* Determine if any errors occurred during matching. */
|
111
|
1737 for (int i = 0; i < TREE_VEC_LENGTH (parm_list); ++i)
|
|
1738 if (TREE_VALUE (TREE_VEC_ELT (parm_list, i)) == error_mark_node)
|
|
1739 {
|
|
1740 end_template_decl ();
|
|
1741 return error_mark_node;
|
|
1742 }
|
|
1743
|
|
1744 /* Build a concept check for our constraint. */
|
145
|
1745 tree check_args = make_tree_vec (nargs);
|
111
|
1746 int n = 0;
|
|
1747 for (; n < TREE_VEC_LENGTH (parm_list); ++n)
|
|
1748 {
|
|
1749 tree parm = TREE_VEC_ELT (parm_list, n);
|
|
1750 TREE_VEC_ELT (check_args, n) = template_parm_to_arg (parm);
|
|
1751 }
|
|
1752 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (check_args, n);
|
|
1753
|
|
1754 /* If the template expects more parameters we should be able
|
|
1755 to use the defaults from our deduced concept. */
|
|
1756 for (; n < TREE_VEC_LENGTH (parms); ++n)
|
|
1757 TREE_VEC_ELT (check_args, n) = TREE_VEC_ELT (parms, n);
|
|
1758
|
145
|
1759 /* Associate the constraint. */
|
|
1760 tree check = build_concept_check (tmpl_decl,
|
|
1761 check_args,
|
|
1762 tf_warning_or_error);
|
|
1763 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = check;
|
111
|
1764
|
|
1765 return parm_list;
|
|
1766 }
|
|
1767
|
|
1768
|
145
|
1769 /* Given the concept check T from a constrained-type-specifier, extract
|
111
|
1770 its TMPL and ARGS. FIXME why do we need two different forms of
|
|
1771 constrained-type-specifier? */
|
|
1772
|
|
1773 void
|
|
1774 placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args)
|
|
1775 {
|
145
|
1776 if (concept_check_p (t))
|
|
1777 {
|
|
1778 t = unpack_concept_check (t);
|
|
1779 tmpl = TREE_OPERAND (t, 0);
|
|
1780 if (TREE_CODE (tmpl) == OVERLOAD)
|
|
1781 tmpl = OVL_FIRST (tmpl);
|
|
1782 args = TREE_OPERAND (t, 1);
|
|
1783 return;
|
|
1784 }
|
|
1785
|
111
|
1786 if (TREE_CODE (t) == TYPE_DECL)
|
|
1787 {
|
|
1788 /* A constrained parameter. Build a constraint check
|
|
1789 based on the prototype parameter and then extract the
|
|
1790 arguments from that. */
|
|
1791 tree proto = CONSTRAINED_PARM_PROTOTYPE (t);
|
|
1792 tree check = finish_shorthand_constraint (proto, t);
|
|
1793 placeholder_extract_concept_and_args (check, tmpl, args);
|
|
1794 return;
|
|
1795 }
|
|
1796 }
|
|
1797
|
|
1798 /* Returns true iff the placeholders C1 and C2 are equivalent. C1
|
145
|
1799 and C2 can be either TEMPLATE_TYPE_PARM or template-ids. */
|
111
|
1800
|
|
1801 bool
|
|
1802 equivalent_placeholder_constraints (tree c1, tree c2)
|
|
1803 {
|
|
1804 if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
|
|
1805 /* A constrained auto. */
|
|
1806 c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
|
|
1807 if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
|
|
1808 c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);
|
|
1809
|
|
1810 if (c1 == c2)
|
|
1811 return true;
|
|
1812 if (!c1 || !c2)
|
|
1813 return false;
|
|
1814 if (c1 == error_mark_node || c2 == error_mark_node)
|
|
1815 /* We get here during satisfaction; when a deduction constraint
|
|
1816 fails, substitution can produce an error_mark_node for the
|
|
1817 placeholder constraints. */
|
|
1818 return false;
|
|
1819
|
|
1820 tree t1, t2, a1, a2;
|
|
1821 placeholder_extract_concept_and_args (c1, t1, a1);
|
|
1822 placeholder_extract_concept_and_args (c2, t2, a2);
|
|
1823
|
|
1824 if (t1 != t2)
|
|
1825 return false;
|
|
1826
|
|
1827 int len1 = TREE_VEC_LENGTH (a1);
|
|
1828 int len2 = TREE_VEC_LENGTH (a2);
|
|
1829 if (len1 != len2)
|
|
1830 return false;
|
|
1831
|
|
1832 /* Skip the first argument so we don't infinitely recurse.
|
|
1833 Also, they may differ in template parameter index. */
|
|
1834 for (int i = 1; i < len1; ++i)
|
|
1835 {
|
|
1836 tree t1 = TREE_VEC_ELT (a1, i);
|
|
1837 tree t2 = TREE_VEC_ELT (a2, i);
|
|
1838 if (!template_args_equal (t1, t2))
|
|
1839 return false;
|
|
1840 }
|
|
1841 return true;
|
|
1842 }
|
|
1843
|
145
|
1844 /* Return a hash value for the placeholder ATOMIC_CONSTR C. */
|
111
|
1845
|
|
1846 hashval_t
|
|
1847 hash_placeholder_constraint (tree c)
|
|
1848 {
|
|
1849 tree t, a;
|
|
1850 placeholder_extract_concept_and_args (c, t, a);
|
|
1851
|
|
1852 /* Like hash_tmpl_and_args, but skip the first argument. */
|
|
1853 hashval_t val = iterative_hash_object (DECL_UID (t), 0);
|
|
1854
|
|
1855 for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
|
|
1856 val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
|
|
1857
|
|
1858 return val;
|
|
1859 }
|
|
1860
|
145
|
1861 /* Substitute through the simple requirement. */
|
|
1862
|
|
1863 static tree
|
|
1864 tsubst_valid_expression_requirement (tree t, tree args, subst_info info)
|
111
|
1865 {
|
145
|
1866 return tsubst_expr (t, args, info.complain, info.in_decl, false);
|
111
|
1867 }
|
|
1868
|
145
|
1869
|
|
1870 /* Substitute through the simple requirement. */
|
|
1871
|
|
1872 static tree
|
|
1873 tsubst_simple_requirement (tree t, tree args, subst_info info)
|
111
|
1874 {
|
145
|
1875 tree t0 = TREE_OPERAND (t, 0);
|
|
1876 tree expr = tsubst_valid_expression_requirement (t0, args, info);
|
|
1877 if (expr == error_mark_node)
|
111
|
1878 return error_mark_node;
|
145
|
1879 return finish_simple_requirement (EXPR_LOCATION (t), expr);
|
111
|
1880 }
|
|
1881
|
145
|
1882 /* Substitute through the type requirement. */
|
|
1883
|
|
1884 static tree
|
|
1885 tsubst_type_requirement (tree t, tree args, subst_info info)
|
111
|
1886 {
|
|
1887 tree t0 = TREE_OPERAND (t, 0);
|
145
|
1888 tree type = tsubst (t0, args, info.complain, info.in_decl);
|
|
1889 if (type == error_mark_node)
|
111
|
1890 return error_mark_node;
|
145
|
1891 return finish_type_requirement (EXPR_LOCATION (t), type);
|
111
|
1892 }
|
|
1893
|
145
|
1894 /* True if TYPE can be deduced from EXPR. */
|
|
1895
|
|
1896 static bool
|
|
1897 type_deducible_p (tree expr, tree type, tree placeholder, tree args,
|
|
1898 subst_info info)
|
111
|
1899 {
|
145
|
1900 /* Make sure deduction is performed against ( EXPR ), so that
|
|
1901 references are preserved in the result. */
|
|
1902 expr = force_paren_expr_uneval (expr);
|
|
1903
|
|
1904 /* Replace the constraints with the instantiated constraints. This
|
|
1905 substitutes args into any template parameters in the trailing
|
|
1906 result type. */
|
|
1907 tree saved_constr = PLACEHOLDER_TYPE_CONSTRAINTS (placeholder);
|
|
1908 tree subst_constr
|
|
1909 = tsubst_constraint (saved_constr,
|
|
1910 args,
|
|
1911 info.complain | tf_partial,
|
|
1912 info.in_decl);
|
|
1913
|
|
1914 if (subst_constr == error_mark_node)
|
|
1915 return false;
|
|
1916
|
|
1917 PLACEHOLDER_TYPE_CONSTRAINTS (placeholder) = subst_constr;
|
|
1918
|
|
1919 /* Temporarily unlink the canonical type. */
|
|
1920 tree saved_type = TYPE_CANONICAL (placeholder);
|
|
1921 TYPE_CANONICAL (placeholder) = NULL_TREE;
|
|
1922
|
|
1923 tree deduced_type
|
|
1924 = do_auto_deduction (type,
|
|
1925 expr,
|
|
1926 placeholder,
|
|
1927 info.complain,
|
|
1928 adc_requirement);
|
|
1929
|
|
1930 PLACEHOLDER_TYPE_CONSTRAINTS (placeholder) = saved_constr;
|
|
1931 TYPE_CANONICAL (placeholder) = saved_type;
|
|
1932
|
|
1933 if (deduced_type == error_mark_node)
|
|
1934 return false;
|
|
1935
|
|
1936 return true;
|
|
1937 }
|
|
1938
|
|
1939 /* True if EXPR can not be converted to TYPE. */
|
|
1940
|
|
1941 static bool
|
|
1942 expression_convertible_p (tree expr, tree type, subst_info info)
|
|
1943 {
|
|
1944 tree conv =
|
|
1945 perform_direct_initialization_if_possible (type, expr, false,
|
|
1946 info.complain);
|
|
1947 if (conv == error_mark_node)
|
|
1948 return false;
|
|
1949 if (conv == NULL_TREE)
|
|
1950 {
|
|
1951 if (info.complain & tf_error)
|
|
1952 {
|
|
1953 location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
|
|
1954 error_at (loc, "cannot convert %qE to %qT", expr, type);
|
|
1955 }
|
|
1956 return false;
|
|
1957 }
|
|
1958 return true;
|
|
1959 }
|
|
1960
|
|
1961
|
|
1962 /* Substitute through the compound requirement. */
|
|
1963
|
|
1964 static tree
|
|
1965 tsubst_compound_requirement (tree t, tree args, subst_info info)
|
|
1966 {
|
|
1967 tree t0 = TREE_OPERAND (t, 0);
|
|
1968 tree t1 = TREE_OPERAND (t, 1);
|
|
1969 tree expr = tsubst_valid_expression_requirement (t0, args, info);
|
|
1970 if (expr == error_mark_node)
|
111
|
1971 return error_mark_node;
|
145
|
1972
|
|
1973 /* Check the noexcept condition. */
|
|
1974 bool noexcept_p = COMPOUND_REQ_NOEXCEPT_P (t);
|
|
1975 if (noexcept_p && !expr_noexcept_p (expr, tf_none))
|
|
1976 return error_mark_node;
|
|
1977
|
|
1978 /* Substitute through the type expression, if any. */
|
|
1979 tree type = tsubst (t1, args, info.complain, info.in_decl);
|
|
1980 if (type == error_mark_node)
|
111
|
1981 return error_mark_node;
|
145
|
1982
|
|
1983 /* Check expression against the result type. */
|
|
1984 if (type)
|
|
1985 {
|
|
1986 if (tree placeholder = type_uses_auto (type))
|
|
1987 {
|
|
1988 if (!type_deducible_p (expr, type, placeholder, args, info))
|
|
1989 return error_mark_node;
|
|
1990 }
|
|
1991 else if (!expression_convertible_p (expr, type, info))
|
|
1992 return error_mark_node;
|
|
1993 }
|
|
1994
|
|
1995 return finish_compound_requirement (EXPR_LOCATION (t),
|
|
1996 expr, type, noexcept_p);
|
|
1997 }
|
|
1998
|
|
1999 static tree
|
|
2000 tsubst_nested_requirement (tree t, tree args, subst_info info)
|
|
2001 {
|
|
2002 gcc_assert (!uses_template_parms (args));
|
|
2003
|
|
2004 /* Ensure that we're in an evaluation context prior to satisfaction. */
|
|
2005 tree norm = TREE_VALUE (TREE_TYPE (t));
|
|
2006 tree result = satisfy_constraint (norm, args, info);
|
|
2007 if (result != boolean_true_node)
|
|
2008 return error_mark_node;
|
|
2009 return result;
|
111
|
2010 }
|
|
2011
|
145
|
2012 /* Substitute ARGS into the requirement T. */
|
|
2013
|
|
2014 static tree
|
|
2015 tsubst_requirement (tree t, tree args, subst_info info)
|
111
|
2016 {
|
145
|
2017 iloc_sentinel loc_s (cp_expr_location (t));
|
|
2018 switch (TREE_CODE (t))
|
|
2019 {
|
|
2020 case SIMPLE_REQ:
|
|
2021 return tsubst_simple_requirement (t, args, info);
|
|
2022 case TYPE_REQ:
|
|
2023 return tsubst_type_requirement (t, args, info);
|
|
2024 case COMPOUND_REQ:
|
|
2025 return tsubst_compound_requirement (t, args, info);
|
|
2026 case NESTED_REQ:
|
|
2027 return tsubst_nested_requirement (t, args, info);
|
|
2028 default:
|
|
2029 break;
|
|
2030 }
|
|
2031 gcc_unreachable ();
|
111
|
2032 }
|
|
2033
|
145
|
2034 /* Substitute ARGS into the list of requirements T. Note that
|
|
2035 substitution failures here result in ill-formed programs. */
|
|
2036
|
|
2037 static tree
|
|
2038 tsubst_requirement_body (tree t, tree args, subst_info info)
|
|
2039 {
|
|
2040 tree result = NULL_TREE;
|
|
2041 while (t)
|
|
2042 {
|
|
2043 tree req = tsubst_requirement (TREE_VALUE (t), args, info);
|
|
2044 if (req == error_mark_node)
|
|
2045 return error_mark_node;
|
|
2046 result = tree_cons (NULL_TREE, req, result);
|
|
2047 t = TREE_CHAIN (t);
|
|
2048 }
|
|
2049 return nreverse (result);
|
|
2050 }
|
|
2051
|
|
2052 static tree
|
111
|
2053 declare_constraint_vars (tree parms, tree vars)
|
|
2054 {
|
|
2055 tree s = vars;
|
|
2056 for (tree t = parms; t; t = DECL_CHAIN (t))
|
|
2057 {
|
|
2058 if (DECL_PACK_P (t))
|
|
2059 {
|
|
2060 tree pack = extract_fnparm_pack (t, &s);
|
|
2061 register_local_specialization (pack, t);
|
|
2062 }
|
|
2063 else
|
|
2064 {
|
|
2065 register_local_specialization (s, t);
|
|
2066 s = DECL_CHAIN (s);
|
|
2067 }
|
|
2068 }
|
|
2069 return vars;
|
|
2070 }
|
|
2071
|
145
|
2072 /* Substitute through as if checking function parameter types. This
|
|
2073 will diagnose common parameter type errors. Returns error_mark_node
|
|
2074 if an error occurred. */
|
|
2075
|
|
2076 static tree
|
|
2077 check_constaint_variables (tree t, tree args, subst_info info)
|
|
2078 {
|
|
2079 tree types = NULL_TREE;
|
|
2080 tree p = t;
|
|
2081 while (p && !VOID_TYPE_P (p))
|
|
2082 {
|
|
2083 types = tree_cons (NULL_TREE, TREE_TYPE (p), types);
|
|
2084 p = TREE_CHAIN (p);
|
|
2085 }
|
|
2086 types = chainon (nreverse (types), void_list_node);
|
|
2087 return tsubst_function_parms (types, args, info.complain, info.in_decl);
|
|
2088 }
|
|
2089
|
111
|
2090 /* A subroutine of tsubst_parameterized_constraint. Substitute ARGS
|
|
2091 into the parameter list T, producing a sequence of constraint
|
|
2092 variables, declared in the current scope.
|
|
2093
|
|
2094 Note that the caller must establish a local specialization stack
|
|
2095 prior to calling this function since this substitution will
|
|
2096 declare the substituted parameters. */
|
|
2097
|
145
|
2098 static tree
|
|
2099 tsubst_constraint_variables (tree t, tree args, subst_info info)
|
111
|
2100 {
|
145
|
2101 /* Perform a trial substitution to check for type errors. */
|
|
2102 tree parms = check_constaint_variables (t, args, info);
|
|
2103 if (parms == error_mark_node)
|
|
2104 return error_mark_node;
|
|
2105
|
111
|
2106 /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain
|
|
2107 of PARM_DECLs. */
|
|
2108 int saved_unevaluated_operand = cp_unevaluated_operand;
|
|
2109 cp_unevaluated_operand = 0;
|
145
|
2110 tree vars = tsubst (t, args, info.complain, info.in_decl);
|
111
|
2111 cp_unevaluated_operand = saved_unevaluated_operand;
|
|
2112 if (vars == error_mark_node)
|
|
2113 return error_mark_node;
|
|
2114 return declare_constraint_vars (t, vars);
|
|
2115 }
|
|
2116
|
145
|
2117 /* Substitute ARGS into the requires-expression T. [8.4.7]p6. The
|
|
2118 substitution of template arguments into a requires-expression
|
|
2119 may result in the formation of invalid types or expressions
|
|
2120 in its requirements ... In such cases, the expression evaluates
|
|
2121 to false; it does not cause the program to be ill-formed.
|
|
2122
|
|
2123 However, there are cases where substitution must produce a
|
|
2124 new requires-expression, that is not a template constraint.
|
|
2125 For example:
|
|
2126
|
|
2127 template<typename T>
|
|
2128 class X {
|
|
2129 template<typename U>
|
|
2130 static constexpr bool var = requires (U u) { T::fn(u); };
|
|
2131 };
|
|
2132
|
|
2133 In the instantiation of X<Y> (assuming Y defines fn), then the
|
|
2134 instantiated requires-expression would include Y::fn(u). If any
|
|
2135 substitution in the requires-expression fails, we can immediately
|
|
2136 fold the expression to false, as would be the case e.g., when
|
|
2137 instantiation X<int>. */
|
111
|
2138
|
|
2139 tree
|
|
2140 tsubst_requires_expr (tree t, tree args,
|
145
|
2141 tsubst_flags_t complain, tree in_decl)
|
111
|
2142 {
|
145
|
2143 local_specialization_stack stack (lss_copy);
|
|
2144
|
|
2145 subst_info info (complain, in_decl);
|
|
2146
|
|
2147 /* A requires-expression is an unevaluated context. */
|
|
2148 cp_unevaluated u;
|
111
|
2149
|
|
2150 tree parms = TREE_OPERAND (t, 0);
|
|
2151 if (parms)
|
|
2152 {
|
145
|
2153 parms = tsubst_constraint_variables (parms, args, info);
|
111
|
2154 if (parms == error_mark_node)
|
145
|
2155 return boolean_false_node;
|
111
|
2156 }
|
|
2157
|
|
2158 tree reqs = TREE_OPERAND (t, 1);
|
145
|
2159 reqs = tsubst_requirement_body (reqs, args, info);
|
111
|
2160 if (reqs == error_mark_node)
|
145
|
2161 return boolean_false_node;
|
|
2162
|
|
2163 /* In certain cases, produce a new requires-expression.
|
|
2164 Otherwise the value of the expression is true. */
|
|
2165 if (processing_template_decl && uses_template_parms (args))
|
|
2166 return finish_requires_expr (cp_expr_location (t), parms, reqs);
|
|
2167
|
|
2168 return boolean_true_node;
|
111
|
2169 }
|
|
2170
|
|
2171 /* Substitute ARGS into the constraint information CI, producing a new
|
145
|
2172 constraint record. */
|
111
|
2173
|
|
2174 tree
|
|
2175 tsubst_constraint_info (tree t, tree args,
|
|
2176 tsubst_flags_t complain, tree in_decl)
|
|
2177 {
|
|
2178 if (!t || t == error_mark_node || !check_constraint_info (t))
|
|
2179 return NULL_TREE;
|
|
2180
|
145
|
2181 tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t), args, complain, in_decl);
|
|
2182 tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t), args, complain, in_decl);
|
|
2183 return build_constraints (tr, dr);
|
111
|
2184 }
|
|
2185
|
145
|
2186 /* Substitute through a parameter mapping, in order to get the actual
|
|
2187 arguments used to instantiate an atomic constraint. This may fail
|
|
2188 if the substitution into arguments produces something ill-formed. */
|
|
2189
|
|
2190 static tree
|
|
2191 tsubst_parameter_mapping (tree map, tree args, subst_info info)
|
|
2192 {
|
|
2193 if (!map)
|
|
2194 return NULL_TREE;
|
|
2195
|
|
2196 tsubst_flags_t complain = info.complain;
|
|
2197 tree in_decl = info.in_decl;
|
|
2198
|
|
2199 tree result = NULL_TREE;
|
|
2200 for (tree p = map; p; p = TREE_CHAIN (p))
|
|
2201 {
|
|
2202 if (p == error_mark_node)
|
|
2203 return error_mark_node;
|
|
2204 tree parm = TREE_VALUE (p);
|
|
2205 tree arg = TREE_PURPOSE (p);
|
|
2206 tree new_arg = NULL_TREE;
|
|
2207 if (TYPE_P (arg))
|
|
2208 {
|
|
2209 /* If a template parameter is declared with a placeholder, we can
|
|
2210 get those in the argument list if decltype is applied to the
|
|
2211 placeholder. For example:
|
|
2212
|
|
2213 template<auto T>
|
|
2214 requires C<decltype(T)>
|
|
2215 void f() { }
|
|
2216
|
|
2217 The normalized argument for C will be an auto type, so we'll
|
|
2218 need to deduce the actual argument from the corresponding
|
|
2219 initializer (whatever argument is provided for T), and use
|
|
2220 that result in the instantiated parameter mapping. */
|
|
2221 if (tree auto_node = type_uses_auto (arg))
|
|
2222 {
|
|
2223 int level;
|
|
2224 int index;
|
|
2225 template_parm_level_and_index (parm, &level, &index);
|
|
2226 tree init = TMPL_ARG (args, level, index);
|
|
2227 new_arg = do_auto_deduction (arg, init, auto_node,
|
|
2228 complain, adc_variable_type,
|
|
2229 make_tree_vec (0));
|
|
2230 }
|
|
2231 }
|
|
2232 else if (ARGUMENT_PACK_P (arg))
|
|
2233 new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
|
|
2234 if (!new_arg)
|
|
2235 new_arg = tsubst_template_arg (arg, args, complain, in_decl);
|
|
2236 if (new_arg == error_mark_node)
|
|
2237 return error_mark_node;
|
|
2238
|
|
2239 result = tree_cons (new_arg, parm, result);
|
|
2240 }
|
|
2241 return nreverse (result);
|
|
2242 }
|
111
|
2243
|
|
2244 tree
|
145
|
2245 tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_decl)
|
111
|
2246 {
|
145
|
2247 return tsubst_parameter_mapping (map, args, subst_info (complain, in_decl));
|
111
|
2248 }
|
|
2249
|
|
2250 /*---------------------------------------------------------------------------
|
|
2251 Constraint satisfaction
|
|
2252 ---------------------------------------------------------------------------*/
|
|
2253
|
145
|
2254 /* Hash functions for satisfaction entries. */
|
|
2255
|
|
2256 struct GTY((for_user)) sat_entry
|
|
2257 {
|
|
2258 tree constr;
|
|
2259 tree args;
|
|
2260 tree result;
|
|
2261 };
|
|
2262
|
|
2263 struct sat_hasher : ggc_ptr_hash<sat_entry>
|
|
2264 {
|
|
2265 static hashval_t hash (sat_entry *e)
|
|
2266 {
|
|
2267 hashval_t value = hash_atomic_constraint (e->constr);
|
|
2268 return iterative_hash_template_arg (e->args, value);
|
|
2269 }
|
|
2270
|
|
2271 static bool equal (sat_entry *e1, sat_entry *e2)
|
|
2272 {
|
|
2273 if (!atomic_constraints_identical_p (e1->constr, e2->constr))
|
|
2274 return false;
|
|
2275 return template_args_equal (e1->args, e2->args);
|
|
2276 }
|
|
2277 };
|
|
2278
|
|
2279 /* Cache the result of satisfy_atom. */
|
|
2280 static GTY((deletable)) hash_table<sat_hasher> *sat_cache;
|
|
2281
|
|
2282 /* Cache the result of constraint_satisfaction_value. */
|
|
2283 static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;
|
|
2284
|
|
2285 static tree
|
|
2286 get_satisfaction (tree constr, tree args)
|
|
2287 {
|
|
2288 if (!sat_cache)
|
|
2289 return NULL_TREE;
|
|
2290 sat_entry elt = { constr, args, NULL_TREE };
|
|
2291 sat_entry* found = sat_cache->find (&elt);
|
|
2292 if (found)
|
|
2293 return found->result;
|
|
2294 else
|
|
2295 return NULL_TREE;
|
|
2296 }
|
|
2297
|
|
2298 static void
|
|
2299 save_satisfaction (tree constr, tree args, tree result)
|
111
|
2300 {
|
145
|
2301 if (!sat_cache)
|
|
2302 sat_cache = hash_table<sat_hasher>::create_ggc (31);
|
|
2303 sat_entry elt = {constr, args, result};
|
|
2304 sat_entry** slot = sat_cache->find_slot (&elt, INSERT);
|
|
2305 sat_entry* entry = ggc_alloc<sat_entry> ();
|
|
2306 *entry = elt;
|
|
2307 *slot = entry;
|
|
2308 }
|
|
2309
|
|
2310 void
|
|
2311 clear_satisfaction_cache ()
|
|
2312 {
|
|
2313 if (sat_cache)
|
|
2314 sat_cache->empty ();
|
|
2315 if (decl_satisfied_cache)
|
|
2316 decl_satisfied_cache->empty ();
|
111
|
2317 }
|
|
2318
|
145
|
2319 /* A tool to help manage satisfaction caching in satisfy_constraint_r.
|
|
2320 Note the cache is only used when not diagnosing errors. */
|
|
2321
|
|
2322 struct satisfaction_cache
|
|
2323 {
|
|
2324 satisfaction_cache (tree constr, tree args, tsubst_flags_t complain)
|
|
2325 : constr(constr), args(args), complain(complain)
|
|
2326 { }
|
|
2327
|
|
2328 tree get ()
|
|
2329 {
|
|
2330 if (complain == tf_none)
|
|
2331 return get_satisfaction (constr, args);
|
|
2332 return NULL_TREE;
|
|
2333 }
|
|
2334
|
|
2335 tree save (tree result)
|
|
2336 {
|
|
2337 if (complain == tf_none)
|
|
2338 save_satisfaction (constr, args, result);
|
|
2339 return result;
|
|
2340 }
|
|
2341
|
|
2342 tree constr;
|
|
2343 tree args;
|
|
2344 tsubst_flags_t complain;
|
|
2345 };
|
|
2346
|
|
2347 static int satisfying_constraint = 0;
|
|
2348
|
|
2349 /* Returns true if we are currently satisfying a constraint.
|
|
2350
|
|
2351 This is used to guard against recursive calls to evaluate_concept_check
|
|
2352 during template argument substitution.
|
|
2353
|
|
2354 TODO: Do we need this now that we fully normalize prior to evaluation?
|
|
2355 I think not. */
|
|
2356
|
|
2357 bool
|
|
2358 satisfying_constraint_p ()
|
|
2359 {
|
|
2360 return satisfying_constraint;
|
|
2361 }
|
|
2362
|
|
2363 /* Substitute ARGS into constraint-expression T during instantiation of
|
|
2364 a member of a class template. */
|
111
|
2365
|
|
2366 tree
|
145
|
2367 tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
111
|
2368 {
|
145
|
2369 /* We also don't want to evaluate concept-checks when substituting the
|
|
2370 constraint-expressions of a declaration. */
|
|
2371 processing_constraint_expression_sentinel s;
|
|
2372 tree expr = tsubst_expr (t, args, complain, in_decl, false);
|
|
2373 return expr;
|
111
|
2374 }
|
|
2375
|
145
|
2376 static tree satisfy_constraint_r (tree, tree, subst_info info);
|
|
2377
|
|
2378 /* Compute the satisfaction of a conjunction. */
|
|
2379
|
|
2380 static tree
|
|
2381 satisfy_conjunction (tree t, tree args, subst_info info)
|
111
|
2382 {
|
145
|
2383 tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
|
|
2384 if (lhs == error_mark_node || lhs == boolean_false_node)
|
|
2385 return lhs;
|
|
2386 return satisfy_constraint_r (TREE_OPERAND (t, 1), args, info);
|
111
|
2387 }
|
|
2388
|
145
|
2389 /* Compute the satisfaction of a disjunction. */
|
|
2390
|
|
2391 static tree
|
|
2392 satisfy_disjunction (tree t, tree args, subst_info info)
|
111
|
2393 {
|
145
|
2394 /* Evaluate the operands quietly. */
|
|
2395 subst_info quiet (tf_none, NULL_TREE);
|
|
2396
|
|
2397 /* Register the constraint for diagnostics, if needed. */
|
|
2398 diagnosing_failed_constraint failure (t, args, info.noisy ());
|
|
2399
|
|
2400 tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, quiet);
|
|
2401 if (lhs == boolean_true_node)
|
|
2402 return boolean_true_node;
|
|
2403 tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, quiet);
|
|
2404 if (rhs != boolean_true_node && info.noisy ())
|
|
2405 {
|
|
2406 location_t loc = cp_expr_location (CONSTR_EXPR (t));
|
|
2407 inform (loc, "neither operand of the disjunction is satisfied");
|
|
2408 /* TODO: Replay the LHS and RHS to find failures in both branches. */
|
|
2409 // satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
|
|
2410 // satisfy_constraint_r (TREE_OPERAND (t, 1), args, info);
|
|
2411 }
|
|
2412 return rhs;
|
111
|
2413 }
|
|
2414
|
145
|
2415 /* Ensures that T is a truth value and not (accidentally, as sometimes
|
|
2416 happens) an integer value. */
|
111
|
2417
|
|
2418 tree
|
145
|
2419 satisfaction_value (tree t)
|
111
|
2420 {
|
145
|
2421 if (t == error_mark_node)
|
|
2422 return t;
|
|
2423 if (t == boolean_true_node || t == integer_one_node)
|
111
|
2424 return boolean_true_node;
|
145
|
2425 if (t == boolean_false_node || t == integer_zero_node)
|
111
|
2426 return boolean_false_node;
|
|
2427
|
145
|
2428 /* Anything else should be invalid. */
|
|
2429 gcc_assert (false);
|
111
|
2430 }
|
|
2431
|
145
|
2432 /* Build a new template argument list with template arguments corresponding
|
|
2433 to the parameters used in an atomic constraint. */
|
111
|
2434
|
|
2435 tree
|
145
|
2436 get_mapped_args (tree map)
|
111
|
2437 {
|
145
|
2438 /* No map, no arguments. */
|
|
2439 if (!map)
|
|
2440 return NULL_TREE;
|
|
2441
|
|
2442 /* Find the mapped parameter with the highest level. */
|
|
2443 int count = 0;
|
|
2444 for (tree p = map; p; p = TREE_CHAIN (p))
|
|
2445 {
|
|
2446 int level;
|
|
2447 int index;
|
|
2448 template_parm_level_and_index (TREE_VALUE (p), &level, &index);
|
|
2449 if (level > count)
|
|
2450 count = level;
|
|
2451 }
|
|
2452
|
|
2453 /* Place each argument at its corresponding position in the argument
|
|
2454 list. Note that the list will be sparse (not all arguments supplied),
|
|
2455 but instantiation is guaranteed to only use the parameters in the
|
|
2456 mapping, so null arguments would never be used. */
|
|
2457 auto_vec< vec<tree> > lists (count);
|
|
2458 lists.quick_grow_cleared (count);
|
|
2459 for (tree p = map; p; p = TREE_CHAIN (p))
|
|
2460 {
|
|
2461 int level;
|
|
2462 int index;
|
|
2463 template_parm_level_and_index (TREE_VALUE (p), &level, &index);
|
|
2464
|
|
2465 /* Insert the argument into its corresponding position. */
|
|
2466 vec<tree> &list = lists[level - 1];
|
|
2467 if (index >= (int)list.length ())
|
|
2468 list.safe_grow_cleared (index + 1);
|
|
2469 list[index] = TREE_PURPOSE (p);
|
|
2470 }
|
|
2471
|
|
2472 /* Build the new argument list. */
|
|
2473 tree args = make_tree_vec (lists.length ());
|
|
2474 for (unsigned i = 0; i != lists.length (); ++i)
|
|
2475 {
|
|
2476 vec<tree> &list = lists[i];
|
|
2477 tree level = make_tree_vec (list.length ());
|
|
2478 for (unsigned j = 0; j < list.length(); ++j)
|
|
2479 TREE_VEC_ELT (level, j) = list[j];
|
|
2480 SET_TMPL_ARGS_LEVEL (args, i + 1, level);
|
|
2481 list.release ();
|
|
2482 }
|
|
2483 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0);
|
|
2484
|
|
2485 return args;
|
111
|
2486 }
|
|
2487
|
145
|
2488 static void diagnose_atomic_constraint (tree, tree, subst_info);
|
|
2489
|
|
2490 /* Compute the satisfaction of an atomic constraint. */
|
|
2491
|
|
2492 static tree
|
|
2493 satisfy_atom (tree t, tree args, subst_info info)
|
111
|
2494 {
|
145
|
2495 satisfaction_cache cache (t, args, info.complain);
|
|
2496 if (tree r = cache.get ())
|
|
2497 return r;
|
|
2498
|
|
2499 /* Perform substitution quietly. */
|
|
2500 subst_info quiet (tf_none, NULL_TREE);
|
|
2501
|
|
2502 /* In case there is a diagnostic, we want to establish the context
|
|
2503 prior to printing errors. If no errors occur, this context is
|
|
2504 removed before returning. */
|
|
2505 diagnosing_failed_constraint failure (t, args, info.noisy ());
|
|
2506
|
|
2507 /* Instantiate the parameter mapping. */
|
|
2508 tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet);
|
|
2509 if (map == error_mark_node)
|
|
2510 {
|
|
2511 /* If instantiation of the parameter mapping fails, the program
|
|
2512 is ill-formed. */
|
|
2513 if (info.noisy())
|
|
2514 tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info);
|
|
2515 return cache.save (boolean_false_node);
|
|
2516 }
|
|
2517
|
|
2518 /* Rebuild the argument vector from the parameter mapping. */
|
|
2519 args = get_mapped_args (map);
|
|
2520
|
|
2521 /* Apply the parameter mapping (i.e., just substitute). */
|
|
2522 tree expr = ATOMIC_CONSTR_EXPR (t);
|
|
2523 tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl, false);
|
|
2524 if (result == error_mark_node)
|
|
2525 {
|
|
2526 /* If substitution results in an invalid type or expression, the constraint
|
|
2527 is not satisfied. Replay the substitution. */
|
|
2528 if (info.noisy ())
|
|
2529 tsubst_expr (expr, args, info.complain, info.in_decl, false);
|
|
2530 return cache.save (boolean_false_node);
|
|
2531 }
|
|
2532
|
|
2533 location_t loc = cp_expr_loc_or_input_loc (expr);
|
|
2534
|
|
2535 /* [17.4.1.2] ... lvalue-to-value conversion is performed as necessary,
|
|
2536 and EXPR shall be a constant expression of type bool. */
|
|
2537 result = force_rvalue (result, info.complain);
|
|
2538 if (result == error_mark_node)
|
|
2539 return cache.save (error_mark_node);
|
|
2540 if (!same_type_p (TREE_TYPE (result), boolean_type_node))
|
|
2541 {
|
|
2542 if (info.noisy ())
|
|
2543 error_at (loc, "constraint does not have type %<bool%>");
|
|
2544 return cache.save (error_mark_node);
|
|
2545 }
|
|
2546
|
|
2547 /* Compute the value of the constraint. */
|
|
2548 result = satisfaction_value (cxx_constant_value (result));
|
|
2549 if (result == boolean_false_node && info.noisy ())
|
|
2550 diagnose_atomic_constraint (t, args, info);
|
|
2551
|
|
2552 return cache.save (result);
|
111
|
2553 }
|
|
2554
|
145
|
2555 /* Determine if the normalized constraint T is satisfied.
|
|
2556 Returns boolean_true_node if the expression/constraint is
|
|
2557 satisfied, boolean_false_node if not, and error_mark_node
|
|
2558 if the there was an error evaluating the constraint.
|
|
2559
|
|
2560 The parameter mapping of atomic constraints is simply the
|
|
2561 set of template arguments that will be substituted into
|
|
2562 the expression, regardless of template parameters appearing
|
|
2563 withing. Whether a template argument is used in the atomic
|
|
2564 constraint only matters for subsumption. */
|
|
2565
|
|
2566 static tree
|
|
2567 satisfy_constraint_r (tree t, tree args, subst_info info)
|
111
|
2568 {
|
|
2569 if (t == error_mark_node)
|
145
|
2570 return error_mark_node;
|
111
|
2571
|
|
2572 switch (TREE_CODE (t))
|
145
|
2573 {
|
|
2574 case CONJ_CONSTR:
|
|
2575 return satisfy_conjunction (t, args, info);
|
|
2576 case DISJ_CONSTR:
|
|
2577 return satisfy_disjunction (t, args, info);
|
|
2578 case ATOMIC_CONSTR:
|
|
2579 return satisfy_atom (t, args, info);
|
|
2580 default:
|
|
2581 gcc_unreachable ();
|
|
2582 }
|
111
|
2583 }
|
|
2584
|
145
|
2585 /* Check that the normalized constraint T is satisfied for ARGS. */
|
|
2586
|
|
2587 static tree
|
|
2588 satisfy_constraint (tree t, tree args, subst_info info)
|
111
|
2589 {
|
|
2590 auto_timevar time (TV_CONSTRAINT_SAT);
|
|
2591
|
|
2592 /* Turn off template processing. Constraint satisfaction only applies
|
|
2593 to non-dependent terms, so we want to ensure full checking here. */
|
|
2594 processing_template_decl_sentinel proc (true);
|
|
2595
|
145
|
2596 /* We need to check access during satisfaction. */
|
|
2597 deferring_access_check_sentinel acs (dk_no_deferred);
|
|
2598
|
|
2599 return satisfy_constraint_r (t, args, info);
|
111
|
2600 }
|
|
2601
|
145
|
2602 /* Check the normalized constraints T against ARGS, returning a satisfaction
|
|
2603 value (either true, false, or error). */
|
|
2604
|
|
2605 static tree
|
|
2606 satisfy_associated_constraints (tree t, tree args, subst_info info)
|
111
|
2607 {
|
145
|
2608 /* If there are no constraints then this is trivially satisfied. */
|
|
2609 if (!t)
|
111
|
2610 return boolean_true_node;
|
|
2611
|
|
2612 /* If any arguments depend on template parameters, we can't
|
145
|
2613 check constraints. Pretend they're satisfied for now. */
|
111
|
2614 if (args && uses_template_parms (args))
|
|
2615 return boolean_true_node;
|
|
2616
|
145
|
2617 return satisfy_constraint (t, args, info);
|
111
|
2618 }
|
|
2619
|
145
|
2620 /* Evaluate EXPR as a constraint expression using ARGS, returning a
|
|
2621 satisfaction value. */
|
|
2622
|
|
2623 static tree
|
|
2624 satisfy_constraint_expression (tree t, tree args, subst_info info)
|
111
|
2625 {
|
145
|
2626 if (t == error_mark_node)
|
|
2627 return error_mark_node;
|
|
2628
|
|
2629 gcc_assert (EXPR_P (t));
|
|
2630
|
|
2631 /* Get the normalized constraints. */
|
|
2632 tree norm;
|
|
2633 if (args == NULL_TREE && concept_check_p (t))
|
|
2634 {
|
|
2635 tree id = unpack_concept_check (t);
|
|
2636 args = TREE_OPERAND (id, 1);
|
|
2637 tree tmpl = get_concept_check_template (id);
|
|
2638 norm = normalize_concept_definition (tmpl, info.noisy ());
|
|
2639 }
|
|
2640 else
|
|
2641 norm = normalize_constraint_expression (t, info.noisy ());
|
|
2642
|
|
2643 /* Perform satisfaction. */
|
|
2644 return satisfy_constraint (norm, args, info);
|
111
|
2645 }
|
|
2646
|
145
|
2647 /* Used only to evaluate requires-expressions during constant expression
|
|
2648 evaluation. */
|
111
|
2649
|
|
2650 tree
|
145
|
2651 satisfy_constraint_expression (tree expr)
|
111
|
2652 {
|
145
|
2653 subst_info info (tf_none, NULL_TREE);
|
|
2654 return satisfy_constraint_expression (expr, NULL_TREE, info);
|
111
|
2655 }
|
|
2656
|
145
|
2657 static tree
|
|
2658 satisfy_declaration_constraints (tree t, subst_info info)
|
111
|
2659 {
|
145
|
2660 gcc_assert (DECL_P (t));
|
|
2661
|
|
2662 /* For inherited constructors, consider the original declaration;
|
|
2663 it has the correct template information attached. */
|
|
2664 if (flag_new_inheriting_ctors)
|
|
2665 t = strip_inheriting_ctors (t);
|
|
2666
|
|
2667 /* Update the declaration for diagnostics. */
|
|
2668 info.in_decl = t;
|
|
2669
|
|
2670 if (info.quiet ())
|
|
2671 if (tree *result = hash_map_safe_get (decl_satisfied_cache, t))
|
|
2672 return *result;
|
|
2673
|
|
2674 /* Get the normalized constraints. */
|
|
2675 tree norm = NULL_TREE;
|
111
|
2676 tree args = NULL_TREE;
|
145
|
2677 if (tree ti = DECL_TEMPLATE_INFO (t))
|
111
|
2678 {
|
|
2679 tree tmpl = TI_TEMPLATE (ti);
|
145
|
2680 norm = normalize_template_requirements (tmpl, info.noisy ());
|
|
2681
|
|
2682 /* The initial parameter mapping is the complete set of
|
|
2683 template arguments substituted into the declaration. */
|
|
2684 args = TI_ARGS (ti);
|
111
|
2685 }
|
|
2686 else
|
|
2687 {
|
145
|
2688 /* These should be empty until we allow constraints on non-templates. */
|
|
2689 norm = normalize_nontemplate_requirements (t, info.noisy ());
|
|
2690 }
|
|
2691
|
|
2692 tree result = boolean_true_node;
|
|
2693 if (norm)
|
|
2694 {
|
|
2695 if (!push_tinst_level (t))
|
|
2696 return result;
|
|
2697 push_access_scope (t);
|
|
2698 result = satisfy_associated_constraints (norm, args, info);
|
|
2699 pop_access_scope (t);
|
|
2700 pop_tinst_level ();
|
|
2701 }
|
|
2702
|
|
2703 if (info.quiet ())
|
|
2704 hash_map_safe_put<hm_ggc> (decl_satisfied_cache, t, result);
|
|
2705
|
|
2706 return result;
|
|
2707 }
|
|
2708
|
|
2709 static tree
|
|
2710 satisfy_declaration_constraints (tree t, tree args, subst_info info)
|
|
2711 {
|
|
2712 /* Update the declaration for diagnostics. */
|
|
2713 info.in_decl = t;
|
|
2714
|
|
2715 gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);
|
|
2716 if (tree norm = normalize_template_requirements (t, info.noisy ()))
|
|
2717 {
|
|
2718 tree pattern = DECL_TEMPLATE_RESULT (t);
|
|
2719 push_access_scope (pattern);
|
|
2720 tree result = satisfy_associated_constraints (norm, args, info);
|
|
2721 pop_access_scope (pattern);
|
|
2722 return result;
|
111
|
2723 }
|
|
2724
|
145
|
2725 return boolean_true_node;
|
|
2726 }
|
|
2727
|
|
2728 static tree
|
|
2729 constraint_satisfaction_value (tree t, tsubst_flags_t complain)
|
|
2730 {
|
|
2731 subst_info info (complain, NULL_TREE);
|
|
2732 if (DECL_P (t))
|
|
2733 return satisfy_declaration_constraints (t, info);
|
|
2734 else
|
|
2735 return satisfy_constraint_expression (t, NULL_TREE, info);
|
111
|
2736 }
|
|
2737
|
145
|
2738 static tree
|
|
2739 constraint_satisfaction_value (tree t, tree args, tsubst_flags_t complain)
|
|
2740 {
|
|
2741 subst_info info (complain, NULL_TREE);
|
|
2742 if (DECL_P (t))
|
|
2743 return satisfy_declaration_constraints (t, args, info);
|
|
2744 else
|
|
2745 return satisfy_constraint_expression (t, args, info);
|
|
2746 }
|
|
2747
|
|
2748 /* True iff the result of satisfying T is BOOLEAN_TRUE_NODE and false
|
|
2749 otherwise, even in the case of errors. */
|
|
2750
|
|
2751 bool
|
|
2752 constraints_satisfied_p (tree t)
|
|
2753 {
|
|
2754 return constraint_satisfaction_value (t, tf_none) == boolean_true_node;
|
|
2755 }
|
|
2756
|
|
2757 /* True iff the result of satisfying T with ARGS is BOOLEAN_TRUE_NODE
|
|
2758 and false otherwise, even in the case of errors. */
|
111
|
2759
|
|
2760 bool
|
|
2761 constraints_satisfied_p (tree t, tree args)
|
|
2762 {
|
145
|
2763 return constraint_satisfaction_value (t, args, tf_none) == boolean_true_node;
|
111
|
2764 }
|
|
2765
|
145
|
2766 /* Evaluate a concept check of the form C<ARGS>. This is only used for the
|
|
2767 evaluation of template-ids as id-expressions. */
|
|
2768
|
|
2769 tree
|
|
2770 evaluate_concept_check (tree check, tsubst_flags_t complain)
|
111
|
2771 {
|
145
|
2772 if (check == error_mark_node)
|
|
2773 return error_mark_node;
|
|
2774
|
|
2775 gcc_assert (concept_check_p (check));
|
|
2776
|
|
2777 /* Check for satisfaction without diagnostics. */
|
|
2778 subst_info quiet (tf_none, NULL_TREE);
|
|
2779 tree result = satisfy_constraint_expression (check, NULL_TREE, quiet);
|
|
2780 if (result == error_mark_node && (complain & tf_error))
|
|
2781 {
|
|
2782 /* Replay the error with re-normalized requirements. */
|
|
2783 subst_info noisy (tf_warning_or_error, NULL_TREE);
|
|
2784 satisfy_constraint_expression (check, NULL_TREE, noisy);
|
|
2785 }
|
|
2786 return result;
|
111
|
2787 }
|
|
2788
|
|
2789 /*---------------------------------------------------------------------------
|
|
2790 Semantic analysis of requires-expressions
|
|
2791 ---------------------------------------------------------------------------*/
|
|
2792
|
|
2793 /* Finish a requires expression for the given PARMS (possibly
|
145
|
2794 null) and the non-empty sequence of requirements. */
|
|
2795
|
111
|
2796 tree
|
145
|
2797 finish_requires_expr (location_t loc, tree parms, tree reqs)
|
111
|
2798 {
|
|
2799 /* Modify the declared parameters by removing their context
|
|
2800 so they don't refer to the enclosing scope and explicitly
|
|
2801 indicating that they are constraint variables. */
|
|
2802 for (tree parm = parms; parm; parm = DECL_CHAIN (parm))
|
|
2803 {
|
|
2804 DECL_CONTEXT (parm) = NULL_TREE;
|
|
2805 CONSTRAINT_VAR_P (parm) = true;
|
|
2806 }
|
|
2807
|
|
2808 /* Build the node. */
|
|
2809 tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs);
|
|
2810 TREE_SIDE_EFFECTS (r) = false;
|
|
2811 TREE_CONSTANT (r) = true;
|
145
|
2812 SET_EXPR_LOCATION (r, loc);
|
111
|
2813 return r;
|
|
2814 }
|
|
2815
|
145
|
2816 /* Construct a requirement for the validity of EXPR. */
|
|
2817
|
111
|
2818 tree
|
145
|
2819 finish_simple_requirement (location_t loc, tree expr)
|
111
|
2820 {
|
145
|
2821 tree r = build_nt (SIMPLE_REQ, expr);
|
|
2822 SET_EXPR_LOCATION (r, loc);
|
|
2823 return r;
|
111
|
2824 }
|
|
2825
|
145
|
2826 /* Construct a requirement for the validity of TYPE. */
|
|
2827
|
111
|
2828 tree
|
145
|
2829 finish_type_requirement (location_t loc, tree type)
|
111
|
2830 {
|
145
|
2831 tree r = build_nt (TYPE_REQ, type);
|
|
2832 SET_EXPR_LOCATION (r, loc);
|
|
2833 return r;
|
111
|
2834 }
|
|
2835
|
|
2836 /* Construct a requirement for the validity of EXPR, along with
|
|
2837 its properties. if TYPE is non-null, then it specifies either
|
|
2838 an implicit conversion or argument deduction constraint,
|
|
2839 depending on whether any placeholders occur in the type name.
|
145
|
2840 NOEXCEPT_P is true iff the noexcept keyword was specified. */
|
|
2841
|
111
|
2842 tree
|
145
|
2843 finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept_p)
|
111
|
2844 {
|
|
2845 tree req = build_nt (COMPOUND_REQ, expr, type);
|
145
|
2846 SET_EXPR_LOCATION (req, loc);
|
111
|
2847 COMPOUND_REQ_NOEXCEPT_P (req) = noexcept_p;
|
|
2848 return req;
|
|
2849 }
|
|
2850
|
145
|
2851 /* Finish a nested requirement. */
|
|
2852
|
111
|
2853 tree
|
145
|
2854 finish_nested_requirement (location_t loc, tree expr)
|
111
|
2855 {
|
145
|
2856 /* Save the normalized constraint and complete set of normalization
|
|
2857 arguments with the requirement. We keep the complete set of arguments
|
|
2858 around for re-normalization during diagnostics. */
|
|
2859 tree args = current_template_parms
|
|
2860 ? template_parms_to_args (current_template_parms) : NULL_TREE;
|
|
2861 tree norm = normalize_constraint_expression (expr, args, false);
|
|
2862 tree info = build_tree_list (args, norm);
|
|
2863
|
|
2864 /* Build the constraint, saving its normalization as its type. */
|
|
2865 tree r = build1 (NESTED_REQ, info, expr);
|
|
2866 SET_EXPR_LOCATION (r, loc);
|
|
2867 return r;
|
111
|
2868 }
|
|
2869
|
145
|
2870 /* Check that FN satisfies the structural requirements of a
|
|
2871 function concept definition. */
|
111
|
2872 tree
|
|
2873 check_function_concept (tree fn)
|
|
2874 {
|
145
|
2875 /* Check that the function is comprised of only a return statement. */
|
111
|
2876 tree body = DECL_SAVED_TREE (fn);
|
|
2877 if (TREE_CODE (body) == BIND_EXPR)
|
|
2878 body = BIND_EXPR_BODY (body);
|
|
2879
|
145
|
2880 /* Sometimes a function call results in the creation of clean up
|
|
2881 points. Allow these to be preserved in the body of the
|
|
2882 constraint, as we might actually need them for some constexpr
|
|
2883 evaluations. */
|
111
|
2884 if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
|
|
2885 body = TREE_OPERAND (body, 0);
|
|
2886
|
145
|
2887 /* Check that the definition is written correctly. */
|
111
|
2888 if (TREE_CODE (body) != RETURN_EXPR)
|
|
2889 {
|
|
2890 location_t loc = DECL_SOURCE_LOCATION (fn);
|
|
2891 if (TREE_CODE (body) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body))
|
|
2892 {
|
|
2893 if (seen_error ())
|
|
2894 /* The definition was probably erroneous, not empty. */;
|
|
2895 else
|
|
2896 error_at (loc, "definition of concept %qD is empty", fn);
|
|
2897 }
|
|
2898 else
|
|
2899 error_at (loc, "definition of concept %qD has multiple statements", fn);
|
|
2900 }
|
|
2901
|
|
2902 return NULL_TREE;
|
|
2903 }
|
|
2904
|
|
2905
|
|
2906 // Check that a constrained friend declaration function declaration,
|
|
2907 // FN, is admissible. This is the case only when the declaration depends
|
|
2908 // on template parameters and does not declare a specialization.
|
|
2909 void
|
|
2910 check_constrained_friend (tree fn, tree reqs)
|
|
2911 {
|
|
2912 if (fn == error_mark_node)
|
|
2913 return;
|
|
2914 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
|
|
2915
|
|
2916 // If there are not constraints, this cannot be an error.
|
|
2917 if (!reqs)
|
|
2918 return;
|
|
2919
|
|
2920 // Constrained friend functions that don't depend on template
|
|
2921 // arguments are effectively meaningless.
|
|
2922 if (!uses_template_parms (TREE_TYPE (fn)))
|
|
2923 {
|
|
2924 error_at (location_of (fn),
|
|
2925 "constrained friend does not depend on template parameters");
|
|
2926 return;
|
|
2927 }
|
|
2928 }
|
|
2929
|
|
2930 /*---------------------------------------------------------------------------
|
|
2931 Equivalence of constraints
|
|
2932 ---------------------------------------------------------------------------*/
|
|
2933
|
|
2934 /* Returns true when A and B are equivalent constraints. */
|
|
2935 bool
|
|
2936 equivalent_constraints (tree a, tree b)
|
|
2937 {
|
|
2938 gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
|
|
2939 gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
|
|
2940 return cp_tree_equal (a, b);
|
|
2941 }
|
|
2942
|
|
2943 /* Returns true if the template declarations A and B have equivalent
|
|
2944 constraints. This is the case when A's constraints subsume B's and
|
|
2945 when B's also constrain A's. */
|
|
2946 bool
|
|
2947 equivalently_constrained (tree d1, tree d2)
|
|
2948 {
|
|
2949 gcc_assert (TREE_CODE (d1) == TREE_CODE (d2));
|
|
2950 return equivalent_constraints (get_constraints (d1), get_constraints (d2));
|
|
2951 }
|
|
2952
|
|
2953 /*---------------------------------------------------------------------------
|
|
2954 Partial ordering of constraints
|
|
2955 ---------------------------------------------------------------------------*/
|
|
2956
|
|
2957 /* Returns true when the the constraints in A subsume those in B. */
|
|
2958
|
|
2959 bool
|
|
2960 subsumes_constraints (tree a, tree b)
|
|
2961 {
|
|
2962 gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
|
|
2963 gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
|
|
2964 return subsumes (a, b);
|
|
2965 }
|
|
2966
|
145
|
2967 /* Returns true when the the constraints in CI (with arguments
|
|
2968 ARGS) strictly subsume the associated constraints of TMPL. */
|
111
|
2969
|
|
2970 bool
|
145
|
2971 strictly_subsumes (tree ci, tree args, tree tmpl)
|
111
|
2972 {
|
145
|
2973 tree n1 = get_normalized_constraints_from_info (ci, args, NULL_TREE);
|
|
2974 tree n2 = get_normalized_constraints_from_decl (tmpl);
|
|
2975
|
|
2976 return subsumes (n1, n2) && !subsumes (n2, n1);
|
|
2977 }
|
|
2978
|
|
2979 /* REturns true when the constraints in CI (with arguments ARGS) subsume
|
|
2980 the associated constraints of TMPL. */
|
|
2981
|
|
2982 bool
|
|
2983 weakly_subsumes (tree ci, tree args, tree tmpl)
|
|
2984 {
|
|
2985 tree n1 = get_normalized_constraints_from_info (ci, args, NULL_TREE);
|
|
2986 tree n2 = get_normalized_constraints_from_decl (tmpl);
|
|
2987
|
|
2988 return subsumes (n1, n2);
|
111
|
2989 }
|
|
2990
|
|
2991 /* Determines which of the declarations, A or B, is more constrained.
|
|
2992 That is, which declaration's constraints subsume but are not subsumed
|
|
2993 by the other's?
|
|
2994
|
145
|
2995 Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
|
|
2996 than D1, and 0 otherwise. */
|
111
|
2997
|
|
2998 int
|
|
2999 more_constrained (tree d1, tree d2)
|
|
3000 {
|
145
|
3001 tree n1 = get_normalized_constraints_from_decl (d1);
|
|
3002 tree n2 = get_normalized_constraints_from_decl (d2);
|
|
3003
|
111
|
3004 int winner = 0;
|
145
|
3005 if (subsumes (n1, n2))
|
111
|
3006 ++winner;
|
145
|
3007 if (subsumes (n2, n1))
|
111
|
3008 --winner;
|
|
3009 return winner;
|
|
3010 }
|
|
3011
|
145
|
3012 /* Return whether D1 is at least as constrained as D2. */
|
111
|
3013
|
|
3014 bool
|
|
3015 at_least_as_constrained (tree d1, tree d2)
|
|
3016 {
|
145
|
3017 tree n1 = get_normalized_constraints_from_decl (d1);
|
|
3018 tree n2 = get_normalized_constraints_from_decl (d2);
|
|
3019
|
|
3020 return subsumes (n1, n2);
|
111
|
3021 }
|
|
3022
|
|
3023 /*---------------------------------------------------------------------------
|
|
3024 Constraint diagnostics
|
|
3025 ---------------------------------------------------------------------------*/
|
|
3026
|
145
|
3027 /* Returns the best location to diagnose a constraint error. */
|
|
3028
|
|
3029 static location_t
|
|
3030 get_constraint_error_location (tree t)
|
111
|
3031 {
|
145
|
3032 /* If we have a specific location give it. */
|
|
3033 tree expr = CONSTR_EXPR (t);
|
|
3034 if (location_t loc = cp_expr_location (expr))
|
|
3035 return loc;
|
|
3036
|
|
3037 /* If the constraint is normalized from a requires-clause, give
|
|
3038 the location as that of the constrained declaration. */
|
|
3039 tree cxt = CONSTR_CONTEXT (t);
|
|
3040 tree src = TREE_VALUE (cxt);
|
|
3041 if (!src)
|
|
3042 /* TODO: This only happens for constrained non-template declarations. */
|
|
3043 return input_location;
|
|
3044 if (DECL_P (src))
|
|
3045 return DECL_SOURCE_LOCATION (src);
|
|
3046
|
|
3047 /* Otherwise, give the location as the defining concept. */
|
|
3048 gcc_assert (concept_check_p (src));
|
|
3049 tree id = unpack_concept_check (src);
|
|
3050 tree tmpl = TREE_OPERAND (id, 0);
|
|
3051 if (OVL_P (tmpl))
|
|
3052 tmpl = OVL_FIRST (tmpl);
|
|
3053 return DECL_SOURCE_LOCATION (tmpl);
|
111
|
3054 }
|
|
3055
|
145
|
3056 /* Emit a diagnostic for a failed trait. */
|
111
|
3057
|
|
3058 void
|
145
|
3059 diagnose_trait_expr (tree expr, tree args)
|
111
|
3060 {
|
145
|
3061 location_t loc = cp_expr_location (expr);
|
|
3062
|
|
3063 /* Build a "fake" version of the instantiated trait, so we can
|
|
3064 get the instantiated types from result. */
|
111
|
3065 ++processing_template_decl;
|
|
3066 expr = tsubst_expr (expr, args, tf_none, NULL_TREE, false);
|
|
3067 --processing_template_decl;
|
|
3068
|
|
3069 tree t1 = TRAIT_EXPR_TYPE1 (expr);
|
|
3070 tree t2 = TRAIT_EXPR_TYPE2 (expr);
|
|
3071 switch (TRAIT_EXPR_KIND (expr))
|
|
3072 {
|
|
3073 case CPTK_HAS_NOTHROW_ASSIGN:
|
145
|
3074 inform (loc, " %qT is not %<nothrow%> copy assignable", t1);
|
111
|
3075 break;
|
|
3076 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
|
145
|
3077 inform (loc, " %qT is not %<nothrow%> default constructible", t1);
|
111
|
3078 break;
|
|
3079 case CPTK_HAS_NOTHROW_COPY:
|
145
|
3080 inform (loc, " %qT is not %<nothrow%> copy constructible", t1);
|
111
|
3081 break;
|
|
3082 case CPTK_HAS_TRIVIAL_ASSIGN:
|
|
3083 inform (loc, " %qT is not trivially copy assignable", t1);
|
|
3084 break;
|
|
3085 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
|
|
3086 inform (loc, " %qT is not trivially default constructible", t1);
|
|
3087 break;
|
|
3088 case CPTK_HAS_TRIVIAL_COPY:
|
|
3089 inform (loc, " %qT is not trivially copy constructible", t1);
|
|
3090 break;
|
|
3091 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
|
|
3092 inform (loc, " %qT is not trivially destructible", t1);
|
|
3093 break;
|
|
3094 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
|
|
3095 inform (loc, " %qT does not have a virtual destructor", t1);
|
|
3096 break;
|
|
3097 case CPTK_IS_ABSTRACT:
|
|
3098 inform (loc, " %qT is not an abstract class", t1);
|
|
3099 break;
|
|
3100 case CPTK_IS_BASE_OF:
|
|
3101 inform (loc, " %qT is not a base of %qT", t1, t2);
|
|
3102 break;
|
|
3103 case CPTK_IS_CLASS:
|
|
3104 inform (loc, " %qT is not a class", t1);
|
|
3105 break;
|
|
3106 case CPTK_IS_EMPTY:
|
|
3107 inform (loc, " %qT is not an empty class", t1);
|
|
3108 break;
|
|
3109 case CPTK_IS_ENUM:
|
|
3110 inform (loc, " %qT is not an enum", t1);
|
|
3111 break;
|
|
3112 case CPTK_IS_FINAL:
|
|
3113 inform (loc, " %qT is not a final class", t1);
|
|
3114 break;
|
|
3115 case CPTK_IS_LITERAL_TYPE:
|
|
3116 inform (loc, " %qT is not a literal type", t1);
|
|
3117 break;
|
|
3118 case CPTK_IS_POD:
|
|
3119 inform (loc, " %qT is not a POD type", t1);
|
|
3120 break;
|
|
3121 case CPTK_IS_POLYMORPHIC:
|
|
3122 inform (loc, " %qT is not a polymorphic type", t1);
|
|
3123 break;
|
|
3124 case CPTK_IS_SAME_AS:
|
|
3125 inform (loc, " %qT is not the same as %qT", t1, t2);
|
|
3126 break;
|
|
3127 case CPTK_IS_STD_LAYOUT:
|
|
3128 inform (loc, " %qT is not an standard layout type", t1);
|
|
3129 break;
|
|
3130 case CPTK_IS_TRIVIAL:
|
|
3131 inform (loc, " %qT is not a trivial type", t1);
|
|
3132 break;
|
|
3133 case CPTK_IS_UNION:
|
|
3134 inform (loc, " %qT is not a union", t1);
|
|
3135 break;
|
|
3136 default:
|
|
3137 gcc_unreachable ();
|
|
3138 }
|
|
3139 }
|
|
3140
|
145
|
3141 static tree
|
|
3142 diagnose_valid_expression (tree expr, tree args, tree in_decl)
|
111
|
3143 {
|
145
|
3144 tree result = tsubst_expr (expr, args, tf_none, in_decl, false);
|
|
3145 if (result != error_mark_node)
|
|
3146 return result;
|
|
3147
|
|
3148 location_t loc = cp_expr_loc_or_input_loc (expr);
|
|
3149 inform (loc, "the required expression %qE is invalid", expr);
|
|
3150
|
|
3151 /* TODO: Replay the substitution to diagnose the error? */
|
|
3152 // tsubst_expr (expr, args, tf_error, in_decl, false);
|
|
3153
|
|
3154 return error_mark_node;
|
111
|
3155 }
|
|
3156
|
145
|
3157 static tree
|
|
3158 diagnose_valid_type (tree type, tree args, tree in_decl)
|
111
|
3159 {
|
145
|
3160 tree result = tsubst (type, args, tf_none, in_decl);
|
|
3161 if (result != error_mark_node)
|
|
3162 return result;
|
|
3163
|
|
3164 location_t loc = cp_expr_loc_or_input_loc (type);
|
|
3165 inform (loc, "the required type %qT is invalid", type);
|
|
3166
|
|
3167 /* TODO: Replay the substitution to diagnose the error? */
|
|
3168 // tsubst (type, args, tf_error, in_decl);
|
|
3169
|
|
3170 return error_mark_node;
|
111
|
3171 }
|
|
3172
|
145
|
3173 static void
|
|
3174 diagnose_simple_requirement (tree req, tree args, tree in_decl)
|
111
|
3175 {
|
145
|
3176 diagnose_valid_expression (TREE_OPERAND (req, 0), args, in_decl);
|
|
3177 }
|
|
3178
|
|
3179 static void
|
|
3180 diagnose_compound_requirement (tree req, tree args, tree in_decl)
|
|
3181 {
|
|
3182 tree expr = TREE_OPERAND (req, 0);
|
|
3183 expr = diagnose_valid_expression (expr, args, in_decl);
|
|
3184 if (expr == error_mark_node)
|
111
|
3185 return;
|
145
|
3186
|
|
3187 location_t loc = cp_expr_loc_or_input_loc (expr);
|
|
3188
|
|
3189 /* Check the noexcept condition. */
|
|
3190 if (COMPOUND_REQ_NOEXCEPT_P (req) && !expr_noexcept_p (expr, tf_none))
|
|
3191 inform (loc, "%qE is not %<noexcept%>", expr);
|
|
3192
|
|
3193 tree type = TREE_OPERAND (req, 1);
|
|
3194 type = diagnose_valid_type (type, args, in_decl);
|
|
3195 if (type == error_mark_node)
|
111
|
3196 return;
|
|
3197
|
145
|
3198 if (type)
|
111
|
3199 {
|
145
|
3200 subst_info quiet (tf_none, in_decl);
|
|
3201 subst_info noisy (tf_error, in_decl);
|
|
3202
|
|
3203 /* Check the expression against the result type. */
|
|
3204 if (tree placeholder = type_uses_auto (type))
|
|
3205 {
|
|
3206 if (!type_deducible_p (expr, type, placeholder, args, quiet))
|
|
3207 {
|
|
3208 tree orig_expr = TREE_OPERAND (req, 0);
|
|
3209 inform (loc, "%qE does not satisfy return-type-requirement",
|
|
3210 orig_expr);
|
|
3211
|
|
3212 /* Further explain the reason for the error. */
|
|
3213 type_deducible_p (expr, type, placeholder, args, noisy);
|
|
3214 }
|
|
3215 }
|
|
3216 else if (!expression_convertible_p (expr, type, quiet))
|
|
3217 {
|
|
3218 tree orig_expr = TREE_OPERAND (req, 0);
|
|
3219 inform (loc, "cannot convert %qE to %qT", orig_expr, type);
|
|
3220
|
|
3221 /* Further explain the reason for the error. */
|
|
3222 expression_convertible_p (expr, type, noisy);
|
|
3223 }
|
111
|
3224 }
|
|
3225 }
|
|
3226
|
145
|
3227 static void
|
|
3228 diagnose_type_requirement (tree req, tree args, tree in_decl)
|
111
|
3229 {
|
145
|
3230 tree type = TREE_OPERAND (req, 0);
|
|
3231 diagnose_valid_type (type, args, in_decl);
|
|
3232 }
|
|
3233
|
|
3234 static void
|
|
3235 diagnose_nested_requirement (tree req, tree args)
|
|
3236 {
|
|
3237 /* Quietly check for satisfaction first. We can elaborate details
|
|
3238 later if needed. */
|
|
3239 tree norm = TREE_VALUE (TREE_TYPE (req));
|
|
3240 subst_info info (tf_none, NULL_TREE);
|
|
3241 tree result = satisfy_constraint (norm, args, info);
|
|
3242 if (result == boolean_true_node)
|
111
|
3243 return;
|
|
3244
|
145
|
3245 tree expr = TREE_OPERAND (req, 0);
|
|
3246 location_t loc = cp_expr_location (expr);
|
|
3247 inform (loc, "nested requirement %qE is not satisfied", expr);
|
|
3248
|
|
3249 /* TODO: Replay the substitution to diagnose the error? */
|
|
3250 // subst_info noisy (tf_warning_or_error, NULL_TREE);
|
|
3251 // satisfy_constraint (norm, args, info);
|
|
3252 }
|
|
3253
|
|
3254 static void
|
|
3255 diagnose_requirement (tree req, tree args, tree in_decl)
|
|
3256 {
|
|
3257 iloc_sentinel loc_s (cp_expr_location (req));
|
|
3258 switch (TREE_CODE (req))
|
111
|
3259 {
|
145
|
3260 case SIMPLE_REQ:
|
|
3261 return diagnose_simple_requirement (req, args, in_decl);
|
|
3262 case COMPOUND_REQ:
|
|
3263 return diagnose_compound_requirement (req, args, in_decl);
|
|
3264 case TYPE_REQ:
|
|
3265 return diagnose_type_requirement (req, args, in_decl);
|
|
3266 case NESTED_REQ:
|
|
3267 return diagnose_nested_requirement (req, args);
|
|
3268 default:
|
|
3269 gcc_unreachable ();
|
111
|
3270 }
|
145
|
3271 }
|
|
3272
|
|
3273 static void
|
|
3274 diagnose_requires_expr (tree expr, tree args, tree in_decl)
|
|
3275 {
|
|
3276 local_specialization_stack stack (lss_copy);
|
|
3277 tree parms = TREE_OPERAND (expr, 0);
|
|
3278 tree body = TREE_OPERAND (expr, 1);
|
|
3279
|
|
3280 cp_unevaluated u;
|
|
3281 subst_info info (tf_warning_or_error, NULL_TREE);
|
|
3282 tree vars = tsubst_constraint_variables (parms, args, info);
|
|
3283 if (vars == error_mark_node)
|
|
3284 return;
|
|
3285
|
|
3286 tree p = body;
|
|
3287 while (p)
|
111
|
3288 {
|
145
|
3289 tree req = TREE_VALUE (p);
|
|
3290 diagnose_requirement (req, args, in_decl);
|
|
3291 p = TREE_CHAIN (p);
|
|
3292 }
|
|
3293 }
|
|
3294
|
|
3295 /* Diagnose a substitution failure in the atomic constraint T. Note that
|
|
3296 ARGS have been previously instantiated through the parameter map. */
|
|
3297
|
|
3298 static void
|
|
3299 diagnose_atomic_constraint (tree t, tree args, subst_info info)
|
|
3300 {
|
|
3301 /* If the constraint is already ill-formed, we've previously diagnosed
|
|
3302 the reason. We should still say why the constraints aren't satisfied. */
|
|
3303 if (t == error_mark_node)
|
|
3304 {
|
|
3305 location_t loc;
|
|
3306 if (info.in_decl)
|
|
3307 loc = DECL_SOURCE_LOCATION (info.in_decl);
|
|
3308 else
|
|
3309 loc = input_location;
|
|
3310 inform (loc, "invalid constraints");
|
111
|
3311 return;
|
|
3312 }
|
|
3313
|
145
|
3314 location_t loc = get_constraint_error_location (t);
|
|
3315 iloc_sentinel loc_s (loc);
|
|
3316
|
|
3317 /* Generate better diagnostics for certain kinds of expressions. */
|
|
3318 tree expr = ATOMIC_CONSTR_EXPR (t);
|
|
3319 STRIP_ANY_LOCATION_WRAPPER (expr);
|
|
3320 switch (TREE_CODE (expr))
|
111
|
3321 {
|
145
|
3322 case TRAIT_EXPR:
|
|
3323 diagnose_trait_expr (expr, args);
|
|
3324 break;
|
|
3325 case REQUIRES_EXPR:
|
|
3326 diagnose_requires_expr (expr, args, info.in_decl);
|
111
|
3327 break;
|
145
|
3328 case INTEGER_CST:
|
|
3329 /* This must be either 0 or false. */
|
|
3330 inform (loc, "%qE is never satisfied", expr);
|
111
|
3331 break;
|
|
3332 default:
|
145
|
3333 inform (loc, "the expression %qE evaluated to %<false%>", expr);
|
111
|
3334 }
|
|
3335 }
|
|
3336
|
145
|
3337 GTY(()) tree current_failed_constraint;
|
|
3338
|
|
3339 diagnosing_failed_constraint::
|
|
3340 diagnosing_failed_constraint (tree t, tree args, bool diag)
|
|
3341 : diagnosing_error (diag)
|
111
|
3342 {
|
145
|
3343 if (diagnosing_error)
|
|
3344 current_failed_constraint = tree_cons (args, t, current_failed_constraint);
|
111
|
3345 }
|
|
3346
|
145
|
3347 diagnosing_failed_constraint::
|
|
3348 ~diagnosing_failed_constraint ()
|
|
3349 {
|
|
3350 if (diagnosing_error && current_failed_constraint)
|
|
3351 current_failed_constraint = TREE_CHAIN (current_failed_constraint);
|
|
3352 }
|
|
3353
|
|
3354 /* Emit diagnostics detailing the failure ARGS to satisfy the constraints
|
|
3355 of T. Here, T can be either a constraint or a declaration. */
|
111
|
3356
|
|
3357 void
|
|
3358 diagnose_constraints (location_t loc, tree t, tree args)
|
|
3359 {
|
145
|
3360 inform (loc, "constraints not satisfied");
|
|
3361
|
|
3362 /* Replay satisfaction, but diagnose errors. */
|
|
3363 if (!args)
|
|
3364 constraint_satisfaction_value (t, tf_warning_or_error);
|
111
|
3365 else
|
145
|
3366 constraint_satisfaction_value (t, args, tf_warning_or_error);
|
111
|
3367 }
|
145
|
3368
|
|
3369 #include "gt-cp-constraint.h"
|