annotate gcc/cp/constraint.cc @ 145:1830386684a0

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