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