OSDN Git Service

266406c7cd0f8d94a4c499df9a89cc1c0e2d2559
[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, 2003, 2004, 2005, 2007, 2008, 2009
5    Free Software Foundation, Inc.
6    Contributed by Michael Tiemann (tiemann@cygnus.com)
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
14
15 GCC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
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 #include "tree-pass.h"
40 #include "diagnostic.h"
41 #include "cgraph.h"
42
43 /* Various flags to control the mangling process.  */
44
45 enum mangling_flags
46 {
47   /* No flags.  */
48   mf_none = 0,
49   /* The thing we are presently mangling is part of a template type,
50      rather than a fully instantiated type.  Therefore, we may see
51      complex expressions where we would normally expect to see a
52      simple integer constant.  */
53   mf_maybe_uninstantiated = 1,
54   /* When mangling a numeric value, use the form `_XX_' (instead of
55      just `XX') if the value has more than one digit.  */
56   mf_use_underscores_around_value = 2
57 };
58
59 typedef enum mangling_flags mangling_flags;
60
61 static tree thunk_adjust (tree, bool, HOST_WIDE_INT, tree);
62 static void do_build_assign_ref (tree);
63 static void do_build_copy_constructor (tree);
64 static tree synthesize_exception_spec (tree, tree (*) (tree, void *), void *);
65 static tree make_alias_for_thunk (tree);
66
67 /* Called once to initialize method.c.  */
68
69 void
70 init_method (void)
71 {
72   init_mangle ();
73 }
74 \f
75 /* Return a this or result adjusting thunk to FUNCTION.  THIS_ADJUSTING
76    indicates whether it is a this or result adjusting thunk.
77    FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
78    (see thunk_adjust).  VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
79    never is.  VIRTUAL_OFFSET is the /index/ into the vtable for this
80    adjusting thunks, we scale it to a byte offset. For covariant
81    thunks VIRTUAL_OFFSET is the virtual binfo.  You must post process
82    the returned thunk with finish_thunk.  */
83
84 tree
85 make_thunk (tree function, bool this_adjusting,
86             tree fixed_offset, tree virtual_offset)
87 {
88   HOST_WIDE_INT d;
89   tree thunk;
90
91   gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
92   /* We can have this thunks to covariant thunks, but not vice versa.  */
93   gcc_assert (!DECL_THIS_THUNK_P (function));
94   gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting);
95
96   /* Scale the VIRTUAL_OFFSET to be in terms of bytes.  */
97   if (this_adjusting && virtual_offset)
98     virtual_offset
99       = size_binop (MULT_EXPR,
100                     virtual_offset,
101                     convert (ssizetype,
102                              TYPE_SIZE_UNIT (vtable_entry_type)));
103
104   d = tree_low_cst (fixed_offset, 0);
105
106   /* See if we already have the thunk in question.  For this_adjusting
107      thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
108      will be a BINFO.  */
109   for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
110     if (DECL_THIS_THUNK_P (thunk) == this_adjusting
111         && THUNK_FIXED_OFFSET (thunk) == d
112         && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
113         && (!virtual_offset
114             || (this_adjusting
115                 ? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
116                                       virtual_offset)
117                 : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
118       return thunk;
119
120   /* All thunks must be created before FUNCTION is actually emitted;
121      the ABI requires that all thunks be emitted together with the
122      function to which they transfer control.  */
123   gcc_assert (!TREE_ASM_WRITTEN (function));
124   /* Likewise, we can only be adding thunks to a function declared in
125      the class currently being laid out.  */
126   gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
127               && TYPE_BEING_DEFINED (DECL_CONTEXT (function)));
128
129   thunk = build_decl (DECL_SOURCE_LOCATION (function),
130                       FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
131   DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
132   cxx_dup_lang_specific_decl (thunk);
133   DECL_THUNKS (thunk) = NULL_TREE;
134
135   DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
136   TREE_READONLY (thunk) = TREE_READONLY (function);
137   TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
138   TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
139   SET_DECL_THUNK_P (thunk, this_adjusting);
140   THUNK_TARGET (thunk) = function;
141   THUNK_FIXED_OFFSET (thunk) = d;
142   THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
143   THUNK_ALIAS (thunk) = NULL_TREE;
144
145   /* The thunk itself is not a constructor or destructor, even if
146      the thing it is thunking to is.  */
147   DECL_INTERFACE_KNOWN (thunk) = 1;
148   DECL_NOT_REALLY_EXTERN (thunk) = 1;
149   DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
150   DECL_DESTRUCTOR_P (thunk) = 0;
151   DECL_CONSTRUCTOR_P (thunk) = 0;
152   DECL_EXTERNAL (thunk) = 1;
153   DECL_ARTIFICIAL (thunk) = 1;
154   /* The THUNK is not a pending inline, even if the FUNCTION is.  */
155   DECL_PENDING_INLINE_P (thunk) = 0;
156   DECL_DECLARED_INLINE_P (thunk) = 0;
157   /* Nor is it a template instantiation.  */
158   DECL_USE_TEMPLATE (thunk) = 0;
159   DECL_TEMPLATE_INFO (thunk) = NULL;
160
161   /* Add it to the list of thunks associated with FUNCTION.  */
162   TREE_CHAIN (thunk) = DECL_THUNKS (function);
163   DECL_THUNKS (function) = thunk;
164
165   return thunk;
166 }
167
168 /* Finish THUNK, a thunk decl.  */
169
170 void
171 finish_thunk (tree thunk)
172 {
173   tree function, name;
174   tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
175   tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
176
177   gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk));
178   if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
179     virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
180   function = THUNK_TARGET (thunk);
181   name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
182                        fixed_offset, virtual_offset);
183
184   /* We can end up with declarations of (logically) different
185      covariant thunks, that do identical adjustments.  The two thunks
186      will be adjusting between within different hierarchies, which
187      happen to have the same layout.  We must nullify one of them to
188      refer to the other.  */
189   if (DECL_RESULT_THUNK_P (thunk))
190     {
191       tree cov_probe;
192
193       for (cov_probe = DECL_THUNKS (function);
194            cov_probe; cov_probe = TREE_CHAIN (cov_probe))
195         if (DECL_NAME (cov_probe) == name)
196           {
197             gcc_assert (!DECL_THUNKS (thunk));
198             THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
199                                    ? THUNK_ALIAS (cov_probe) : cov_probe);
200             break;
201           }
202     }
203
204   DECL_NAME (thunk) = name;
205   SET_DECL_ASSEMBLER_NAME (thunk, name);
206 }
207
208 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
209    offset indicated by VIRTUAL_OFFSET, if that is
210    non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
211    zero for a result adjusting thunk.  */
212
213 static tree
214 thunk_adjust (tree ptr, bool this_adjusting,
215               HOST_WIDE_INT fixed_offset, tree virtual_offset)
216 {
217   if (this_adjusting)
218     /* Adjust the pointer by the constant.  */
219     ptr = fold_build2_loc (input_location,
220                        POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
221                        size_int (fixed_offset));
222
223   /* If there's a virtual offset, look up that value in the vtable and
224      adjust the pointer again.  */
225   if (virtual_offset)
226     {
227       tree vtable;
228
229       ptr = save_expr (ptr);
230       /* The vptr is always at offset zero in the object.  */
231       vtable = build1 (NOP_EXPR,
232                        build_pointer_type (build_pointer_type
233                                            (vtable_entry_type)),
234                        ptr);
235       /* Form the vtable address.  */
236       vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
237       /* Find the entry with the vcall offset.  */
238       vtable = fold_build2_loc (input_location,
239                             POINTER_PLUS_EXPR, TREE_TYPE (vtable), vtable,
240                             fold_convert (sizetype, virtual_offset));
241       /* Get the offset itself.  */
242       vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
243       /* Adjust the `this' pointer.  */
244       ptr = fold_build2_loc (input_location,
245                          POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
246                          fold_convert (sizetype, vtable));
247     }
248
249   if (!this_adjusting)
250     /* Adjust the pointer by the constant.  */
251     ptr = fold_build2_loc (input_location,
252                        POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
253                        size_int (fixed_offset));
254
255   return ptr;
256 }
257
258 static GTY (()) int thunk_labelno;
259
260 /* Create a static alias to function.  */
261
262 tree
263 make_alias_for (tree function, tree newid)
264 {
265   tree alias = build_decl (DECL_SOURCE_LOCATION (function),
266                            FUNCTION_DECL, newid, TREE_TYPE (function));
267   DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
268   cxx_dup_lang_specific_decl (alias);
269   DECL_CONTEXT (alias) = NULL;
270   TREE_READONLY (alias) = TREE_READONLY (function);
271   TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);
272   TREE_PUBLIC (alias) = 0;
273   DECL_INTERFACE_KNOWN (alias) = 1;
274   DECL_NOT_REALLY_EXTERN (alias) = 1;
275   DECL_THIS_STATIC (alias) = 1;
276   DECL_SAVED_FUNCTION_DATA (alias) = NULL;
277   DECL_DESTRUCTOR_P (alias) = 0;
278   DECL_CONSTRUCTOR_P (alias) = 0;
279   DECL_EXTERNAL (alias) = 0;
280   DECL_ARTIFICIAL (alias) = 1;
281   DECL_PENDING_INLINE_P (alias) = 0;
282   DECL_DECLARED_INLINE_P (alias) = 0;
283   DECL_USE_TEMPLATE (alias) = 0;
284   DECL_TEMPLATE_INSTANTIATED (alias) = 0;
285   DECL_TEMPLATE_INFO (alias) = NULL;
286   DECL_INITIAL (alias) = error_mark_node;
287   TREE_ADDRESSABLE (alias) = 1;
288   TREE_USED (alias) = 1;
289   SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
290   TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
291   return alias;
292 }
293
294 static tree
295 make_alias_for_thunk (tree function)
296 {
297   tree alias;
298   char buf[256];
299
300   ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
301   thunk_labelno++;
302
303   alias = make_alias_for (function, get_identifier (buf));
304
305   if (!flag_syntax_only)
306     assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
307
308   return alias;
309 }
310
311 /* Emit the definition of a C++ multiple inheritance or covariant
312    return vtable thunk.  If EMIT_P is nonzero, the thunk is emitted
313    immediately.  */
314
315 void
316 use_thunk (tree thunk_fndecl, bool emit_p)
317 {
318   tree a, t, function, alias;
319   tree virtual_offset;
320   HOST_WIDE_INT fixed_offset, virtual_value;
321   bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
322
323   /* We should have called finish_thunk to give it a name.  */
324   gcc_assert (DECL_NAME (thunk_fndecl));
325
326   /* We should never be using an alias, always refer to the
327      aliased thunk.  */
328   gcc_assert (!THUNK_ALIAS (thunk_fndecl));
329
330   if (TREE_ASM_WRITTEN (thunk_fndecl))
331     return;
332
333   function = THUNK_TARGET (thunk_fndecl);
334   if (DECL_RESULT (thunk_fndecl))
335     /* We already turned this thunk into an ordinary function.
336        There's no need to process this thunk again.  */
337     return;
338
339   if (DECL_THUNK_P (function))
340     /* The target is itself a thunk, process it now.  */
341     use_thunk (function, emit_p);
342
343   /* Thunks are always addressable; they only appear in vtables.  */
344   TREE_ADDRESSABLE (thunk_fndecl) = 1;
345
346   /* Figure out what function is being thunked to.  It's referenced in
347      this translation unit.  */
348   TREE_ADDRESSABLE (function) = 1;
349   mark_used (function);
350   if (!emit_p)
351     return;
352
353   if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
354    alias = make_alias_for_thunk (function);
355   else
356    alias = function;
357
358   fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
359   virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
360
361   if (virtual_offset)
362     {
363       if (!this_adjusting)
364         virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
365       virtual_value = tree_low_cst (virtual_offset, /*pos=*/0);
366       gcc_assert (virtual_value);
367     }
368   else
369     virtual_value = 0;
370
371   /* And, if we need to emit the thunk, it's used.  */
372   mark_used (thunk_fndecl);
373   /* This thunk is actually defined.  */
374   DECL_EXTERNAL (thunk_fndecl) = 0;
375   /* The linkage of the function may have changed.  FIXME in linkage
376      rewrite.  */
377   TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
378   DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
379   DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
380     = DECL_VISIBILITY_SPECIFIED (function);
381   if (DECL_ONE_ONLY (function))
382     make_decl_one_only (thunk_fndecl, cxx_comdat_group (thunk_fndecl));
383
384   if (flag_syntax_only)
385     {
386       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
387       return;
388     }
389
390   push_to_top_level ();
391
392   if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
393       && targetm.have_named_sections)
394     {
395       resolve_unique_section (function, 0, flag_function_sections);
396
397       if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
398         {
399           resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
400
401           /* Output the thunk into the same section as function.  */
402           DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
403         }
404     }
405
406   /* Set up cloned argument trees for the thunk.  */
407   t = NULL_TREE;
408   for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
409     {
410       tree x = copy_node (a);
411       TREE_CHAIN (x) = t;
412       DECL_CONTEXT (x) = thunk_fndecl;
413       SET_DECL_RTL (x, NULL_RTX);
414       DECL_HAS_VALUE_EXPR_P (x) = 0;
415       t = x;
416     }
417   a = nreverse (t);
418   DECL_ARGUMENTS (thunk_fndecl) = a;
419
420   if (this_adjusting
421       && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
422                                               virtual_value, alias))
423     {
424       const char *fnname;
425       tree fn_block;
426       
427       current_function_decl = thunk_fndecl;
428       DECL_RESULT (thunk_fndecl)
429         = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
430                       RESULT_DECL, 0, integer_type_node);
431       fnname = IDENTIFIER_POINTER (DECL_NAME (thunk_fndecl));
432       /* The back end expects DECL_INITIAL to contain a BLOCK, so we
433          create one.  */
434       fn_block = make_node (BLOCK);
435       BLOCK_VARS (fn_block) = a;
436       DECL_INITIAL (thunk_fndecl) = fn_block;
437       init_function_start (thunk_fndecl);
438       cfun->is_thunk = 1;
439       assemble_start_function (thunk_fndecl, fnname);
440
441       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
442                                        fixed_offset, virtual_value, alias);
443
444       assemble_end_function (thunk_fndecl, fnname);
445       init_insn_lengths ();
446       free_after_compilation (cfun);
447       current_function_decl = 0;
448       set_cfun (NULL);
449       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
450     }
451   else
452     {
453       int i;
454       tree *argarray = (tree *) alloca (list_length (a) * sizeof (tree));
455       /* If this is a covariant thunk, or we don't have the necessary
456          code for efficient thunks, generate a thunk function that
457          just makes a call to the real function.  Unfortunately, this
458          doesn't work for varargs.  */
459
460       if (varargs_function_p (function))
461         error ("generic thunk code fails for method %q#D which uses %<...%>",
462                function);
463
464       DECL_RESULT (thunk_fndecl) = NULL_TREE;
465
466       start_preparsed_function (thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
467       /* We don't bother with a body block for thunks.  */
468
469       /* There's no need to check accessibility inside the thunk body.  */
470       push_deferring_access_checks (dk_no_check);
471
472       t = a;
473       if (this_adjusting)
474         t = thunk_adjust (t, /*this_adjusting=*/1,
475                           fixed_offset, virtual_offset);
476
477       /* Build up the call to the real function.  */
478       argarray[0] = t;
479       for (i = 1, a = TREE_CHAIN (a); a; a = TREE_CHAIN (a), i++)
480         argarray[i] = a;
481       t = build_call_a (alias, i, argarray);
482       CALL_FROM_THUNK_P (t) = 1;
483       CALL_CANNOT_INLINE_P (t) = 1;
484
485       if (VOID_TYPE_P (TREE_TYPE (t)))
486         finish_expr_stmt (t);
487       else
488         {
489           if (!this_adjusting)
490             {
491               tree cond = NULL_TREE;
492
493               if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
494                 {
495                   /* If the return type is a pointer, we need to
496                      protect against NULL.  We know there will be an
497                      adjustment, because that's why we're emitting a
498                      thunk.  */
499                   t = save_expr (t);
500                   cond = cp_convert (boolean_type_node, t);
501                 }
502
503               t = thunk_adjust (t, /*this_adjusting=*/0,
504                                 fixed_offset, virtual_offset);
505               if (cond)
506                 t = build3 (COND_EXPR, TREE_TYPE (t), cond, t,
507                             cp_convert (TREE_TYPE (t), integer_zero_node));
508             }
509           if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
510             t = build_cplus_new (TREE_TYPE (t), t);
511           finish_return_stmt (t);
512         }
513
514       /* Since we want to emit the thunk, we explicitly mark its name as
515          referenced.  */
516       mark_decl_referenced (thunk_fndecl);
517
518       /* But we don't want debugging information about it.  */
519       DECL_IGNORED_P (thunk_fndecl) = 1;
520
521       /* Re-enable access control.  */
522       pop_deferring_access_checks ();
523
524       thunk_fndecl = finish_function (0);
525       cgraph_add_new_function (thunk_fndecl, false);
526     }
527
528   pop_from_top_level ();
529 }
530 \f
531 /* Code for synthesizing methods which have default semantics defined.  */
532
533 /* Generate code for default X(X&) or X(X&&) constructor.  */
534
535 static void
536 do_build_copy_constructor (tree fndecl)
537 {
538   tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
539   bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
540
541   parm = convert_from_reference (parm);
542
543   if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
544       && is_empty_class (current_class_type))
545     /* Don't copy the padding byte; it might not have been allocated
546        if *this is a base subobject.  */;
547   else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
548     {
549       tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
550       finish_expr_stmt (t);
551     }
552   else
553     {
554       tree fields = TYPE_FIELDS (current_class_type);
555       tree member_init_list = NULL_TREE;
556       int cvquals = cp_type_quals (TREE_TYPE (parm));
557       int i;
558       tree binfo, base_binfo;
559       tree init;
560       VEC(tree,gc) *vbases;
561
562       /* Initialize all the base-classes with the parameter converted
563          to their type so that we get their copy constructor and not
564          another constructor that takes current_class_type.  We must
565          deal with the binfo's directly as a direct base might be
566          inaccessible due to ambiguity.  */
567       for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
568            VEC_iterate (tree, vbases, i, binfo); i++)
569         {
570           init = build_base_path (PLUS_EXPR, parm, binfo, 1);
571           if (move_p)
572             init = move (init);
573           member_init_list
574             = tree_cons (binfo,
575                          build_tree_list (NULL_TREE, init),
576                          member_init_list);
577         }
578
579       for (binfo = TYPE_BINFO (current_class_type), i = 0;
580            BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
581         {
582           if (BINFO_VIRTUAL_P (base_binfo))
583             continue;
584
585           init = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
586           if (move_p)
587             init = move (init);
588           member_init_list
589             = tree_cons (base_binfo,
590                          build_tree_list (NULL_TREE, init),
591                          member_init_list);
592         }
593
594       for (; fields; fields = TREE_CHAIN (fields))
595         {
596           tree field = fields;
597           tree expr_type;
598
599           if (TREE_CODE (field) != FIELD_DECL)
600             continue;
601
602           expr_type = TREE_TYPE (field);
603           if (DECL_NAME (field))
604             {
605               if (VFIELD_NAME_P (DECL_NAME (field)))
606                 continue;
607             }
608           else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
609             /* Just use the field; anonymous types can't have
610                nontrivial copy ctors or assignment ops.  */;
611           else
612             continue;
613
614           /* Compute the type of "init->field".  If the copy-constructor
615              parameter is, for example, "const S&", and the type of
616              the field is "T", then the type will usually be "const
617              T".  (There are no cv-qualified variants of reference
618              types.)  */
619           if (TREE_CODE (expr_type) != REFERENCE_TYPE)
620             {
621               int quals = cvquals;
622
623               if (DECL_MUTABLE_P (field))
624                 quals &= ~TYPE_QUAL_CONST;
625               expr_type = cp_build_qualified_type (expr_type, quals);
626             }
627
628           init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
629           if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE)
630             init = move (init);
631           init = build_tree_list (NULL_TREE, init);
632
633           member_init_list = tree_cons (field, init, member_init_list);
634         }
635       finish_mem_initializers (member_init_list);
636     }
637 }
638
639 static void
640 do_build_assign_ref (tree fndecl)
641 {
642   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
643   tree compound_stmt;
644
645   compound_stmt = begin_compound_stmt (0);
646   parm = convert_from_reference (parm);
647
648   if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)
649       && is_empty_class (current_class_type))
650     /* Don't copy the padding byte; it might not have been allocated
651        if *this is a base subobject.  */;
652   else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))
653     {
654       tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm);
655       finish_expr_stmt (t);
656     }
657   else
658     {
659       tree fields;
660       int cvquals = cp_type_quals (TREE_TYPE (parm));
661       int i;
662       tree binfo, base_binfo;
663
664       /* Assign to each of the direct base classes.  */
665       for (binfo = TYPE_BINFO (current_class_type), i = 0;
666            BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
667         {
668           tree converted_parm;
669           VEC(tree,gc) *parmvec;
670
671           /* We must convert PARM directly to the base class
672              explicitly since the base class may be ambiguous.  */
673           converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
674           /* Call the base class assignment operator.  */
675           parmvec = make_tree_vector_single (converted_parm);
676           finish_expr_stmt
677             (build_special_member_call (current_class_ref,
678                                         ansi_assopname (NOP_EXPR),
679                                         &parmvec,
680                                         base_binfo,
681                                         LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
682                                         tf_warning_or_error));
683           release_tree_vector (parmvec);
684         }
685
686       /* Assign to each of the non-static data members.  */
687       for (fields = TYPE_FIELDS (current_class_type);
688            fields;
689            fields = TREE_CHAIN (fields))
690         {
691           tree comp = current_class_ref;
692           tree init = parm;
693           tree field = fields;
694           tree expr_type;
695           int quals;
696
697           if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
698             continue;
699
700           expr_type = TREE_TYPE (field);
701
702           if (CP_TYPE_CONST_P (expr_type))
703             {
704               error ("non-static const member %q#D, can't use default "
705                      "assignment operator", field);
706               continue;
707             }
708           else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
709             {
710               error ("non-static reference member %q#D, can't use "
711                      "default assignment operator", field);
712               continue;
713             }
714
715           if (DECL_NAME (field))
716             {
717               if (VFIELD_NAME_P (DECL_NAME (field)))
718                 continue;
719             }
720           else if (ANON_AGGR_TYPE_P (expr_type)
721                    && TYPE_FIELDS (expr_type) != NULL_TREE)
722             /* Just use the field; anonymous types can't have
723                nontrivial copy ctors or assignment ops.  */;
724           else
725             continue;
726
727           comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);
728
729           /* Compute the type of init->field  */
730           quals = cvquals;
731           if (DECL_MUTABLE_P (field))
732             quals &= ~TYPE_QUAL_CONST;
733           expr_type = cp_build_qualified_type (expr_type, quals);
734
735           init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
736
737           if (DECL_NAME (field))
738             init = cp_build_modify_expr (comp, NOP_EXPR, init, 
739                                          tf_warning_or_error);
740           else
741             init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
742           finish_expr_stmt (init);
743         }
744     }
745   finish_return_stmt (current_class_ref);
746   finish_compound_stmt (compound_stmt);
747 }
748
749 /* Synthesize FNDECL, a non-static member function.   */
750
751 void
752 synthesize_method (tree fndecl)
753 {
754   bool nested = (current_function_decl != NULL_TREE);
755   tree context = decl_function_context (fndecl);
756   bool need_body = true;
757   tree stmt;
758   location_t save_input_location = input_location;
759   int error_count = errorcount;
760   int warning_count = warningcount;
761
762   /* Reset the source location, we might have been previously
763      deferred, and thus have saved where we were first needed.  */
764   DECL_SOURCE_LOCATION (fndecl)
765     = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
766
767   /* If we've been asked to synthesize a clone, just synthesize the
768      cloned function instead.  Doing so will automatically fill in the
769      body for the clone.  */
770   if (DECL_CLONED_FUNCTION_P (fndecl))
771     fndecl = DECL_CLONED_FUNCTION (fndecl);
772
773   /* We may be in the middle of deferred access check.  Disable
774      it now.  */
775   push_deferring_access_checks (dk_no_deferred);
776
777   if (! context)
778     push_to_top_level ();
779   else if (nested)
780     push_function_context ();
781
782   input_location = DECL_SOURCE_LOCATION (fndecl);
783
784   start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
785   stmt = begin_function_body ();
786
787   if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
788     {
789       do_build_assign_ref (fndecl);
790       need_body = false;
791     }
792   else if (DECL_CONSTRUCTOR_P (fndecl))
793     {
794       tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
795       if (arg_chain != void_list_node)
796         do_build_copy_constructor (fndecl);
797       else
798         finish_mem_initializers (NULL_TREE);
799     }
800
801   /* If we haven't yet generated the body of the function, just
802      generate an empty compound statement.  */
803   if (need_body)
804     {
805       tree compound_stmt;
806       compound_stmt = begin_compound_stmt (BCS_FN_BODY);
807       finish_compound_stmt (compound_stmt);
808     }
809
810   finish_function_body (stmt);
811   expand_or_defer_fn (finish_function (0));
812
813   input_location = save_input_location;
814
815   if (! context)
816     pop_from_top_level ();
817   else if (nested)
818     pop_function_context ();
819
820   pop_deferring_access_checks ();
821
822   if (error_count != errorcount || warning_count != warningcount)
823     inform (input_location, "synthesized method %qD first required here ",
824             fndecl);
825 }
826
827 /* Use EXTRACTOR to locate the relevant function called for each base &
828    class field of TYPE. CLIENT allows additional information to be passed
829    to EXTRACTOR.  Generates the union of all exceptions generated by those
830    functions.  Note that we haven't updated TYPE_FIELDS and such of any
831    variants yet, so we need to look at the main one.  */
832
833 static tree
834 synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
835                            void *client)
836 {
837   tree raises = empty_except_spec;
838   tree fields = TYPE_FIELDS (type);
839   tree binfo, base_binfo;
840   int i;
841
842   for (binfo = TYPE_BINFO (type), i = 0;
843        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
844     {
845       tree fn = (*extractor) (BINFO_TYPE (base_binfo), client);
846       if (fn)
847         {
848           tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
849
850           raises = merge_exception_specifiers (raises, fn_raises);
851         }
852     }
853   for (; fields; fields = TREE_CHAIN (fields))
854     {
855       tree type = TREE_TYPE (fields);
856       tree fn;
857
858       if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
859         continue;
860       while (TREE_CODE (type) == ARRAY_TYPE)
861         type = TREE_TYPE (type);
862       if (!CLASS_TYPE_P (type))
863         continue;
864
865       fn = (*extractor) (type, client);
866       if (fn)
867         {
868           tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
869
870           raises = merge_exception_specifiers (raises, fn_raises);
871         }
872     }
873   return raises;
874 }
875
876 /* Locate the dtor of TYPE.  */
877
878 tree
879 locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
880 {
881   return CLASSTYPE_DESTRUCTORS (type);
882 }
883
884 /* Locate the default ctor of TYPE.  */
885
886 tree
887 locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
888 {
889   tree fns;
890
891   if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
892     return NULL_TREE;
893
894   /* Call lookup_fnfields_1 to create the constructor declarations, if
895      necessary.  */
896   if (CLASSTYPE_LAZY_DEFAULT_CTOR (type))
897     return lazily_declare_fn (sfk_constructor, type);
898
899   for (fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns))
900     {
901       tree fn = OVL_CURRENT (fns);
902       tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
903
904       parms = skip_artificial_parms_for (fn, parms);
905
906       if (sufficient_parms_p (parms))
907         return fn;
908     }
909   gcc_unreachable ();
910 }
911
912 struct copy_data
913 {
914   tree name;
915   int quals;
916 };
917
918 /* Locate the copy ctor or copy assignment of TYPE. CLIENT_
919    points to a COPY_DATA holding the name (NULL for the ctor)
920    and desired qualifiers of the source operand.  */
921
922 tree
923 locate_copy (tree type, void *client_)
924 {
925   struct copy_data *client = (struct copy_data *)client_;
926   tree fns;
927   tree best = NULL_TREE;
928   bool excess_p = false;
929
930   if (client->name)
931     {
932       int ix;
933       ix = lookup_fnfields_1 (type, client->name);
934       if (ix < 0)
935         return NULL_TREE;
936       fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (type), ix);
937     }
938   else if (TYPE_HAS_INIT_REF (type))
939     {
940       /* If construction of the copy constructor was postponed, create
941          it now.  */
942       if (CLASSTYPE_LAZY_COPY_CTOR (type))
943         lazily_declare_fn (sfk_copy_constructor, type);
944       if (CLASSTYPE_LAZY_MOVE_CTOR (type))
945         lazily_declare_fn (sfk_move_constructor, type);
946       fns = CLASSTYPE_CONSTRUCTORS (type);
947     }
948   else
949     return NULL_TREE;
950   for (; fns; fns = OVL_NEXT (fns))
951     {
952       tree fn = OVL_CURRENT (fns);
953       tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
954       tree src_type;
955       int excess;
956       int quals;
957
958       parms = skip_artificial_parms_for (fn, parms);
959       if (!parms)
960         continue;
961       src_type = non_reference (TREE_VALUE (parms));
962
963       if (src_type == error_mark_node)
964         return NULL_TREE;
965
966       if (!same_type_ignoring_top_level_qualifiers_p (src_type, type))
967         continue;
968       if (!sufficient_parms_p (TREE_CHAIN (parms)))
969         continue;
970       quals = cp_type_quals (src_type);
971       if (client->quals & ~quals)
972         continue;
973       excess = quals & ~client->quals;
974       if (!best || (excess_p && !excess))
975         {
976           best = fn;
977           excess_p = excess;
978         }
979       else
980         /* Ambiguous */
981         return NULL_TREE;
982     }
983   return best;
984 }
985
986 /* Implicitly declare the special function indicated by KIND, as a
987    member of TYPE.  For copy constructors and assignment operators,
988    CONST_P indicates whether these functions should take a const
989    reference argument or a non-const reference.  Returns the
990    FUNCTION_DECL for the implicitly declared function.  */
991
992 static tree
993 implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
994 {
995   tree fn;
996   tree parameter_types = void_list_node;
997   tree return_type;
998   tree fn_type;
999   tree raises = empty_except_spec;
1000   tree rhs_parm_type = NULL_TREE;
1001   tree this_parm;
1002   tree name;
1003   HOST_WIDE_INT saved_processing_template_decl;
1004
1005   /* Because we create declarations for implicitly declared functions
1006      lazily, we may be creating the declaration for a member of TYPE
1007      while in some completely different context.  However, TYPE will
1008      never be a dependent class (because we never want to do lookups
1009      for implicitly defined functions in a dependent class).
1010      Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
1011      because we only create clones for constructors and destructors
1012      when not in a template.  */
1013   gcc_assert (!dependent_type_p (type));
1014   saved_processing_template_decl = processing_template_decl;
1015   processing_template_decl = 0;
1016
1017   type = TYPE_MAIN_VARIANT (type);
1018
1019   if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type))
1020     {
1021       if (kind == sfk_destructor)
1022         /* See comment in check_special_function_return_type.  */
1023         return_type = build_pointer_type (void_type_node);
1024       else
1025         return_type = build_pointer_type (type);
1026     }
1027   else
1028     return_type = void_type_node;
1029
1030   switch (kind)
1031     {
1032     case sfk_destructor:
1033       /* Destructor.  */
1034       name = constructor_name (type);
1035       raises = synthesize_exception_spec (type, &locate_dtor, 0);
1036       break;
1037
1038     case sfk_constructor:
1039       /* Default constructor.  */
1040       name = constructor_name (type);
1041       raises = synthesize_exception_spec (type, &locate_ctor, 0);
1042       break;
1043
1044     case sfk_copy_constructor:
1045     case sfk_assignment_operator:
1046     case sfk_move_constructor:
1047     {
1048       struct copy_data data;
1049
1050       data.name = NULL;
1051       data.quals = 0;
1052       if (kind == sfk_assignment_operator)
1053         {
1054           return_type = build_reference_type (type);
1055           name = ansi_assopname (NOP_EXPR);
1056           data.name = name;
1057         }
1058       else
1059         name = constructor_name (type);
1060
1061       if (const_p)
1062         {
1063           data.quals = TYPE_QUAL_CONST;
1064           rhs_parm_type = build_qualified_type (type, TYPE_QUAL_CONST);
1065         }
1066       else
1067         rhs_parm_type = type;
1068       rhs_parm_type
1069         = cp_build_reference_type (rhs_parm_type,
1070                                    kind == sfk_move_constructor);
1071       parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
1072       raises = synthesize_exception_spec (type, &locate_copy, &data);
1073       break;
1074     }
1075     default:
1076       gcc_unreachable ();
1077     }
1078
1079   /* Create the function.  */
1080   fn_type = build_method_type_directly (type, return_type, parameter_types);
1081   if (raises)
1082     fn_type = build_exception_variant (fn_type, raises);
1083   fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
1084   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
1085   if (kind == sfk_constructor || kind == sfk_copy_constructor
1086       || kind == sfk_move_constructor)
1087     DECL_CONSTRUCTOR_P (fn) = 1;
1088   else if (kind == sfk_destructor)
1089     DECL_DESTRUCTOR_P (fn) = 1;
1090   else
1091     {
1092       DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
1093       SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
1094     }
1095   
1096   /* If pointers to member functions use the least significant bit to
1097      indicate whether a function is virtual, ensure a pointer
1098      to this function will have that bit clear.  */
1099   if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
1100       && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
1101     DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
1102
1103   /* Create the explicit arguments.  */
1104   if (rhs_parm_type)
1105     {
1106       /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
1107          want its type to be included in the mangled function
1108          name.  */
1109       DECL_ARGUMENTS (fn) = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
1110       TREE_READONLY (DECL_ARGUMENTS (fn)) = 1;
1111     }
1112   /* Add the "this" parameter.  */
1113   this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
1114   TREE_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
1115   DECL_ARGUMENTS (fn) = this_parm;
1116
1117   grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
1118   set_linkage_according_to_type (type, fn);
1119   rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
1120   DECL_IN_AGGR_P (fn) = 1;
1121   DECL_ARTIFICIAL (fn) = 1;
1122   DECL_DEFAULTED_FN (fn) = 1;
1123   DECL_NOT_REALLY_EXTERN (fn) = 1;
1124   DECL_DECLARED_INLINE_P (fn) = 1;
1125   gcc_assert (!TREE_USED (fn));
1126
1127   /* Restore PROCESSING_TEMPLATE_DECL.  */
1128   processing_template_decl = saved_processing_template_decl;
1129
1130   return fn;
1131 }
1132
1133 /* Gives any errors about defaulted functions which need to be deferred
1134    until the containing class is complete.  */
1135
1136 void
1137 defaulted_late_check (tree fn)
1138 {
1139   /* Complain about invalid signature for defaulted fn.  */
1140   tree ctx = DECL_CONTEXT (fn);
1141   special_function_kind kind = special_function_p (fn);
1142   bool fn_const_p = (copy_fn_p (fn) == 2);
1143   tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p);
1144
1145   if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
1146                     TREE_TYPE (TREE_TYPE (implicit_fn)))
1147       || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
1148                      TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
1149     {
1150       error ("defaulted declaration %q+D", fn);
1151       error_at (DECL_SOURCE_LOCATION (fn),
1152                 "does not match expected signature %qD", implicit_fn);
1153     }
1154 }
1155
1156 /* Returns true iff FN can be explicitly defaulted, and gives any
1157    errors if defaulting FN is ill-formed.  */
1158
1159 bool
1160 defaultable_fn_check (tree fn)
1161 {
1162   special_function_kind kind = sfk_none;
1163
1164   if (DECL_CONSTRUCTOR_P (fn))
1165     {
1166       if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
1167         kind = sfk_constructor;
1168       else if (copy_fn_p (fn) > 0
1169                && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
1170                    == void_list_node))
1171         kind = sfk_copy_constructor;
1172       else if (move_fn_p (fn))
1173         kind = sfk_move_constructor;
1174     }
1175   else if (DECL_DESTRUCTOR_P (fn))
1176     kind = sfk_destructor;
1177   else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
1178            && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
1179            && copy_fn_p (fn))
1180     kind = sfk_assignment_operator;
1181
1182   if (kind == sfk_none)
1183     {
1184       error ("%qD cannot be defaulted", fn);
1185       return false;
1186     }
1187   else
1188     {
1189       tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
1190       for (; t && t != void_list_node; t = TREE_CHAIN (t))
1191         if (TREE_PURPOSE (t))
1192           {
1193             error ("defaulted function %q+D with default argument", fn);
1194             break;
1195           }
1196       if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn)))
1197         {
1198           if (DECL_NONCONVERTING_P (fn))
1199             error ("%qD declared explicit cannot be defaulted in the class "
1200                    "body", fn);
1201           if (current_access_specifier != access_public_node)
1202             error ("%qD declared with non-public access cannot be defaulted "
1203                    "in the class body", fn);
1204           if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
1205             error ("function %q+D defaulted on its first declaration "
1206                    "must not have an exception-specification", fn);
1207         }
1208       else if (!processing_template_decl)
1209         defaulted_late_check (fn);
1210
1211       return true;
1212     }
1213 }
1214
1215 /* Add an implicit declaration to TYPE for the kind of function
1216    indicated by SFK.  Return the FUNCTION_DECL for the new implicit
1217    declaration.  */
1218
1219 tree
1220 lazily_declare_fn (special_function_kind sfk, tree type)
1221 {
1222   tree fn;
1223   bool const_p;
1224
1225   /* Figure out whether or not the argument has a const reference
1226      type.  */
1227   if (sfk == sfk_copy_constructor)
1228     const_p = TYPE_HAS_CONST_INIT_REF (type);
1229   else if (sfk == sfk_assignment_operator)
1230     const_p = TYPE_HAS_CONST_ASSIGN_REF (type);
1231   else
1232     /* In this case, CONST_P will be ignored.  */
1233     const_p = false;
1234   /* Declare the function.  */
1235   fn = implicitly_declare_fn (sfk, type, const_p);
1236   /* A destructor may be virtual.  */
1237   if (sfk == sfk_destructor)
1238     check_for_override (fn, type);
1239   /* Add it to CLASSTYPE_METHOD_VEC.  */
1240   add_method (type, fn, NULL_TREE);
1241   /* Add it to TYPE_METHODS.  */
1242   if (sfk == sfk_destructor
1243       && DECL_VIRTUAL_P (fn)
1244       && abi_version_at_least (2))
1245     /* The ABI requires that a virtual destructor go at the end of the
1246        vtable.  */
1247     TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
1248   else
1249     {
1250       /* G++ 3.2 put the implicit destructor at the *beginning* of the
1251          TYPE_METHODS list, which cause the destructor to be emitted
1252          in an incorrect location in the vtable.  */
1253       if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn))
1254         warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant"
1255                  "and may change in a future version of GCC due to "
1256                  "implicit virtual destructor",
1257                  type);
1258       TREE_CHAIN (fn) = TYPE_METHODS (type);
1259       TYPE_METHODS (type) = fn;
1260     }
1261   maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
1262   if (sfk == sfk_assignment_operator)
1263     CLASSTYPE_LAZY_ASSIGNMENT_OP (type) = 0;
1264   else
1265     {
1266       /* Remember that the function has been created.  */
1267       if (sfk == sfk_constructor)
1268         CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
1269       else if (sfk == sfk_copy_constructor)
1270         CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
1271       else if (sfk == sfk_move_constructor)
1272         CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
1273       else if (sfk == sfk_destructor)
1274         CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
1275       /* Create appropriate clones.  */
1276       clone_function_decl (fn, /*update_method_vec=*/true);
1277     }
1278
1279   return fn;
1280 }
1281
1282 /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
1283    as there are artificial parms in FN.  */
1284
1285 tree
1286 skip_artificial_parms_for (const_tree fn, tree list)
1287 {
1288   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1289     list = TREE_CHAIN (list);
1290   else
1291     return list;
1292
1293   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1294     list = TREE_CHAIN (list);
1295   if (DECL_HAS_VTT_PARM_P (fn))
1296     list = TREE_CHAIN (list);
1297   return list;
1298 }
1299
1300 /* Given a FUNCTION_DECL FN and a chain LIST, return the number of
1301    artificial parms in FN.  */
1302
1303 int
1304 num_artificial_parms_for (const_tree fn)
1305 {
1306   int count = 0;
1307
1308   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1309     count++;
1310   else
1311     return 0;
1312
1313   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1314     count++;
1315   if (DECL_HAS_VTT_PARM_P (fn))
1316     count++;
1317   return count;
1318 }
1319
1320
1321 #include "gt-cp-method.h"