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