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