]>
Commit | Line | Data |
---|---|---|
8d08fdba MS |
1 | /* Handle the hair of processing (but not expanding) inline functions. |
2 | Also manage function and variable name overloading. | |
23a5b65a | 3 | Copyright (C) 1987-2014 Free Software Foundation, Inc. |
8d08fdba MS |
4 | Contributed by Michael Tiemann (tiemann@cygnus.com) |
5 | ||
f5adbb8d | 6 | This file is part of GCC. |
c8094d83 | 7 | |
f5adbb8d | 8 | GCC is free software; you can redistribute it and/or modify |
8d08fdba | 9 | it under the terms of the GNU General Public License as published by |
e77f031d | 10 | the Free Software Foundation; either version 3, or (at your option) |
8d08fdba MS |
11 | any later version. |
12 | ||
f5adbb8d | 13 | GCC is distributed in the hope that it will be useful, |
8d08fdba MS |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
e77f031d NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
8d08fdba MS |
21 | |
22 | ||
8d08fdba | 23 | /* Handle method declarations. */ |
8d08fdba | 24 | #include "config.h" |
e817b5e3 | 25 | #include "system.h" |
4977bab6 ZW |
26 | #include "coretypes.h" |
27 | #include "tm.h" | |
8d08fdba | 28 | #include "tree.h" |
d8a2d370 DN |
29 | #include "stringpool.h" |
30 | #include "varasm.h" | |
8d08fdba | 31 | #include "cp-tree.h" |
8926095f | 32 | #include "flags.h" |
54f92bfb | 33 | #include "toplev.h" |
b1afd7f4 | 34 | #include "tm_p.h" |
483ab821 | 35 | #include "target.h" |
677f3fa8 | 36 | #include "common/common-target.h" |
3e3935a9 | 37 | #include "diagnostic.h" |
ff2c88a5 | 38 | #include "cgraph.h" |
45b0be94 | 39 | #include "pointer-set.h" |
8d08fdba | 40 | |
669ec2b4 JM |
41 | /* Various flags to control the mangling process. */ |
42 | ||
43 | enum mangling_flags | |
44 | { | |
45 | /* No flags. */ | |
46 | mf_none = 0, | |
47 | /* The thing we are presently mangling is part of a template type, | |
48 | rather than a fully instantiated type. Therefore, we may see | |
49 | complex expressions where we would normally expect to see a | |
50 | simple integer constant. */ | |
51 | mf_maybe_uninstantiated = 1, | |
52 | /* When mangling a numeric value, use the form `_XX_' (instead of | |
53 | just `XX') if the value has more than one digit. */ | |
de94b46c | 54 | mf_use_underscores_around_value = 2 |
669ec2b4 JM |
55 | }; |
56 | ||
57 | typedef enum mangling_flags mangling_flags; | |
58 | ||
066ec0a4 | 59 | static void do_build_copy_assign (tree); |
4977bab6 | 60 | static void do_build_copy_constructor (tree); |
d46c570d | 61 | static tree make_alias_for_thunk (tree); |
669ec2b4 | 62 | |
669ec2b4 JM |
63 | /* Called once to initialize method.c. */ |
64 | ||
65 | void | |
4977bab6 | 66 | init_method (void) |
669ec2b4 | 67 | { |
1f84ec23 | 68 | init_mangle (); |
669ec2b4 | 69 | } |
8926095f | 70 | \f |
4977bab6 ZW |
71 | /* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING |
72 | indicates whether it is a this or result adjusting thunk. | |
73 | FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment | |
74 | (see thunk_adjust). VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET | |
75 | never is. VIRTUAL_OFFSET is the /index/ into the vtable for this | |
76 | adjusting thunks, we scale it to a byte offset. For covariant | |
77 | thunks VIRTUAL_OFFSET is the virtual binfo. You must post process | |
78 | the returned thunk with finish_thunk. */ | |
1f6e1acc | 79 | |
8926095f | 80 | tree |
4977bab6 ZW |
81 | make_thunk (tree function, bool this_adjusting, |
82 | tree fixed_offset, tree virtual_offset) | |
8926095f | 83 | { |
31f8e4f3 | 84 | HOST_WIDE_INT d; |
4977bab6 | 85 | tree thunk; |
c8094d83 | 86 | |
50bc768d | 87 | gcc_assert (TREE_CODE (function) == FUNCTION_DECL); |
9bcb9aae | 88 | /* We can have this thunks to covariant thunks, but not vice versa. */ |
50bc768d NS |
89 | gcc_assert (!DECL_THIS_THUNK_P (function)); |
90 | gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting); | |
c8094d83 | 91 | |
4977bab6 ZW |
92 | /* Scale the VIRTUAL_OFFSET to be in terms of bytes. */ |
93 | if (this_adjusting && virtual_offset) | |
c8094d83 | 94 | virtual_offset |
31f8e4f3 | 95 | = size_binop (MULT_EXPR, |
0cbd7506 MS |
96 | virtual_offset, |
97 | convert (ssizetype, | |
98 | TYPE_SIZE_UNIT (vtable_entry_type))); | |
c8094d83 | 99 | |
9439e9a1 | 100 | d = tree_to_shwi (fixed_offset); |
c8094d83 | 101 | |
4977bab6 ZW |
102 | /* See if we already have the thunk in question. For this_adjusting |
103 | thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it | |
9bcb9aae | 104 | will be a BINFO. */ |
910ad8de | 105 | for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk)) |
e00853fd NS |
106 | if (DECL_THIS_THUNK_P (thunk) == this_adjusting |
107 | && THUNK_FIXED_OFFSET (thunk) == d | |
108 | && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk) | |
109 | && (!virtual_offset | |
110 | || (this_adjusting | |
111 | ? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk), | |
112 | virtual_offset) | |
113 | : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset))) | |
114 | return thunk; | |
c8094d83 | 115 | |
bb5e8a7f MM |
116 | /* All thunks must be created before FUNCTION is actually emitted; |
117 | the ABI requires that all thunks be emitted together with the | |
118 | function to which they transfer control. */ | |
50bc768d | 119 | gcc_assert (!TREE_ASM_WRITTEN (function)); |
90d46c28 NS |
120 | /* Likewise, we can only be adding thunks to a function declared in |
121 | the class currently being laid out. */ | |
50bc768d NS |
122 | gcc_assert (TYPE_SIZE (DECL_CONTEXT (function)) |
123 | && TYPE_BEING_DEFINED (DECL_CONTEXT (function))); | |
bb5e8a7f | 124 | |
c2255bc4 AH |
125 | thunk = build_decl (DECL_SOURCE_LOCATION (function), |
126 | FUNCTION_DECL, NULL_TREE, TREE_TYPE (function)); | |
bb5e8a7f | 127 | DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function); |
07fa4878 | 128 | cxx_dup_lang_specific_decl (thunk); |
21a092a9 JM |
129 | DECL_VIRTUAL_P (thunk) = true; |
130 | SET_DECL_THUNKS (thunk, NULL_TREE); | |
c8094d83 | 131 | |
bb5e8a7f MM |
132 | DECL_CONTEXT (thunk) = DECL_CONTEXT (function); |
133 | TREE_READONLY (thunk) = TREE_READONLY (function); | |
134 | TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function); | |
135 | TREE_PUBLIC (thunk) = TREE_PUBLIC (function); | |
4977bab6 | 136 | SET_DECL_THUNK_P (thunk, this_adjusting); |
07fa4878 NS |
137 | THUNK_TARGET (thunk) = function; |
138 | THUNK_FIXED_OFFSET (thunk) = d; | |
4977bab6 | 139 | THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset; |
e00853fd | 140 | THUNK_ALIAS (thunk) = NULL_TREE; |
c8094d83 | 141 | |
bb5e8a7f MM |
142 | DECL_INTERFACE_KNOWN (thunk) = 1; |
143 | DECL_NOT_REALLY_EXTERN (thunk) = 1; | |
f02f35b9 | 144 | DECL_COMDAT (thunk) = DECL_COMDAT (function); |
bb5e8a7f | 145 | DECL_SAVED_FUNCTION_DATA (thunk) = NULL; |
f02f35b9 JM |
146 | /* The thunk itself is not a constructor or destructor, even if |
147 | the thing it is thunking to is. */ | |
bb5e8a7f MM |
148 | DECL_DESTRUCTOR_P (thunk) = 0; |
149 | DECL_CONSTRUCTOR_P (thunk) = 0; | |
bb5e8a7f MM |
150 | DECL_EXTERNAL (thunk) = 1; |
151 | DECL_ARTIFICIAL (thunk) = 1; | |
bb5e8a7f MM |
152 | /* The THUNK is not a pending inline, even if the FUNCTION is. */ |
153 | DECL_PENDING_INLINE_P (thunk) = 0; | |
eab5474f | 154 | DECL_DECLARED_INLINE_P (thunk) = 0; |
cf5131b4 JM |
155 | /* Nor is it a template instantiation. */ |
156 | DECL_USE_TEMPLATE (thunk) = 0; | |
157 | DECL_TEMPLATE_INFO (thunk) = NULL; | |
c8094d83 | 158 | |
bb5e8a7f | 159 | /* Add it to the list of thunks associated with FUNCTION. */ |
910ad8de | 160 | DECL_CHAIN (thunk) = DECL_THUNKS (function); |
21a092a9 | 161 | SET_DECL_THUNKS (function, thunk); |
cc600f33 | 162 | |
8926095f MS |
163 | return thunk; |
164 | } | |
165 | ||
07fa4878 | 166 | /* Finish THUNK, a thunk decl. */ |
eb448459 | 167 | |
8926095f | 168 | void |
07fa4878 | 169 | finish_thunk (tree thunk) |
4977bab6 ZW |
170 | { |
171 | tree function, name; | |
ce552f75 | 172 | tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk)); |
07fa4878 NS |
173 | tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk); |
174 | ||
50bc768d | 175 | gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk)); |
07fa4878 NS |
176 | if (virtual_offset && DECL_RESULT_THUNK_P (thunk)) |
177 | virtual_offset = BINFO_VPTR_FIELD (virtual_offset); | |
178 | function = THUNK_TARGET (thunk); | |
4977bab6 | 179 | name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk), |
07fa4878 | 180 | fixed_offset, virtual_offset); |
bb885938 NS |
181 | |
182 | /* We can end up with declarations of (logically) different | |
183 | covariant thunks, that do identical adjustments. The two thunks | |
184 | will be adjusting between within different hierarchies, which | |
185 | happen to have the same layout. We must nullify one of them to | |
186 | refer to the other. */ | |
187 | if (DECL_RESULT_THUNK_P (thunk)) | |
188 | { | |
189 | tree cov_probe; | |
190 | ||
191 | for (cov_probe = DECL_THUNKS (function); | |
910ad8de | 192 | cov_probe; cov_probe = DECL_CHAIN (cov_probe)) |
bb885938 NS |
193 | if (DECL_NAME (cov_probe) == name) |
194 | { | |
50bc768d | 195 | gcc_assert (!DECL_THUNKS (thunk)); |
e00853fd | 196 | THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe) |
bb885938 NS |
197 | ? THUNK_ALIAS (cov_probe) : cov_probe); |
198 | break; | |
199 | } | |
200 | } | |
c8094d83 | 201 | |
4977bab6 ZW |
202 | DECL_NAME (thunk) = name; |
203 | SET_DECL_ASSEMBLER_NAME (thunk, name); | |
204 | } | |
205 | ||
89ce1c8f JJ |
206 | static GTY (()) int thunk_labelno; |
207 | ||
d6dcdbd5 | 208 | /* Create a static alias to target. */ |
89ce1c8f | 209 | |
6de33afa | 210 | tree |
d6dcdbd5 | 211 | make_alias_for (tree target, tree newid) |
89ce1c8f | 212 | { |
d6dcdbd5 JM |
213 | tree alias = build_decl (DECL_SOURCE_LOCATION (target), |
214 | TREE_CODE (target), newid, TREE_TYPE (target)); | |
215 | DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target); | |
89ce1c8f JJ |
216 | cxx_dup_lang_specific_decl (alias); |
217 | DECL_CONTEXT (alias) = NULL; | |
d6dcdbd5 JM |
218 | TREE_READONLY (alias) = TREE_READONLY (target); |
219 | TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target); | |
89ce1c8f JJ |
220 | TREE_PUBLIC (alias) = 0; |
221 | DECL_INTERFACE_KNOWN (alias) = 1; | |
39bac010 DS |
222 | if (DECL_LANG_SPECIFIC (alias)) |
223 | { | |
224 | DECL_NOT_REALLY_EXTERN (alias) = 1; | |
225 | DECL_USE_TEMPLATE (alias) = 0; | |
226 | DECL_TEMPLATE_INFO (alias) = NULL; | |
227 | } | |
89ce1c8f JJ |
228 | DECL_EXTERNAL (alias) = 0; |
229 | DECL_ARTIFICIAL (alias) = 1; | |
89ce1c8f | 230 | DECL_TEMPLATE_INSTANTIATED (alias) = 0; |
d6dcdbd5 JM |
231 | if (TREE_CODE (alias) == FUNCTION_DECL) |
232 | { | |
233 | DECL_SAVED_FUNCTION_DATA (alias) = NULL; | |
234 | DECL_DESTRUCTOR_P (alias) = 0; | |
235 | DECL_CONSTRUCTOR_P (alias) = 0; | |
236 | DECL_PENDING_INLINE_P (alias) = 0; | |
237 | DECL_DECLARED_INLINE_P (alias) = 0; | |
238 | DECL_INITIAL (alias) = error_mark_node; | |
239 | DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target)); | |
240 | } | |
241 | else | |
242 | TREE_STATIC (alias) = 1; | |
89ce1c8f JJ |
243 | TREE_ADDRESSABLE (alias) = 1; |
244 | TREE_USED (alias) = 1; | |
245 | SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias)); | |
6de33afa RH |
246 | return alias; |
247 | } | |
248 | ||
249 | static tree | |
250 | make_alias_for_thunk (tree function) | |
251 | { | |
252 | tree alias; | |
253 | char buf[256]; | |
254 | ||
4ee3b013 | 255 | targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno); |
6de33afa RH |
256 | thunk_labelno++; |
257 | ||
258 | alias = make_alias_for (function, get_identifier (buf)); | |
259 | ||
89ce1c8f | 260 | if (!flag_syntax_only) |
6744a6ab | 261 | { |
0fa1f9b7 MJ |
262 | struct cgraph_node *funcn, *aliasn; |
263 | funcn = cgraph_get_node (function); | |
264 | gcc_checking_assert (funcn); | |
265 | aliasn = cgraph_same_body_alias (funcn, alias, function); | |
6744a6ab | 266 | DECL_ASSEMBLER_NAME (function); |
051f8cc6 | 267 | gcc_assert (aliasn != NULL); |
6744a6ab | 268 | } |
6de33afa | 269 | |
89ce1c8f JJ |
270 | return alias; |
271 | } | |
272 | ||
4977bab6 ZW |
273 | /* Emit the definition of a C++ multiple inheritance or covariant |
274 | return vtable thunk. If EMIT_P is nonzero, the thunk is emitted | |
275 | immediately. */ | |
276 | ||
277 | void | |
278 | use_thunk (tree thunk_fndecl, bool emit_p) | |
8926095f | 279 | { |
7a3e01c4 | 280 | tree a, t, function, alias; |
4977bab6 ZW |
281 | tree virtual_offset; |
282 | HOST_WIDE_INT fixed_offset, virtual_value; | |
07fa4878 | 283 | bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl); |
2fda8e14 | 284 | struct cgraph_node *funcn, *thunk_node; |
4977bab6 | 285 | |
9bcb9aae | 286 | /* We should have called finish_thunk to give it a name. */ |
50bc768d | 287 | gcc_assert (DECL_NAME (thunk_fndecl)); |
8926095f | 288 | |
bb885938 NS |
289 | /* We should never be using an alias, always refer to the |
290 | aliased thunk. */ | |
50bc768d | 291 | gcc_assert (!THUNK_ALIAS (thunk_fndecl)); |
bb885938 | 292 | |
8926095f MS |
293 | if (TREE_ASM_WRITTEN (thunk_fndecl)) |
294 | return; | |
c8094d83 | 295 | |
07fa4878 NS |
296 | function = THUNK_TARGET (thunk_fndecl); |
297 | if (DECL_RESULT (thunk_fndecl)) | |
6462c441 | 298 | /* We already turned this thunk into an ordinary function. |
dff94ad7 | 299 | There's no need to process this thunk again. */ |
6462c441 MM |
300 | return; |
301 | ||
742f25b3 NS |
302 | if (DECL_THUNK_P (function)) |
303 | /* The target is itself a thunk, process it now. */ | |
304 | use_thunk (function, emit_p); | |
c8094d83 | 305 | |
31f8e4f3 MM |
306 | /* Thunks are always addressable; they only appear in vtables. */ |
307 | TREE_ADDRESSABLE (thunk_fndecl) = 1; | |
a0a33927 | 308 | |
31f8e4f3 MM |
309 | /* Figure out what function is being thunked to. It's referenced in |
310 | this translation unit. */ | |
809c8c30 JM |
311 | TREE_ADDRESSABLE (function) = 1; |
312 | mark_used (function); | |
31f8e4f3 MM |
313 | if (!emit_p) |
314 | return; | |
809c8c30 | 315 | |
4a77e08c DS |
316 | if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)) |
317 | alias = make_alias_for_thunk (function); | |
318 | else | |
319 | alias = function; | |
89ce1c8f | 320 | |
4977bab6 ZW |
321 | fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl); |
322 | virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl); | |
3961e8fe | 323 | |
07fa4878 NS |
324 | if (virtual_offset) |
325 | { | |
326 | if (!this_adjusting) | |
327 | virtual_offset = BINFO_VPTR_FIELD (virtual_offset); | |
9439e9a1 | 328 | virtual_value = tree_to_shwi (virtual_offset); |
50bc768d | 329 | gcc_assert (virtual_value); |
07fa4878 NS |
330 | } |
331 | else | |
332 | virtual_value = 0; | |
c8094d83 | 333 | |
31f8e4f3 MM |
334 | /* And, if we need to emit the thunk, it's used. */ |
335 | mark_used (thunk_fndecl); | |
336 | /* This thunk is actually defined. */ | |
337 | DECL_EXTERNAL (thunk_fndecl) = 0; | |
15eb1e43 JM |
338 | /* The linkage of the function may have changed. FIXME in linkage |
339 | rewrite. */ | |
99c18869 | 340 | gcc_assert (DECL_INTERFACE_KNOWN (function)); |
15eb1e43 | 341 | TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function); |
968b41a1 | 342 | DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function); |
c8094d83 | 343 | DECL_VISIBILITY_SPECIFIED (thunk_fndecl) |
73a8adb6 | 344 | = DECL_VISIBILITY_SPECIFIED (function); |
f02f35b9 | 345 | DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function); |
2fda8e14 | 346 | DECL_WEAK (thunk_fndecl) = DECL_WEAK (function); |
a0128b67 | 347 | |
6462c441 MM |
348 | if (flag_syntax_only) |
349 | { | |
350 | TREE_ASM_WRITTEN (thunk_fndecl) = 1; | |
351 | return; | |
352 | } | |
353 | ||
31f8e4f3 MM |
354 | push_to_top_level (); |
355 | ||
4a77e08c | 356 | if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function) |
677f3fa8 | 357 | && targetm_common.have_named_sections) |
89ce1c8f JJ |
358 | { |
359 | resolve_unique_section (function, 0, flag_function_sections); | |
360 | ||
361 | if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function)) | |
362 | { | |
363 | resolve_unique_section (thunk_fndecl, 0, flag_function_sections); | |
364 | ||
365 | /* Output the thunk into the same section as function. */ | |
366 | DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function); | |
367 | } | |
368 | } | |
89ce1c8f | 369 | |
7a3e01c4 JDA |
370 | /* Set up cloned argument trees for the thunk. */ |
371 | t = NULL_TREE; | |
910ad8de | 372 | for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a)) |
7a3e01c4 JDA |
373 | { |
374 | tree x = copy_node (a); | |
910ad8de | 375 | DECL_CHAIN (x) = t; |
7a3e01c4 | 376 | DECL_CONTEXT (x) = thunk_fndecl; |
245763e3 | 377 | SET_DECL_RTL (x, NULL); |
dbb87a8a | 378 | DECL_HAS_VALUE_EXPR_P (x) = 0; |
bf6817f2 | 379 | TREE_ADDRESSABLE (x) = 0; |
7a3e01c4 JDA |
380 | t = x; |
381 | } | |
382 | a = nreverse (t); | |
383 | DECL_ARGUMENTS (thunk_fndecl) = a; | |
6744a6ab | 384 | TREE_ASM_WRITTEN (thunk_fndecl) = 1; |
0fa1f9b7 MJ |
385 | funcn = cgraph_get_node (function); |
386 | gcc_checking_assert (funcn); | |
2fda8e14 JM |
387 | thunk_node = cgraph_add_thunk (funcn, thunk_fndecl, function, |
388 | this_adjusting, fixed_offset, virtual_value, | |
389 | virtual_offset, alias); | |
390 | if (DECL_ONE_ONLY (function)) | |
67348ccc DM |
391 | symtab_add_to_same_comdat_group (thunk_node, |
392 | funcn); | |
6744a6ab JH |
393 | |
394 | if (!this_adjusting | |
395 | || !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, | |
396 | virtual_value, alias)) | |
3b62f224 | 397 | { |
4977bab6 ZW |
398 | /* If this is a covariant thunk, or we don't have the necessary |
399 | code for efficient thunks, generate a thunk function that | |
400 | just makes a call to the real function. Unfortunately, this | |
401 | doesn't work for varargs. */ | |
14691f8d | 402 | |
14691f8d | 403 | if (varargs_function_p (function)) |
2a13a625 | 404 | error ("generic thunk code fails for method %q#D which uses %<...%>", |
14691f8d | 405 | function); |
14691f8d | 406 | } |
31f8e4f3 MM |
407 | |
408 | pop_from_top_level (); | |
8926095f | 409 | } |
f376e137 MS |
410 | \f |
411 | /* Code for synthesizing methods which have default semantics defined. */ | |
412 | ||
ac177431 JM |
413 | /* True iff CTYPE has a trivial SFK. */ |
414 | ||
415 | static bool | |
416 | type_has_trivial_fn (tree ctype, special_function_kind sfk) | |
417 | { | |
418 | switch (sfk) | |
419 | { | |
420 | case sfk_constructor: | |
421 | return !TYPE_HAS_COMPLEX_DFLT (ctype); | |
422 | case sfk_copy_constructor: | |
423 | return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype); | |
424 | case sfk_move_constructor: | |
425 | return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype); | |
426 | case sfk_copy_assignment: | |
427 | return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype); | |
428 | case sfk_move_assignment: | |
429 | return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype); | |
430 | case sfk_destructor: | |
431 | return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype); | |
85b5d65a JM |
432 | case sfk_inheriting_constructor: |
433 | return false; | |
ac177431 JM |
434 | default: |
435 | gcc_unreachable (); | |
436 | } | |
437 | } | |
438 | ||
439 | /* Note that CTYPE has a non-trivial SFK even though we previously thought | |
440 | it was trivial. */ | |
441 | ||
442 | static void | |
443 | type_set_nontrivial_flag (tree ctype, special_function_kind sfk) | |
444 | { | |
445 | switch (sfk) | |
446 | { | |
447 | case sfk_constructor: | |
448 | TYPE_HAS_COMPLEX_DFLT (ctype) = true; | |
449 | return; | |
450 | case sfk_copy_constructor: | |
451 | TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true; | |
452 | return; | |
453 | case sfk_move_constructor: | |
454 | TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true; | |
455 | return; | |
456 | case sfk_copy_assignment: | |
457 | TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true; | |
458 | return; | |
459 | case sfk_move_assignment: | |
460 | TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true; | |
461 | return; | |
462 | case sfk_destructor: | |
463 | TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true; | |
464 | return; | |
85b5d65a | 465 | case sfk_inheriting_constructor: |
ac177431 JM |
466 | default: |
467 | gcc_unreachable (); | |
468 | } | |
469 | } | |
470 | ||
471 | /* True iff FN is a trivial defaulted member function ([cd]tor, op=). */ | |
472 | ||
473 | bool | |
474 | trivial_fn_p (tree fn) | |
475 | { | |
476 | if (!DECL_DEFAULTED_FN (fn)) | |
477 | return false; | |
478 | ||
479 | /* If fn is a clone, get the primary variant. */ | |
1f26ac87 JM |
480 | if (tree prim = DECL_CLONED_FUNCTION (fn)) |
481 | fn = prim; | |
ac177431 JM |
482 | return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn)); |
483 | } | |
484 | ||
85b5d65a JM |
485 | /* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO |
486 | given the parameter or parameters PARM, possibly inherited constructor | |
487 | base INH, or move flag MOVE_P. */ | |
488 | ||
489 | static tree | |
490 | add_one_base_init (tree binfo, tree parm, bool move_p, tree inh, | |
491 | tree member_init_list) | |
492 | { | |
493 | tree init; | |
494 | if (inh) | |
495 | { | |
496 | /* An inheriting constructor only has a mem-initializer for | |
497 | the base it inherits from. */ | |
498 | if (BINFO_TYPE (binfo) != inh) | |
499 | return member_init_list; | |
500 | ||
501 | tree *p = &init; | |
502 | init = NULL_TREE; | |
503 | for (; parm; parm = DECL_CHAIN (parm)) | |
504 | { | |
505 | tree exp = convert_from_reference (parm); | |
d8af1a55 JM |
506 | if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE |
507 | || TYPE_REF_IS_RVALUE (TREE_TYPE (parm))) | |
85b5d65a JM |
508 | exp = move (exp); |
509 | *p = build_tree_list (NULL_TREE, exp); | |
510 | p = &TREE_CHAIN (*p); | |
511 | } | |
512 | } | |
513 | else | |
514 | { | |
515 | init = build_base_path (PLUS_EXPR, parm, binfo, 1, | |
516 | tf_warning_or_error); | |
517 | if (move_p) | |
518 | init = move (init); | |
519 | init = build_tree_list (NULL_TREE, init); | |
520 | } | |
521 | return tree_cons (binfo, init, member_init_list); | |
522 | } | |
523 | ||
524 | /* Generate code for default X(X&) or X(X&&) constructor or an inheriting | |
525 | constructor. */ | |
e92cc029 | 526 | |
824b9a4c | 527 | static void |
4977bab6 | 528 | do_build_copy_constructor (tree fndecl) |
f376e137 | 529 | { |
e0fff4b3 | 530 | tree parm = FUNCTION_FIRST_USER_PARM (fndecl); |
d5f4eddd | 531 | bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl); |
ac177431 | 532 | bool trivial = trivial_fn_p (fndecl); |
85b5d65a | 533 | tree inh = DECL_INHERITED_CTOR_BASE (fndecl); |
f376e137 | 534 | |
85b5d65a JM |
535 | if (!inh) |
536 | parm = convert_from_reference (parm); | |
f376e137 | 537 | |
ac177431 | 538 | if (trivial |
a59ca936 JM |
539 | && is_empty_class (current_class_type)) |
540 | /* Don't copy the padding byte; it might not have been allocated | |
541 | if *this is a base subobject. */; | |
ac177431 | 542 | else if (trivial) |
f376e137 | 543 | { |
fd749a60 | 544 | tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm); |
f1dedc31 | 545 | finish_expr_stmt (t); |
f376e137 MS |
546 | } |
547 | else | |
548 | { | |
549 | tree fields = TYPE_FIELDS (current_class_type); | |
fd74ca0b | 550 | tree member_init_list = NULL_TREE; |
89d684bb | 551 | int cvquals = cp_type_quals (TREE_TYPE (parm)); |
f376e137 | 552 | int i; |
fa743e8c | 553 | tree binfo, base_binfo; |
d5f4eddd | 554 | tree init; |
9771b263 | 555 | vec<tree, va_gc> *vbases; |
f376e137 | 556 | |
713ccd0c NS |
557 | /* Initialize all the base-classes with the parameter converted |
558 | to their type so that we get their copy constructor and not | |
559 | another constructor that takes current_class_type. We must | |
560 | deal with the binfo's directly as a direct base might be | |
561 | inaccessible due to ambiguity. */ | |
9ba5ff0f | 562 | for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0; |
9771b263 | 563 | vec_safe_iterate (vbases, i, &binfo); i++) |
01f9e964 | 564 | { |
85b5d65a JM |
565 | member_init_list = add_one_base_init (binfo, parm, move_p, inh, |
566 | member_init_list); | |
01f9e964 JM |
567 | } |
568 | ||
fa743e8c NS |
569 | for (binfo = TYPE_BINFO (current_class_type), i = 0; |
570 | BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | |
f376e137 | 571 | { |
fa743e8c | 572 | if (BINFO_VIRTUAL_P (base_binfo)) |
c8094d83 | 573 | continue; |
85b5d65a JM |
574 | member_init_list = add_one_base_init (base_binfo, parm, move_p, |
575 | inh, member_init_list); | |
f376e137 | 576 | } |
1b5f5f76 | 577 | |
910ad8de | 578 | for (; fields; fields = DECL_CHAIN (fields)) |
f376e137 | 579 | { |
a5894242 | 580 | tree field = fields; |
33dd07ee | 581 | tree expr_type; |
a5894242 MS |
582 | |
583 | if (TREE_CODE (field) != FIELD_DECL) | |
f376e137 | 584 | continue; |
85b5d65a JM |
585 | if (inh) |
586 | continue; | |
8dff1027 | 587 | |
fd749a60 | 588 | expr_type = TREE_TYPE (field); |
a5894242 | 589 | if (DECL_NAME (field)) |
f376e137 | 590 | { |
a5894242 | 591 | if (VFIELD_NAME_P (DECL_NAME (field))) |
f376e137 | 592 | continue; |
f376e137 | 593 | } |
fd749a60 | 594 | else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type)) |
6bdb8141 | 595 | /* Just use the field; anonymous types can't have |
57ece258 JM |
596 | nontrivial copy ctors or assignment ops or this |
597 | function would be deleted. */; | |
0171aeab JM |
598 | else |
599 | continue; | |
f376e137 | 600 | |
33dd07ee MM |
601 | /* Compute the type of "init->field". If the copy-constructor |
602 | parameter is, for example, "const S&", and the type of | |
603 | the field is "T", then the type will usually be "const | |
604 | T". (There are no cv-qualified variants of reference | |
605 | types.) */ | |
33dd07ee | 606 | if (TREE_CODE (expr_type) != REFERENCE_TYPE) |
fd749a60 NS |
607 | { |
608 | int quals = cvquals; | |
c8094d83 | 609 | |
fd749a60 NS |
610 | if (DECL_MUTABLE_P (field)) |
611 | quals &= ~TYPE_QUAL_CONST; | |
a3360e77 | 612 | quals |= cp_type_quals (expr_type); |
fd749a60 NS |
613 | expr_type = cp_build_qualified_type (expr_type, quals); |
614 | } | |
c8094d83 | 615 | |
d5f4eddd | 616 | init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE); |
702f9fe5 JM |
617 | if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE |
618 | /* 'move' breaks bit-fields, and has no effect for scalars. */ | |
619 | && !scalarish_type_p (expr_type)) | |
d5f4eddd | 620 | init = move (init); |
f376e137 MS |
621 | init = build_tree_list (NULL_TREE, init); |
622 | ||
fd749a60 | 623 | member_init_list = tree_cons (field, init, member_init_list); |
f376e137 | 624 | } |
2282d28d | 625 | finish_mem_initializers (member_init_list); |
f376e137 | 626 | } |
f376e137 MS |
627 | } |
628 | ||
824b9a4c | 629 | static void |
066ec0a4 | 630 | do_build_copy_assign (tree fndecl) |
f376e137 | 631 | { |
910ad8de | 632 | tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl)); |
f1dedc31 | 633 | tree compound_stmt; |
ac177431 JM |
634 | bool move_p = move_fn_p (fndecl); |
635 | bool trivial = trivial_fn_p (fndecl); | |
b8bf6ad9 | 636 | int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED; |
f376e137 | 637 | |
325c3691 | 638 | compound_stmt = begin_compound_stmt (0); |
f376e137 MS |
639 | parm = convert_from_reference (parm); |
640 | ||
ac177431 | 641 | if (trivial |
a59ca936 JM |
642 | && is_empty_class (current_class_type)) |
643 | /* Don't copy the padding byte; it might not have been allocated | |
644 | if *this is a base subobject. */; | |
ac177431 | 645 | else if (trivial) |
f376e137 | 646 | { |
f293ce4b | 647 | tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm); |
f1dedc31 | 648 | finish_expr_stmt (t); |
f376e137 MS |
649 | } |
650 | else | |
651 | { | |
4ba126e4 | 652 | tree fields; |
89d684bb | 653 | int cvquals = cp_type_quals (TREE_TYPE (parm)); |
f376e137 | 654 | int i; |
fa743e8c | 655 | tree binfo, base_binfo; |
f376e137 | 656 | |
22ed7e5f | 657 | /* Assign to each of the direct base classes. */ |
fa743e8c NS |
658 | for (binfo = TYPE_BINFO (current_class_type), i = 0; |
659 | BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | |
f376e137 | 660 | { |
4ba126e4 | 661 | tree converted_parm; |
9771b263 | 662 | vec<tree, va_gc> *parmvec; |
4ba126e4 | 663 | |
4ba126e4 MM |
664 | /* We must convert PARM directly to the base class |
665 | explicitly since the base class may be ambiguous. */ | |
a271590a PC |
666 | converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1, |
667 | tf_warning_or_error); | |
ac177431 JM |
668 | if (move_p) |
669 | converted_parm = move (converted_parm); | |
4ba126e4 | 670 | /* Call the base class assignment operator. */ |
c166b898 | 671 | parmvec = make_tree_vector_single (converted_parm); |
c8094d83 MS |
672 | finish_expr_stmt |
673 | (build_special_member_call (current_class_ref, | |
4ba126e4 | 674 | ansi_assopname (NOP_EXPR), |
c166b898 | 675 | &parmvec, |
fa743e8c | 676 | base_binfo, |
b8bf6ad9 | 677 | flags, |
5ade1ed2 | 678 | tf_warning_or_error)); |
c166b898 | 679 | release_tree_vector (parmvec); |
f376e137 | 680 | } |
4ba126e4 MM |
681 | |
682 | /* Assign to each of the non-static data members. */ | |
c8094d83 MS |
683 | for (fields = TYPE_FIELDS (current_class_type); |
684 | fields; | |
910ad8de | 685 | fields = DECL_CHAIN (fields)) |
f376e137 | 686 | { |
fd749a60 NS |
687 | tree comp = current_class_ref; |
688 | tree init = parm; | |
a5894242 | 689 | tree field = fields; |
fd749a60 NS |
690 | tree expr_type; |
691 | int quals; | |
a5894242 | 692 | |
17bbb839 | 693 | if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field)) |
f376e137 | 694 | continue; |
e349ee73 | 695 | |
fd749a60 | 696 | expr_type = TREE_TYPE (field); |
c8094d83 | 697 | |
fd749a60 | 698 | if (CP_TYPE_CONST_P (expr_type)) |
e349ee73 | 699 | { |
d8a07487 | 700 | error ("non-static const member %q#D, can%'t use default " |
0cbd7506 | 701 | "assignment operator", field); |
e349ee73 MS |
702 | continue; |
703 | } | |
fd749a60 | 704 | else if (TREE_CODE (expr_type) == REFERENCE_TYPE) |
e349ee73 | 705 | { |
d8a07487 | 706 | error ("non-static reference member %q#D, can%'t use " |
0cbd7506 | 707 | "default assignment operator", field); |
e349ee73 MS |
708 | continue; |
709 | } | |
710 | ||
a5894242 | 711 | if (DECL_NAME (field)) |
f376e137 | 712 | { |
a5894242 | 713 | if (VFIELD_NAME_P (DECL_NAME (field))) |
f376e137 | 714 | continue; |
f376e137 | 715 | } |
fd749a60 NS |
716 | else if (ANON_AGGR_TYPE_P (expr_type) |
717 | && TYPE_FIELDS (expr_type) != NULL_TREE) | |
6bdb8141 | 718 | /* Just use the field; anonymous types can't have |
57ece258 JM |
719 | nontrivial copy ctors or assignment ops or this |
720 | function would be deleted. */; | |
0171aeab JM |
721 | else |
722 | continue; | |
f376e137 | 723 | |
fd749a60 | 724 | comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE); |
c8094d83 | 725 | |
fd749a60 NS |
726 | /* Compute the type of init->field */ |
727 | quals = cvquals; | |
728 | if (DECL_MUTABLE_P (field)) | |
729 | quals &= ~TYPE_QUAL_CONST; | |
730 | expr_type = cp_build_qualified_type (expr_type, quals); | |
c8094d83 | 731 | |
fd749a60 | 732 | init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE); |
702f9fe5 JM |
733 | if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE |
734 | /* 'move' breaks bit-fields, and has no effect for scalars. */ | |
735 | && !scalarish_type_p (expr_type)) | |
ac177431 | 736 | init = move (init); |
f376e137 | 737 | |
a1c2b86d | 738 | if (DECL_NAME (field)) |
5ade1ed2 DG |
739 | init = cp_build_modify_expr (comp, NOP_EXPR, init, |
740 | tf_warning_or_error); | |
a1c2b86d | 741 | else |
fd749a60 NS |
742 | init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init); |
743 | finish_expr_stmt (init); | |
f376e137 MS |
744 | } |
745 | } | |
62409b39 | 746 | finish_return_stmt (current_class_ref); |
7a3397c7 | 747 | finish_compound_stmt (compound_stmt); |
f376e137 MS |
748 | } |
749 | ||
3e3935a9 NS |
750 | /* Synthesize FNDECL, a non-static member function. */ |
751 | ||
f376e137 | 752 | void |
4977bab6 | 753 | synthesize_method (tree fndecl) |
f376e137 | 754 | { |
4977bab6 | 755 | bool nested = (current_function_decl != NULL_TREE); |
4f1c5b7d | 756 | tree context = decl_function_context (fndecl); |
4977bab6 | 757 | bool need_body = true; |
ade3dc07 | 758 | tree stmt; |
39a87435 | 759 | location_t save_input_location = input_location; |
3e3935a9 | 760 | int error_count = errorcount; |
37e99116 | 761 | int warning_count = warningcount + werrorcount; |
db5ae43f | 762 | |
3e3935a9 NS |
763 | /* Reset the source location, we might have been previously |
764 | deferred, and thus have saved where we were first needed. */ | |
765 | DECL_SOURCE_LOCATION (fndecl) | |
766 | = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl))); | |
c8094d83 | 767 | |
db9b2174 MM |
768 | /* If we've been asked to synthesize a clone, just synthesize the |
769 | cloned function instead. Doing so will automatically fill in the | |
770 | body for the clone. */ | |
771 | if (DECL_CLONED_FUNCTION_P (fndecl)) | |
3e3935a9 | 772 | fndecl = DECL_CLONED_FUNCTION (fndecl); |
db9b2174 | 773 | |
afb19ffb KL |
774 | /* We may be in the middle of deferred access check. Disable |
775 | it now. */ | |
776 | push_deferring_access_checks (dk_no_deferred); | |
777 | ||
9a3b49ac MS |
778 | if (! context) |
779 | push_to_top_level (); | |
780 | else if (nested) | |
d2784db4 | 781 | push_function_context (); |
db5ae43f | 782 | |
39a87435 | 783 | input_location = DECL_SOURCE_LOCATION (fndecl); |
62409b39 | 784 | |
058b15c1 | 785 | start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED); |
ade3dc07 | 786 | stmt = begin_function_body (); |
db5ae43f | 787 | |
596ea4e5 | 788 | if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR) |
62409b39 | 789 | { |
066ec0a4 | 790 | do_build_copy_assign (fndecl); |
4977bab6 | 791 | need_body = false; |
62409b39 | 792 | } |
cdd2559c | 793 | else if (DECL_CONSTRUCTOR_P (fndecl)) |
db5ae43f | 794 | { |
e0fff4b3 | 795 | tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl); |
db5ae43f MS |
796 | if (arg_chain != void_list_node) |
797 | do_build_copy_constructor (fndecl); | |
c7b0e027 | 798 | else |
cdd2559c | 799 | finish_mem_initializers (NULL_TREE); |
62409b39 | 800 | } |
f18a14bc | 801 | |
62409b39 MM |
802 | /* If we haven't yet generated the body of the function, just |
803 | generate an empty compound statement. */ | |
804 | if (need_body) | |
805 | { | |
806 | tree compound_stmt; | |
325c3691 | 807 | compound_stmt = begin_compound_stmt (BCS_FN_BODY); |
7a3397c7 | 808 | finish_compound_stmt (compound_stmt); |
db5ae43f MS |
809 | } |
810 | ||
ade3dc07 | 811 | finish_function_body (stmt); |
8cd2462c | 812 | expand_or_defer_fn (finish_function (0)); |
28cbf42c | 813 | |
39a87435 AO |
814 | input_location = save_input_location; |
815 | ||
9a3b49ac MS |
816 | if (! context) |
817 | pop_from_top_level (); | |
818 | else if (nested) | |
d2784db4 | 819 | pop_function_context (); |
afb19ffb KL |
820 | |
821 | pop_deferring_access_checks (); | |
3e3935a9 | 822 | |
37e99116 | 823 | if (error_count != errorcount || warning_count != warningcount + werrorcount) |
1f5b3869 MLI |
824 | inform (input_location, "synthesized method %qD first required here ", |
825 | fndecl); | |
f376e137 | 826 | } |
9eb71d8c | 827 | |
ac177431 JM |
828 | /* Build a reference to type TYPE with cv-quals QUALS, which is an |
829 | rvalue if RVALUE is true. */ | |
03378143 NS |
830 | |
831 | static tree | |
ac177431 | 832 | build_stub_type (tree type, int quals, bool rvalue) |
03378143 | 833 | { |
ac177431 JM |
834 | tree argtype = cp_build_qualified_type (type, quals); |
835 | return cp_build_reference_type (argtype, rvalue); | |
836 | } | |
f62ea157 | 837 | |
ac177431 JM |
838 | /* Build a dummy glvalue from dereferencing a dummy reference of type |
839 | REFTYPE. */ | |
c8094d83 | 840 | |
ac177431 JM |
841 | static tree |
842 | build_stub_object (tree reftype) | |
843 | { | |
844 | tree stub = build1 (NOP_EXPR, reftype, integer_one_node); | |
845 | return convert_from_reference (stub); | |
846 | } | |
c8094d83 | 847 | |
ac177431 JM |
848 | /* Determine which function will be called when looking up NAME in TYPE, |
849 | called with a single ARGTYPE argument, or no argument if ARGTYPE is | |
850 | null. FLAGS and COMPLAIN are as for build_new_method_call. | |
c8094d83 | 851 | |
ac177431 JM |
852 | Returns a FUNCTION_DECL if all is well. |
853 | Returns NULL_TREE if overload resolution failed. | |
854 | Returns error_mark_node if the chosen function cannot be called. */ | |
c8094d83 | 855 | |
ac177431 JM |
856 | static tree |
857 | locate_fn_flags (tree type, tree name, tree argtype, int flags, | |
858 | tsubst_flags_t complain) | |
859 | { | |
860 | tree ob, fn, fns, binfo, rval; | |
9771b263 | 861 | vec<tree, va_gc> *args; |
ac177431 JM |
862 | |
863 | if (TYPE_P (type)) | |
864 | binfo = TYPE_BINFO (type); | |
865 | else | |
866 | { | |
867 | binfo = type; | |
868 | type = BINFO_TYPE (binfo); | |
869 | } | |
870 | ||
871 | ob = build_stub_object (cp_build_reference_type (type, false)); | |
872 | args = make_tree_vector (); | |
873 | if (argtype) | |
874 | { | |
85b5d65a JM |
875 | if (TREE_CODE (argtype) == TREE_LIST) |
876 | { | |
877 | for (tree elt = argtype; elt != void_list_node; | |
878 | elt = TREE_CHAIN (elt)) | |
879 | { | |
880 | tree type = TREE_VALUE (elt); | |
881 | if (TREE_CODE (type) != REFERENCE_TYPE) | |
882 | type = cp_build_reference_type (type, /*rval*/true); | |
883 | tree arg = build_stub_object (type); | |
9771b263 | 884 | vec_safe_push (args, arg); |
85b5d65a JM |
885 | } |
886 | } | |
887 | else | |
888 | { | |
889 | tree arg = build_stub_object (argtype); | |
9771b263 | 890 | args->quick_push (arg); |
85b5d65a | 891 | } |
03378143 | 892 | } |
ac177431 JM |
893 | |
894 | fns = lookup_fnfields (binfo, name, 0); | |
895 | rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain); | |
896 | ||
897 | release_tree_vector (args); | |
898 | if (fn && rval == error_mark_node) | |
899 | return rval; | |
900 | else | |
901 | return fn; | |
03378143 NS |
902 | } |
903 | ||
904 | /* Locate the dtor of TYPE. */ | |
905 | ||
cb68ec50 | 906 | tree |
4577f730 | 907 | get_dtor (tree type, tsubst_flags_t complain) |
03378143 | 908 | { |
b73a4704 | 909 | tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE, |
4577f730 | 910 | LOOKUP_NORMAL, complain); |
ac177431 JM |
911 | if (fn == error_mark_node) |
912 | return NULL_TREE; | |
913 | return fn; | |
03378143 NS |
914 | } |
915 | ||
916 | /* Locate the default ctor of TYPE. */ | |
917 | ||
cb68ec50 | 918 | tree |
ac177431 | 919 | locate_ctor (tree type) |
03378143 | 920 | { |
f7d042e2 JM |
921 | tree fn; |
922 | ||
923 | push_deferring_access_checks (dk_no_check); | |
924 | fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, | |
925 | LOOKUP_SPECULATIVE, tf_none); | |
926 | pop_deferring_access_checks (); | |
ac177431 JM |
927 | if (fn == error_mark_node) |
928 | return NULL_TREE; | |
929 | return fn; | |
930 | } | |
931 | ||
932 | /* Likewise, but give any appropriate errors. */ | |
c8094d83 | 933 | |
ac177431 JM |
934 | tree |
935 | get_default_ctor (tree type) | |
936 | { | |
937 | tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, | |
938 | LOOKUP_NORMAL, tf_warning_or_error); | |
939 | if (fn == error_mark_node) | |
940 | return NULL_TREE; | |
941 | return fn; | |
942 | } | |
943 | ||
944 | /* Locate the copy ctor of TYPE. */ | |
945 | ||
946 | tree | |
4577f730 | 947 | get_copy_ctor (tree type, tsubst_flags_t complain) |
ac177431 JM |
948 | { |
949 | int quals = (TYPE_HAS_CONST_COPY_CTOR (type) | |
950 | ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); | |
951 | tree argtype = build_stub_type (type, quals, false); | |
952 | tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype, | |
4577f730 | 953 | LOOKUP_NORMAL, complain); |
ac177431 | 954 | if (fn == error_mark_node) |
03378143 | 955 | return NULL_TREE; |
ac177431 JM |
956 | return fn; |
957 | } | |
aaaa46d2 | 958 | |
ac177431 | 959 | /* Locate the copy assignment operator of TYPE. */ |
508a1c9c | 960 | |
ac177431 JM |
961 | tree |
962 | get_copy_assign (tree type) | |
963 | { | |
964 | int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type) | |
965 | ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); | |
966 | tree argtype = build_stub_type (type, quals, false); | |
967 | tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype, | |
968 | LOOKUP_NORMAL, tf_warning_or_error); | |
969 | if (fn == error_mark_node) | |
970 | return NULL_TREE; | |
971 | return fn; | |
972 | } | |
973 | ||
5af1876c PC |
974 | /* Locate the inherited constructor of constructor CTOR. */ |
975 | ||
976 | tree | |
977 | get_inherited_ctor (tree ctor) | |
978 | { | |
979 | gcc_assert (DECL_INHERITED_CTOR_BASE (ctor)); | |
980 | ||
981 | push_deferring_access_checks (dk_no_check); | |
982 | tree fn = locate_fn_flags (DECL_INHERITED_CTOR_BASE (ctor), | |
983 | complete_ctor_identifier, | |
984 | FUNCTION_FIRST_USER_PARMTYPE (ctor), | |
985 | LOOKUP_NORMAL|LOOKUP_SPECULATIVE, | |
986 | tf_none); | |
987 | pop_deferring_access_checks (); | |
988 | if (fn == error_mark_node) | |
989 | return NULL_TREE; | |
990 | return fn; | |
991 | } | |
992 | ||
ac177431 JM |
993 | /* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and |
994 | DELETED_P or give an error message MSG with argument ARG. */ | |
995 | ||
996 | static void | |
f14edc1a JM |
997 | process_subob_fn (tree fn, tree *spec_p, bool *trivial_p, |
998 | bool *deleted_p, bool *constexpr_p, | |
45ffb6f7 | 999 | bool diag, tree arg) |
ac177431 JM |
1000 | { |
1001 | if (!fn || fn == error_mark_node) | |
1002 | goto bad; | |
1003 | ||
1004 | if (spec_p) | |
03378143 | 1005 | { |
b273cdb1 JM |
1006 | tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); |
1007 | *spec_p = merge_exception_specifiers (*spec_p, raises, fn); | |
ac177431 | 1008 | } |
c8094d83 | 1009 | |
57ece258 JM |
1010 | if (!trivial_fn_p (fn)) |
1011 | { | |
1012 | if (trivial_p) | |
1013 | *trivial_p = false; | |
1014 | if (TREE_CODE (arg) == FIELD_DECL | |
1015 | && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE) | |
1016 | { | |
1017 | if (deleted_p) | |
1018 | *deleted_p = true; | |
45ffb6f7 | 1019 | if (diag) |
57ece258 JM |
1020 | error ("union member %q+D with non-trivial %qD", arg, fn); |
1021 | } | |
1022 | } | |
63752e29 | 1023 | |
aee88012 | 1024 | if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn)) |
525c617d | 1025 | { |
aee88012 | 1026 | *constexpr_p = false; |
45ffb6f7 | 1027 | if (diag) |
f732fa7b | 1028 | { |
aee88012 JM |
1029 | inform (0, "defaulted constructor calls non-constexpr " |
1030 | "%q+D", fn); | |
1031 | explain_invalid_constexpr_fn (fn); | |
f732fa7b | 1032 | } |
525c617d | 1033 | } |
225a6584 | 1034 | |
ac177431 JM |
1035 | return; |
1036 | ||
1037 | bad: | |
1038 | if (deleted_p) | |
1039 | *deleted_p = true; | |
03378143 NS |
1040 | } |
1041 | ||
57ece258 JM |
1042 | /* Subroutine of synthesized_method_walk to allow recursion into anonymous |
1043 | aggregates. */ | |
1044 | ||
1045 | static void | |
1046 | walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, | |
1047 | int quals, bool copy_arg_p, bool move_p, | |
1048 | bool assign_p, tree *spec_p, bool *trivial_p, | |
f14edc1a | 1049 | bool *deleted_p, bool *constexpr_p, |
45ffb6f7 | 1050 | bool diag, int flags, tsubst_flags_t complain) |
57ece258 JM |
1051 | { |
1052 | tree field; | |
910ad8de | 1053 | for (field = fields; field; field = DECL_CHAIN (field)) |
57ece258 JM |
1054 | { |
1055 | tree mem_type, argtype, rval; | |
1056 | ||
1057 | if (TREE_CODE (field) != FIELD_DECL | |
1058 | || DECL_ARTIFICIAL (field)) | |
1059 | continue; | |
1060 | ||
1061 | mem_type = strip_array_types (TREE_TYPE (field)); | |
1062 | if (assign_p) | |
1063 | { | |
1064 | bool bad = true; | |
1065 | if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type)) | |
1066 | { | |
45ffb6f7 | 1067 | if (diag) |
d8a07487 | 1068 | error ("non-static const member %q#D, can%'t use default " |
57ece258 JM |
1069 | "assignment operator", field); |
1070 | } | |
1071 | else if (TREE_CODE (mem_type) == REFERENCE_TYPE) | |
1072 | { | |
45ffb6f7 | 1073 | if (diag) |
d8a07487 | 1074 | error ("non-static reference member %q#D, can%'t use " |
57ece258 JM |
1075 | "default assignment operator", field); |
1076 | } | |
1077 | else | |
1078 | bad = false; | |
1079 | ||
1080 | if (bad && deleted_p) | |
1081 | *deleted_p = true; | |
1082 | } | |
1083 | else if (sfk == sfk_constructor) | |
1084 | { | |
37d8632b | 1085 | bool bad; |
225a6584 | 1086 | |
0e5f8a59 JM |
1087 | if (DECL_INITIAL (field)) |
1088 | { | |
45ffb6f7 | 1089 | if (diag && DECL_INITIAL (field) == error_mark_node) |
0e5f8a59 JM |
1090 | inform (0, "initializer for %q+#D is invalid", field); |
1091 | if (trivial_p) | |
1092 | *trivial_p = false; | |
f10eaa2d | 1093 | #if 0 |
6eaade31 JM |
1094 | /* Core 1351: If the field has an NSDMI that could throw, the |
1095 | default constructor is noexcept(false). FIXME this is | |
f10eaa2d JM |
1096 | broken by deferred parsing and 1360 saying we can't lazily |
1097 | declare a non-trivial default constructor. Also this | |
1098 | needs to do deferred instantiation. Disable until the | |
1099 | conflict between 1351 and 1360 is resolved. */ | |
6eaade31 JM |
1100 | if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain)) |
1101 | *spec_p = noexcept_false_spec; | |
f10eaa2d | 1102 | #endif |
0e5f8a59 JM |
1103 | |
1104 | /* Don't do the normal processing. */ | |
1105 | continue; | |
1106 | } | |
1107 | ||
37d8632b JM |
1108 | bad = false; |
1109 | if (CP_TYPE_CONST_P (mem_type) | |
1110 | && default_init_uninitialized_part (mem_type)) | |
1111 | { | |
45ffb6f7 | 1112 | if (diag) |
37d8632b JM |
1113 | error ("uninitialized non-static const member %q#D", |
1114 | field); | |
1115 | bad = true; | |
1116 | } | |
1117 | else if (TREE_CODE (mem_type) == REFERENCE_TYPE) | |
1118 | { | |
45ffb6f7 | 1119 | if (diag) |
37d8632b JM |
1120 | error ("uninitialized non-static reference member %q#D", |
1121 | field); | |
1122 | bad = true; | |
1123 | } | |
1124 | ||
1125 | if (bad && deleted_p) | |
1126 | *deleted_p = true; | |
1127 | ||
225a6584 | 1128 | /* For an implicitly-defined default constructor to be constexpr, |
0e5f8a59 JM |
1129 | every member must have a user-provided default constructor or |
1130 | an explicit initializer. */ | |
ab807569 JM |
1131 | if (constexpr_p && !CLASS_TYPE_P (mem_type) |
1132 | && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE) | |
f732fa7b JM |
1133 | { |
1134 | *constexpr_p = false; | |
45ffb6f7 | 1135 | if (diag) |
f732fa7b JM |
1136 | inform (0, "defaulted default constructor does not " |
1137 | "initialize %q+#D", field); | |
1138 | } | |
57ece258 | 1139 | } |
5275b2c7 JM |
1140 | else if (sfk == sfk_copy_constructor) |
1141 | { | |
1142 | /* 12.8p11b5 */ | |
1143 | if (TREE_CODE (mem_type) == REFERENCE_TYPE | |
1144 | && TYPE_REF_IS_RVALUE (mem_type)) | |
1145 | { | |
1146 | if (diag) | |
1147 | error ("copying non-static data member %q#D of rvalue " | |
1148 | "reference type", field); | |
1149 | if (deleted_p) | |
1150 | *deleted_p = true; | |
1151 | } | |
1152 | } | |
57ece258 JM |
1153 | |
1154 | if (!CLASS_TYPE_P (mem_type)) | |
1155 | continue; | |
1156 | ||
1157 | if (ANON_AGGR_TYPE_P (mem_type)) | |
1158 | { | |
1159 | walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals, | |
1160 | copy_arg_p, move_p, assign_p, spec_p, trivial_p, | |
f14edc1a | 1161 | deleted_p, constexpr_p, |
45ffb6f7 | 1162 | diag, flags, complain); |
57ece258 JM |
1163 | continue; |
1164 | } | |
1165 | ||
1166 | if (copy_arg_p) | |
1167 | { | |
1168 | int mem_quals = cp_type_quals (mem_type) | quals; | |
1169 | if (DECL_MUTABLE_P (field)) | |
1170 | mem_quals &= ~TYPE_QUAL_CONST; | |
1171 | argtype = build_stub_type (mem_type, mem_quals, move_p); | |
1172 | } | |
1173 | else | |
1174 | argtype = NULL_TREE; | |
1175 | ||
1176 | rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain); | |
1177 | ||
f14edc1a JM |
1178 | process_subob_fn (rval, spec_p, trivial_p, deleted_p, |
1179 | constexpr_p, diag, field); | |
57ece258 JM |
1180 | } |
1181 | } | |
1182 | ||
ac177431 JM |
1183 | /* The caller wants to generate an implicit declaration of SFK for CTYPE |
1184 | which is const if relevant and CONST_P is set. If spec_p, trivial_p and | |
1185 | deleted_p are non-null, set their referent appropriately. If diag is | |
f732fa7b JM |
1186 | true, we're either being called from maybe_explain_implicit_delete to |
1187 | give errors, or if constexpr_p is non-null, from | |
1188 | explain_invalid_constexpr_fn. */ | |
ac177431 JM |
1189 | |
1190 | static void | |
1191 | synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, | |
1192 | tree *spec_p, bool *trivial_p, bool *deleted_p, | |
f14edc1a | 1193 | bool *constexpr_p, bool diag, |
85b5d65a | 1194 | tree inherited_base, tree inherited_parms) |
03378143 | 1195 | { |
57ece258 | 1196 | tree binfo, base_binfo, scope, fnname, rval, argtype; |
ac177431 | 1197 | bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor; |
9771b263 | 1198 | vec<tree, va_gc> *vbases; |
ac177431 JM |
1199 | int i, quals, flags; |
1200 | tsubst_flags_t complain; | |
ea76c60a | 1201 | bool ctor_p; |
ac177431 JM |
1202 | |
1203 | if (spec_p) | |
604b2bfc | 1204 | *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec); |
ac177431 JM |
1205 | |
1206 | if (deleted_p) | |
1207 | { | |
1208 | /* "The closure type associated with a lambda-expression has a deleted | |
1209 | default constructor and a deleted copy assignment operator." | |
1210 | This is diagnosed in maybe_explain_implicit_delete. */ | |
1211 | if (LAMBDA_TYPE_P (ctype) | |
1212 | && (sfk == sfk_constructor | |
1213 | || sfk == sfk_copy_assignment)) | |
1214 | { | |
1215 | *deleted_p = true; | |
1216 | return; | |
1217 | } | |
03378143 | 1218 | |
ac177431 JM |
1219 | *deleted_p = false; |
1220 | } | |
03378143 | 1221 | |
225a6584 GDR |
1222 | ctor_p = false; |
1223 | assign_p = false; | |
1224 | check_vdtor = false; | |
1225 | switch (sfk) | |
1226 | { | |
1227 | case sfk_move_assignment: | |
1228 | case sfk_copy_assignment: | |
1229 | assign_p = true; | |
1230 | fnname = ansi_assopname (NOP_EXPR); | |
1231 | break; | |
1232 | ||
1233 | case sfk_destructor: | |
1234 | check_vdtor = true; | |
1235 | /* The synthesized method will call base dtors, but check complete | |
1236 | here to avoid having to deal with VTT. */ | |
1237 | fnname = complete_dtor_identifier; | |
1238 | break; | |
1239 | ||
1240 | case sfk_constructor: | |
1241 | case sfk_move_constructor: | |
1242 | case sfk_copy_constructor: | |
85b5d65a | 1243 | case sfk_inheriting_constructor: |
225a6584 GDR |
1244 | ctor_p = true; |
1245 | fnname = complete_ctor_identifier; | |
1246 | break; | |
1247 | ||
1248 | default: | |
1249 | gcc_unreachable (); | |
1250 | } | |
1251 | ||
85b5d65a JM |
1252 | gcc_assert ((sfk == sfk_inheriting_constructor) |
1253 | == (inherited_base != NULL_TREE)); | |
1254 | ||
225a6584 GDR |
1255 | /* If that user-written default constructor would satisfy the |
1256 | requirements of a constexpr constructor (7.1.5), the | |
1257 | implicitly-defined default constructor is constexpr. */ | |
1258 | if (constexpr_p) | |
1259 | *constexpr_p = ctor_p; | |
1260 | ||
ac177431 JM |
1261 | move_p = false; |
1262 | switch (sfk) | |
1263 | { | |
1264 | case sfk_constructor: | |
1265 | case sfk_destructor: | |
85b5d65a | 1266 | case sfk_inheriting_constructor: |
ac177431 JM |
1267 | copy_arg_p = false; |
1268 | break; | |
1269 | ||
1270 | case sfk_move_constructor: | |
1271 | case sfk_move_assignment: | |
1272 | move_p = true; | |
1273 | case sfk_copy_constructor: | |
1274 | case sfk_copy_assignment: | |
1275 | copy_arg_p = true; | |
1276 | break; | |
1277 | ||
1278 | default: | |
1279 | gcc_unreachable (); | |
1280 | } | |
1281 | ||
1282 | expected_trivial = type_has_trivial_fn (ctype, sfk); | |
1283 | if (trivial_p) | |
1284 | *trivial_p = expected_trivial; | |
1285 | ||
ac177431 JM |
1286 | /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base |
1287 | class versions and other properties of the type. But a subobject | |
1288 | class can be trivially copyable and yet have overload resolution | |
1289 | choose a template constructor for initialization, depending on | |
eca7fc57 JM |
1290 | rvalueness and cv-quals. And furthermore, a member in a base might |
1291 | be trivial but deleted or otherwise not callable. So we can't exit | |
1292 | early in C++0x. The same considerations apply in C++98/03, but | |
503c8e86 JM |
1293 | there the definition of triviality does not consider overload |
1294 | resolution, so a constructor can be trivial even if it would otherwise | |
1295 | call a non-trivial constructor. */ | |
ac177431 | 1296 | if (expected_trivial |
604b2bfc | 1297 | && (!copy_arg_p || cxx_dialect < cxx11)) |
0930cc0e JM |
1298 | { |
1299 | if (constexpr_p && sfk == sfk_constructor) | |
ab807569 JM |
1300 | { |
1301 | bool cx = trivial_default_constructor_is_constexpr (ctype); | |
1302 | *constexpr_p = cx; | |
1303 | if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE) | |
1304 | /* A trivial constructor doesn't have any NSDMI. */ | |
1305 | inform (input_location, "defaulted default constructor does " | |
1306 | "not initialize any non-static data member"); | |
1307 | } | |
eca7fc57 | 1308 | if (!diag && cxx_dialect < cxx11) |
ab807569 | 1309 | return; |
0930cc0e | 1310 | } |
c8094d83 | 1311 | |
ac177431 JM |
1312 | ++cp_unevaluated_operand; |
1313 | ++c_inhibit_evaluation_warnings; | |
0e69fdf0 | 1314 | push_deferring_access_checks (dk_no_deferred); |
ac177431 JM |
1315 | |
1316 | scope = push_scope (ctype); | |
1317 | ||
85b5d65a JM |
1318 | flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE; |
1319 | if (!inherited_base) | |
1320 | flags |= LOOKUP_DEFAULTED; | |
4b978f96 PC |
1321 | |
1322 | complain = diag ? tf_warning_or_error : tf_none; | |
492b73bd | 1323 | |
ac177431 JM |
1324 | if (const_p) |
1325 | quals = TYPE_QUAL_CONST; | |
1326 | else | |
1327 | quals = TYPE_UNQUALIFIED; | |
1328 | argtype = NULL_TREE; | |
492b73bd | 1329 | |
ac177431 JM |
1330 | for (binfo = TYPE_BINFO (ctype), i = 0; |
1331 | BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) | |
1332 | { | |
1333 | tree basetype = BINFO_TYPE (base_binfo); | |
45ffb6f7 JM |
1334 | |
1335 | if (!assign_p && BINFO_VIRTUAL_P (base_binfo)) | |
1336 | /* We'll handle virtual bases below. */ | |
1337 | continue; | |
1338 | ||
ac177431 JM |
1339 | if (copy_arg_p) |
1340 | argtype = build_stub_type (basetype, quals, move_p); | |
85b5d65a JM |
1341 | else if (basetype == inherited_base) |
1342 | argtype = inherited_parms; | |
ac177431 | 1343 | rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); |
85b5d65a JM |
1344 | if (inherited_base) |
1345 | argtype = NULL_TREE; | |
ac177431 | 1346 | |
f14edc1a JM |
1347 | process_subob_fn (rval, spec_p, trivial_p, deleted_p, |
1348 | constexpr_p, diag, basetype); | |
eca7fc57 | 1349 | if (ctor_p) |
ea76c60a JM |
1350 | { |
1351 | /* In a constructor we also need to check the subobject | |
1352 | destructors for cleanup of partially constructed objects. */ | |
1353 | rval = locate_fn_flags (base_binfo, complete_dtor_identifier, | |
1354 | NULL_TREE, flags, complain); | |
92d0652c | 1355 | /* Note that we don't pass down trivial_p; the subobject |
bb828cc7 JM |
1356 | destructors don't affect triviality of the constructor. Nor |
1357 | do they affect constexpr-ness (a constant expression doesn't | |
1358 | throw) or exception-specification (a throw from one of the | |
1359 | dtors would be a double-fault). */ | |
f14edc1a JM |
1360 | process_subob_fn (rval, NULL, NULL, |
1361 | deleted_p, NULL, false, | |
225a6584 | 1362 | basetype); |
ea76c60a | 1363 | } |
ac177431 JM |
1364 | |
1365 | if (check_vdtor && type_has_virtual_destructor (basetype)) | |
1366 | { | |
1367 | rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR), | |
1368 | ptr_type_node, flags, complain); | |
1369 | /* Unlike for base ctor/op=/dtor, for operator delete it's fine | |
1370 | to have a null rval (no class-specific op delete). */ | |
1371 | if (rval && rval == error_mark_node && deleted_p) | |
1372 | *deleted_p = true; | |
ea76c60a | 1373 | check_vdtor = false; |
ac177431 | 1374 | } |
f14edc1a JM |
1375 | |
1376 | if (diag && assign_p && move_p | |
1377 | && BINFO_VIRTUAL_P (base_binfo) | |
1378 | && rval && TREE_CODE (rval) == FUNCTION_DECL | |
32bfcf80 JM |
1379 | && move_fn_p (rval) && !trivial_fn_p (rval) |
1380 | && vbase_has_user_provided_move_assign (basetype)) | |
f14edc1a JM |
1381 | warning (OPT_Wvirtual_move_assign, |
1382 | "defaulted move assignment for %qT calls a non-trivial " | |
1383 | "move assignment operator for virtual base %qT", | |
1384 | ctype, basetype); | |
ac177431 JM |
1385 | } |
1386 | ||
1387 | vbases = CLASSTYPE_VBASECLASSES (ctype); | |
f344f525 | 1388 | if (vec_safe_is_empty (vbases)) |
45ffb6f7 | 1389 | /* No virtual bases to worry about. */; |
ac177431 | 1390 | else if (!assign_p) |
ac177431 | 1391 | { |
45ffb6f7 | 1392 | if (constexpr_p) |
225a6584 | 1393 | *constexpr_p = false; |
9771b263 | 1394 | FOR_EACH_VEC_ELT (*vbases, i, base_binfo) |
ac177431 | 1395 | { |
ea76c60a | 1396 | tree basetype = BINFO_TYPE (base_binfo); |
57ece258 | 1397 | if (copy_arg_p) |
ea76c60a | 1398 | argtype = build_stub_type (basetype, quals, move_p); |
57ece258 | 1399 | rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain); |
ac177431 | 1400 | |
f14edc1a JM |
1401 | process_subob_fn (rval, spec_p, trivial_p, deleted_p, |
1402 | constexpr_p, diag, basetype); | |
ea76c60a JM |
1403 | if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype)) |
1404 | { | |
1405 | rval = locate_fn_flags (base_binfo, complete_dtor_identifier, | |
1406 | NULL_TREE, flags, complain); | |
f14edc1a JM |
1407 | process_subob_fn (rval, NULL, NULL, |
1408 | deleted_p, NULL, false, | |
225a6584 | 1409 | basetype); |
ea76c60a | 1410 | } |
ac177431 | 1411 | } |
03378143 | 1412 | } |
45ffb6f7 JM |
1413 | |
1414 | /* Now handle the non-static data members. */ | |
57ece258 JM |
1415 | walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals, |
1416 | copy_arg_p, move_p, assign_p, spec_p, trivial_p, | |
f14edc1a | 1417 | deleted_p, constexpr_p, |
45ffb6f7 | 1418 | diag, flags, complain); |
ea76c60a JM |
1419 | if (ctor_p) |
1420 | walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier, | |
1421 | sfk_destructor, TYPE_UNQUALIFIED, false, | |
60b9991b | 1422 | false, false, NULL, NULL, |
92d0652c | 1423 | deleted_p, NULL, |
f14edc1a | 1424 | false, flags, complain); |
ac177431 JM |
1425 | |
1426 | pop_scope (scope); | |
1427 | ||
0e69fdf0 | 1428 | pop_deferring_access_checks (); |
ac177431 JM |
1429 | --cp_unevaluated_operand; |
1430 | --c_inhibit_evaluation_warnings; | |
ac177431 JM |
1431 | } |
1432 | ||
1433 | /* DECL is a deleted function. If it's implicitly deleted, explain why and | |
1434 | return true; else return false. */ | |
1435 | ||
1436 | bool | |
1437 | maybe_explain_implicit_delete (tree decl) | |
1438 | { | |
1439 | /* If decl is a clone, get the primary variant. */ | |
1440 | decl = DECL_ORIGIN (decl); | |
1441 | gcc_assert (DECL_DELETED_FN (decl)); | |
f4842525 | 1442 | if (DECL_DEFAULTED_FN (decl)) |
ac177431 JM |
1443 | { |
1444 | /* Not marked GTY; it doesn't need to be GC'd or written to PCH. */ | |
874d29e5 | 1445 | static struct pointer_set_t *explained; |
ac177431 JM |
1446 | |
1447 | special_function_kind sfk; | |
1448 | location_t loc; | |
1449 | bool informed; | |
1450 | tree ctype; | |
1451 | ||
874d29e5 JM |
1452 | if (!explained) |
1453 | explained = pointer_set_create (); | |
1454 | if (pointer_set_insert (explained, decl)) | |
ac177431 | 1455 | return true; |
ac177431 JM |
1456 | |
1457 | sfk = special_function_p (decl); | |
1458 | ctype = DECL_CONTEXT (decl); | |
1459 | loc = input_location; | |
1460 | input_location = DECL_SOURCE_LOCATION (decl); | |
1461 | ||
1462 | informed = false; | |
1463 | if (LAMBDA_TYPE_P (ctype)) | |
1464 | { | |
1465 | informed = true; | |
1466 | if (sfk == sfk_constructor) | |
a2e70335 JM |
1467 | inform (DECL_SOURCE_LOCATION (decl), |
1468 | "a lambda closure type has a deleted default constructor"); | |
ac177431 | 1469 | else if (sfk == sfk_copy_assignment) |
a2e70335 JM |
1470 | inform (DECL_SOURCE_LOCATION (decl), |
1471 | "a lambda closure type has a deleted copy assignment operator"); | |
ac177431 JM |
1472 | else |
1473 | informed = false; | |
1474 | } | |
a2e70335 JM |
1475 | else if (DECL_ARTIFICIAL (decl) |
1476 | && (sfk == sfk_copy_assignment | |
1477 | || sfk == sfk_copy_constructor) | |
1478 | && (type_has_user_declared_move_constructor (ctype) | |
1479 | || type_has_user_declared_move_assign (ctype))) | |
1480 | { | |
1481 | inform (0, "%q+#D is implicitly declared as deleted because %qT " | |
1482 | "declares a move constructor or move assignment operator", | |
1483 | decl, ctype); | |
1484 | informed = true; | |
1485 | } | |
ac177431 JM |
1486 | if (!informed) |
1487 | { | |
85b5d65a JM |
1488 | tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl); |
1489 | tree parm_type = TREE_VALUE (parms); | |
ac177431 | 1490 | bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); |
e2fbf4c5 JM |
1491 | tree raises = NULL_TREE; |
1492 | bool deleted_p = false; | |
ac177431 | 1493 | tree scope = push_scope (ctype); |
e2fbf4c5 | 1494 | |
ac177431 | 1495 | synthesized_method_walk (ctype, sfk, const_p, |
e2fbf4c5 | 1496 | &raises, NULL, &deleted_p, NULL, false, |
85b5d65a | 1497 | DECL_INHERITED_CTOR_BASE (decl), parms); |
e2fbf4c5 JM |
1498 | if (deleted_p) |
1499 | { | |
1500 | inform (0, "%q+#D is implicitly deleted because the default " | |
1501 | "definition would be ill-formed:", decl); | |
1502 | synthesized_method_walk (ctype, sfk, const_p, | |
1503 | NULL, NULL, NULL, NULL, true, | |
1504 | DECL_INHERITED_CTOR_BASE (decl), parms); | |
1505 | } | |
1506 | else if (!comp_except_specs | |
1507 | (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)), | |
1508 | raises, ce_normal)) | |
1509 | inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly " | |
1510 | "deleted because its exception-specification does not " | |
1511 | "match the implicit exception-specification %qX", | |
1512 | decl, raises); | |
1513 | #ifdef ENABLE_CHECKING | |
1514 | else | |
1515 | gcc_unreachable (); | |
1516 | #endif | |
1517 | ||
1518 | pop_scope (scope); | |
ac177431 JM |
1519 | } |
1520 | ||
1521 | input_location = loc; | |
1522 | return true; | |
1523 | } | |
1524 | return false; | |
03378143 NS |
1525 | } |
1526 | ||
f732fa7b JM |
1527 | /* DECL is a defaulted function which was declared constexpr. Explain why |
1528 | it can't be constexpr. */ | |
1529 | ||
1530 | void | |
1531 | explain_implicit_non_constexpr (tree decl) | |
1532 | { | |
1533 | tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl)); | |
1534 | bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); | |
1535 | bool dummy; | |
1536 | synthesized_method_walk (DECL_CLASS_CONTEXT (decl), | |
1537 | special_function_p (decl), const_p, | |
f14edc1a | 1538 | NULL, NULL, NULL, &dummy, true, |
85b5d65a JM |
1539 | NULL_TREE, NULL_TREE); |
1540 | } | |
1541 | ||
1542 | /* DECL is an instantiation of an inheriting constructor template. Deduce | |
1543 | the correct exception-specification and deletedness for this particular | |
1544 | specialization. */ | |
1545 | ||
1546 | void | |
1547 | deduce_inheriting_ctor (tree decl) | |
1548 | { | |
1549 | gcc_assert (DECL_INHERITED_CTOR_BASE (decl)); | |
1550 | tree spec; | |
f14edc1a | 1551 | bool trivial, constexpr_, deleted; |
85b5d65a JM |
1552 | synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor, |
1553 | false, &spec, &trivial, &deleted, &constexpr_, | |
f14edc1a | 1554 | /*diag*/false, |
85b5d65a JM |
1555 | DECL_INHERITED_CTOR_BASE (decl), |
1556 | FUNCTION_FIRST_USER_PARMTYPE (decl)); | |
1557 | DECL_DELETED_FN (decl) = deleted; | |
1558 | TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec); | |
f732fa7b JM |
1559 | } |
1560 | ||
9eb71d8c MM |
1561 | /* Implicitly declare the special function indicated by KIND, as a |
1562 | member of TYPE. For copy constructors and assignment operators, | |
1563 | CONST_P indicates whether these functions should take a const | |
27d6592c MM |
1564 | reference argument or a non-const reference. Returns the |
1565 | FUNCTION_DECL for the implicitly declared function. */ | |
9eb71d8c | 1566 | |
593a0835 | 1567 | tree |
85b5d65a JM |
1568 | implicitly_declare_fn (special_function_kind kind, tree type, |
1569 | bool const_p, tree inherited_ctor, | |
1570 | tree inherited_parms) | |
9eb71d8c | 1571 | { |
058b15c1 MM |
1572 | tree fn; |
1573 | tree parameter_types = void_list_node; | |
44d10c10 | 1574 | tree return_type; |
058b15c1 | 1575 | tree fn_type; |
03378143 | 1576 | tree raises = empty_except_spec; |
058b15c1 | 1577 | tree rhs_parm_type = NULL_TREE; |
e2537f2c | 1578 | tree this_parm; |
058b15c1 | 1579 | tree name; |
64b2bdb3 | 1580 | HOST_WIDE_INT saved_processing_template_decl; |
ac177431 | 1581 | bool deleted_p; |
225a6584 | 1582 | bool constexpr_p; |
64b2bdb3 | 1583 | |
b2b800a0 | 1584 | /* Because we create declarations for implicitly declared functions |
64b2bdb3 MM |
1585 | lazily, we may be creating the declaration for a member of TYPE |
1586 | while in some completely different context. However, TYPE will | |
1587 | never be a dependent class (because we never want to do lookups | |
1588 | for implicitly defined functions in a dependent class). | |
1589 | Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here | |
1590 | because we only create clones for constructors and destructors | |
1591 | when not in a template. */ | |
1592 | gcc_assert (!dependent_type_p (type)); | |
1593 | saved_processing_template_decl = processing_template_decl; | |
1594 | processing_template_decl = 0; | |
9eb71d8c | 1595 | |
508a1c9c MM |
1596 | type = TYPE_MAIN_VARIANT (type); |
1597 | ||
44d10c10 PB |
1598 | if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type)) |
1599 | { | |
1600 | if (kind == sfk_destructor) | |
1601 | /* See comment in check_special_function_return_type. */ | |
1602 | return_type = build_pointer_type (void_type_node); | |
1603 | else | |
1604 | return_type = build_pointer_type (type); | |
1605 | } | |
1606 | else | |
1607 | return_type = void_type_node; | |
1608 | ||
9eb71d8c MM |
1609 | switch (kind) |
1610 | { | |
9eb71d8c | 1611 | case sfk_destructor: |
03378143 | 1612 | /* Destructor. */ |
058b15c1 | 1613 | name = constructor_name (type); |
9eb71d8c MM |
1614 | break; |
1615 | ||
1616 | case sfk_constructor: | |
1617 | /* Default constructor. */ | |
058b15c1 | 1618 | name = constructor_name (type); |
9eb71d8c MM |
1619 | break; |
1620 | ||
1621 | case sfk_copy_constructor: | |
066ec0a4 | 1622 | case sfk_copy_assignment: |
d5f4eddd | 1623 | case sfk_move_constructor: |
ac177431 | 1624 | case sfk_move_assignment: |
85b5d65a | 1625 | case sfk_inheriting_constructor: |
03378143 | 1626 | { |
ac177431 JM |
1627 | bool move_p; |
1628 | if (kind == sfk_copy_assignment | |
1629 | || kind == sfk_move_assignment) | |
0cbd7506 | 1630 | { |
058b15c1 | 1631 | return_type = build_reference_type (type); |
0cbd7506 | 1632 | name = ansi_assopname (NOP_EXPR); |
0cbd7506 | 1633 | } |
058b15c1 MM |
1634 | else |
1635 | name = constructor_name (type); | |
1636 | ||
85b5d65a JM |
1637 | if (kind == sfk_inheriting_constructor) |
1638 | parameter_types = inherited_parms; | |
058b15c1 | 1639 | else |
85b5d65a JM |
1640 | { |
1641 | if (const_p) | |
1642 | rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST); | |
1643 | else | |
1644 | rhs_parm_type = type; | |
1645 | move_p = (kind == sfk_move_assignment | |
1646 | || kind == sfk_move_constructor); | |
1647 | rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p); | |
ac177431 | 1648 | |
85b5d65a JM |
1649 | parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types); |
1650 | } | |
9eb71d8c | 1651 | break; |
03378143 | 1652 | } |
9eb71d8c | 1653 | default: |
8dc2b103 | 1654 | gcc_unreachable (); |
9eb71d8c MM |
1655 | } |
1656 | ||
85b5d65a JM |
1657 | tree inherited_base = (inherited_ctor |
1658 | ? DECL_CONTEXT (inherited_ctor) | |
1659 | : NULL_TREE); | |
59ddadab MT |
1660 | bool trivial_p = false; |
1661 | ||
85b5d65a JM |
1662 | if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL) |
1663 | { | |
1664 | /* For an inheriting constructor template, just copy these flags from | |
1665 | the inherited constructor template for now. */ | |
1666 | raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor)); | |
c582aac9 PC |
1667 | deleted_p = DECL_DELETED_FN (inherited_ctor); |
1668 | constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor); | |
85b5d65a JM |
1669 | } |
1670 | else | |
1671 | synthesized_method_walk (type, kind, const_p, &raises, &trivial_p, | |
f14edc1a | 1672 | &deleted_p, &constexpr_p, false, |
85b5d65a | 1673 | inherited_base, inherited_parms); |
225a6584 GDR |
1674 | /* Don't bother marking a deleted constructor as constexpr. */ |
1675 | if (deleted_p) | |
1676 | constexpr_p = false; | |
6cfbc023 PC |
1677 | /* A trivial copy/move constructor is also a constexpr constructor, |
1678 | unless the class has virtual bases (7.1.5p4). */ | |
604b2bfc | 1679 | else if (trivial_p && cxx_dialect >= cxx11 |
225a6584 | 1680 | && (kind == sfk_copy_constructor |
6cfbc023 PC |
1681 | || kind == sfk_move_constructor) |
1682 | && !CLASSTYPE_VBASECLASSES (type)) | |
225a6584 | 1683 | gcc_assert (constexpr_p); |
ac177431 JM |
1684 | |
1685 | if (!trivial_p && type_has_trivial_fn (type, kind)) | |
1686 | type_set_nontrivial_flag (type, kind); | |
1687 | ||
058b15c1 MM |
1688 | /* Create the function. */ |
1689 | fn_type = build_method_type_directly (type, return_type, parameter_types); | |
1690 | if (raises) | |
1691 | fn_type = build_exception_variant (fn_type, raises); | |
1692 | fn = build_lang_decl (FUNCTION_DECL, name, fn_type); | |
85b5d65a JM |
1693 | if (kind != sfk_inheriting_constructor) |
1694 | DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type)); | |
d5f4eddd | 1695 | if (kind == sfk_constructor || kind == sfk_copy_constructor |
85b5d65a | 1696 | || kind == sfk_move_constructor || kind == sfk_inheriting_constructor) |
058b15c1 MM |
1697 | DECL_CONSTRUCTOR_P (fn) = 1; |
1698 | else if (kind == sfk_destructor) | |
1699 | DECL_DESTRUCTOR_P (fn) = 1; | |
1700 | else | |
1701 | { | |
1702 | DECL_ASSIGNMENT_OPERATOR_P (fn) = 1; | |
1703 | SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR); | |
1704 | } | |
b21a6ea1 NS |
1705 | |
1706 | /* If pointers to member functions use the least significant bit to | |
1707 | indicate whether a function is virtual, ensure a pointer | |
1708 | to this function will have that bit clear. */ | |
1709 | if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn | |
1710 | && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT) | |
1711 | DECL_ALIGN (fn) = 2 * BITS_PER_UNIT; | |
1712 | ||
e2537f2c | 1713 | /* Create the explicit arguments. */ |
058b15c1 MM |
1714 | if (rhs_parm_type) |
1715 | { | |
1716 | /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we | |
1717 | want its type to be included in the mangled function | |
1718 | name. */ | |
e2c17be0 JM |
1719 | tree decl = cp_build_parm_decl (NULL_TREE, rhs_parm_type); |
1720 | TREE_READONLY (decl) = 1; | |
1721 | retrofit_lang_decl (decl); | |
1722 | DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1; | |
1723 | DECL_ARGUMENTS (fn) = decl; | |
058b15c1 | 1724 | } |
85b5d65a JM |
1725 | else if (kind == sfk_inheriting_constructor) |
1726 | { | |
1727 | tree *p = &DECL_ARGUMENTS (fn); | |
61d1b821 | 1728 | int index = 1; |
85b5d65a JM |
1729 | for (tree parm = inherited_parms; parm != void_list_node; |
1730 | parm = TREE_CHAIN (parm)) | |
1731 | { | |
1732 | *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm)); | |
61d1b821 JM |
1733 | retrofit_lang_decl (*p); |
1734 | DECL_PARM_LEVEL (*p) = 1; | |
1735 | DECL_PARM_INDEX (*p) = index++; | |
85b5d65a JM |
1736 | DECL_CONTEXT (*p) = fn; |
1737 | p = &DECL_CHAIN (*p); | |
1738 | } | |
1739 | SET_DECL_INHERITED_CTOR_BASE (fn, inherited_base); | |
1740 | DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor); | |
1741 | /* A constructor so declared has the same access as the corresponding | |
1742 | constructor in X. */ | |
1743 | TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor); | |
1744 | TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor); | |
1745 | /* Copy constexpr from the inherited constructor even if the | |
1746 | inheriting constructor doesn't satisfy the requirements. */ | |
c582aac9 | 1747 | constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor); |
85b5d65a | 1748 | } |
3db45ab5 | 1749 | /* Add the "this" parameter. */ |
e2537f2c | 1750 | this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED); |
910ad8de | 1751 | DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn); |
e2537f2c | 1752 | DECL_ARGUMENTS (fn) = this_parm; |
9eb71d8c | 1753 | |
e2537f2c | 1754 | grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL); |
4684cd27 | 1755 | set_linkage_according_to_type (type, fn); |
0e6df31e | 1756 | rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof); |
058b15c1 | 1757 | DECL_IN_AGGR_P (fn) = 1; |
c727aa5e | 1758 | DECL_ARTIFICIAL (fn) = 1; |
b87d79e6 | 1759 | DECL_DEFAULTED_FN (fn) = 1; |
604b2bfc | 1760 | if (cxx_dialect >= cxx11) |
225a6584 GDR |
1761 | { |
1762 | DECL_DELETED_FN (fn) = deleted_p; | |
1763 | DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p; | |
1764 | } | |
92caa91a | 1765 | DECL_EXTERNAL (fn) = true; |
9eb71d8c | 1766 | DECL_NOT_REALLY_EXTERN (fn) = 1; |
79065db2 | 1767 | DECL_DECLARED_INLINE_P (fn) = 1; |
8dc2b103 | 1768 | gcc_assert (!TREE_USED (fn)); |
9f4faeae | 1769 | |
64b2bdb3 MM |
1770 | /* Restore PROCESSING_TEMPLATE_DECL. */ |
1771 | processing_template_decl = saved_processing_template_decl; | |
1772 | ||
85b5d65a JM |
1773 | if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL) |
1774 | fn = add_inherited_template_parms (fn, inherited_ctor); | |
1775 | ||
f14edc1a JM |
1776 | /* Warn about calling a non-trivial move assignment in a virtual base. */ |
1777 | if (kind == sfk_move_assignment && !deleted_p && !trivial_p | |
1778 | && CLASSTYPE_VBASECLASSES (type)) | |
1779 | { | |
1780 | location_t loc = input_location; | |
1781 | input_location = DECL_SOURCE_LOCATION (fn); | |
1782 | synthesized_method_walk (type, kind, const_p, | |
1783 | NULL, NULL, NULL, NULL, true, | |
1784 | NULL_TREE, NULL_TREE); | |
1785 | input_location = loc; | |
1786 | } | |
1787 | ||
9eb71d8c MM |
1788 | return fn; |
1789 | } | |
e0fff4b3 | 1790 | |
20f2653e JM |
1791 | /* Gives any errors about defaulted functions which need to be deferred |
1792 | until the containing class is complete. */ | |
1793 | ||
1794 | void | |
1795 | defaulted_late_check (tree fn) | |
1796 | { | |
1797 | /* Complain about invalid signature for defaulted fn. */ | |
1798 | tree ctx = DECL_CONTEXT (fn); | |
1799 | special_function_kind kind = special_function_p (fn); | |
1800 | bool fn_const_p = (copy_fn_p (fn) == 2); | |
85b5d65a JM |
1801 | tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p, |
1802 | NULL, NULL); | |
fc7721ee | 1803 | tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); |
20f2653e JM |
1804 | |
1805 | if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)), | |
1806 | TREE_TYPE (TREE_TYPE (implicit_fn))) | |
1807 | || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), | |
1808 | TYPE_ARG_TYPES (TREE_TYPE (implicit_fn)))) | |
1809 | { | |
1810 | error ("defaulted declaration %q+D", fn); | |
1811 | error_at (DECL_SOURCE_LOCATION (fn), | |
1812 | "does not match expected signature %qD", implicit_fn); | |
1813 | } | |
7c69566f | 1814 | |
fc7721ee PC |
1815 | /* 8.4.2/2: An explicitly-defaulted function (...) may have an explicit |
1816 | exception-specification only if it is compatible (15.4) with the | |
1817 | exception-specification on the implicit declaration. If a function | |
1818 | is explicitly defaulted on its first declaration, (...) it is | |
7c69566f JM |
1819 | implicitly considered to have the same exception-specification as if |
1820 | it had been implicitly declared. */ | |
fc7721ee | 1821 | if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) |
7c69566f | 1822 | { |
fc7721ee PC |
1823 | maybe_instantiate_noexcept (fn); |
1824 | if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)), | |
1825 | eh_spec, ce_normal)) | |
b273cdb1 | 1826 | { |
fc7721ee | 1827 | if (DECL_DEFAULTED_IN_CLASS_P (fn)) |
e2fbf4c5 JM |
1828 | { |
1829 | DECL_DELETED_FN (fn) = true; | |
1830 | eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); | |
1831 | } | |
fc7721ee PC |
1832 | else |
1833 | error ("function %q+D defaulted on its redeclaration " | |
1834 | "with an exception-specification that differs from " | |
1835 | "the implicit declaration %q#D", fn, implicit_fn); | |
b273cdb1 | 1836 | } |
fc7721ee PC |
1837 | } |
1838 | if (DECL_DEFAULTED_IN_CLASS_P (fn)) | |
1839 | TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec); | |
1840 | ||
1841 | if (DECL_DEFAULTED_IN_CLASS_P (fn) | |
1842 | && DECL_DECLARED_CONSTEXPR_P (implicit_fn)) | |
1843 | { | |
1844 | /* Hmm...should we do this for out-of-class too? Should it be OK to | |
1845 | add constexpr later like inline, rather than requiring | |
1846 | declarations to match? */ | |
1847 | DECL_DECLARED_CONSTEXPR_P (fn) = true; | |
1848 | if (kind == sfk_constructor) | |
1849 | TYPE_HAS_CONSTEXPR_CTOR (ctx) = true; | |
225a6584 GDR |
1850 | } |
1851 | ||
1852 | if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn) | |
1853 | && DECL_DECLARED_CONSTEXPR_P (fn)) | |
1854 | { | |
1855 | if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) | |
f732fa7b JM |
1856 | { |
1857 | error ("explicitly defaulted function %q+D cannot be declared " | |
1858 | "as constexpr because the implicit declaration is not " | |
1859 | "constexpr:", fn); | |
1860 | explain_implicit_non_constexpr (fn); | |
1861 | } | |
225a6584 | 1862 | DECL_DECLARED_CONSTEXPR_P (fn) = false; |
7c69566f | 1863 | } |
ac177431 JM |
1864 | |
1865 | if (DECL_DELETED_FN (implicit_fn)) | |
1866 | DECL_DELETED_FN (fn) = 1; | |
20f2653e JM |
1867 | } |
1868 | ||
1869 | /* Returns true iff FN can be explicitly defaulted, and gives any | |
1870 | errors if defaulting FN is ill-formed. */ | |
1871 | ||
1872 | bool | |
1873 | defaultable_fn_check (tree fn) | |
1874 | { | |
1875 | special_function_kind kind = sfk_none; | |
1876 | ||
c454d74a JM |
1877 | if (template_parm_scope_p ()) |
1878 | { | |
1879 | error ("a template cannot be defaulted"); | |
1880 | return false; | |
1881 | } | |
1882 | ||
20f2653e JM |
1883 | if (DECL_CONSTRUCTOR_P (fn)) |
1884 | { | |
1885 | if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node) | |
1886 | kind = sfk_constructor; | |
1887 | else if (copy_fn_p (fn) > 0 | |
1888 | && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn)) | |
1889 | == void_list_node)) | |
1890 | kind = sfk_copy_constructor; | |
1891 | else if (move_fn_p (fn)) | |
1892 | kind = sfk_move_constructor; | |
1893 | } | |
1894 | else if (DECL_DESTRUCTOR_P (fn)) | |
1895 | kind = sfk_destructor; | |
1896 | else if (DECL_ASSIGNMENT_OPERATOR_P (fn) | |
ac177431 JM |
1897 | && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) |
1898 | { | |
1899 | if (copy_fn_p (fn)) | |
1900 | kind = sfk_copy_assignment; | |
1901 | else if (move_fn_p (fn)) | |
1902 | kind = sfk_move_assignment; | |
1903 | } | |
20f2653e JM |
1904 | |
1905 | if (kind == sfk_none) | |
1906 | { | |
1907 | error ("%qD cannot be defaulted", fn); | |
1908 | return false; | |
1909 | } | |
1910 | else | |
1911 | { | |
2ac2f83d PC |
1912 | for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn); |
1913 | t && t != void_list_node; t = TREE_CHAIN (t)) | |
20f2653e JM |
1914 | if (TREE_PURPOSE (t)) |
1915 | { | |
1916 | error ("defaulted function %q+D with default argument", fn); | |
1917 | break; | |
1918 | } | |
2ac2f83d PC |
1919 | |
1920 | /* Avoid do_warn_unused_parameter warnings. */ | |
1921 | for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p)) | |
1922 | if (DECL_NAME (p)) | |
1923 | TREE_NO_WARNING (p) = 1; | |
1924 | ||
20f2653e | 1925 | if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn))) |
5ade176d | 1926 | /* Defer checking. */; |
20f2653e JM |
1927 | else if (!processing_template_decl) |
1928 | defaulted_late_check (fn); | |
1929 | ||
1930 | return true; | |
1931 | } | |
1932 | } | |
1933 | ||
508a1c9c MM |
1934 | /* Add an implicit declaration to TYPE for the kind of function |
1935 | indicated by SFK. Return the FUNCTION_DECL for the new implicit | |
1936 | declaration. */ | |
1937 | ||
1938 | tree | |
1939 | lazily_declare_fn (special_function_kind sfk, tree type) | |
1940 | { | |
1941 | tree fn; | |
ac177431 JM |
1942 | /* Whether or not the argument has a const reference type. */ |
1943 | bool const_p = false; | |
1944 | ||
1945 | switch (sfk) | |
1946 | { | |
1947 | case sfk_constructor: | |
1948 | CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0; | |
1949 | break; | |
1950 | case sfk_copy_constructor: | |
1951 | const_p = TYPE_HAS_CONST_COPY_CTOR (type); | |
1952 | CLASSTYPE_LAZY_COPY_CTOR (type) = 0; | |
1953 | break; | |
1954 | case sfk_move_constructor: | |
1955 | CLASSTYPE_LAZY_MOVE_CTOR (type) = 0; | |
1956 | break; | |
1957 | case sfk_copy_assignment: | |
1958 | const_p = TYPE_HAS_CONST_COPY_ASSIGN (type); | |
1959 | CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0; | |
1960 | break; | |
1961 | case sfk_move_assignment: | |
1962 | CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0; | |
1963 | break; | |
1964 | case sfk_destructor: | |
1965 | CLASSTYPE_LAZY_DESTRUCTOR (type) = 0; | |
1966 | break; | |
1967 | default: | |
1968 | gcc_unreachable (); | |
1969 | } | |
1970 | ||
508a1c9c | 1971 | /* Declare the function. */ |
85b5d65a | 1972 | fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL); |
ac177431 | 1973 | |
a2e70335 JM |
1974 | /* [class.copy]/8 If the class definition declares a move constructor or |
1975 | move assignment operator, the implicitly declared copy constructor is | |
1976 | defined as deleted.... */ | |
1977 | if ((sfk == sfk_copy_assignment | |
1978 | || sfk == sfk_copy_constructor) | |
1979 | && (type_has_user_declared_move_constructor (type) | |
1980 | || type_has_user_declared_move_assign (type))) | |
1981 | DECL_DELETED_FN (fn) = true; | |
1982 | ||
9f4faeae | 1983 | /* A destructor may be virtual. */ |
d1a115f8 | 1984 | if (sfk == sfk_destructor |
ac177431 | 1985 | || sfk == sfk_move_assignment |
066ec0a4 | 1986 | || sfk == sfk_copy_assignment) |
9f4faeae | 1987 | check_for_override (fn, type); |
508a1c9c | 1988 | /* Add it to CLASSTYPE_METHOD_VEC. */ |
b2a9b208 | 1989 | add_method (type, fn, NULL_TREE); |
508a1c9c | 1990 | /* Add it to TYPE_METHODS. */ |
c8094d83 | 1991 | if (sfk == sfk_destructor |
9f4faeae MM |
1992 | && DECL_VIRTUAL_P (fn) |
1993 | && abi_version_at_least (2)) | |
1994 | /* The ABI requires that a virtual destructor go at the end of the | |
1995 | vtable. */ | |
1996 | TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn); | |
1997 | else | |
1998 | { | |
1999 | /* G++ 3.2 put the implicit destructor at the *beginning* of the | |
2000 | TYPE_METHODS list, which cause the destructor to be emitted | |
c8094d83 | 2001 | in an incorrect location in the vtable. */ |
ee18fe39 | 2002 | if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn)) |
b323323f | 2003 | warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant" |
9f4faeae MM |
2004 | "and may change in a future version of GCC due to " |
2005 | "implicit virtual destructor", | |
2006 | type); | |
910ad8de | 2007 | DECL_CHAIN (fn) = TYPE_METHODS (type); |
9f4faeae MM |
2008 | TYPE_METHODS (type) = fn; |
2009 | } | |
508a1c9c | 2010 | maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0); |
ac177431 JM |
2011 | if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) |
2012 | || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) | |
2013 | /* Create appropriate clones. */ | |
2014 | clone_function_decl (fn, /*update_method_vec=*/true); | |
508a1c9c MM |
2015 | |
2016 | return fn; | |
2017 | } | |
2018 | ||
e0fff4b3 JM |
2019 | /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST |
2020 | as there are artificial parms in FN. */ | |
2021 | ||
2022 | tree | |
58f9752a | 2023 | skip_artificial_parms_for (const_tree fn, tree list) |
e0fff4b3 JM |
2024 | { |
2025 | if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) | |
2026 | list = TREE_CHAIN (list); | |
2027 | else | |
2028 | return list; | |
2029 | ||
2030 | if (DECL_HAS_IN_CHARGE_PARM_P (fn)) | |
2031 | list = TREE_CHAIN (list); | |
2032 | if (DECL_HAS_VTT_PARM_P (fn)) | |
2033 | list = TREE_CHAIN (list); | |
2034 | return list; | |
2035 | } | |
89ce1c8f | 2036 | |
94a0dd7b SL |
2037 | /* Given a FUNCTION_DECL FN and a chain LIST, return the number of |
2038 | artificial parms in FN. */ | |
2039 | ||
2040 | int | |
58f9752a | 2041 | num_artificial_parms_for (const_tree fn) |
94a0dd7b SL |
2042 | { |
2043 | int count = 0; | |
2044 | ||
2045 | if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) | |
2046 | count++; | |
2047 | else | |
2048 | return 0; | |
2049 | ||
2050 | if (DECL_HAS_IN_CHARGE_PARM_P (fn)) | |
2051 | count++; | |
2052 | if (DECL_HAS_VTT_PARM_P (fn)) | |
2053 | count++; | |
2054 | return count; | |
2055 | } | |
2056 | ||
2057 | ||
89ce1c8f | 2058 | #include "gt-cp-method.h" |