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