Branch data Line data Source code
1 : : /* Perform optimizations on tree structure.
2 : : Copyright (C) 1998-2024 Free Software Foundation, Inc.
3 : : Written by Mark Michell (mark@codesourcery.com).
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "target.h"
25 : : #include "cp-tree.h"
26 : : #include "decl.h"
27 : : #include "stringpool.h"
28 : : #include "cgraph.h"
29 : : #include "debug.h"
30 : : #include "tree-inline.h"
31 : : #include "tree-iterator.h"
32 : : #include "attribs.h"
33 : :
34 : : /* Prototypes. */
35 : :
36 : : static void update_cloned_parm (tree, tree, bool);
37 : :
38 : : /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
39 : : or destructor. Update it to ensure that the source-position for
40 : : the cloned parameter matches that for the original, and that the
41 : : debugging generation code will be able to find the original PARM. */
42 : :
43 : : static void
44 : 22243535 : update_cloned_parm (tree parm, tree cloned_parm, bool first)
45 : : {
46 : 22243535 : DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
47 : :
48 : : /* We may have taken its address. */
49 : 22243535 : TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
50 : :
51 : 22243535 : DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);
52 : :
53 : : /* The definition might have different constness. */
54 : 22243535 : TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
55 : :
56 : 22243535 : TREE_USED (cloned_parm) = !first || TREE_USED (parm);
57 : :
58 : : /* The name may have changed from the declaration. */
59 : 22243535 : DECL_NAME (cloned_parm) = DECL_NAME (parm);
60 : 22243535 : DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
61 : 22243535 : TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
62 : :
63 : 22243535 : DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
64 : 22243535 : }
65 : :
66 : : /* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
67 : : properly. */
68 : :
69 : : static tree
70 : 1230837 : cxx_copy_decl (tree decl, copy_body_data *id)
71 : : {
72 : 1230837 : tree copy = copy_decl_no_change (decl, id);
73 : 1230837 : if (VAR_P (decl)
74 : 1142400 : && DECL_HAS_VALUE_EXPR_P (decl)
75 : 36 : && DECL_ARTIFICIAL (decl)
76 : 36 : && DECL_LANG_SPECIFIC (decl)
77 : 1230863 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
78 : : {
79 : 26 : tree expr = DECL_VALUE_EXPR (copy);
80 : 26 : walk_tree (&expr, copy_tree_body_r, id, NULL);
81 : 26 : SET_DECL_VALUE_EXPR (copy, expr);
82 : : }
83 : 1230837 : return copy;
84 : : }
85 : :
86 : : /* FN is a function in High GIMPLE form that has a complete body and no
87 : : CFG. CLONE is a function whose body is to be set to a copy of FN,
88 : : mapping argument declarations according to the ARG_MAP splay_tree. */
89 : :
90 : : static void
91 : 6377003 : clone_body (tree clone, tree fn, void *arg_map)
92 : : {
93 : 6377003 : copy_body_data id;
94 : 6377003 : tree stmts;
95 : :
96 : : /* Clone the body, as if we were making an inline call. But, remap
97 : : the parameters in the callee to the parameters of caller. */
98 : 6377003 : memset (&id, 0, sizeof (id));
99 : 6377003 : id.src_fn = fn;
100 : 6377003 : id.dst_fn = clone;
101 : 6377003 : id.src_cfun = DECL_STRUCT_FUNCTION (fn);
102 : 6377003 : id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
103 : :
104 : 6377003 : id.copy_decl = cxx_copy_decl;
105 : 6377003 : id.transform_call_graph_edges = CB_CGE_DUPLICATE;
106 : 6377003 : id.transform_new_cfg = true;
107 : 6377003 : id.transform_return_to_modify = false;
108 : :
109 : : /* We're not inside any EH region. */
110 : 6377003 : id.eh_lp_nr = 0;
111 : :
112 : 6377003 : stmts = DECL_SAVED_TREE (fn);
113 : 6377003 : walk_tree (&stmts, copy_tree_body_r, &id, NULL);
114 : :
115 : : /* Also remap the initializer of any static variables so that they (in
116 : : particular, any label addresses) correspond to the base variant rather
117 : : than the abstract one. */
118 : 6377003 : if (DECL_NAME (clone) == base_dtor_identifier
119 : 6377003 : || DECL_NAME (clone) == base_ctor_identifier)
120 : : {
121 : 6358909 : unsigned ix;
122 : 6358909 : tree decl;
123 : :
124 : 6360680 : FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
125 : 1172 : walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
126 : : }
127 : :
128 : 6377003 : append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
129 : 6377003 : }
130 : :
131 : : /* DELETE_DTOR is a delete destructor whose body will be built.
132 : : COMPLETE_DTOR is the corresponding complete destructor. */
133 : :
134 : : static void
135 : 250189 : build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
136 : : {
137 : 250189 : tree parm = DECL_ARGUMENTS (delete_dtor);
138 : 250189 : tree virtual_size = cxx_sizeof (current_class_type);
139 : :
140 : : /* Call the delete function. */
141 : 250189 : tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
142 : : virtual_size,
143 : : /*global_p=*/false,
144 : : /*placement=*/NULL_TREE,
145 : : /*alloc_fn=*/NULL_TREE,
146 : : tf_warning_or_error);
147 : :
148 : 250189 : tree op = get_callee_fndecl (call_delete);
149 : 250189 : if (op && DECL_P (op) && destroying_delete_p (op))
150 : : {
151 : : /* The destroying delete will handle calling complete_dtor. */
152 : 3 : add_stmt (call_delete);
153 : : }
154 : : else
155 : : {
156 : : /* Call the corresponding complete destructor. */
157 : 250186 : gcc_assert (complete_dtor);
158 : 250186 : tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
159 : : tf_warning_or_error);
160 : :
161 : : /* Operator delete must be called, whether or not the dtor throws. */
162 : 250186 : add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node,
163 : : call_dtor, call_delete));
164 : : }
165 : :
166 : : /* Return the address of the object.
167 : : ??? How is it useful to return an invalid address? */
168 : 250189 : maybe_return_this ();
169 : 250189 : }
170 : :
171 : : /* Return name of comdat group for complete and base ctor (or dtor)
172 : : that have the same body. If dtor is virtual, deleting dtor goes
173 : : into this comdat group as well. */
174 : :
175 : : static tree
176 : 6104149 : cdtor_comdat_group (tree complete, tree base)
177 : : {
178 : 6104149 : tree complete_name = DECL_ASSEMBLER_NAME (complete);
179 : 6104149 : tree base_name = DECL_ASSEMBLER_NAME (base);
180 : 6104149 : char *grp_name;
181 : 6104149 : const char *p, *q;
182 : 6104149 : bool diff_seen = false;
183 : 6104149 : size_t idx;
184 : 6104149 : gcc_assert (IDENTIFIER_LENGTH (complete_name)
185 : : == IDENTIFIER_LENGTH (base_name));
186 : 6104149 : grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
187 : 6104149 : p = IDENTIFIER_POINTER (complete_name);
188 : 6104149 : q = IDENTIFIER_POINTER (base_name);
189 : 358209079 : for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
190 : 352104930 : if (p[idx] == q[idx])
191 : 346000781 : grp_name[idx] = p[idx];
192 : : else
193 : : {
194 : 6104149 : gcc_assert (!diff_seen
195 : : && idx > 0
196 : : && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
197 : : || p[idx - 1] == 'I')
198 : : && p[idx] == '1'
199 : : && q[idx] == '2');
200 : 6104149 : grp_name[idx] = '5';
201 : 6104149 : diff_seen = true;
202 : : }
203 : 6104149 : grp_name[idx] = '\0';
204 : 6104149 : gcc_assert (diff_seen);
205 : 6104149 : return get_identifier (grp_name);
206 : : }
207 : :
208 : : /* Returns true iff we can make the base and complete [cd]tor aliases of
209 : : the same symbol rather than separate functions. */
210 : :
211 : : static bool
212 : 6359242 : can_alias_cdtor (tree fn)
213 : : {
214 : : /* If aliases aren't supported by the assembler, fail. */
215 : 6359242 : if (!TARGET_SUPPORTS_ALIASES)
216 : : return false;
217 : :
218 : : /* We can't use an alias if there are virtual bases. */
219 : 6359242 : if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
220 : : return false;
221 : 6340833 : gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
222 : : /* Don't use aliases for weak/linkonce definitions unless we can put both
223 : : symbols in the same COMDAT group. */
224 : 6340833 : return (DECL_WEAK (fn) ? (HAVE_COMDAT_GROUP && DECL_ONE_ONLY (fn))
225 : 236958 : : (DECL_INTERFACE_KNOWN (fn) && !DECL_ONE_ONLY (fn)));
226 : : }
227 : :
228 : : /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
229 : : with pointers to the base, complete, and deleting variants. */
230 : :
231 : : static void
232 : 6359560 : populate_clone_array (tree fn, tree *fns)
233 : : {
234 : 6359560 : tree clone;
235 : :
236 : 6359560 : fns[0] = NULL_TREE;
237 : 6359560 : fns[1] = NULL_TREE;
238 : 6359560 : fns[2] = NULL_TREE;
239 : :
240 : 19328884 : FOR_EACH_CLONE (clone, fn)
241 : 12969324 : if (DECL_NAME (clone) == complete_dtor_identifier
242 : 12969324 : || DECL_NAME (clone) == complete_ctor_identifier)
243 : 6359543 : fns[1] = clone;
244 : 6609781 : else if (DECL_NAME (clone) == base_dtor_identifier
245 : 6609781 : || DECL_NAME (clone) == base_ctor_identifier)
246 : 6359543 : fns[0] = clone;
247 : 250238 : else if (DECL_NAME (clone) == deleting_dtor_identifier)
248 : 250238 : fns[2] = clone;
249 : : else
250 : 0 : gcc_unreachable ();
251 : 6359560 : }
252 : :
253 : : /* FN is a constructor or destructor, and there are FUNCTION_DECLs
254 : : cloned from it nearby. Instead of cloning this body, leave it
255 : : alone and create tiny one-call bodies for the cloned
256 : : FUNCTION_DECLs. These clones are sibcall candidates, and their
257 : : resulting code will be very thunk-esque. */
258 : :
259 : : static bool
260 : 18421 : maybe_thunk_body (tree fn, bool force)
261 : : {
262 : 18421 : tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
263 : 18421 : tree last_arg, modify, *args;
264 : 18421 : int parmno, vtt_parmno, max_parms;
265 : 18421 : tree fns[3];
266 : :
267 : 18421 : if (!force && !flag_declone_ctor_dtor)
268 : : return 0;
269 : :
270 : : /* If function accepts variable arguments, give up. */
271 : 318 : last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
272 : 318 : if (last_arg != void_list_node)
273 : : return 0;
274 : :
275 : : /* If we got this far, we've decided to turn the clones into thunks. */
276 : :
277 : : /* We're going to generate code for fn, so it is no longer "abstract."
278 : : Also make the unified ctor/dtor private to either the translation unit
279 : : (for non-vague linkage ctors) or the COMDAT group (otherwise). */
280 : :
281 : 318 : populate_clone_array (fn, fns);
282 : :
283 : : /* Can happen during error recovery (c++/71464). */
284 : 318 : if (!fns[0] || !fns[1])
285 : : return 0;
286 : :
287 : : /* Don't use thunks if the base clone omits inherited parameters. */
288 : 317 : if (ctor_omit_inherited_parms (fns[0]))
289 : : return 0;
290 : :
291 : : /* Don't diagnose deprecated or unavailable cdtors just because they
292 : : have thunks emitted for them. */
293 : 317 : auto du = make_temp_override (deprecated_state,
294 : 317 : UNAVAILABLE_DEPRECATED_SUPPRESS);
295 : :
296 : 317 : DECL_ABSTRACT_P (fn) = false;
297 : 317 : if (!DECL_WEAK (fn))
298 : : {
299 : 37 : TREE_PUBLIC (fn) = false;
300 : 37 : DECL_EXTERNAL (fn) = false;
301 : 37 : DECL_INTERFACE_KNOWN (fn) = true;
302 : : }
303 : 280 : else if (HAVE_COMDAT_GROUP)
304 : : {
305 : : /* At eof, defer creation of mangling aliases temporarily. */
306 : 280 : bool save_defer_mangling_aliases = defer_mangling_aliases;
307 : 280 : defer_mangling_aliases = true;
308 : 280 : tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
309 : 280 : defer_mangling_aliases = save_defer_mangling_aliases;
310 : 280 : cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
311 : 280 : cgraph_node::get_create (fns[1])->add_to_same_comdat_group
312 : 280 : (cgraph_node::get_create (fns[0]));
313 : 280 : symtab_node::get (fn)->add_to_same_comdat_group
314 : 280 : (symtab_node::get (fns[0]));
315 : 280 : if (fns[2])
316 : : /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
317 : : virtual, it goes into the same comdat group as well. */
318 : 36 : cgraph_node::get_create (fns[2])->add_to_same_comdat_group
319 : 36 : (symtab_node::get (fns[0]));
320 : : /* Emit them now that the thunks are same comdat group aliases. */
321 : 280 : if (!save_defer_mangling_aliases)
322 : 0 : generate_mangling_aliases ();
323 : 280 : TREE_PUBLIC (fn) = false;
324 : 280 : DECL_EXTERNAL (fn) = false;
325 : 280 : DECL_INTERFACE_KNOWN (fn) = true;
326 : : /* function_and_variable_visibility doesn't want !PUBLIC decls to
327 : : have these flags set. */
328 : 280 : DECL_WEAK (fn) = false;
329 : 280 : DECL_COMDAT (fn) = false;
330 : : }
331 : :
332 : : /* Find the vtt_parm, if present. */
333 : 317 : for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
334 : 951 : fn_parm;
335 : 634 : ++parmno, fn_parm = TREE_CHAIN (fn_parm))
336 : : {
337 : 951 : if (DECL_ARTIFICIAL (fn_parm)
338 : 951 : && DECL_NAME (fn_parm) == vtt_parm_identifier)
339 : : {
340 : : /* Compensate for removed in_charge parameter. */
341 : : vtt_parmno = parmno;
342 : : break;
343 : : }
344 : : }
345 : :
346 : : /* Allocate an argument buffer for build_cxx_call().
347 : : Make sure it is large enough for any of the clones. */
348 : 317 : max_parms = 0;
349 : 1000 : FOR_EACH_CLONE (clone, fn)
350 : : {
351 : 683 : int length = list_length (DECL_ARGUMENTS (fn));
352 : 683 : if (length > max_parms)
353 : : max_parms = length;
354 : : }
355 : 317 : args = XALLOCAVEC (tree, max_parms);
356 : :
357 : : /* We know that any clones immediately follow FN in TYPE_FIELDS. */
358 : 1000 : FOR_EACH_CLONE (clone, fn)
359 : : {
360 : 683 : tree clone_parm;
361 : :
362 : : /* If we've already generated a body for this clone, avoid
363 : : duplicating it. (Is it possible for a clone-list to grow after we
364 : : first see it?) */
365 : 683 : if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
366 : 0 : continue;
367 : :
368 : : /* Start processing the function. */
369 : 683 : start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
370 : :
371 : 683 : if (clone == fns[2])
372 : : {
373 : 98 : for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
374 : 49 : clone_parm = TREE_CHAIN (clone_parm))
375 : 49 : DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
376 : : /* Build the delete destructor by calling complete destructor and
377 : : delete function. */
378 : 49 : build_delete_destructor_body (clone, fns[1]);
379 : : }
380 : : else
381 : : {
382 : : /* Walk parameter lists together, creating parameter list for
383 : : call to original function. */
384 : 634 : for (parmno = 0,
385 : 634 : fn_parm = DECL_ARGUMENTS (fn),
386 : 634 : fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
387 : 634 : clone_parm = DECL_ARGUMENTS (clone);
388 : 2564 : fn_parm;
389 : 1930 : ++parmno,
390 : 1930 : fn_parm = TREE_CHAIN (fn_parm))
391 : : {
392 : 1930 : if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
393 : : {
394 : 317 : gcc_assert (fn_parm_typelist);
395 : : /* Clobber argument with formal parameter type. */
396 : 634 : args[parmno]
397 : 317 : = convert (TREE_VALUE (fn_parm_typelist),
398 : : null_pointer_node);
399 : : }
400 : 1613 : else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
401 : : {
402 : 634 : tree in_charge
403 : 634 : = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
404 : 634 : args[parmno] = in_charge;
405 : : }
406 : : /* Map other parameters to their equivalents in the cloned
407 : : function. */
408 : : else
409 : : {
410 : 979 : gcc_assert (clone_parm);
411 : 979 : DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
412 : 979 : args[parmno] = clone_parm;
413 : : /* Clear TREE_ADDRESSABLE on thunk arguments. */
414 : 979 : TREE_ADDRESSABLE (clone_parm) = 0;
415 : 979 : clone_parm = TREE_CHAIN (clone_parm);
416 : : }
417 : 1930 : if (fn_parm_typelist)
418 : 1930 : fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
419 : : }
420 : :
421 : : /* We built this list backwards; fix now. */
422 : 634 : mark_used (fn);
423 : 634 : call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
424 : : /* Arguments passed to the thunk by invisible reference should
425 : : be transmitted to the callee unchanged. Do not create a
426 : : temporary and invoke the copy constructor. The thunking
427 : : transformation must not introduce any constructor calls. */
428 : 634 : CALL_FROM_THUNK_P (call) = 1;
429 : 634 : block = make_node (BLOCK);
430 : 634 : if (targetm.cxx.cdtor_returns_this ())
431 : : {
432 : 0 : clone_result = DECL_RESULT (clone);
433 : 0 : modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
434 : : clone_result, call);
435 : 0 : modify = build1 (RETURN_EXPR, void_type_node, modify);
436 : 0 : add_stmt (modify);
437 : : }
438 : : else
439 : : {
440 : 634 : add_stmt (call);
441 : : }
442 : 634 : bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
443 : 634 : block, cur_stmt_list);
444 : 634 : DECL_SAVED_TREE (clone) = push_stmt_list ();
445 : 634 : add_stmt (bind);
446 : : }
447 : :
448 : 683 : DECL_ABSTRACT_ORIGIN (clone) = NULL;
449 : 683 : expand_or_defer_fn (finish_function (/*inline_p=*/false));
450 : : }
451 : 317 : return 1;
452 : 317 : }
453 : :
454 : : /* Copy most attributes from ATTRS, omitting attributes that can really only
455 : : apply to a single decl. */
456 : :
457 : : tree
458 : 13210463 : clone_attrs (tree attrs)
459 : : {
460 : 13210463 : tree new_attrs = NULL_TREE;
461 : 13210463 : tree *p = &new_attrs;
462 : :
463 : 14181248 : for (tree a = attrs; a; a = TREE_CHAIN (a))
464 : : {
465 : 970785 : tree aname = get_attribute_name (a);
466 : 970785 : if (is_attribute_namespace_p ("", a)
467 : 970785 : && (is_attribute_p ("alias", aname)
468 : 970785 : || is_attribute_p ("ifunc", aname)))
469 : 0 : continue;
470 : 970785 : *p = copy_node (a);
471 : 970785 : p = &TREE_CHAIN (*p);
472 : : }
473 : 13210463 : *p = NULL_TREE;
474 : 13210463 : return new_attrs;
475 : : }
476 : :
477 : : /* FN is a function that has a complete body. Clone the body as
478 : : necessary. Returns nonzero if there's no longer any need to
479 : : process the main body. */
480 : :
481 : : bool
482 : 52100255 : maybe_clone_body (tree fn)
483 : : {
484 : 52100255 : tree comdat_group = NULL_TREE;
485 : 52100255 : tree clone;
486 : 52100255 : tree fns[3];
487 : 52100255 : bool first = true;
488 : 52100255 : int idx;
489 : 52100255 : bool need_alias = false;
490 : :
491 : : /* We only clone constructors and destructors. */
492 : 52100255 : if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
493 : : return 0;
494 : :
495 : 6359242 : populate_clone_array (fn, fns);
496 : :
497 : : /* Remember if we can't have multiple clones for some reason. We need to
498 : : check this before we remap local static initializers in clone_body. */
499 : 6359242 : if (!tree_versionable_function_p (fn))
500 : 76 : need_alias = true;
501 : :
502 : : /* We know that any clones immediately follow FN in the TYPE_FIELDS
503 : : list. */
504 : 6359242 : push_to_top_level ();
505 : 25436968 : for (idx = 0; idx < 3; idx++)
506 : : {
507 : 19077726 : tree parm;
508 : 19077726 : tree clone_parm;
509 : :
510 : 19077726 : clone = fns[idx];
511 : 19077726 : if (!clone)
512 : 6109085 : continue;
513 : :
514 : : /* Update CLONE's source position information to match FN's. */
515 : 12968641 : DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
516 : 12968641 : DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
517 : 12968641 : DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
518 : 12968641 : DECL_COMDAT (clone) = DECL_COMDAT (fn);
519 : 12968641 : DECL_WEAK (clone) = DECL_WEAK (fn);
520 : :
521 : : /* We don't copy the comdat group from fn to clone because the assembler
522 : : name of fn was corrupted by write_mangled_name by adding *INTERNAL*
523 : : to it. By doing so, it also corrupted the comdat group. */
524 : 12968641 : if (DECL_ONE_ONLY (fn))
525 : 12454738 : cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
526 : 12968641 : DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
527 : 12968641 : DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
528 : 12968641 : DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
529 : 12968641 : DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
530 : 12968641 : TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
531 : 12968641 : DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
532 : 12968641 : DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
533 : 12968641 : DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
534 : 12968641 : DECL_ATTRIBUTES (clone) = clone_attrs (DECL_ATTRIBUTES (fn));
535 : 12968641 : DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
536 : 12968641 : set_decl_section_name (clone, fn);
537 : :
538 : : /* Adjust the parameter names and locations. */
539 : 12968641 : parm = DECL_ARGUMENTS (fn);
540 : 12968641 : clone_parm = DECL_ARGUMENTS (clone);
541 : : /* Update the `this' parameter, which is always first. */
542 : 12968641 : update_cloned_parm (parm, clone_parm, first);
543 : 12968641 : parm = DECL_CHAIN (parm);
544 : 12968641 : clone_parm = DECL_CHAIN (clone_parm);
545 : 12968641 : if (DECL_HAS_IN_CHARGE_PARM_P (fn))
546 : 44032 : parm = DECL_CHAIN (parm);
547 : 12968641 : if (DECL_HAS_VTT_PARM_P (fn))
548 : 44032 : parm = DECL_CHAIN (parm);
549 : 12968641 : if (DECL_HAS_VTT_PARM_P (clone))
550 : 18399 : clone_parm = DECL_CHAIN (clone_parm);
551 : 22243535 : for (; parm && clone_parm;
552 : 9274894 : parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
553 : : /* Update this parameter. */
554 : 9274894 : update_cloned_parm (parm, clone_parm, first);
555 : : }
556 : :
557 : 6359242 : bool can_alias = can_alias_cdtor (fn);
558 : :
559 : : /* If we decide to turn clones into thunks, they will branch to fn.
560 : : Must have original function available to call. */
561 : 6359242 : if (!can_alias && maybe_thunk_body (fn, need_alias))
562 : : {
563 : 317 : pop_from_top_level ();
564 : : /* We still need to emit the original function. */
565 : 317 : return 0;
566 : : }
567 : :
568 : : /* Emit the DWARF1 abstract instance. */
569 : 6358925 : (*debug_hooks->deferred_inline_function) (fn);
570 : :
571 : : /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
572 : 25435700 : for (idx = 0; idx < 3; idx++)
573 : : {
574 : 19076775 : tree parm;
575 : 19076775 : tree clone_parm;
576 : 19076775 : int parmno;
577 : 19076775 : hash_map<tree, tree> *decl_map;
578 : 19076775 : bool alias = false;
579 : :
580 : 19076775 : clone = fns[idx];
581 : 19076775 : if (!clone)
582 : 6108817 : continue;
583 : :
584 : : /* Start processing the function. */
585 : 12967958 : start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
586 : :
587 : : /* Tell cgraph if both ctors or both dtors are known to have
588 : : the same body. */
589 : 12967958 : if (can_alias
590 : 12924585 : && fns[0]
591 : 12924585 : && idx == 1
592 : 25649588 : && cgraph_node::get_create (fns[0])->create_same_body_alias
593 : 6340815 : (clone, fns[0]))
594 : : {
595 : 6340815 : alias = true;
596 : 6340815 : if (DECL_ONE_ONLY (fns[0]))
597 : : {
598 : : /* For comdat base and complete cdtors put them
599 : : into the same, *[CD]5* comdat group instead of
600 : : *[CD][12]*. */
601 : 6103869 : comdat_group = cdtor_comdat_group (fns[1], fns[0]);
602 : 6103869 : cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
603 : 6103869 : if (symtab_node::get (clone)->same_comdat_group)
604 : 3027221 : symtab_node::get (clone)->remove_from_same_comdat_group ();
605 : 6103869 : symtab_node::get (clone)->add_to_same_comdat_group
606 : 6103869 : (symtab_node::get (fns[0]));
607 : : }
608 : : }
609 : :
610 : : /* Build the delete destructor by calling complete destructor
611 : : and delete function. */
612 : 12967958 : if (idx == 2)
613 : : {
614 : 250140 : build_delete_destructor_body (clone, fns[1]);
615 : : /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
616 : : virtual, it goes into the same comdat group as well. */
617 : 250140 : if (comdat_group)
618 : 235526 : cgraph_node::get_create (clone)->add_to_same_comdat_group
619 : 235526 : (symtab_node::get (fns[0]));
620 : : }
621 : 12717818 : else if (alias)
622 : : /* No need to populate body. */ ;
623 : : else
624 : : {
625 : : /* If we can't have multiple copies of FN (say, because there's a
626 : : static local initialized with the address of a label), we need
627 : : to use an alias for the complete variant. */
628 : 6377003 : if (idx == 1 && need_alias)
629 : : {
630 : 0 : if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
631 : 0 : sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
632 : : else
633 : 0 : sorry ("making multiple clones of %qD", fn);
634 : : }
635 : :
636 : : /* Remap the parameters. */
637 : 6377003 : decl_map = new hash_map<tree, tree>;
638 : 6377003 : for (parmno = 0,
639 : 6377003 : parm = DECL_ARGUMENTS (fn),
640 : 6377003 : clone_parm = DECL_ARGUMENTS (clone);
641 : 17466967 : parm;
642 : 11089964 : ++parmno,
643 : 11089964 : parm = DECL_CHAIN (parm))
644 : : {
645 : : /* Map the in-charge parameter to an appropriate constant. */
646 : 11089964 : if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
647 : : {
648 : 36164 : tree in_charge;
649 : 36164 : in_charge = in_charge_arg_for_name (DECL_NAME (clone));
650 : 36164 : decl_map->put (parm, in_charge);
651 : : }
652 : 11053800 : else if (DECL_ARTIFICIAL (parm)
653 : 11053800 : && DECL_NAME (parm) == vtt_parm_identifier)
654 : : {
655 : : /* For a subobject constructor or destructor, the next
656 : : argument is the VTT parameter. Remap the VTT_PARM
657 : : from the CLONE to this parameter. */
658 : 36164 : if (DECL_HAS_VTT_PARM_P (clone))
659 : : {
660 : 18082 : DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
661 : 18082 : decl_map->put (parm, clone_parm);
662 : 18082 : clone_parm = DECL_CHAIN (clone_parm);
663 : : }
664 : : /* Otherwise, map the VTT parameter to `NULL'. */
665 : : else
666 : : {
667 : 18082 : tree t
668 : 18082 : = fold_convert (TREE_TYPE (parm), null_pointer_node);
669 : 18082 : decl_map->put (parm, t);
670 : : }
671 : : }
672 : : /* Map other parameters to their equivalents in the cloned
673 : : function. */
674 : : else
675 : : {
676 : 11017636 : tree replacement;
677 : 11017636 : if (clone_parm)
678 : : {
679 : 11017600 : replacement = clone_parm;
680 : 11017600 : clone_parm = DECL_CHAIN (clone_parm);
681 : : }
682 : : else
683 : : {
684 : : /* Inheriting ctors can omit parameters from the base
685 : : clone. Replace them with null lvalues. */
686 : 36 : tree reftype = build_reference_type (TREE_TYPE (parm));
687 : 36 : replacement = fold_convert (reftype, null_pointer_node);
688 : 36 : replacement = convert_from_reference (replacement);
689 : : }
690 : 11017636 : decl_map->put (parm, replacement);
691 : : }
692 : : }
693 : :
694 : 6377003 : if (targetm.cxx.cdtor_returns_this ())
695 : : {
696 : 0 : parm = DECL_RESULT (fn);
697 : 0 : clone_parm = DECL_RESULT (clone);
698 : 0 : decl_map->put (parm, clone_parm);
699 : : }
700 : :
701 : : /* Clone the body. */
702 : 6377003 : clone_body (clone, fn, decl_map);
703 : :
704 : : /* Clean up. */
705 : 6377003 : delete decl_map;
706 : : }
707 : :
708 : : /* The clone can throw iff the original function can throw. */
709 : 12967958 : cp_function_chain->can_throw = !TREE_NOTHROW (fn);
710 : :
711 : : /* Now, expand this function into RTL, if appropriate. */
712 : 12967958 : finish_function (/*inline_p=*/false);
713 : 12967958 : BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
714 : 12967958 : if (alias)
715 : : {
716 : 6340815 : if (expand_or_defer_fn_1 (clone))
717 : 6340020 : emit_associated_thunks (clone);
718 : : /* We didn't generate a body, so remove the empty one. */
719 : 6340815 : DECL_SAVED_TREE (clone) = void_node;
720 : : }
721 : : else
722 : 6627143 : expand_or_defer_fn (clone);
723 : 12967958 : first = false;
724 : : }
725 : 6358925 : pop_from_top_level ();
726 : :
727 : : /* We don't need to process the original function any further. */
728 : 6358925 : return 1;
729 : : }
|