OSDN Git Service

* expr.c (expand_expr): Use gen_int_mode for the argument
[pf3gnuchains/gcc-fork.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 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
66 /* Called once to initialize method.c.  */
67
68 void
69 init_method (void)
70 {
71   init_mangle ();
72 }
73
74 \f
75 /* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL.  */
76
77 void
78 set_mangled_name_for_decl (tree decl)
79 {
80   if (processing_template_decl)
81     /* There's no need to mangle the name of a template function.  */
82     return;
83
84   mangle_decl (decl);
85 }
86
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)
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
107 tree
108 hack_identifier (tree value, tree name)
109 {
110   tree type;
111
112   if (value == error_mark_node)
113     return error_mark_node;
114
115   type = TREE_TYPE (value);
116   if (TREE_CODE (value) == FIELD_DECL)
117     value = finish_non_static_data_member (value, 
118                                            /*qualifying_scope=*/NULL_TREE);
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))))
123     {
124       tree decl;
125
126       if (TREE_CODE (value) == OVERLOAD)
127         value = OVL_CURRENT (value);
128
129       decl = maybe_dummy_object (DECL_CONTEXT (value), 0);
130       value = finish_class_member_access_expr (decl, name);
131     }
132   else if (really_overloaded_fn (value))
133     ;
134   else if (TREE_CODE (value) == OVERLOAD)
135     /* not really overloaded function */
136     mark_used (OVL_FUNCTION (value));
137   else if (TREE_CODE (value) == TREE_LIST)
138     {
139       /* Ambiguous reference to base members, possibly other cases?.  */
140       tree t = value;
141       while (t && TREE_CODE (t) == TREE_LIST)
142         {
143           mark_used (TREE_VALUE (t));
144           t = TREE_CHAIN (t);
145         }
146     }
147   else if (TREE_CODE (value) == NAMESPACE_DECL)
148     {
149       error ("use of namespace `%D' as expression", value);
150       return error_mark_node;
151     }
152   else if (DECL_CLASS_TEMPLATE_P (value))
153     {
154       error ("use of class template `%T' as expression", value);
155       return error_mark_node;
156     }
157   else
158     mark_used (value);
159
160   if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL
161       || TREE_CODE (value) == RESULT_DECL)
162     {
163       tree context = decl_function_context (value);
164       if (context != NULL_TREE && context != current_function_decl
165           && ! TREE_STATIC (value))
166         {
167           error ("use of %s from containing function",
168                       (TREE_CODE (value) == VAR_DECL
169                        ? "`auto' variable" : "parameter"));
170           cp_error_at ("  `%#D' declared here", value);
171           value = error_mark_node;
172         }
173     }
174
175   if (DECL_P (value) && DECL_NONLOCAL (value))
176     {
177       if (DECL_CLASS_SCOPE_P (value)
178           && DECL_CONTEXT (value) != current_class_type)
179         {
180           tree path;
181           path = currently_open_derived_class (DECL_CONTEXT (value));
182           enforce_access (path, value);
183         }
184     }
185   else if (TREE_CODE (value) == TREE_LIST 
186            && TREE_TYPE (value) == error_mark_node)
187     {
188       error ("\
189 request for member `%D' is ambiguous in multiple inheritance lattice",
190                 name);
191       print_candidates (value);
192       return error_mark_node;
193     }
194
195   if (! processing_template_decl)
196     value = convert_from_reference (value);
197   return value;
198 }
199
200 \f
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.  */
209
210 tree
211 make_thunk (tree function, bool this_adjusting,
212             tree fixed_offset, tree virtual_offset)
213 {
214   HOST_WIDE_INT d;
215   tree thunk;
216   
217   my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 20021025);
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 
224       = size_binop (MULT_EXPR,
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
233      will be a BINFO. */
234   for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
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))
243       return thunk;
244   
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
250   thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
251   DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
252   cxx_dup_lang_specific_decl (thunk);
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);
259   SET_DECL_THUNK_P (thunk, this_adjusting);
260   THUNK_TARGET (thunk) = function;
261   THUNK_FIXED_OFFSET (thunk) = d;
262   THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
263   
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;
280   DECL_INLINE (thunk) = 0;
281   DECL_DECLARED_INLINE_P (thunk) = 0;
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;
287
288   return thunk;
289 }
290
291 /* Finish THUNK, a thunk decl.  */
292
293 void
294 finish_thunk (tree thunk)
295 {
296   tree function, name;
297   tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
298   tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
299
300   my_friendly_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk), 20021127);
301   if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
302     virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
303   function = THUNK_TARGET (thunk);
304   name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
305                        fixed_offset, virtual_offset);
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
312    non-null. THIS_ADJUSTING is non-zero for a this adjusting thunk and
313    zero for a result adjusting thunk. */
314
315 static tree
316 thunk_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
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
358 void
359 use_thunk (tree thunk_fndecl, bool emit_p)
360 {
361   tree function;
362   tree virtual_offset;
363   HOST_WIDE_INT fixed_offset, virtual_value;
364   bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
365
366   /* We should have called finish_thunk to give it a name. */
367   my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
368
369   if (TREE_ASM_WRITTEN (thunk_fndecl))
370     return;
371   
372   function = THUNK_TARGET (thunk_fndecl);
373   if (DECL_RESULT (thunk_fndecl))
374     /* We already turned this thunk into an ordinary function.
375        There's no need to process this thunk again.  */
376     return;
377
378   /* Thunks are always addressable; they only appear in vtables.  */
379   TREE_ADDRESSABLE (thunk_fndecl) = 1;
380
381   /* Figure out what function is being thunked to.  It's referenced in
382      this translation unit.  */
383   TREE_ADDRESSABLE (function) = 1;
384   mark_used (function);
385   TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (function)) = 1;
386   if (!emit_p)
387     return;
388
389   fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
390   virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
391
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;
401   
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;
406   /* The linkage of the function may have changed.  FIXME in linkage
407      rewrite.  */
408   TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
409
410   if (flag_syntax_only)
411     {
412       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
413       return;
414     }
415
416   push_to_top_level ();
417
418   /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
419      create one.  */
420   DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
421   BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) = DECL_ARGUMENTS (thunk_fndecl);
422   
423   if (this_adjusting
424       && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
425                                               virtual_value, function))
426     {
427       const char *fnname;
428       current_function_decl = thunk_fndecl;
429       DECL_RESULT (thunk_fndecl)
430         = build_decl (RESULT_DECL, 0, integer_type_node);
431       fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
432       init_function_start (thunk_fndecl, input_filename, lineno);
433       current_function_is_thunk = 1;
434       assemble_start_function (thunk_fndecl, fnname);
435
436       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
437                                        fixed_offset, virtual_value, function);
438
439       assemble_end_function (thunk_fndecl, fnname);
440       current_function_decl = 0;
441       cfun = 0;
442       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
443     }
444   else
445     {
446       /* If this is a covariant thunk, or we don't have the necessary
447          code for efficient thunks, generate a thunk function that
448          just makes a call to the real function.  Unfortunately, this
449          doesn't work for varargs.  */
450
451       tree a, t;
452       int saved_check_access;
453
454       if (varargs_function_p (function))
455         error ("generic thunk code fails for method `%#D' which uses `...'",
456                function);
457
458       /* Set up cloned argument trees for the thunk.  */
459       t = NULL_TREE;
460       for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
461         {
462           tree x = copy_node (a);
463           TREE_CHAIN (x) = t;
464           DECL_CONTEXT (x) = thunk_fndecl;
465           t = x;
466         }
467       a = nreverse (t);
468       DECL_ARGUMENTS (thunk_fndecl) = a;
469       DECL_RESULT (thunk_fndecl) = NULL_TREE;
470
471       start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
472       /* We don't bother with a body block for thunks.  */
473
474       /* There's no need to check accessibility inside the thunk body.  */
475       saved_check_access = scope_chain->check_access;
476       scope_chain->check_access = 0;
477
478       t = a;
479       if (this_adjusting)
480         t = thunk_adjust (t, /*this_adjusting=*/1,
481                           fixed_offset, virtual_offset);
482       
483       /* Build up the call to the real function.  */
484       t = tree_cons (NULL_TREE, t, NULL_TREE);
485       for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
486         t = tree_cons (NULL_TREE, a, t);
487       t = nreverse (t);
488       t = build_call (function, t);
489       if (!this_adjusting)
490         t = thunk_adjust (t, /*this_adjusting=*/0,
491                           fixed_offset, virtual_offset);
492       
493       if (VOID_TYPE_P (TREE_TYPE (t)))
494         finish_expr_stmt (t);
495       else
496         finish_return_stmt (t);
497
498       /* Since we want to emit the thunk, we explicitly mark its name as
499          referenced.  */
500       TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (thunk_fndecl)) = 1;
501
502       /* But we don't want debugging information about it.  */
503       DECL_IGNORED_P (thunk_fndecl) = 1;
504
505       /* Re-enable access control.  */
506       scope_chain->check_access = saved_check_access;
507
508       expand_body (finish_function (0));
509     }
510
511   pop_from_top_level ();
512 }
513 \f
514 /* Code for synthesizing methods which have default semantics defined.  */
515
516 /* Generate code for default X(X&) constructor.  */
517
518 static void
519 do_build_copy_constructor (tree fndecl)
520 {
521   tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
522   tree t;
523
524   parm = convert_from_reference (parm);
525
526   if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
527       && is_empty_class (current_class_type))
528     /* Don't copy the padding byte; it might not have been allocated
529        if *this is a base subobject.  */;
530   else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
531     {
532       t = build (INIT_EXPR, void_type_node, current_class_ref, parm);
533       finish_expr_stmt (t);
534     }
535   else
536     {
537       tree fields = TYPE_FIELDS (current_class_type);
538       int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
539       tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
540       tree member_init_list = NULL_TREE;
541       int cvquals = cp_type_quals (TREE_TYPE (parm));
542       int i;
543
544       /* Initialize all the base-classes with the parameter converted
545          to their type so that we get their copy constructor and not
546          another constructor that takes current_class_type.  We must
547          deal with the binfo's directly as a direct base might be
548          inaccessible due to ambiguity.  */
549       for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
550            t = TREE_CHAIN (t))
551         {
552           tree binfo = TREE_VALUE (t);
553           
554           member_init_list 
555             = tree_cons (binfo,
556                          build_tree_list (NULL_TREE,
557                                           build_base_path (PLUS_EXPR, parm,
558                                                            binfo, 1)),
559                          member_init_list);
560         }
561
562       for (i = 0; i < n_bases; ++i)
563         {
564           tree binfo = TREE_VEC_ELT (binfos, i);
565           if (TREE_VIA_VIRTUAL (binfo))
566             continue; 
567
568           member_init_list 
569             = tree_cons (binfo,
570                          build_tree_list (NULL_TREE,
571                                           build_base_path (PLUS_EXPR, parm,
572                                                            binfo, 1)),
573                          member_init_list);
574         }
575
576       for (; fields; fields = TREE_CHAIN (fields))
577         {
578           tree init;
579           tree field = fields;
580           tree expr_type;
581
582           if (TREE_CODE (field) != FIELD_DECL)
583             continue;
584
585           init = parm;
586           if (DECL_NAME (field))
587             {
588               if (VFIELD_NAME_P (DECL_NAME (field)))
589                 continue;
590
591               /* True for duplicate members.  */
592               if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
593                 continue;
594             }
595           else if ((t = TREE_TYPE (field)) != NULL_TREE
596                    && ANON_AGGR_TYPE_P (t)
597                    && TYPE_FIELDS (t) != NULL_TREE)
598             /* Just use the field; anonymous types can't have
599                nontrivial copy ctors or assignment ops.  */;
600           else
601             continue;
602
603           /* Compute the type of "init->field".  If the copy-constructor
604              parameter is, for example, "const S&", and the type of
605              the field is "T", then the type will usually be "const
606              T".  (There are no cv-qualified variants of reference
607              types.)  */
608           expr_type = TREE_TYPE (field);
609           if (TREE_CODE (expr_type) != REFERENCE_TYPE)
610             expr_type = cp_build_qualified_type (expr_type, cvquals);
611           init = build (COMPONENT_REF, expr_type, init, field);
612           init = build_tree_list (NULL_TREE, init);
613
614           member_init_list
615             = tree_cons (field, init, member_init_list);
616         }
617       finish_mem_initializers (member_init_list);
618     }
619 }
620
621 static void
622 do_build_assign_ref (tree fndecl)
623 {
624   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
625   tree compound_stmt;
626
627   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
628   parm = convert_from_reference (parm);
629
630   if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)
631       && is_empty_class (current_class_type))
632     /* Don't copy the padding byte; it might not have been allocated
633        if *this is a base subobject.  */;
634   else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))
635     {
636       tree t = build (MODIFY_EXPR, void_type_node, current_class_ref, parm);
637       finish_expr_stmt (t);
638     }
639   else
640     {
641       tree fields;
642       int cvquals = cp_type_quals (TREE_TYPE (parm));
643       int i;
644
645       /* Assign to each of thedirect base classes.  */
646       for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
647         {
648           tree binfo;
649           tree converted_parm;
650
651           binfo = BINFO_BASETYPE (TYPE_BINFO (current_class_type), i);
652           /* We must convert PARM directly to the base class
653              explicitly since the base class may be ambiguous.  */
654           converted_parm = build_base_path (PLUS_EXPR, parm, binfo, 1);
655           /* Call the base class assignment operator.  */
656           finish_expr_stmt 
657             (build_special_member_call (current_class_ref, 
658                                         ansi_assopname (NOP_EXPR),
659                                         build_tree_list (NULL_TREE, 
660                                                          converted_parm),
661                                         binfo,
662                                         LOOKUP_NORMAL | LOOKUP_NONVIRTUAL));
663         }
664
665       /* Assign to each of the non-static data members.  */
666       for (fields = TYPE_FIELDS (current_class_type); 
667            fields; 
668            fields = TREE_CHAIN (fields))
669         {
670           tree comp, init, t;
671           tree field = fields;
672
673           if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
674             continue;
675
676           if (CP_TYPE_CONST_P (TREE_TYPE (field)))
677             {
678               error ("non-static const member `%#D', can't use default assignment operator", field);
679               continue;
680             }
681           else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
682             {
683               error ("non-static reference member `%#D', can't use default assignment operator", field);
684               continue;
685             }
686
687           comp = current_class_ref;
688           init = parm;
689
690           if (DECL_NAME (field))
691             {
692               if (VFIELD_NAME_P (DECL_NAME (field)))
693                 continue;
694
695               /* True for duplicate members.  */
696               if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
697                 continue;
698             }
699           else if ((t = TREE_TYPE (field)) != NULL_TREE
700                    && ANON_AGGR_TYPE_P (t)
701                    && TYPE_FIELDS (t) != NULL_TREE)
702             /* Just use the field; anonymous types can't have
703                nontrivial copy ctors or assignment ops.  */;
704           else
705             continue;
706
707           comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
708           init = build (COMPONENT_REF,
709                         cp_build_qualified_type (TREE_TYPE (field), cvquals),
710                         init, field);
711
712           if (DECL_NAME (field))
713             finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
714           else
715             finish_expr_stmt (build (MODIFY_EXPR, TREE_TYPE (comp), comp,
716                                      init));
717         }
718     }
719   finish_return_stmt (current_class_ref);
720   finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
721 }
722
723 void
724 synthesize_method (tree fndecl)
725 {
726   bool nested = (current_function_decl != NULL_TREE);
727   tree context = decl_function_context (fndecl);
728   bool need_body = true;
729   tree stmt;
730
731   if (at_eof)
732     import_export_decl (fndecl);
733
734   /* If we've been asked to synthesize a clone, just synthesize the
735      cloned function instead.  Doing so will automatically fill in the
736      body for the clone.  */
737   if (DECL_CLONED_FUNCTION_P (fndecl))
738     {
739       synthesize_method (DECL_CLONED_FUNCTION (fndecl));
740       return;
741     }
742
743   if (! context)
744     push_to_top_level ();
745   else if (nested)
746     push_function_context_to (context);
747
748   /* Put the function definition at the position where it is needed,
749      rather than within the body of the class.  That way, an error
750      during the generation of the implicit body points at the place
751      where the attempt to generate the function occurs, giving the
752      user a hint as to why we are attempting to generate the
753      function.  */
754   DECL_SOURCE_LINE (fndecl) = lineno;
755   DECL_SOURCE_FILE (fndecl) = input_filename;
756
757   interface_unknown = 1;
758   start_function (NULL_TREE, fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
759   clear_last_expr ();
760   stmt = begin_function_body ();
761
762   if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
763     {
764       do_build_assign_ref (fndecl);
765       need_body = false;
766     }
767   else if (DECL_CONSTRUCTOR_P (fndecl))
768     {
769       tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
770       if (arg_chain != void_list_node)
771         do_build_copy_constructor (fndecl);
772       else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
773         finish_mem_initializers (NULL_TREE);
774     }
775
776   /* If we haven't yet generated the body of the function, just
777      generate an empty compound statement.  */
778   if (need_body)
779     {
780       tree compound_stmt;
781       compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
782       finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
783     }
784
785   finish_function_body (stmt);
786   expand_body (finish_function (0));
787
788   extract_interface_info ();
789   if (! context)
790     pop_from_top_level ();
791   else if (nested)
792     pop_function_context_from (context);
793 }
794
795 /* Use EXTRACTOR to locate the relevant function called for each base &
796    class field of TYPE. CLIENT allows additional information to be passed
797    to EXTRACTOR.  Generates the union of all exceptions generated by those
798    functions.  Note that we haven't updated TYPE_FIELDS and such of any
799    variants yet, so we need to look at the main one.  */
800
801 static tree
802 synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
803                            void *client)
804 {
805   tree raises = empty_except_spec;
806   tree fields = TYPE_FIELDS (type);
807   int i, n_bases = CLASSTYPE_N_BASECLASSES (type);
808   tree binfos = TYPE_BINFO_BASETYPES (type);
809
810   for (i = 0; i != n_bases; i++)
811     {
812       tree base = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
813       tree fn = (*extractor) (base, client);
814       if (fn)
815         {
816           tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
817           
818           raises = merge_exception_specifiers (raises, fn_raises);
819         }
820     }
821   for (; fields; fields = TREE_CHAIN (fields))
822     {
823       tree type = TREE_TYPE (fields);
824       tree fn;
825       
826       if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
827         continue;
828       while (TREE_CODE (type) == ARRAY_TYPE)
829         type = TREE_TYPE (type);
830       if (TREE_CODE (type) != RECORD_TYPE)
831         continue;
832       
833       fn = (*extractor) (type, client);
834       if (fn)
835         {
836           tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
837           
838           raises = merge_exception_specifiers (raises, fn_raises);
839         }
840     }
841   return raises;
842 }
843
844 /* Locate the dtor of TYPE.  */
845
846 static tree
847 locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
848 {
849   tree fns;
850   
851   if (!TYPE_HAS_DESTRUCTOR (type))
852     return NULL_TREE;
853   fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
854                       CLASSTYPE_DESTRUCTOR_SLOT);
855   return fns;
856 }
857
858 /* Locate the default ctor of TYPE.  */
859
860 static tree
861 locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
862 {
863   tree fns;
864   
865   if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
866     return NULL_TREE;
867   
868   fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type),
869                       CLASSTYPE_CONSTRUCTOR_SLOT);
870   for (; fns; fns = OVL_NEXT (fns))
871     {
872       tree fn = OVL_CURRENT (fns);
873       tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
874       
875       if (sufficient_parms_p (TREE_CHAIN (parms)))
876         return fn;
877     }
878   return NULL_TREE;
879 }
880
881 struct copy_data
882 {
883   tree name;
884   int quals;
885 };
886
887 /* Locate the copy ctor or copy assignment of TYPE. CLIENT_
888    points to a COPY_DATA holding the name (NULL for the ctor)
889    and desired qualifiers of the source operand.  */
890
891 static tree
892 locate_copy (tree type, void *client_)
893 {
894   struct copy_data *client = (struct copy_data *)client_;
895   tree fns;
896   int ix = -1;
897   tree best = NULL_TREE;
898   bool excess_p = false;
899   
900   if (client->name)
901     {
902       if (TYPE_HAS_ASSIGN_REF (type))
903         ix = lookup_fnfields_1 (type, client->name);
904     }
905   else if (TYPE_HAS_INIT_REF (type))
906     ix = CLASSTYPE_CONSTRUCTOR_SLOT;
907   if (ix < 0)
908     return NULL_TREE;
909   fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix);
910   
911   for (; fns; fns = OVL_NEXT (fns))
912     {
913       tree fn = OVL_CURRENT (fns);
914       tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
915       tree src_type;
916       int excess;
917       int quals;
918       
919       parms = TREE_CHAIN (parms);
920       if (!parms)
921         continue;
922       src_type = TREE_VALUE (parms);
923       if (TREE_CODE (src_type) == REFERENCE_TYPE)
924         src_type = TREE_TYPE (src_type);
925       if (!same_type_ignoring_top_level_qualifiers_p (src_type, type))
926         continue;
927       if (!sufficient_parms_p (TREE_CHAIN (parms)))
928         continue;
929       quals = cp_type_quals (src_type);
930       if (client->quals & ~quals)
931         continue;
932       excess = quals & ~client->quals;
933       if (!best || (excess_p && !excess))
934         {
935           best = fn;
936           excess_p = excess;
937         }
938       else
939         /* Ambiguous */
940         return NULL_TREE;
941     }
942   return best;
943 }
944
945 /* Implicitly declare the special function indicated by KIND, as a
946    member of TYPE.  For copy constructors and assignment operators,
947    CONST_P indicates whether these functions should take a const
948    reference argument or a non-const reference.  */
949
950 tree
951 implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
952 {
953   tree declspecs = NULL_TREE;
954   tree fn, args = NULL_TREE;
955   tree raises = empty_except_spec;
956   bool retref = false;
957   bool has_parm = false;
958   tree name = constructor_name (type);
959
960   switch (kind)
961     {
962     case sfk_destructor:
963       /* Destructor.  */
964       name = build_nt (BIT_NOT_EXPR, name);
965       args = void_list_node;
966       raises = synthesize_exception_spec (type, &locate_dtor, 0);
967       break;
968
969     case sfk_constructor:
970       /* Default constructor.  */
971       args = void_list_node;
972       raises = synthesize_exception_spec (type, &locate_ctor, 0);
973       break;
974
975     case sfk_copy_constructor:
976     case sfk_assignment_operator:
977     {
978       struct copy_data data;
979       tree argtype = type;
980       
981       has_parm = true;
982       data.name = NULL;
983       data.quals = 0;
984       if (kind == sfk_assignment_operator)
985         {
986           retref = true;
987           declspecs = build_tree_list (NULL_TREE, type);
988
989           name = ansi_assopname (NOP_EXPR);
990           data.name = name;
991         }
992       if (const_p)
993         {
994           data.quals = TYPE_QUAL_CONST;
995           argtype = build_qualified_type (argtype, TYPE_QUAL_CONST);
996         }
997     
998       argtype = build_reference_type (argtype);
999       args = build_tree_list (hash_tree_chain (argtype, NULL_TREE),
1000                               get_identifier ("_ctor_arg"));
1001       args = tree_cons (NULL_TREE, args, void_list_node);
1002       
1003       raises = synthesize_exception_spec (type, &locate_copy, &data);
1004       break;
1005     }
1006     default:
1007       abort ();
1008     }
1009
1010   TREE_PARMLIST (args) = 1;
1011
1012   {
1013     tree declarator = make_call_declarator (name, args, NULL_TREE, raises);
1014     
1015     if (retref)
1016       declarator = build_nt (ADDR_EXPR, declarator);
1017
1018     fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
1019     if (has_parm)
1020       TREE_USED (FUNCTION_FIRST_USER_PARM (fn)) = 1;
1021   }
1022
1023   my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 20000408);
1024
1025   DECL_ARTIFICIAL (fn) = 1;
1026   DECL_NOT_REALLY_EXTERN (fn) = 1;
1027   DECL_DECLARED_INLINE_P (fn) = 1;
1028   DECL_INLINE (fn) = 1;
1029   defer_fn (fn);
1030   
1031   return fn;
1032 }
1033
1034 /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
1035    as there are artificial parms in FN.  */
1036
1037 tree
1038 skip_artificial_parms_for (tree fn, tree list)
1039 {
1040   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1041     list = TREE_CHAIN (list);
1042   else
1043     return list;
1044
1045   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1046     list = TREE_CHAIN (list);
1047   if (DECL_HAS_VTT_PARM_P (fn))
1048     list = TREE_CHAIN (list);
1049   return list;
1050 }