]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/method.c
PR c++/12698, c++/12699, c++/12700, c++/12566
[thirdparty/gcc.git] / gcc / cp / method.c
CommitLineData
8d08fdba
MS
1/* Handle the hair of processing (but not expanding) inline functions.
2 Also manage function and variable name overloading.
17211ab5 3 Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
d479d37f 4 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
8d08fdba
MS
5 Contributed by Michael Tiemann (tiemann@cygnus.com)
6
f5adbb8d 7This file is part of GCC.
8d08fdba 8
f5adbb8d 9GCC is free software; you can redistribute it and/or modify
8d08fdba
MS
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
f5adbb8d 14GCC is distributed in the hope that it will be useful,
8d08fdba
MS
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
f5adbb8d 20along with GCC; see the file COPYING. If not, write to
e9fa0c7c
RK
21the Free Software Foundation, 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
8d08fdba
MS
23
24
8d08fdba 25/* Handle method declarations. */
8d08fdba 26#include "config.h"
e817b5e3 27#include "system.h"
4977bab6
ZW
28#include "coretypes.h"
29#include "tm.h"
8d08fdba
MS
30#include "tree.h"
31#include "cp-tree.h"
8926095f
MS
32#include "rtl.h"
33#include "expr.h"
34#include "output.h"
8926095f 35#include "flags.h"
54f92bfb 36#include "toplev.h"
b1afd7f4 37#include "tm_p.h"
483ab821 38#include "target.h"
8d08fdba 39
669ec2b4
JM
40/* Various flags to control the mangling process. */
41
42enum mangling_flags
43{
44 /* No flags. */
45 mf_none = 0,
46 /* The thing we are presently mangling is part of a template type,
47 rather than a fully instantiated type. Therefore, we may see
48 complex expressions where we would normally expect to see a
49 simple integer constant. */
50 mf_maybe_uninstantiated = 1,
51 /* When mangling a numeric value, use the form `_XX_' (instead of
52 just `XX') if the value has more than one digit. */
de94b46c 53 mf_use_underscores_around_value = 2
669ec2b4
JM
54};
55
56typedef enum mangling_flags mangling_flags;
57
4977bab6
ZW
58static tree thunk_adjust (tree, bool, HOST_WIDE_INT, tree);
59static void do_build_assign_ref (tree);
60static void do_build_copy_constructor (tree);
61static tree synthesize_exception_spec (tree, tree (*) (tree, void *), void *);
62static tree locate_dtor (tree, void *);
63static tree locate_ctor (tree, void *);
64static tree locate_copy (tree, void *);
d46c570d
AP
65#ifdef ASM_OUTPUT_DEF
66static tree make_alias_for_thunk (tree);
67#endif
669ec2b4 68
669ec2b4
JM
69/* Called once to initialize method.c. */
70
71void
4977bab6 72init_method (void)
669ec2b4 73{
1f84ec23 74 init_mangle ();
669ec2b4
JM
75}
76
669ec2b4 77\f
36a117a5 78/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */
386b8a85 79
c1def683 80void
4977bab6 81set_mangled_name_for_decl (tree decl)
386b8a85 82{
6b4b3deb
MM
83 if (processing_template_decl)
84 /* There's no need to mangle the name of a template function. */
85 return;
86
92643fea 87 mangle_decl (decl);
669ec2b4
JM
88}
89
8926095f 90\f
4977bab6
ZW
91/* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING
92 indicates whether it is a this or result adjusting thunk.
93 FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
94 (see thunk_adjust). VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
95 never is. VIRTUAL_OFFSET is the /index/ into the vtable for this
96 adjusting thunks, we scale it to a byte offset. For covariant
97 thunks VIRTUAL_OFFSET is the virtual binfo. You must post process
98 the returned thunk with finish_thunk. */
1f6e1acc 99
8926095f 100tree
4977bab6
ZW
101make_thunk (tree function, bool this_adjusting,
102 tree fixed_offset, tree virtual_offset)
8926095f 103{
31f8e4f3 104 HOST_WIDE_INT d;
4977bab6
ZW
105 tree thunk;
106
bb5e8a7f 107 my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 20021025);
9bcb9aae 108 /* We can have this thunks to covariant thunks, but not vice versa. */
4977bab6 109 my_friendly_assert (!DECL_THIS_THUNK_P (function), 20021127);
bb885938
NS
110 my_friendly_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting,
111 20031123);
4977bab6
ZW
112
113 /* Scale the VIRTUAL_OFFSET to be in terms of bytes. */
114 if (this_adjusting && virtual_offset)
115 virtual_offset
31f8e4f3 116 = size_binop (MULT_EXPR,
4977bab6
ZW
117 virtual_offset,
118 convert (ssizetype,
119 TYPE_SIZE_UNIT (vtable_entry_type)));
120
121 d = tree_low_cst (fixed_offset, 0);
122
123 /* See if we already have the thunk in question. For this_adjusting
124 thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
9bcb9aae 125 will be a BINFO. */
bb5e8a7f 126 for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
4977bab6
ZW
127 if (DECL_THIS_THUNK_P (thunk) == this_adjusting
128 && THUNK_FIXED_OFFSET (thunk) == d
129 && (this_adjusting
130 ? (!THUNK_VIRTUAL_OFFSET (thunk) == !virtual_offset
131 && (!virtual_offset
132 || tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
133 virtual_offset)))
134 : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset))
bb5e8a7f 135 return thunk;
4977bab6 136
bb5e8a7f
MM
137 /* All thunks must be created before FUNCTION is actually emitted;
138 the ABI requires that all thunks be emitted together with the
139 function to which they transfer control. */
140 my_friendly_assert (!TREE_ASM_WRITTEN (function), 20021025);
141
4977bab6 142 thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
bb5e8a7f 143 DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
07fa4878 144 cxx_dup_lang_specific_decl (thunk);
bb885938
NS
145 DECL_THUNKS (thunk) = NULL_TREE;
146
bb5e8a7f
MM
147 DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
148 TREE_READONLY (thunk) = TREE_READONLY (function);
149 TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
150 TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
151 if (flag_weak)
152 comdat_linkage (thunk);
4977bab6 153 SET_DECL_THUNK_P (thunk, this_adjusting);
07fa4878
NS
154 THUNK_TARGET (thunk) = function;
155 THUNK_FIXED_OFFSET (thunk) = d;
4977bab6
ZW
156 THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
157
bb5e8a7f
MM
158 /* The thunk itself is not a constructor or destructor, even if
159 the thing it is thunking to is. */
160 DECL_INTERFACE_KNOWN (thunk) = 1;
161 DECL_NOT_REALLY_EXTERN (thunk) = 1;
162 DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
163 DECL_DESTRUCTOR_P (thunk) = 0;
164 DECL_CONSTRUCTOR_P (thunk) = 0;
165 /* And neither is it a clone. */
166 DECL_CLONED_FUNCTION (thunk) = NULL_TREE;
167 DECL_EXTERNAL (thunk) = 1;
168 DECL_ARTIFICIAL (thunk) = 1;
169 /* Even if this thunk is a member of a local class, we don't
170 need a static chain. */
171 DECL_NO_STATIC_CHAIN (thunk) = 1;
172 /* The THUNK is not a pending inline, even if the FUNCTION is. */
173 DECL_PENDING_INLINE_P (thunk) = 0;
eab5474f
NS
174 DECL_INLINE (thunk) = 0;
175 DECL_DECLARED_INLINE_P (thunk) = 0;
bb5e8a7f
MM
176 /* Nor has it been deferred. */
177 DECL_DEFERRED_FN (thunk) = 0;
bb885938 178
bb5e8a7f
MM
179 /* Add it to the list of thunks associated with FUNCTION. */
180 TREE_CHAIN (thunk) = DECL_THUNKS (function);
181 DECL_THUNKS (function) = thunk;
cc600f33 182
8926095f
MS
183 return thunk;
184}
185
07fa4878 186/* Finish THUNK, a thunk decl. */
eb448459 187
8926095f 188void
07fa4878 189finish_thunk (tree thunk)
4977bab6
ZW
190{
191 tree function, name;
07fa4878
NS
192 tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
193 tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
194
4977bab6 195 my_friendly_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk), 20021127);
07fa4878
NS
196 if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
197 virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
198 function = THUNK_TARGET (thunk);
4977bab6 199 name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
07fa4878 200 fixed_offset, virtual_offset);
bb885938
NS
201
202 /* We can end up with declarations of (logically) different
203 covariant thunks, that do identical adjustments. The two thunks
204 will be adjusting between within different hierarchies, which
205 happen to have the same layout. We must nullify one of them to
206 refer to the other. */
207 if (DECL_RESULT_THUNK_P (thunk))
208 {
209 tree cov_probe;
210
211 for (cov_probe = DECL_THUNKS (function);
212 cov_probe; cov_probe = TREE_CHAIN (cov_probe))
213 if (DECL_NAME (cov_probe) == name)
214 {
215 my_friendly_assert (!DECL_THUNKS (thunk), 20031023);
216 THUNK_ALIAS (thunk) = (THUNK_ALIAS_P (cov_probe)
217 ? THUNK_ALIAS (cov_probe) : cov_probe);
218 break;
219 }
220 }
221
4977bab6
ZW
222 DECL_NAME (thunk) = name;
223 SET_DECL_ASSEMBLER_NAME (thunk, name);
224}
225
226/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
227 offset indicated by VIRTUAL_OFFSET, if that is
4de8668e 228 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
9bcb9aae 229 zero for a result adjusting thunk. */
4977bab6
ZW
230
231static tree
232thunk_adjust (tree ptr, bool this_adjusting,
233 HOST_WIDE_INT fixed_offset, tree virtual_offset)
234{
235 if (this_adjusting)
236 /* Adjust the pointer by the constant. */
237 ptr = fold (build (PLUS_EXPR, TREE_TYPE (ptr), ptr,
238 ssize_int (fixed_offset)));
239
240 /* If there's a virtual offset, look up that value in the vtable and
241 adjust the pointer again. */
242 if (virtual_offset)
243 {
244 tree vtable;
245
4977bab6
ZW
246 ptr = save_expr (ptr);
247 /* The vptr is always at offset zero in the object. */
248 vtable = build1 (NOP_EXPR,
249 build_pointer_type (build_pointer_type
250 (vtable_entry_type)),
251 ptr);
252 /* Form the vtable address. */
253 vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
254 /* Find the entry with the vcall offset. */
255 vtable = build (PLUS_EXPR, TREE_TYPE (vtable), vtable, virtual_offset);
256 /* Get the offset itself. */
257 vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
258 /* Adjust the `this' pointer. */
259 ptr = fold (build (PLUS_EXPR, TREE_TYPE (ptr), ptr, vtable));
260 }
261
262 if (!this_adjusting)
263 /* Adjust the pointer by the constant. */
264 ptr = fold (build (PLUS_EXPR, TREE_TYPE (ptr), ptr,
265 ssize_int (fixed_offset)));
266
267 return ptr;
268}
269
cebebe72
JH
270/* Garbage collector tables contains thunk_labelno even when places
271 inside ifdef block. */
89ce1c8f 272static GTY (()) int thunk_labelno;
cebebe72 273#ifdef ASM_OUTPUT_DEF
89ce1c8f
JJ
274
275/* Create a static alias to function. */
276
277static tree
278make_alias_for_thunk (tree function)
279{
280 tree alias;
281 char buf[256];
282
283 ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
284 thunk_labelno++;
285 alias = build_decl (FUNCTION_DECL, get_identifier (buf),
286 TREE_TYPE (function));
287 DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
288 cxx_dup_lang_specific_decl (alias);
289 DECL_CONTEXT (alias) = NULL;
290 TREE_READONLY (alias) = TREE_READONLY (function);
291 TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);
292 TREE_PUBLIC (alias) = 0;
293 DECL_INTERFACE_KNOWN (alias) = 1;
294 DECL_NOT_REALLY_EXTERN (alias) = 1;
295 DECL_THIS_STATIC (alias) = 1;
296 DECL_SAVED_FUNCTION_DATA (alias) = NULL;
297 DECL_DESTRUCTOR_P (alias) = 0;
298 DECL_CONSTRUCTOR_P (alias) = 0;
299 DECL_CLONED_FUNCTION (alias) = NULL_TREE;
300 DECL_EXTERNAL (alias) = 0;
301 DECL_ARTIFICIAL (alias) = 1;
302 DECL_NO_STATIC_CHAIN (alias) = 1;
303 DECL_PENDING_INLINE_P (alias) = 0;
304 DECL_INLINE (alias) = 0;
305 DECL_DECLARED_INLINE_P (alias) = 0;
306 DECL_DEFERRED_FN (alias) = 0;
307 DECL_USE_TEMPLATE (alias) = 0;
308 DECL_TEMPLATE_INSTANTIATED (alias) = 0;
309 DECL_TEMPLATE_INFO (alias) = NULL;
310 DECL_INITIAL (alias) = error_mark_node;
311 TREE_ADDRESSABLE (alias) = 1;
312 TREE_USED (alias) = 1;
313 SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
314 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
315 if (!flag_syntax_only)
316 assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
317 return alias;
318}
d46c570d 319#endif
89ce1c8f 320
4977bab6
ZW
321/* Emit the definition of a C++ multiple inheritance or covariant
322 return vtable thunk. If EMIT_P is nonzero, the thunk is emitted
323 immediately. */
324
325void
326use_thunk (tree thunk_fndecl, bool emit_p)
8926095f 327{
89ce1c8f 328 tree function, alias;
4977bab6
ZW
329 tree virtual_offset;
330 HOST_WIDE_INT fixed_offset, virtual_value;
07fa4878 331 bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
4977bab6 332
9bcb9aae 333 /* We should have called finish_thunk to give it a name. */
4977bab6 334 my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
8926095f 335
bb885938
NS
336 /* We should never be using an alias, always refer to the
337 aliased thunk. */
338 my_friendly_assert (!THUNK_ALIAS_P (thunk_fndecl), 20031023);
339
8926095f
MS
340 if (TREE_ASM_WRITTEN (thunk_fndecl))
341 return;
31f8e4f3 342
07fa4878
NS
343 function = THUNK_TARGET (thunk_fndecl);
344 if (DECL_RESULT (thunk_fndecl))
6462c441 345 /* We already turned this thunk into an ordinary function.
dff94ad7 346 There's no need to process this thunk again. */
6462c441
MM
347 return;
348
31f8e4f3
MM
349 /* Thunks are always addressable; they only appear in vtables. */
350 TREE_ADDRESSABLE (thunk_fndecl) = 1;
a0a33927 351
31f8e4f3
MM
352 /* Figure out what function is being thunked to. It's referenced in
353 this translation unit. */
809c8c30
JM
354 TREE_ADDRESSABLE (function) = 1;
355 mark_used (function);
9faa149c 356 mark_referenced (DECL_ASSEMBLER_NAME (function));
31f8e4f3
MM
357 if (!emit_p)
358 return;
809c8c30 359
89ce1c8f
JJ
360#ifdef ASM_OUTPUT_DEF
361 alias = make_alias_for_thunk (function);
362#else
363 alias = function;
364#endif
365
4977bab6
ZW
366 fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
367 virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
3961e8fe 368
07fa4878
NS
369 if (virtual_offset)
370 {
371 if (!this_adjusting)
372 virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
373 virtual_value = tree_low_cst (virtual_offset, /*pos=*/0);
374 my_friendly_assert (virtual_value, 20021026);
375 }
376 else
377 virtual_value = 0;
4977bab6 378
31f8e4f3
MM
379 /* And, if we need to emit the thunk, it's used. */
380 mark_used (thunk_fndecl);
381 /* This thunk is actually defined. */
382 DECL_EXTERNAL (thunk_fndecl) = 0;
15eb1e43
JM
383 /* The linkage of the function may have changed. FIXME in linkage
384 rewrite. */
385 TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
a0128b67 386
6462c441
MM
387 if (flag_syntax_only)
388 {
389 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
390 return;
391 }
392
31f8e4f3
MM
393 push_to_top_level ();
394
89ce1c8f
JJ
395#ifdef ASM_OUTPUT_DEF
396 if (targetm.have_named_sections)
397 {
398 resolve_unique_section (function, 0, flag_function_sections);
399
400 if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
401 {
402 resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
403
404 /* Output the thunk into the same section as function. */
405 DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
406 }
407 }
408#endif
409
14691f8d
RH
410 /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
411 create one. */
412 DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
07fa4878
NS
413 BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) = DECL_ARGUMENTS (thunk_fndecl);
414
415 if (this_adjusting
4977bab6 416 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
89ce1c8f 417 virtual_value, alias))
3b62f224 418 {
3cce094d 419 const char *fnname;
3b62f224 420 current_function_decl = thunk_fndecl;
3b62f224
MM
421 DECL_RESULT (thunk_fndecl)
422 = build_decl (RESULT_DECL, 0, integer_type_node);
423 fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
ee6b0296 424 init_function_start (thunk_fndecl);
3b62f224
MM
425 current_function_is_thunk = 1;
426 assemble_start_function (thunk_fndecl, fnname);
eb0424da 427
4977bab6 428 targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
89ce1c8f 429 fixed_offset, virtual_value, alias);
3961e8fe 430
3b62f224 431 assemble_end_function (thunk_fndecl, fnname);
3b62f224 432 current_function_decl = 0;
01d939e8 433 cfun = 0;
772f8889
MM
434 /* Because init_function_start increments this, we must
435 decrement it. */
436 immediate_size_expand--;
6462c441 437 TREE_ASM_WRITTEN (thunk_fndecl) = 1;
3b62f224 438 }
4e7512c9 439 else
14691f8d 440 {
4977bab6
ZW
441 /* If this is a covariant thunk, or we don't have the necessary
442 code for efficient thunks, generate a thunk function that
443 just makes a call to the real function. Unfortunately, this
444 doesn't work for varargs. */
14691f8d
RH
445
446 tree a, t;
447
448 if (varargs_function_p (function))
449 error ("generic thunk code fails for method `%#D' which uses `...'",
450 function);
451
4977bab6 452 /* Set up cloned argument trees for the thunk. */
14691f8d
RH
453 t = NULL_TREE;
454 for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
455 {
456 tree x = copy_node (a);
457 TREE_CHAIN (x) = t;
458 DECL_CONTEXT (x) = thunk_fndecl;
22898f9a 459 SET_DECL_RTL (x, NULL_RTX);
14691f8d
RH
460 t = x;
461 }
462 a = nreverse (t);
463 DECL_ARGUMENTS (thunk_fndecl) = a;
464 DECL_RESULT (thunk_fndecl) = NULL_TREE;
465
466 start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
467 /* We don't bother with a body block for thunks. */
468
1bb2cc34 469 /* There's no need to check accessibility inside the thunk body. */
78757caa 470 push_deferring_access_checks (dk_no_check);
1bb2cc34 471
4977bab6 472 t = a;
07fa4878 473 if (this_adjusting)
4977bab6
ZW
474 t = thunk_adjust (t, /*this_adjusting=*/1,
475 fixed_offset, virtual_offset);
476
14691f8d
RH
477 /* Build up the call to the real function. */
478 t = tree_cons (NULL_TREE, t, NULL_TREE);
479 for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
480 t = tree_cons (NULL_TREE, a, t);
481 t = nreverse (t);
89ce1c8f 482 t = build_call (alias, t);
07fa4878 483 if (!this_adjusting)
4977bab6
ZW
484 t = thunk_adjust (t, /*this_adjusting=*/0,
485 fixed_offset, virtual_offset);
486
14691f8d
RH
487 if (VOID_TYPE_P (TREE_TYPE (t)))
488 finish_expr_stmt (t);
489 else
490 finish_return_stmt (t);
491
492 /* Since we want to emit the thunk, we explicitly mark its name as
493 referenced. */
9faa149c 494 mark_referenced (DECL_ASSEMBLER_NAME (thunk_fndecl));
14691f8d
RH
495
496 /* But we don't want debugging information about it. */
497 DECL_IGNORED_P (thunk_fndecl) = 1;
498
1bb2cc34 499 /* Re-enable access control. */
78757caa 500 pop_deferring_access_checks ();
1bb2cc34 501
ab0ba00c 502 expand_body (finish_function (0));
14691f8d 503 }
31f8e4f3
MM
504
505 pop_from_top_level ();
8926095f 506}
f376e137
MS
507\f
508/* Code for synthesizing methods which have default semantics defined. */
509
f376e137 510/* Generate code for default X(X&) constructor. */
e92cc029 511
824b9a4c 512static void
4977bab6 513do_build_copy_constructor (tree fndecl)
f376e137 514{
e0fff4b3 515 tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
f376e137
MS
516 tree t;
517
f376e137
MS
518 parm = convert_from_reference (parm);
519
a59ca936
JM
520 if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
521 && is_empty_class (current_class_type))
522 /* Don't copy the padding byte; it might not have been allocated
523 if *this is a base subobject. */;
524 else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
f376e137 525 {
4ac14744 526 t = build (INIT_EXPR, void_type_node, current_class_ref, parm);
f1dedc31 527 finish_expr_stmt (t);
f376e137
MS
528 }
529 else
530 {
531 tree fields = TYPE_FIELDS (current_class_type);
532 int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
533 tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
fd74ca0b 534 tree member_init_list = NULL_TREE;
89d684bb 535 int cvquals = cp_type_quals (TREE_TYPE (parm));
f376e137
MS
536 int i;
537
713ccd0c
NS
538 /* Initialize all the base-classes with the parameter converted
539 to their type so that we get their copy constructor and not
540 another constructor that takes current_class_type. We must
541 deal with the binfo's directly as a direct base might be
542 inaccessible due to ambiguity. */
f376e137
MS
543 for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
544 t = TREE_CHAIN (t))
01f9e964 545 {
713ccd0c
NS
546 tree binfo = TREE_VALUE (t);
547
2282d28d
MM
548 member_init_list
549 = tree_cons (binfo,
550 build_tree_list (NULL_TREE,
551 build_base_path (PLUS_EXPR, parm,
552 binfo, 1)),
553 member_init_list);
01f9e964
JM
554 }
555
f376e137
MS
556 for (i = 0; i < n_bases; ++i)
557 {
713ccd0c
NS
558 tree binfo = TREE_VEC_ELT (binfos, i);
559 if (TREE_VIA_VIRTUAL (binfo))
8ccc31eb 560 continue;
f376e137 561
2282d28d
MM
562 member_init_list
563 = tree_cons (binfo,
564 build_tree_list (NULL_TREE,
565 build_base_path (PLUS_EXPR, parm,
566 binfo, 1)),
567 member_init_list);
f376e137 568 }
1b5f5f76 569
f376e137
MS
570 for (; fields; fields = TREE_CHAIN (fields))
571 {
01f9e964 572 tree init;
a5894242 573 tree field = fields;
33dd07ee 574 tree expr_type;
a5894242
MS
575
576 if (TREE_CODE (field) != FIELD_DECL)
f376e137 577 continue;
8dff1027
MS
578
579 init = parm;
a5894242 580 if (DECL_NAME (field))
f376e137 581 {
a5894242 582 if (VFIELD_NAME_P (DECL_NAME (field)))
f376e137 583 continue;
f376e137
MS
584
585 /* True for duplicate members. */
a5894242 586 if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
f376e137
MS
587 continue;
588 }
a5894242 589 else if ((t = TREE_TYPE (field)) != NULL_TREE
6bdb8141 590 && ANON_AGGR_TYPE_P (t)
0171aeab 591 && TYPE_FIELDS (t) != NULL_TREE)
6bdb8141
JM
592 /* Just use the field; anonymous types can't have
593 nontrivial copy ctors or assignment ops. */;
0171aeab
JM
594 else
595 continue;
f376e137 596
33dd07ee
MM
597 /* Compute the type of "init->field". If the copy-constructor
598 parameter is, for example, "const S&", and the type of
599 the field is "T", then the type will usually be "const
600 T". (There are no cv-qualified variants of reference
601 types.) */
602 expr_type = TREE_TYPE (field);
603 if (TREE_CODE (expr_type) != REFERENCE_TYPE)
604 expr_type = cp_build_qualified_type (expr_type, cvquals);
605 init = build (COMPONENT_REF, expr_type, init, field);
f376e137
MS
606 init = build_tree_list (NULL_TREE, init);
607
fd74ca0b
MM
608 member_init_list
609 = tree_cons (field, init, member_init_list);
f376e137 610 }
2282d28d 611 finish_mem_initializers (member_init_list);
f376e137 612 }
f376e137
MS
613}
614
824b9a4c 615static void
4977bab6 616do_build_assign_ref (tree fndecl)
f376e137
MS
617{
618 tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
f1dedc31 619 tree compound_stmt;
f376e137 620
7a3397c7 621 compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
f376e137
MS
622 parm = convert_from_reference (parm);
623
a59ca936
JM
624 if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)
625 && is_empty_class (current_class_type))
626 /* Don't copy the padding byte; it might not have been allocated
627 if *this is a base subobject. */;
628 else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))
f376e137 629 {
4ac14744 630 tree t = build (MODIFY_EXPR, void_type_node, current_class_ref, parm);
f1dedc31 631 finish_expr_stmt (t);
f376e137
MS
632 }
633 else
634 {
4ba126e4 635 tree fields;
89d684bb 636 int cvquals = cp_type_quals (TREE_TYPE (parm));
f376e137
MS
637 int i;
638
22ed7e5f 639 /* Assign to each of the direct base classes. */
4ba126e4 640 for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
f376e137 641 {
4ba126e4
MM
642 tree binfo;
643 tree converted_parm;
644
645 binfo = BINFO_BASETYPE (TYPE_BINFO (current_class_type), i);
646 /* We must convert PARM directly to the base class
647 explicitly since the base class may be ambiguous. */
648 converted_parm = build_base_path (PLUS_EXPR, parm, binfo, 1);
649 /* Call the base class assignment operator. */
650 finish_expr_stmt
651 (build_special_member_call (current_class_ref,
652 ansi_assopname (NOP_EXPR),
653 build_tree_list (NULL_TREE,
654 converted_parm),
655 binfo,
656 LOOKUP_NORMAL | LOOKUP_NONVIRTUAL));
f376e137 657 }
4ba126e4
MM
658
659 /* Assign to each of the non-static data members. */
660 for (fields = TYPE_FIELDS (current_class_type);
661 fields;
662 fields = TREE_CHAIN (fields))
f376e137 663 {
0171aeab 664 tree comp, init, t;
a5894242
MS
665 tree field = fields;
666
17bbb839 667 if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
f376e137 668 continue;
e349ee73 669
1b8899d1 670 if (CP_TYPE_CONST_P (TREE_TYPE (field)))
e349ee73 671 {
33bd39a2 672 error ("non-static const member `%#D', can't use default assignment operator", field);
e349ee73
MS
673 continue;
674 }
675 else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
676 {
33bd39a2 677 error ("non-static reference member `%#D', can't use default assignment operator", field);
e349ee73
MS
678 continue;
679 }
680
8dff1027
MS
681 comp = current_class_ref;
682 init = parm;
683
a5894242 684 if (DECL_NAME (field))
f376e137 685 {
a5894242 686 if (VFIELD_NAME_P (DECL_NAME (field)))
f376e137 687 continue;
f376e137
MS
688
689 /* True for duplicate members. */
a5894242 690 if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
f376e137
MS
691 continue;
692 }
a5894242 693 else if ((t = TREE_TYPE (field)) != NULL_TREE
6bdb8141 694 && ANON_AGGR_TYPE_P (t)
0171aeab 695 && TYPE_FIELDS (t) != NULL_TREE)
6bdb8141
JM
696 /* Just use the field; anonymous types can't have
697 nontrivial copy ctors or assignment ops. */;
0171aeab
JM
698 else
699 continue;
f376e137 700
8dff1027 701 comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
31b1b957 702 init = build (COMPONENT_REF,
451c0899 703 cp_build_qualified_type (TREE_TYPE (field), cvquals),
31b1b957 704 init, field);
f376e137 705
a1c2b86d
JJ
706 if (DECL_NAME (field))
707 finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
708 else
709 finish_expr_stmt (build (MODIFY_EXPR, TREE_TYPE (comp), comp,
710 init));
f376e137
MS
711 }
712 }
62409b39 713 finish_return_stmt (current_class_ref);
7a3397c7 714 finish_compound_stmt (compound_stmt);
f376e137
MS
715}
716
717void
4977bab6 718synthesize_method (tree fndecl)
f376e137 719{
4977bab6 720 bool nested = (current_function_decl != NULL_TREE);
4f1c5b7d 721 tree context = decl_function_context (fndecl);
4977bab6 722 bool need_body = true;
ade3dc07 723 tree stmt;
db5ae43f 724
b7067a12
JM
725 if (at_eof)
726 import_export_decl (fndecl);
727
db9b2174
MM
728 /* If we've been asked to synthesize a clone, just synthesize the
729 cloned function instead. Doing so will automatically fill in the
730 body for the clone. */
731 if (DECL_CLONED_FUNCTION_P (fndecl))
732 {
733 synthesize_method (DECL_CLONED_FUNCTION (fndecl));
734 return;
735 }
736
afb19ffb
KL
737 /* We may be in the middle of deferred access check. Disable
738 it now. */
739 push_deferring_access_checks (dk_no_deferred);
740
9a3b49ac
MS
741 if (! context)
742 push_to_top_level ();
743 else if (nested)
99dccabc 744 push_function_context_to (context);
db5ae43f 745
62409b39
MM
746 /* Put the function definition at the position where it is needed,
747 rather than within the body of the class. That way, an error
748 during the generation of the implicit body points at the place
749 where the attempt to generate the function occurs, giving the
750 user a hint as to why we are attempting to generate the
c6002625 751 function. */
f31686a3 752 DECL_SOURCE_LOCATION (fndecl) = input_location;
62409b39 753
e76a2646 754 interface_unknown = 1;
a8f73d4b 755 start_function (NULL_TREE, fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
f1dedc31 756 clear_last_expr ();
ade3dc07 757 stmt = begin_function_body ();
db5ae43f 758
596ea4e5 759 if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
62409b39
MM
760 {
761 do_build_assign_ref (fndecl);
4977bab6 762 need_body = false;
62409b39 763 }
cdd2559c 764 else if (DECL_CONSTRUCTOR_P (fndecl))
db5ae43f 765 {
e0fff4b3 766 tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
db5ae43f
MS
767 if (arg_chain != void_list_node)
768 do_build_copy_constructor (fndecl);
769 else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
cdd2559c 770 finish_mem_initializers (NULL_TREE);
62409b39 771 }
f18a14bc 772
62409b39
MM
773 /* If we haven't yet generated the body of the function, just
774 generate an empty compound statement. */
775 if (need_body)
776 {
777 tree compound_stmt;
7a3397c7
NS
778 compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
779 finish_compound_stmt (compound_stmt);
db5ae43f
MS
780 }
781
ade3dc07 782 finish_function_body (stmt);
8cd2462c 783 expand_or_defer_fn (finish_function (0));
28cbf42c 784
db5ae43f 785 extract_interface_info ();
9a3b49ac
MS
786 if (! context)
787 pop_from_top_level ();
788 else if (nested)
99dccabc 789 pop_function_context_from (context);
afb19ffb
KL
790
791 pop_deferring_access_checks ();
f376e137 792}
9eb71d8c 793
03378143
NS
794/* Use EXTRACTOR to locate the relevant function called for each base &
795 class field of TYPE. CLIENT allows additional information to be passed
f62ea157
JM
796 to EXTRACTOR. Generates the union of all exceptions generated by those
797 functions. Note that we haven't updated TYPE_FIELDS and such of any
798 variants yet, so we need to look at the main one. */
03378143
NS
799
800static tree
4977bab6
ZW
801synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
802 void *client)
03378143
NS
803{
804 tree raises = empty_except_spec;
805 tree fields = TYPE_FIELDS (type);
806 int i, n_bases = CLASSTYPE_N_BASECLASSES (type);
807 tree binfos = TYPE_BINFO_BASETYPES (type);
f62ea157 808
03378143
NS
809 for (i = 0; i != n_bases; i++)
810 {
811 tree base = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
812 tree fn = (*extractor) (base, client);
813 if (fn)
814 {
815 tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
816
817 raises = merge_exception_specifiers (raises, fn_raises);
818 }
819 }
820 for (; fields; fields = TREE_CHAIN (fields))
821 {
822 tree type = TREE_TYPE (fields);
823 tree fn;
824
17bbb839 825 if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
03378143
NS
826 continue;
827 while (TREE_CODE (type) == ARRAY_TYPE)
828 type = TREE_TYPE (type);
829 if (TREE_CODE (type) != RECORD_TYPE)
830 continue;
831
832 fn = (*extractor) (type, client);
833 if (fn)
834 {
835 tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
836
837 raises = merge_exception_specifiers (raises, fn_raises);
838 }
839 }
840 return raises;
841}
842
843/* Locate the dtor of TYPE. */
844
845static tree
4977bab6 846locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
03378143
NS
847{
848 tree fns;
849
850 if (!TYPE_HAS_DESTRUCTOR (type))
851 return NULL_TREE;
852 fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
853 CLASSTYPE_DESTRUCTOR_SLOT);
854 return fns;
855}
856
857/* Locate the default ctor of TYPE. */
858
859static tree
4977bab6 860locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
03378143
NS
861{
862 tree fns;
863
864 if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
865 return NULL_TREE;
866
867 fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
868 CLASSTYPE_CONSTRUCTOR_SLOT);
869 for (; fns; fns = OVL_NEXT (fns))
870 {
871 tree fn = OVL_CURRENT (fns);
872 tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
873
874 if (sufficient_parms_p (TREE_CHAIN (parms)))
875 return fn;
876 }
877 return NULL_TREE;
878}
879
880struct copy_data
881{
882 tree name;
883 int quals;
884};
885
886/* Locate the copy ctor or copy assignment of TYPE. CLIENT_
887 points to a COPY_DATA holding the name (NULL for the ctor)
888 and desired qualifiers of the source operand. */
889
890static tree
4977bab6 891locate_copy (tree type, void *client_)
03378143
NS
892{
893 struct copy_data *client = (struct copy_data *)client_;
894 tree fns;
895 int ix = -1;
896 tree best = NULL_TREE;
4977bab6 897 bool excess_p = false;
03378143
NS
898
899 if (client->name)
900 {
901 if (TYPE_HAS_ASSIGN_REF (type))
902 ix = lookup_fnfields_1 (type, client->name);
903 }
904 else if (TYPE_HAS_INIT_REF (type))
905 ix = CLASSTYPE_CONSTRUCTOR_SLOT;
906 if (ix < 0)
907 return NULL_TREE;
908 fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix);
909
910 for (; fns; fns = OVL_NEXT (fns))
911 {
912 tree fn = OVL_CURRENT (fns);
913 tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
914 tree src_type;
915 int excess;
916 int quals;
917
918 parms = TREE_CHAIN (parms);
919 if (!parms)
920 continue;
ee76b931 921 src_type = non_reference (TREE_VALUE (parms));
03378143
NS
922 if (!same_type_ignoring_top_level_qualifiers_p (src_type, type))
923 continue;
924 if (!sufficient_parms_p (TREE_CHAIN (parms)))
925 continue;
89d684bb 926 quals = cp_type_quals (src_type);
03378143
NS
927 if (client->quals & ~quals)
928 continue;
929 excess = quals & ~client->quals;
930 if (!best || (excess_p && !excess))
931 {
932 best = fn;
933 excess_p = excess;
934 }
935 else
936 /* Ambiguous */
937 return NULL_TREE;
938 }
939 return best;
940}
941
9eb71d8c
MM
942/* Implicitly declare the special function indicated by KIND, as a
943 member of TYPE. For copy constructors and assignment operators,
944 CONST_P indicates whether these functions should take a const
945 reference argument or a non-const reference. */
946
947tree
4977bab6 948implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
9eb71d8c
MM
949{
950 tree declspecs = NULL_TREE;
951 tree fn, args = NULL_TREE;
03378143 952 tree raises = empty_except_spec;
4977bab6
ZW
953 bool retref = false;
954 bool has_parm = false;
a723baf1 955 tree name = constructor_name (type);
9eb71d8c
MM
956
957 switch (kind)
958 {
9eb71d8c 959 case sfk_destructor:
03378143 960 /* Destructor. */
718b8ea5 961 name = build_nt (BIT_NOT_EXPR, name);
9eb71d8c 962 args = void_list_node;
03378143 963 raises = synthesize_exception_spec (type, &locate_dtor, 0);
9eb71d8c
MM
964 break;
965
966 case sfk_constructor:
967 /* Default constructor. */
968 args = void_list_node;
03378143 969 raises = synthesize_exception_spec (type, &locate_ctor, 0);
9eb71d8c
MM
970 break;
971
972 case sfk_copy_constructor:
9eb71d8c 973 case sfk_assignment_operator:
03378143
NS
974 {
975 struct copy_data data;
f62ea157 976 tree argtype = type;
03378143 977
4977bab6 978 has_parm = true;
a2095778
NS
979 data.name = NULL;
980 data.quals = 0;
981 if (kind == sfk_assignment_operator)
982 {
4977bab6 983 retref = true;
a2095778 984 declspecs = build_tree_list (NULL_TREE, type);
9eb71d8c 985
a2095778
NS
986 name = ansi_assopname (NOP_EXPR);
987 data.name = name;
988 }
9eb71d8c 989 if (const_p)
a2095778
NS
990 {
991 data.quals = TYPE_QUAL_CONST;
f62ea157 992 argtype = build_qualified_type (argtype, TYPE_QUAL_CONST);
a2095778
NS
993 }
994
f62ea157 995 argtype = build_reference_type (argtype);
a2095778
NS
996 args = build_tree_list (hash_tree_chain (argtype, NULL_TREE),
997 get_identifier ("_ctor_arg"));
998 args = tree_cons (NULL_TREE, args, void_list_node);
999
03378143 1000 raises = synthesize_exception_spec (type, &locate_copy, &data);
9eb71d8c 1001 break;
03378143 1002 }
9eb71d8c 1003 default:
a98facb0 1004 abort ();
9eb71d8c
MM
1005 }
1006
1007 TREE_PARMLIST (args) = 1;
1008
1009 {
03378143 1010 tree declarator = make_call_declarator (name, args, NULL_TREE, raises);
a2095778 1011
9eb71d8c 1012 if (retref)
718b8ea5 1013 declarator = build_nt (ADDR_EXPR, declarator);
9eb71d8c
MM
1014
1015 fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
a2095778
NS
1016 if (has_parm)
1017 TREE_USED (FUNCTION_FIRST_USER_PARM (fn)) = 1;
9eb71d8c
MM
1018 }
1019
1020 my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 20000408);
1021
c727aa5e 1022 DECL_ARTIFICIAL (fn) = 1;
9eb71d8c 1023 DECL_NOT_REALLY_EXTERN (fn) = 1;
79065db2 1024 DECL_DECLARED_INLINE_P (fn) = 1;
9eb71d8c
MM
1025 DECL_INLINE (fn) = 1;
1026 defer_fn (fn);
1027
1028 return fn;
1029}
e0fff4b3
JM
1030
1031/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
1032 as there are artificial parms in FN. */
1033
1034tree
4977bab6 1035skip_artificial_parms_for (tree fn, tree list)
e0fff4b3
JM
1036{
1037 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1038 list = TREE_CHAIN (list);
1039 else
1040 return list;
1041
1042 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1043 list = TREE_CHAIN (list);
1044 if (DECL_HAS_VTT_PARM_P (fn))
1045 list = TREE_CHAIN (list);
1046 return list;
1047}
89ce1c8f
JJ
1048
1049#include "gt-cp-method.h"