]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cp/optimize.c
genattrtab.c (write_header): Include hash-set.h...
[thirdparty/gcc.git] / gcc / cp / optimize.c
1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2015 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 "tm.h"
25 #include "hash-set.h"
26 #include "machmode.h"
27 #include "vec.h"
28 #include "double-int.h"
29 #include "input.h"
30 #include "alias.h"
31 #include "symtab.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "stringpool.h"
36 #include "cp-tree.h"
37 #include "input.h"
38 #include "params.h"
39 #include "hashtab.h"
40 #include "target.h"
41 #include "debug.h"
42 #include "tree-inline.h"
43 #include "flags.h"
44 #include "langhooks.h"
45 #include "diagnostic-core.h"
46 #include "dumpfile.h"
47 #include "tree-iterator.h"
48 #include "hash-map.h"
49 #include "is-a.h"
50 #include "plugin-api.h"
51 #include "hard-reg-set.h"
52 #include "function.h"
53 #include "ipa-ref.h"
54 #include "cgraph.h"
55
56 /* Prototypes. */
57
58 static void update_cloned_parm (tree, tree, bool);
59
60 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
61 or destructor. Update it to ensure that the source-position for
62 the cloned parameter matches that for the original, and that the
63 debugging generation code will be able to find the original PARM. */
64
65 static void
66 update_cloned_parm (tree parm, tree cloned_parm, bool first)
67 {
68 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
69
70 /* We may have taken its address. */
71 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
72
73 /* The definition might have different constness. */
74 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
75
76 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
77
78 /* The name may have changed from the declaration. */
79 DECL_NAME (cloned_parm) = DECL_NAME (parm);
80 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
81 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
82
83 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
84 }
85
86
87 /* FN is a function in High GIMPLE form that has a complete body and no
88 CFG. CLONE is a function whose body is to be set to a copy of FN,
89 mapping argument declarations according to the ARG_MAP splay_tree. */
90
91 static void
92 clone_body (tree clone, tree fn, void *arg_map)
93 {
94 copy_body_data id;
95 tree stmts;
96
97 /* Clone the body, as if we were making an inline call. But, remap
98 the parameters in the callee to the parameters of caller. */
99 memset (&id, 0, sizeof (id));
100 id.src_fn = fn;
101 id.dst_fn = clone;
102 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
103 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
104
105 id.copy_decl = copy_decl_no_change;
106 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
107 id.transform_new_cfg = true;
108 id.transform_return_to_modify = false;
109 id.transform_lang_insert_block = NULL;
110
111 /* We're not inside any EH region. */
112 id.eh_lp_nr = 0;
113
114 stmts = DECL_SAVED_TREE (fn);
115 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
116
117 /* Also remap the initializer of any static variables so that they (in
118 particular, any label addresses) correspond to the base variant rather
119 than the abstract one. */
120 if (DECL_NAME (clone) == base_dtor_identifier
121 || DECL_NAME (clone) == base_ctor_identifier)
122 {
123 unsigned ix;
124 tree decl;
125
126 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
127 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
128 }
129
130 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
131 }
132
133 /* DELETE_DTOR is a delete destructor whose body will be built.
134 COMPLETE_DTOR is the corresponding complete destructor. */
135
136 static void
137 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
138 {
139 tree call_dtor, call_delete;
140 tree parm = DECL_ARGUMENTS (delete_dtor);
141 tree virtual_size = cxx_sizeof (current_class_type);
142
143 /* Call the corresponding complete destructor. */
144 gcc_assert (complete_dtor);
145 call_dtor = build_cxx_call (complete_dtor, 1, &parm,
146 tf_warning_or_error);
147 add_stmt (call_dtor);
148
149 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
150
151 /* Call the delete function. */
152 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
153 virtual_size,
154 /*global_p=*/false,
155 /*placement=*/NULL_TREE,
156 /*alloc_fn=*/NULL_TREE,
157 tf_warning_or_error);
158 add_stmt (call_delete);
159
160 /* Return the address of the object. */
161 if (targetm.cxx.cdtor_returns_this ())
162 {
163 tree val = DECL_ARGUMENTS (delete_dtor);
164 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
165 DECL_RESULT (delete_dtor), val);
166 add_stmt (build_stmt (0, RETURN_EXPR, val));
167 }
168 }
169
170 /* Return name of comdat group for complete and base ctor (or dtor)
171 that have the same body. If dtor is virtual, deleting dtor goes
172 into this comdat group as well. */
173
174 static tree
175 cdtor_comdat_group (tree complete, tree base)
176 {
177 tree complete_name = DECL_ASSEMBLER_NAME (complete);
178 tree base_name = DECL_ASSEMBLER_NAME (base);
179 char *grp_name;
180 const char *p, *q;
181 bool diff_seen = false;
182 size_t idx;
183 gcc_assert (IDENTIFIER_LENGTH (complete_name)
184 == IDENTIFIER_LENGTH (base_name));
185 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
186 p = IDENTIFIER_POINTER (complete_name);
187 q = IDENTIFIER_POINTER (base_name);
188 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
189 if (p[idx] == q[idx])
190 grp_name[idx] = p[idx];
191 else
192 {
193 gcc_assert (!diff_seen
194 && idx > 0
195 && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
196 && p[idx] == '1'
197 && q[idx] == '2');
198 grp_name[idx] = '5';
199 diff_seen = true;
200 }
201 grp_name[idx] = '\0';
202 gcc_assert (diff_seen);
203 return get_identifier (grp_name);
204 }
205
206 /* Returns true iff we can make the base and complete [cd]tor aliases of
207 the same symbol rather than separate functions. */
208
209 static bool
210 can_alias_cdtor (tree fn)
211 {
212 #ifndef ASM_OUTPUT_DEF
213 /* If aliases aren't supported by the assembler, fail. */
214 return false;
215 #endif
216 /* We can't use an alias if there are virtual bases. */
217 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
218 return false;
219 /* ??? Why not use aliases with -frepo? */
220 if (flag_use_repository)
221 return false;
222 gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
223 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
224 /* Don't use aliases for weak/linkonce definitions unless we can put both
225 symbols in the same COMDAT group. */
226 return (DECL_INTERFACE_KNOWN (fn)
227 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
228 && (!DECL_ONE_ONLY (fn)
229 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
230 }
231
232 /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
233 with pointers to the base, complete, and deleting variants. */
234
235 static void
236 populate_clone_array (tree fn, tree *fns)
237 {
238 tree clone;
239
240 fns[0] = NULL_TREE;
241 fns[1] = NULL_TREE;
242 fns[2] = NULL_TREE;
243
244 /* Look for the complete destructor which may be used to build the
245 delete destructor. */
246 FOR_EACH_CLONE (clone, fn)
247 if (DECL_NAME (clone) == complete_dtor_identifier
248 || DECL_NAME (clone) == complete_ctor_identifier)
249 fns[1] = clone;
250 else if (DECL_NAME (clone) == base_dtor_identifier
251 || DECL_NAME (clone) == base_ctor_identifier)
252 fns[0] = clone;
253 else if (DECL_NAME (clone) == deleting_dtor_identifier)
254 fns[2] = clone;
255 else
256 gcc_unreachable ();
257 }
258
259 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
260 cloned from it nearby. Instead of cloning this body, leave it
261 alone and create tiny one-call bodies for the cloned
262 FUNCTION_DECLs. These clones are sibcall candidates, and their
263 resulting code will be very thunk-esque. */
264
265 static bool
266 maybe_thunk_body (tree fn, bool force)
267 {
268 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
269 tree last_arg, modify, *args;
270 int parmno, vtt_parmno, max_parms;
271 tree fns[3];
272
273 if (!force && !flag_declone_ctor_dtor)
274 return 0;
275
276 /* If function accepts variable arguments, give up. */
277 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
278 if (last_arg != void_list_node)
279 return 0;
280
281 /* If we got this far, we've decided to turn the clones into thunks. */
282
283 /* We're going to generate code for fn, so it is no longer "abstract."
284 Also make the unified ctor/dtor private to either the translation unit
285 (for non-vague linkage ctors) or the COMDAT group (otherwise). */
286
287 populate_clone_array (fn, fns);
288 DECL_ABSTRACT_P (fn) = false;
289 if (!DECL_WEAK (fn))
290 {
291 TREE_PUBLIC (fn) = false;
292 DECL_EXTERNAL (fn) = false;
293 DECL_INTERFACE_KNOWN (fn) = true;
294 }
295 else if (HAVE_COMDAT_GROUP)
296 {
297 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
298 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
299 cgraph_node::get_create (fns[1])->add_to_same_comdat_group
300 (cgraph_node::get_create (fns[0]));
301 symtab_node::get (fn)->add_to_same_comdat_group
302 (symtab_node::get (fns[0]));
303 if (fns[2])
304 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
305 virtual, it goes into the same comdat group as well. */
306 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
307 (symtab_node::get (fns[0]));
308 TREE_PUBLIC (fn) = false;
309 DECL_EXTERNAL (fn) = false;
310 DECL_INTERFACE_KNOWN (fn) = true;
311 /* function_and_variable_visibility doesn't want !PUBLIC decls to
312 have these flags set. */
313 DECL_WEAK (fn) = false;
314 DECL_COMDAT (fn) = false;
315 }
316
317 /* Find the vtt_parm, if present. */
318 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
319 fn_parm;
320 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
321 {
322 if (DECL_ARTIFICIAL (fn_parm)
323 && DECL_NAME (fn_parm) == vtt_parm_identifier)
324 {
325 /* Compensate for removed in_charge parameter. */
326 vtt_parmno = parmno;
327 break;
328 }
329 }
330
331 /* Allocate an argument buffer for build_cxx_call().
332 Make sure it is large enough for any of the clones. */
333 max_parms = 0;
334 FOR_EACH_CLONE (clone, fn)
335 {
336 int length = list_length (DECL_ARGUMENTS (fn));
337 if (length > max_parms)
338 max_parms = length;
339 }
340 args = (tree *) alloca (max_parms * sizeof (tree));
341
342 /* We know that any clones immediately follow FN in TYPE_METHODS. */
343 FOR_EACH_CLONE (clone, fn)
344 {
345 tree clone_parm;
346
347 /* If we've already generated a body for this clone, avoid
348 duplicating it. (Is it possible for a clone-list to grow after we
349 first see it?) */
350 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
351 continue;
352
353 /* Start processing the function. */
354 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
355
356 if (clone == fns[2])
357 {
358 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
359 clone_parm = TREE_CHAIN (clone_parm))
360 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
361 /* Build the delete destructor by calling complete destructor and
362 delete function. */
363 build_delete_destructor_body (clone, fns[1]);
364 }
365 else
366 {
367 /* Walk parameter lists together, creating parameter list for
368 call to original function. */
369 for (parmno = 0,
370 fn_parm = DECL_ARGUMENTS (fn),
371 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
372 clone_parm = DECL_ARGUMENTS (clone);
373 fn_parm;
374 ++parmno,
375 fn_parm = TREE_CHAIN (fn_parm))
376 {
377 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
378 {
379 gcc_assert (fn_parm_typelist);
380 /* Clobber argument with formal parameter type. */
381 args[parmno]
382 = convert (TREE_VALUE (fn_parm_typelist),
383 null_pointer_node);
384 }
385 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
386 {
387 tree in_charge
388 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
389 args[parmno] = in_charge;
390 }
391 /* Map other parameters to their equivalents in the cloned
392 function. */
393 else
394 {
395 gcc_assert (clone_parm);
396 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
397 args[parmno] = clone_parm;
398 clone_parm = TREE_CHAIN (clone_parm);
399 }
400 if (fn_parm_typelist)
401 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
402 }
403
404 /* We built this list backwards; fix now. */
405 mark_used (fn);
406 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
407 /* Arguments passed to the thunk by invisible reference should
408 be transmitted to the callee unchanged. Do not create a
409 temporary and invoke the copy constructor. The thunking
410 transformation must not introduce any constructor calls. */
411 CALL_FROM_THUNK_P (call) = 1;
412 block = make_node (BLOCK);
413 if (targetm.cxx.cdtor_returns_this ())
414 {
415 clone_result = DECL_RESULT (clone);
416 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
417 clone_result, call);
418 modify = build1 (RETURN_EXPR, void_type_node, modify);
419 add_stmt (modify);
420 }
421 else
422 {
423 add_stmt (call);
424 }
425 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
426 block, cur_stmt_list);
427 DECL_SAVED_TREE (clone) = push_stmt_list ();
428 add_stmt (bind);
429 }
430
431 DECL_ABSTRACT_ORIGIN (clone) = NULL;
432 expand_or_defer_fn (finish_function (0));
433 }
434 return 1;
435 }
436
437 /* FN is a function that has a complete body. Clone the body as
438 necessary. Returns nonzero if there's no longer any need to
439 process the main body. */
440
441 bool
442 maybe_clone_body (tree fn)
443 {
444 tree comdat_group = NULL_TREE;
445 tree clone;
446 tree fns[3];
447 bool first = true;
448 int idx;
449 bool need_alias = false;
450
451 /* We only clone constructors and destructors. */
452 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
453 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
454 return 0;
455
456 populate_clone_array (fn, fns);
457
458 /* Remember if we can't have multiple clones for some reason. We need to
459 check this before we remap local static initializers in clone_body. */
460 if (!tree_versionable_function_p (fn))
461 need_alias = true;
462
463 /* We know that any clones immediately follow FN in the TYPE_METHODS
464 list. */
465 push_to_top_level ();
466 for (idx = 0; idx < 3; idx++)
467 {
468 tree parm;
469 tree clone_parm;
470
471 clone = fns[idx];
472 if (!clone)
473 continue;
474
475 /* Update CLONE's source position information to match FN's. */
476 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
477 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
478 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
479 DECL_COMDAT (clone) = DECL_COMDAT (fn);
480 DECL_WEAK (clone) = DECL_WEAK (fn);
481
482 /* We don't copy the comdat group from fn to clone because the assembler
483 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
484 to it. By doing so, it also corrupted the comdat group. */
485 if (DECL_ONE_ONLY (fn))
486 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
487 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
488 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
489 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
490 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
491 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
492 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
493 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
494 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
495 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
496 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
497 set_decl_section_name (clone, DECL_SECTION_NAME (fn));
498
499 /* Adjust the parameter names and locations. */
500 parm = DECL_ARGUMENTS (fn);
501 clone_parm = DECL_ARGUMENTS (clone);
502 /* Update the `this' parameter, which is always first. */
503 update_cloned_parm (parm, clone_parm, first);
504 parm = DECL_CHAIN (parm);
505 clone_parm = DECL_CHAIN (clone_parm);
506 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
507 parm = DECL_CHAIN (parm);
508 if (DECL_HAS_VTT_PARM_P (fn))
509 parm = DECL_CHAIN (parm);
510 if (DECL_HAS_VTT_PARM_P (clone))
511 clone_parm = DECL_CHAIN (clone_parm);
512 for (; parm;
513 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
514 /* Update this parameter. */
515 update_cloned_parm (parm, clone_parm, first);
516 }
517
518 bool can_alias = can_alias_cdtor (fn);
519
520 /* If we decide to turn clones into thunks, they will branch to fn.
521 Must have original function available to call. */
522 if (!can_alias && maybe_thunk_body (fn, need_alias))
523 {
524 pop_from_top_level ();
525 /* We still need to emit the original function. */
526 return 0;
527 }
528
529 /* Emit the DWARF1 abstract instance. */
530 (*debug_hooks->deferred_inline_function) (fn);
531
532 /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
533 for (idx = 0; idx < 3; idx++)
534 {
535 tree parm;
536 tree clone_parm;
537 int parmno;
538 hash_map<tree, tree> *decl_map;
539 bool alias = false;
540
541 clone = fns[idx];
542 if (!clone)
543 continue;
544
545 /* Start processing the function. */
546 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
547
548 /* Tell cgraph if both ctors or both dtors are known to have
549 the same body. */
550 if (can_alias
551 && fns[0]
552 && idx == 1
553 && cgraph_node::get_create (fns[0])->create_same_body_alias
554 (clone, fns[0]))
555 {
556 alias = true;
557 if (DECL_ONE_ONLY (fns[0]))
558 {
559 /* For comdat base and complete cdtors put them
560 into the same, *[CD]5* comdat group instead of
561 *[CD][12]*. */
562 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
563 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
564 if (symtab_node::get (clone)->same_comdat_group)
565 symtab_node::get (clone)->remove_from_same_comdat_group ();
566 symtab_node::get (clone)->add_to_same_comdat_group
567 (symtab_node::get (fns[0]));
568 }
569 }
570
571 /* Build the delete destructor by calling complete destructor
572 and delete function. */
573 if (idx == 2)
574 {
575 build_delete_destructor_body (clone, fns[1]);
576 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
577 virtual, it goes into the same comdat group as well. */
578 if (comdat_group)
579 cgraph_node::get_create (clone)->add_to_same_comdat_group
580 (symtab_node::get (fns[0]));
581 }
582 else if (alias)
583 /* No need to populate body. */ ;
584 else
585 {
586 /* If we can't have multiple copies of FN (say, because there's a
587 static local initialized with the address of a label), we need
588 to use an alias for the complete variant. */
589 if (idx == 1 && need_alias)
590 {
591 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
592 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
593 else
594 sorry ("making multiple clones of %qD", fn);
595 }
596
597 /* Remap the parameters. */
598 decl_map = new hash_map<tree, tree>;
599 for (parmno = 0,
600 parm = DECL_ARGUMENTS (fn),
601 clone_parm = DECL_ARGUMENTS (clone);
602 parm;
603 ++parmno,
604 parm = DECL_CHAIN (parm))
605 {
606 /* Map the in-charge parameter to an appropriate constant. */
607 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
608 {
609 tree in_charge;
610 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
611 decl_map->put (parm, in_charge);
612 }
613 else if (DECL_ARTIFICIAL (parm)
614 && DECL_NAME (parm) == vtt_parm_identifier)
615 {
616 /* For a subobject constructor or destructor, the next
617 argument is the VTT parameter. Remap the VTT_PARM
618 from the CLONE to this parameter. */
619 if (DECL_HAS_VTT_PARM_P (clone))
620 {
621 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
622 decl_map->put (parm, clone_parm);
623 clone_parm = DECL_CHAIN (clone_parm);
624 }
625 /* Otherwise, map the VTT parameter to `NULL'. */
626 else
627 {
628 tree t
629 = fold_convert (TREE_TYPE (parm), null_pointer_node);
630 decl_map->put (parm, t);
631 }
632 }
633 /* Map other parameters to their equivalents in the cloned
634 function. */
635 else
636 {
637 decl_map->put (parm, clone_parm);
638 clone_parm = DECL_CHAIN (clone_parm);
639 }
640 }
641
642 if (targetm.cxx.cdtor_returns_this ())
643 {
644 parm = DECL_RESULT (fn);
645 clone_parm = DECL_RESULT (clone);
646 decl_map->put (parm, clone_parm);
647 }
648
649 /* Clone the body. */
650 clone_body (clone, fn, decl_map);
651
652 /* Clean up. */
653 delete decl_map;
654 }
655
656 /* The clone can throw iff the original function can throw. */
657 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
658
659 /* Now, expand this function into RTL, if appropriate. */
660 finish_function (0);
661 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
662 if (alias)
663 {
664 if (expand_or_defer_fn_1 (clone))
665 emit_associated_thunks (clone);
666 }
667 else
668 expand_or_defer_fn (clone);
669 first = false;
670 }
671 pop_from_top_level ();
672
673 /* We don't need to process the original function any further. */
674 return 1;
675 }