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