OSDN Git Service

90th Cygnus<->FSF quick merge
[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, 89, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
4    Contributed by Michael Tiemann (tiemann@cygnus.com)
5
6    This file is part of GNU CC.
7    
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23
24 #ifndef PARM_CAN_BE_ARRAY_TYPE
25 #define PARM_CAN_BE_ARRAY_TYPE 1
26 #endif
27
28 /* Handle method declarations.  */
29 #include <stdio.h>
30 #include "config.h"
31 #include "tree.h"
32 #include "cp-tree.h"
33 #include "class.h"
34 #include "obstack.h"
35 #include <ctype.h>
36 #include "rtl.h"
37 #include "expr.h"
38 #include "output.h"
39 #include "hard-reg-set.h"
40 #include "flags.h"
41
42 /* TREE_LIST of the current inline functions that need to be
43    processed.  */
44 struct pending_inline *pending_inlines;
45
46 #define obstack_chunk_alloc xmalloc
47 #define obstack_chunk_free free
48
49 /* Obstack where we build text strings for overloading, etc.  */
50 static struct obstack scratch_obstack;
51 static char *scratch_firstobj;
52
53 # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
54 # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
55 # define OB_PUTC2(C1,C2)        \
56   (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
57 # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
58 # define OB_PUTID(ID)  \
59   (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),     \
60                  IDENTIFIER_LENGTH (ID)))
61 # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
62 # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
63 # define OB_LAST() (obstack_next_free (&scratch_obstack)[-1])
64
65 void
66 init_method ()
67 {
68   gcc_obstack_init (&scratch_obstack);
69   scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
70 }
71
72 /* This must be large enough to hold any printed integer or floating-point
73    value.  */
74 static char digit_buffer[128];
75
76 /* Move inline function definitions out of structure so that they
77    can be processed normally.  CNAME is the name of the class
78    we are working from, METHOD_LIST is the list of method lists
79    of the structure.  We delete friend methods here, after
80    saving away their inline function definitions (if any).  */
81
82 void
83 do_inline_function_hair (type, friend_list)
84      tree type, friend_list;
85 {
86   tree method = TYPE_METHODS (type);
87
88   if (method && TREE_CODE (method) == TREE_VEC)
89     {
90       if (TREE_VEC_ELT (method, 1))
91         method = TREE_VEC_ELT (method, 1);
92       else if (TREE_VEC_ELT (method, 0))
93         method = TREE_VEC_ELT (method, 0);
94       else
95         method = TREE_VEC_ELT (method, 2);
96     }
97
98   while (method)
99     {
100       /* Do inline member functions.  */
101       struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);
102       if (info)
103         {
104           tree args;
105
106           my_friendly_assert (info->fndecl == method, 238);
107           args = DECL_ARGUMENTS (method);
108           while (args)
109             {
110               DECL_CONTEXT (args) = method;
111               args = TREE_CHAIN (args);
112             }
113
114           /* Allow this decl to be seen in global scope.  Don't do this for
115              local class methods, though.  */
116           if (! current_function_decl)
117             IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
118         }
119       method = TREE_CHAIN (method);
120     }
121   while (friend_list)
122     {
123       tree fndecl = TREE_VALUE (friend_list);
124       struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);
125       if (info)
126         {
127           tree args;
128
129           my_friendly_assert (info->fndecl == fndecl, 239);
130           args = DECL_ARGUMENTS (fndecl);
131           while (args)
132             {
133               DECL_CONTEXT (args) = fndecl;
134               args = TREE_CHAIN (args);
135             }
136
137           /* Allow this decl to be seen in global scope */
138           if (! current_function_decl)
139             IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
140         }
141
142       friend_list = TREE_CHAIN (friend_list);
143     }
144 }
145 \f
146 /* Report an argument type mismatch between the best declared function
147    we could find and the current argument list that we have.  */
148
149 void
150 report_type_mismatch (cp, parmtypes, name_kind)
151      struct candidate *cp;
152      tree parmtypes;
153      char *name_kind;
154 {
155   int i = cp->u.bad_arg;
156   tree ttf, tta;
157   char *tmp_firstobj;
158
159   switch (i)
160     {
161     case -4:
162       my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240);
163       cp_error ("type unification failed for function template `%#D'",
164                 cp->function);
165       return;
166
167     case -2:
168       cp_error ("too few arguments for %s `%#D'", name_kind, cp->function);
169       return;
170     case -1:
171       cp_error ("too many arguments for %s `%#D'", name_kind, cp->function);
172       return;
173     case 0:
174       if (TREE_CODE (TREE_TYPE (cp->function)) != METHOD_TYPE)
175         break;
176     case -3:
177       /* Happens when the implicit object parameter is rejected.  */
178       my_friendly_assert (! TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))),
179                           241);
180       if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))))
181           && ! TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (cp->function))))))
182         cp_error ("call to non-volatile %s `%#D' with volatile object",
183                   name_kind, cp->function);
184       else
185         cp_error ("call to non-const %s `%#D' with const object",
186                   name_kind, cp->function);
187       return;
188     }
189
190   ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function));
191   tta = parmtypes;
192
193   while (i-- > 0)
194     {
195       ttf = TREE_CHAIN (ttf);
196       tta = TREE_CHAIN (tta);
197     }
198
199   OB_INIT ();
200   OB_PUTS ("bad argument ");
201   sprintf (digit_buffer, "%d", cp->u.bad_arg
202            - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
203            + 1);
204   OB_PUTCP (digit_buffer);
205
206   OB_PUTS (" for function `");
207   OB_PUTCP (decl_as_string (cp->function, 1));
208   OB_PUTS ("' (type was ");
209
210   /* Reset `i' so that type printing routines do the right thing.  */
211   if (tta)
212     {
213       enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta)));
214       if (code == ERROR_MARK)
215         OB_PUTS ("(failed type instantiation)");
216       else
217         {
218           i = (code == FUNCTION_TYPE || code == METHOD_TYPE);
219           OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1));
220         }
221     }
222   else OB_PUTS ("void");
223   OB_PUTC (')');
224   OB_FINISH ();
225
226   tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack));
227   bcopy (obstack_base (&scratch_obstack), tmp_firstobj,
228          obstack_object_size (&scratch_obstack));
229   error (tmp_firstobj);
230 }
231 \f
232 /* Here is where overload code starts.  */
233
234 /* Array of types seen so far in top-level call to `build_overload_name'.
235    Allocated and deallocated by caller.  */
236 static tree *typevec;
237
238 /* Number of types interned by `build_overload_name' so far.  */
239 static int maxtype;
240
241 /* Number of occurrences of last type seen.  */
242 static int nrepeats;
243
244 /* Nonzero if we should not try folding parameter types.  */
245 static int nofold;
246
247 #define ALLOCATE_TYPEVEC(PARMTYPES) \
248   do { maxtype = 0, nrepeats = 0; \
249        typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)
250
251 #define DEALLOCATE_TYPEVEC(PARMTYPES) \
252   do { tree t = (PARMTYPES); \
253        while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \
254   } while (0)
255
256 /* Code to concatenate an asciified integer to a string.  */
257
258 static
259 #ifdef __GNUC__
260 __inline
261 #endif
262 void
263 icat (i)
264      int i;
265 {
266   /* Handle this case first, to go really quickly.  For many common values,
267      the result of i/10 below is 1.  */
268   if (i == 1)
269     {
270       OB_PUTC ('1');
271       return;
272     }
273
274   if (i < 0)
275     {
276       OB_PUTC ('m');
277       i = -i;
278     }
279   if (i < 10)
280     OB_PUTC ('0' + i);
281   else
282     {
283       icat (i / 10);
284       OB_PUTC ('0' + (i % 10));
285     }
286 }
287
288 static
289 #ifdef __GNUC__
290 __inline
291 #endif
292 void
293 flush_repeats (type)
294      tree type;
295 {
296   int tindex = 0;
297
298   while (typevec[tindex] != type)
299     tindex++;
300
301   if (nrepeats > 1)
302     {
303       OB_PUTC ('N');
304       icat (nrepeats);
305       if (nrepeats > 9)
306         OB_PUTC ('_');
307     }
308   else
309     OB_PUTC ('T');
310   nrepeats = 0;
311   icat (tindex);
312   if (tindex > 9)
313     OB_PUTC ('_');
314 }
315
316 static int numeric_output_need_bar;
317 static void build_overload_identifier ();
318
319 static void
320 build_overload_nested_name (decl)
321      tree decl;
322 {
323   if (DECL_CONTEXT (decl))
324     {
325       tree context = DECL_CONTEXT (decl);
326       if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
327         context = TYPE_NAME (context);
328       build_overload_nested_name (context);
329     }
330
331   if (TREE_CODE (decl) == FUNCTION_DECL)
332     {
333       tree name = DECL_ASSEMBLER_NAME (decl);
334       char *label;
335       extern int var_labelno;
336
337       ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
338       var_labelno++;
339
340       if (numeric_output_need_bar)
341         {
342           OB_PUTC ('_');
343           numeric_output_need_bar = 0;
344         }
345       icat (strlen (label));
346       OB_PUTCP (label);
347     }
348   else                          /* TYPE_DECL */
349     build_overload_identifier (decl);
350 }
351
352 /* Encoding for an INTEGER_CST value.  */
353
354 static void
355 build_overload_int (value)
356      tree value;
357 {
358   if (TREE_CODE (value) == TEMPLATE_CONST_PARM)
359     {
360       OB_PUTC ('Y');
361       if (TEMPLATE_CONST_IDX (value) > 9)
362         OB_PUTC ('_');
363       icat (TEMPLATE_CONST_IDX (value)); 
364       if (TEMPLATE_CONST_IDX (value) > 9)
365         OB_PUTC ('_');
366       return;
367     }
368   else if (processing_template_decl
369            && TREE_CODE (value) != INTEGER_CST)
370     /* We don't ever want this output, but it's inconvenient not to
371        be able to build the string.  This should cause assembler
372        errors we'll notice.  */
373     {
374       static int n;
375       sprintf (digit_buffer, " *%d", n++);
376       OB_PUTCP (digit_buffer);
377       return;
378     }
379
380   my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
381   if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
382     {
383       if (tree_int_cst_lt (value, integer_zero_node))
384         {
385           OB_PUTC ('m');
386           value = build_int_2 (~ TREE_INT_CST_LOW (value),
387                                - TREE_INT_CST_HIGH (value));
388         }
389       if (TREE_INT_CST_HIGH (value)
390           != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
391         {
392           /* need to print a DImode value in decimal */
393           sorry ("conversion of long long as PT parameter");
394         }
395       /* else fall through to print in smaller mode */
396     }
397   /* Wordsize or smaller */
398   icat (TREE_INT_CST_LOW (value));
399 }
400
401 static void
402 build_overload_value (type, value)
403      tree type, value;
404 {
405   while (TREE_CODE (value) == NON_LVALUE_EXPR
406          || TREE_CODE (value) == NOP_EXPR)
407     value = TREE_OPERAND (value, 0);
408   my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242);
409   type = TREE_TYPE (type);
410
411   if (numeric_output_need_bar)
412     {
413       OB_PUTC ('_');
414       numeric_output_need_bar = 0;
415     }
416
417   if (TREE_CODE (type) == POINTER_TYPE
418       && TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
419     {
420       /* Handle a pointer to data member as a template instantiation
421          parameter, boy, what fun!  */
422       type = integer_type_node;
423       if (TREE_CODE (value) != INTEGER_CST)
424         {
425           sorry ("unknown pointer to member constant");
426           return;
427         }
428     }
429
430   if (TYPE_PTRMEMFUNC_P (type))
431     type = TYPE_PTRMEMFUNC_FN_TYPE (type);
432
433   switch (TREE_CODE (type))
434     {
435     case INTEGER_TYPE:
436     case ENUMERAL_TYPE:
437     case BOOLEAN_TYPE:
438       {
439         build_overload_int (value);
440         numeric_output_need_bar = 1;
441         return;
442       }
443 #ifndef REAL_IS_NOT_DOUBLE
444     case REAL_TYPE:
445       {
446         REAL_VALUE_TYPE val;
447         char *bufp = digit_buffer;
448         extern char *index ();
449
450         my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
451         val = TREE_REAL_CST (value);
452         if (val < 0)
453           {
454             val = -val;
455             *bufp++ = 'm';
456           }
457         sprintf (bufp, "%e", val);
458         bufp = (char *) index (bufp, 'e');
459         if (!bufp)
460           strcat (digit_buffer, "e0");
461         else
462           {
463             char *p;
464             bufp++;
465             if (*bufp == '-')
466               {
467                 *bufp++ = 'm';
468               }
469             p = bufp;
470             if (*p == '+')
471               p++;
472             while (*p == '0')
473               p++;
474             if (*p == 0)
475               {
476                 *bufp++ = '0';
477                 *bufp = 0;
478               }
479             else if (p != bufp)
480               {
481                 while (*p)
482                   *bufp++ = *p++;
483                 *bufp = 0;
484               }
485           }
486         OB_PUTCP (digit_buffer);
487         numeric_output_need_bar = 1;
488         return;
489       }
490 #endif
491     case POINTER_TYPE:
492       if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
493           && TREE_CODE (value) != ADDR_EXPR)
494         {
495           if (TREE_CODE (value) == CONSTRUCTOR)
496             {
497               /* This is dangerous code, crack built up pointer to members.  */
498               tree args = CONSTRUCTOR_ELTS (value);
499               tree a1 = TREE_VALUE (args);
500               tree a2 = TREE_VALUE (TREE_CHAIN (args));
501               tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))));
502               a3 = TREE_VALUE (a3);
503               STRIP_NOPS (a3);
504               if (TREE_CODE (a1) == INTEGER_CST
505                   && TREE_CODE (a2) == INTEGER_CST)
506                 {
507                   build_overload_int (a1);
508                   OB_PUTC ('_');
509                   build_overload_int (a2);
510                   OB_PUTC ('_');
511                   if (TREE_CODE (a3) == ADDR_EXPR)
512                     {
513                       a3 = TREE_OPERAND (a3, 0);
514                       if (TREE_CODE (a3) == FUNCTION_DECL)
515                         {
516                           numeric_output_need_bar = 0;
517                           build_overload_identifier (DECL_ASSEMBLER_NAME (a3));
518                           return;
519                         }
520                     }
521                   else if (TREE_CODE (a3) == INTEGER_CST)
522                     {
523                       OB_PUTC ('i');
524                       build_overload_int (a3);
525                       numeric_output_need_bar = 1;
526                       return;
527                     }
528                 }
529             }
530           sorry ("template instantiation with pointer to method that is too complex");
531           return;
532         }
533       if (TREE_CODE (value) == INTEGER_CST)
534         {
535           build_overload_int (value);
536           numeric_output_need_bar = 1;
537           return;
538         }
539       value = TREE_OPERAND (value, 0);
540       if (TREE_CODE (value) == VAR_DECL)
541         {
542           my_friendly_assert (DECL_NAME (value) != 0, 245);
543           build_overload_identifier (DECL_ASSEMBLER_NAME (value));
544           return;
545         }
546       else if (TREE_CODE (value) == FUNCTION_DECL)
547         {
548           my_friendly_assert (DECL_NAME (value) != 0, 246);
549           build_overload_identifier (DECL_ASSEMBLER_NAME (value));
550           return;
551         }
552       else
553         my_friendly_abort (71);
554       break; /* not really needed */
555
556     default:
557       sorry ("conversion of %s as template parameter",
558              tree_code_name [(int) TREE_CODE (type)]);
559       my_friendly_abort (72);
560     }
561 }
562
563 static void
564 build_overload_identifier (name)
565      tree name;
566 {
567   if (TREE_CODE (name) == TYPE_DECL
568       && IS_AGGR_TYPE (TREE_TYPE (name))
569       && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
570       && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))))
571     {
572       tree template, parmlist, arglist, tname;
573       int i, nparms;
574       template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name));
575       arglist = TREE_VALUE (template);
576       template = TREE_PURPOSE (template);
577       tname = DECL_NAME (template);
578       parmlist = DECL_ARGUMENTS (template);
579       nparms = TREE_VEC_LENGTH (parmlist);
580       OB_PUTC ('t');
581       icat (IDENTIFIER_LENGTH (tname));
582       OB_PUTID (tname);
583       icat (nparms);
584       for (i = 0; i < nparms; i++)
585         {
586           tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
587           tree arg = TREE_VEC_ELT (arglist, i);
588           if (TREE_CODE (parm) == TYPE_DECL)
589             {
590               /* This parameter is a type.  */
591               OB_PUTC ('Z');
592               build_overload_name (arg, 0, 0);
593             }
594           else
595             {
596               parm = tsubst (parm, &TREE_VEC_ELT (arglist, 0),
597                              TREE_VEC_LENGTH (arglist), NULL_TREE);
598               /* It's a PARM_DECL.  */
599               build_overload_name (TREE_TYPE (parm), 0, 0);
600               build_overload_value (parm, arg);
601             }
602         }
603     }
604   else
605     {
606       if (TREE_CODE (name) == TYPE_DECL)
607         name = DECL_NAME (name);
608       if (numeric_output_need_bar)
609         {
610           OB_PUTC ('_');
611           numeric_output_need_bar = 0;
612         }
613       icat (IDENTIFIER_LENGTH (name));
614       OB_PUTID (name);
615     }
616 }
617
618 /* Given a list of parameters in PARMTYPES, create an unambiguous
619    overload string. Should distinguish any type that C (or C++) can
620    distinguish. I.e., pointers to functions are treated correctly.
621
622    Caller must deal with whether a final `e' goes on the end or not.
623
624    Any default conversions must take place before this function
625    is called.
626
627    BEGIN and END control initialization and finalization of the
628    obstack where we build the string.  */
629
630 char *
631 build_overload_name (parmtypes, begin, end)
632      tree parmtypes;
633      int begin, end;
634 {
635   int just_one;
636   tree parmtype;
637
638   if (begin) OB_INIT ();
639   numeric_output_need_bar = 0;
640
641   if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST)))
642     {
643       parmtype = parmtypes;
644       goto only_one;
645     }
646
647   while (parmtypes)
648     {
649       parmtype = TREE_VALUE (parmtypes);
650
651     only_one:
652
653       if (! nofold && ! just_one)
654         {
655           /* Every argument gets counted.  */
656           typevec[maxtype++] = parmtype;
657
658           if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
659             {
660               nrepeats++;
661               goto next;
662             }
663
664           if (nrepeats)
665             flush_repeats (typevec[maxtype-2]);
666
667           if (TREE_USED (parmtype))
668             {
669 #if 0
670               /* We can turn this on at some point when we want
671                  improved symbol mangling.  */
672               nrepeats++;
673 #else
674               /* This is bug compatible with 2.7.x  */
675               flush_repeats (parmtype);
676 #endif
677               goto next;
678             }
679
680           /* Only cache types which take more than one character.  */
681           if (parmtype != TYPE_MAIN_VARIANT (parmtype)
682               || (TREE_CODE (parmtype) != INTEGER_TYPE
683                   && TREE_CODE (parmtype) != REAL_TYPE))
684             TREE_USED (parmtype) = 1;
685         }
686
687       if (TYPE_PTRMEMFUNC_P (parmtype))
688         parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
689
690       if (TREE_READONLY (parmtype))
691         OB_PUTC ('C');
692       if (TREE_CODE (parmtype) == INTEGER_TYPE
693           && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
694         OB_PUTC ('U');
695       if (TYPE_VOLATILE (parmtype))
696         OB_PUTC ('V');
697
698       switch (TREE_CODE (parmtype))
699         {
700         case OFFSET_TYPE:
701           OB_PUTC ('O');
702           build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0);
703           OB_PUTC ('_');
704           build_overload_name (TREE_TYPE (parmtype), 0, 0);
705           break;
706
707         case REFERENCE_TYPE:
708           OB_PUTC ('R');
709           goto more;
710
711         case ARRAY_TYPE:
712 #if PARM_CAN_BE_ARRAY_TYPE
713           {
714             tree length;
715
716             OB_PUTC ('A');
717             if (TYPE_DOMAIN (parmtype) == NULL_TREE)
718               error ("pointer or reference to array of unknown bound in parm type");
719             else
720               {
721                 length = array_type_nelts (parmtype);
722                 if (TREE_CODE (length) == INTEGER_CST)
723                   icat (TREE_INT_CST_LOW (length) + 1);
724               }
725             OB_PUTC ('_');
726             goto more;
727           }
728 #else
729           OB_PUTC ('P');
730           goto more;
731 #endif
732
733         case POINTER_TYPE:
734           OB_PUTC ('P');
735         more:
736           build_overload_name (TREE_TYPE (parmtype), 0, 0);
737           break;
738
739         case FUNCTION_TYPE:
740         case METHOD_TYPE:
741           {
742             tree firstarg = TYPE_ARG_TYPES (parmtype);
743             /* Otherwise have to implement reentrant typevecs,
744                unmark and remark types, etc.  */
745             int old_nofold = nofold;
746             nofold = 1;
747
748             if (nrepeats)
749               flush_repeats (typevec[maxtype-1]);
750
751             /* @@ It may be possible to pass a function type in
752                which is not preceded by a 'P'.  */
753             if (TREE_CODE (parmtype) == FUNCTION_TYPE)
754               {
755                 OB_PUTC ('F');
756                 if (firstarg == NULL_TREE)
757                   OB_PUTC ('e');
758                 else if (firstarg == void_list_node)
759                   OB_PUTC ('v');
760                 else
761                   build_overload_name (firstarg, 0, 0);
762               }
763             else
764               {
765                 int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg)));
766                 int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg)));
767                 OB_PUTC ('M');
768                 firstarg = TREE_CHAIN (firstarg);
769
770                 build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0);
771                 if (constp)
772                   OB_PUTC ('C');
773                 if (volatilep)
774                   OB_PUTC ('V');
775
776                 /* For cfront 2.0 compatibility.  */
777                 OB_PUTC ('F');
778
779                 if (firstarg == NULL_TREE)
780                   OB_PUTC ('e');
781                 else if (firstarg == void_list_node)
782                   OB_PUTC ('v');
783                 else
784                   build_overload_name (firstarg, 0, 0);
785               }
786
787             /* Separate args from return type.  */
788             OB_PUTC ('_');
789             build_overload_name (TREE_TYPE (parmtype), 0, 0);
790             nofold = old_nofold;
791             break;
792           }
793
794         case INTEGER_TYPE:
795           parmtype = TYPE_MAIN_VARIANT (parmtype);
796           if (parmtype == integer_type_node
797               || parmtype == unsigned_type_node)
798             OB_PUTC ('i');
799           else if (parmtype == long_integer_type_node
800                    || parmtype == long_unsigned_type_node)
801             OB_PUTC ('l');
802           else if (parmtype == short_integer_type_node
803                    || parmtype == short_unsigned_type_node)
804             OB_PUTC ('s');
805           else if (parmtype == signed_char_type_node)
806             {
807               OB_PUTC ('S');
808               OB_PUTC ('c');
809             }
810           else if (parmtype == char_type_node
811                    || parmtype == unsigned_char_type_node)
812             OB_PUTC ('c');
813           else if (parmtype == wchar_type_node)
814             OB_PUTC ('w');
815           else if (parmtype == long_long_integer_type_node
816               || parmtype == long_long_unsigned_type_node)
817             OB_PUTC ('x');
818 #if 0
819           /* it would seem there is no way to enter these in source code,
820              yet.  (mrs) */
821           else if (parmtype == long_long_long_integer_type_node
822               || parmtype == long_long_long_unsigned_type_node)
823             OB_PUTC ('q');
824 #endif
825           else
826             my_friendly_abort (73);
827           break;
828
829         case BOOLEAN_TYPE:
830           OB_PUTC ('b');
831           break;
832
833         case REAL_TYPE:
834           parmtype = TYPE_MAIN_VARIANT (parmtype);
835           if (parmtype == long_double_type_node)
836             OB_PUTC ('r');
837           else if (parmtype == double_type_node)
838             OB_PUTC ('d');
839           else if (parmtype == float_type_node)
840             OB_PUTC ('f');
841           else my_friendly_abort (74);
842           break;
843
844         case VOID_TYPE:
845           if (! just_one)
846             {
847 #if 0
848               extern tree void_list_node;
849
850               /* See if anybody is wasting memory.  */
851               my_friendly_assert (parmtypes == void_list_node, 247);
852 #endif
853               /* This is the end of a parameter list.  */
854               if (end) OB_FINISH ();
855               return (char *)obstack_base (&scratch_obstack);
856             }
857           OB_PUTC ('v');
858           break;
859
860         case ERROR_MARK:        /* not right, but nothing is anyway */
861           break;
862
863           /* have to do these */
864         case UNION_TYPE:
865         case RECORD_TYPE:
866           if (! just_one)
867             /* Make this type signature look incompatible
868                with AT&T.  */
869             OB_PUTC ('G');
870           goto common;
871         case ENUMERAL_TYPE:
872         common:
873           {
874             tree name = TYPE_NAME (parmtype);
875             int i = 1;
876
877             if (TREE_CODE (name) == TYPE_DECL)
878               {
879                 tree context = name;
880
881                 /* If DECL_ASSEMBLER_NAME has been set properly, use it.  */
882                 if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
883                   {
884                     OB_PUTID (DECL_ASSEMBLER_NAME (context));
885                     break;
886                   }
887                 while (DECL_CONTEXT (context))
888                   {
889                     i += 1;
890                     context = DECL_CONTEXT (context);
891                     if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
892                       context = TYPE_NAME (context);
893                   }
894                 name = DECL_NAME (name);
895               }
896             my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
897             if (i > 1)
898               {
899                 OB_PUTC ('Q');
900                 if (i > 9)
901                   OB_PUTC ('_');
902                 icat (i);
903                 if (i > 9)
904                   OB_PUTC ('_');
905                 numeric_output_need_bar = 0;
906                 build_overload_nested_name (TYPE_NAME (parmtype));
907               }
908             else              
909               build_overload_identifier (TYPE_NAME (parmtype));
910             break;
911           }
912
913         case UNKNOWN_TYPE:
914           /* This will take some work.  */
915           OB_PUTC ('?');
916           break;
917
918         case TEMPLATE_TYPE_PARM:
919           OB_PUTC ('X');
920           if (TEMPLATE_TYPE_IDX (parmtype) > 9)
921             OB_PUTC ('_');
922           icat (TEMPLATE_TYPE_IDX (parmtype)); 
923           if (TEMPLATE_TYPE_IDX (parmtype) > 9)
924             OB_PUTC ('_');
925           break;
926             
927         case TYPENAME_TYPE:
928           /* We don't ever want this output, but it's inconvenient not to
929              be able to build the string.  This should cause assembler
930              errors we'll notice.  */
931           {
932             static int n;
933             sprintf (digit_buffer, " *%d", n++);
934             OB_PUTCP (digit_buffer);
935           }
936           break;
937
938         default:
939           my_friendly_abort (75);
940         }
941
942     next:
943       if (just_one) break;
944       parmtypes = TREE_CHAIN (parmtypes);
945     }
946   if (! just_one)
947     {
948       if (nrepeats)
949         flush_repeats (typevec[maxtype-1]);
950
951       /* To get here, parms must end with `...'.  */
952       OB_PUTC ('e');
953     }
954
955   if (end) OB_FINISH ();
956   return (char *)obstack_base (&scratch_obstack);
957 }
958
959 tree
960 build_static_name (basetype, name)
961   tree basetype, name;
962 {
963   char *basename  = build_overload_name (basetype, 1, 1);
964   char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)
965                                + sizeof (STATIC_NAME_FORMAT)
966                                + strlen (basename));
967   sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));
968   return get_identifier (buf);
969 }  
970 \f
971 /* Change the name of a function definition so that it may be
972    overloaded. NAME is the name of the function to overload,
973    PARMS is the parameter list (which determines what name the
974    final function obtains).
975
976    FOR_METHOD is 1 if this overload is being performed
977    for a method, rather than a function type.  It is 2 if
978    this overload is being performed for a constructor.  */
979
980 tree
981 build_decl_overload (dname, parms, for_method)
982      tree dname;
983      tree parms;
984      int for_method;
985 {
986   char *name = IDENTIFIER_POINTER (dname);
987
988   /* member operators new and delete look like methods at this point.  */
989   if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
990     {
991       if (dname == ansi_opname[(int) DELETE_EXPR])
992         return get_identifier ("__builtin_delete");
993       else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
994         return get_identifier ("__builtin_vec_delete");
995       else if (TREE_CHAIN (parms) == void_list_node)
996         {
997           if (dname == ansi_opname[(int) NEW_EXPR])
998             return get_identifier ("__builtin_new");
999           else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
1000             return get_identifier ("__builtin_vec_new");
1001         }
1002     }
1003
1004   OB_INIT ();
1005   if (for_method != 2)
1006     OB_PUTCP (name);
1007   /* Otherwise, we can divine that this is a constructor,
1008      and figure out its name without any extra encoding.  */
1009
1010   OB_PUTC2 ('_', '_');
1011   if (for_method)
1012     {
1013 #if 0
1014       /* We can get away without doing this.  */
1015       OB_PUTC ('M');
1016 #endif
1017       {
1018         tree this_type = TREE_VALUE (parms);
1019
1020         if (TREE_CODE (this_type) == RECORD_TYPE)  /* a signature pointer */
1021           parms = temp_tree_cons (NULL_TREE, SIGNATURE_TYPE (this_type),
1022                                   TREE_CHAIN (parms));
1023         else
1024           parms = temp_tree_cons (NULL_TREE, TREE_TYPE (this_type),
1025                                   TREE_CHAIN (parms));
1026       }
1027     }
1028   else
1029     OB_PUTC ('F');
1030
1031   if (parms == NULL_TREE)
1032     OB_PUTC2 ('e', '\0');
1033   else if (parms == void_list_node)
1034     OB_PUTC2 ('v', '\0');
1035   else
1036     {
1037       ALLOCATE_TYPEVEC (parms);
1038       nofold = 0;
1039       if (for_method)
1040         {
1041           build_overload_name (TREE_VALUE (parms), 0, 0);
1042
1043           typevec[maxtype++] = TREE_VALUE (parms);
1044           TREE_USED (TREE_VALUE (parms)) = 1;
1045
1046           if (TREE_CHAIN (parms))
1047             build_overload_name (TREE_CHAIN (parms), 0, 1);
1048           else
1049             OB_PUTC2 ('e', '\0');
1050         }
1051       else
1052         build_overload_name (parms, 0, 1);
1053       DEALLOCATE_TYPEVEC (parms);
1054     }
1055   {
1056     tree n = get_identifier (obstack_base (&scratch_obstack));
1057     if (IDENTIFIER_OPNAME_P (dname))
1058       IDENTIFIER_OPNAME_P (n) = 1;
1059     return n;
1060   }
1061 }
1062
1063 /* Build an overload name for the type expression TYPE.  */
1064
1065 tree
1066 build_typename_overload (type)
1067      tree type;
1068 {
1069   tree id;
1070
1071   OB_INIT ();
1072   OB_PUTID (ansi_opname[(int) TYPE_EXPR]);
1073   nofold = 1;
1074   build_overload_name (type, 0, 1);
1075   id = get_identifier (obstack_base (&scratch_obstack));
1076   IDENTIFIER_OPNAME_P (id) = 1;
1077 #if 0
1078   IDENTIFIER_GLOBAL_VALUE (id) = TYPE_MAIN_DECL (type);
1079 #endif
1080   TREE_TYPE (id) = type;
1081   return id;
1082 }
1083
1084 tree
1085 build_overload_with_type (name, type)
1086      tree name, type;
1087 {
1088   OB_INIT ();
1089   OB_PUTID (name);
1090   nofold = 1;
1091
1092   build_overload_name (type, 0, 1);
1093   return get_identifier (obstack_base (&scratch_obstack));
1094 }
1095
1096 tree
1097 get_id_2 (name, name2)
1098      char *name;
1099      tree name2;
1100 {
1101   OB_INIT ();
1102   OB_PUTCP (name);
1103   OB_PUTID (name2);
1104   OB_FINISH ();
1105   return get_identifier (obstack_base (&scratch_obstack));
1106 }
1107 \f
1108 /* Given a tree_code CODE, and some arguments (at least one),
1109    attempt to use an overloaded operator on the arguments.
1110
1111    For unary operators, only the first argument need be checked.
1112    For binary operators, both arguments may need to be checked.
1113
1114    Member functions can convert class references to class pointers,
1115    for one-level deep indirection.  More than that is not supported.
1116    Operators [](), ()(), and ->() must be member functions.
1117
1118    We call function call building calls with LOOKUP_COMPLAIN if they
1119    are our only hope.  This is true when we see a vanilla operator
1120    applied to something of aggregate type.  If this fails, we are free
1121    to return `error_mark_node', because we will have reported the
1122    error.
1123
1124    Operators NEW and DELETE overload in funny ways: operator new takes
1125    a single `size' parameter, and operator delete takes a pointer to the
1126    storage being deleted.  When overloading these operators, success is
1127    assumed.  If there is a failure, report an error message and return
1128    `error_mark_node'.  */
1129
1130 /* NOSTRICT */
1131 tree
1132 build_opfncall (code, flags, xarg1, xarg2, arg3)
1133      enum tree_code code;
1134      int flags;
1135      tree xarg1, xarg2, arg3;
1136 {
1137   tree rval = 0;
1138   tree arg1, arg2;
1139   tree type1, type2, fnname;
1140   tree fields1 = 0, parms = 0;
1141   tree global_fn;
1142   int try_second;
1143   int binary_is_unary;
1144
1145   if (flag_ansi_overloading)
1146     return build_new_op (code, flags, xarg1, xarg2, arg3);
1147
1148   if (xarg1 == error_mark_node)
1149     return error_mark_node;
1150
1151   if (code == COND_EXPR)
1152     {
1153       if (TREE_CODE (xarg2) == ERROR_MARK
1154           || TREE_CODE (arg3) == ERROR_MARK)
1155         return error_mark_node;
1156     }
1157   if (code == COMPONENT_REF)
1158     if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)
1159       return rval;
1160
1161   /* First, see if we can work with the first argument */
1162   type1 = TREE_TYPE (xarg1);
1163
1164   /* Some tree codes have length > 1, but we really only want to
1165      overload them if their first argument has a user defined type.  */
1166   switch (code)
1167     {
1168     case PREINCREMENT_EXPR:
1169     case PREDECREMENT_EXPR:
1170     case POSTINCREMENT_EXPR:
1171     case POSTDECREMENT_EXPR:
1172     case COMPONENT_REF:
1173       binary_is_unary = 1;
1174       try_second = 0;
1175       break;
1176
1177       /* ARRAY_REFs and CALL_EXPRs must overload successfully.
1178          If they do not, return error_mark_node instead of NULL_TREE.  */
1179     case ARRAY_REF:
1180       if (xarg2 == error_mark_node)
1181         return error_mark_node;
1182     case CALL_EXPR:
1183       rval = error_mark_node;
1184       binary_is_unary = 0;
1185       try_second = 0;
1186       break;
1187
1188     case VEC_NEW_EXPR:
1189     case NEW_EXPR:
1190       {
1191         tree args = tree_cons (NULL_TREE, xarg2, arg3);
1192         fnname = ansi_opname[(int) code];
1193         if (flags & LOOKUP_GLOBAL)
1194           return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN);
1195
1196         rval = build_method_call
1197           (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node),
1198                                "new"),
1199            fnname, args, NULL_TREE, flags);
1200         if (rval == error_mark_node)
1201           /* User might declare fancy operator new, but invoke it
1202              like standard one.  */
1203           return rval;
1204
1205         TREE_TYPE (rval) = xarg1;
1206         TREE_CALLS_NEW (rval) = 1;
1207         return rval;
1208       }
1209       break;
1210
1211     case VEC_DELETE_EXPR:
1212     case DELETE_EXPR:
1213       {
1214         fnname = ansi_opname[(int) code];
1215         if (flags & LOOKUP_GLOBAL)
1216           return build_overload_call (fnname,
1217                                       build_tree_list (NULL_TREE, xarg1),
1218                                       flags & LOOKUP_COMPLAIN);
1219         arg1 = TREE_TYPE (xarg1);
1220
1221         /* This handles the case where we're trying to delete
1222            X (*a)[10];
1223            a=new X[5][10];
1224            delete[] a; */
1225            
1226         if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1227           {
1228             /* Strip off the pointer and the array.  */
1229             arg1 = TREE_TYPE (TREE_TYPE (arg1));
1230
1231             while (TREE_CODE (arg1) == ARRAY_TYPE)
1232                 arg1 = (TREE_TYPE (arg1));
1233
1234             arg1 = build_pointer_type (arg1);
1235           }
1236
1237         rval = build_method_call
1238           (build_indirect_ref (build1 (NOP_EXPR, arg1,
1239                                        error_mark_node),
1240                                NULL_PTR),
1241            fnname, tree_cons (NULL_TREE, xarg1,
1242                                build_tree_list (NULL_TREE, xarg2)),
1243            NULL_TREE, flags);
1244 #if 0
1245         /* This can happen when operator delete is protected.  */
1246         my_friendly_assert (rval != error_mark_node, 250);
1247         TREE_TYPE (rval) = void_type_node;
1248 #endif
1249         return rval;
1250       }
1251       break;
1252
1253     default:
1254       binary_is_unary = 0;
1255       try_second = tree_code_length [(int) code] == 2;
1256       if (try_second && xarg2 == error_mark_node)
1257         return error_mark_node;
1258       break;
1259     }
1260
1261   if (try_second && xarg2 == error_mark_node)
1262     return error_mark_node;
1263
1264   /* What ever it was, we do not know how to deal with it.  */
1265   if (type1 == NULL_TREE)
1266     return rval;
1267
1268   if (TREE_CODE (type1) == OFFSET_TYPE)
1269     type1 = TREE_TYPE (type1);
1270
1271   if (TREE_CODE (type1) == REFERENCE_TYPE)
1272     {
1273       arg1 = convert_from_reference (xarg1);
1274       type1 = TREE_TYPE (arg1);
1275     }
1276   else
1277     {
1278       arg1 = xarg1;
1279     }
1280
1281   if (!IS_AGGR_TYPE (type1) || TYPE_PTRMEMFUNC_P (type1))
1282     {
1283       /* Try to fail. First, fail if unary */
1284       if (! try_second)
1285         return rval;
1286       /* Second, see if second argument is non-aggregate.  */
1287       type2 = TREE_TYPE (xarg2);
1288       if (TREE_CODE (type2) == OFFSET_TYPE)
1289         type2 = TREE_TYPE (type2);
1290       if (TREE_CODE (type2) == REFERENCE_TYPE)
1291         {
1292           arg2 = convert_from_reference (xarg2);
1293           type2 = TREE_TYPE (arg2);
1294         }
1295       else
1296         {
1297           arg2 = xarg2;
1298         }
1299
1300       if (!IS_AGGR_TYPE (type2))
1301         return rval;
1302       try_second = 0;
1303     }
1304
1305   if (try_second)
1306     {
1307       /* First arg may succeed; see whether second should.  */
1308       type2 = TREE_TYPE (xarg2);
1309       if (TREE_CODE (type2) == OFFSET_TYPE)
1310         type2 = TREE_TYPE (type2);
1311       if (TREE_CODE (type2) == REFERENCE_TYPE)
1312         {
1313           arg2 = convert_from_reference (xarg2);
1314           type2 = TREE_TYPE (arg2);
1315         }
1316       else
1317         {
1318           arg2 = xarg2;
1319         }
1320
1321       if (! IS_AGGR_TYPE (type2))
1322         try_second = 0;
1323     }
1324
1325   if (type1 == unknown_type_node
1326       || (try_second && TREE_TYPE (xarg2) == unknown_type_node))
1327     {
1328       /* This will not be implemented in the foreseeable future.  */
1329       return rval;
1330     }
1331
1332   if (code == MODIFY_EXPR)
1333     fnname = ansi_assopname[(int) TREE_CODE (arg3)];
1334   else
1335     fnname = ansi_opname[(int) code];
1336
1337   global_fn = lookup_name_nonclass (fnname);
1338
1339   /* This is the last point where we will accept failure.  This
1340      may be too eager if we wish an overloaded operator not to match,
1341      but would rather a normal operator be called on a type-converted
1342      argument.  */
1343
1344   if (IS_AGGR_TYPE (type1))
1345     {
1346       fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0);
1347       /* ARM $13.4.7, prefix/postfix ++/--.  */
1348       if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
1349         {
1350           xarg2 = integer_zero_node;
1351           binary_is_unary = 0;
1352
1353           if (fields1)
1354             {
1355               tree t, t2;
1356               int have_postfix = 0;
1357
1358               /* Look for an `operator++ (int)'.  If they didn't have
1359                  one, then we fall back to the old way of doing things.  */
1360               for (t = TREE_VALUE (fields1); t ; t = DECL_CHAIN (t))
1361                 {
1362                   t2 = TYPE_ARG_TYPES (TREE_TYPE (t));
1363                   if (TREE_CHAIN (t2) != NULL_TREE
1364                       && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node)
1365                     {
1366                       have_postfix = 1;
1367                       break;
1368                     }
1369                 }
1370
1371               if (! have_postfix)
1372                 {
1373                   char *op = POSTINCREMENT_EXPR ? "++" : "--";
1374
1375                   /* There's probably a LOT of code in the world that
1376                      relies upon this old behavior.  */
1377                   pedwarn ("no `operator%s (int)' declared for postfix `%s', using prefix operator instead",
1378                            op, op);
1379                   xarg2 = NULL_TREE;
1380                   binary_is_unary = 1;
1381                 }
1382             }
1383         }
1384     }
1385
1386   if (fields1 == NULL_TREE && global_fn == NULL_TREE)
1387     return rval;
1388
1389   /* If RVAL winds up being `error_mark_node', we will return
1390      that... There is no way that normal semantics of these
1391      operators will succeed.  */
1392
1393   /* This argument may be an uncommitted OFFSET_REF.  This is
1394      the case for example when dealing with static class members
1395      which are referenced from their class name rather than
1396      from a class instance.  */
1397   if (TREE_CODE (xarg1) == OFFSET_REF
1398       && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL)
1399     xarg1 = TREE_OPERAND (xarg1, 1);
1400   if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF
1401       && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL)
1402     xarg2 = TREE_OPERAND (xarg2, 1);
1403
1404   if (global_fn)
1405     flags |= LOOKUP_GLOBAL;
1406
1407   if (code == CALL_EXPR)
1408     {
1409       /* This can only be a member function.  */
1410       return build_method_call (xarg1, fnname, xarg2,
1411                                 NULL_TREE, LOOKUP_NORMAL);
1412     }
1413   else if (tree_code_length[(int) code] == 1 || binary_is_unary)
1414     {
1415       parms = NULL_TREE;
1416       rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags);
1417     }
1418   else if (code == COND_EXPR)
1419     {
1420       parms = tree_cons (NULL_TREE, xarg2, build_tree_list (NULL_TREE, arg3));
1421       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
1422     }
1423   else if (code == METHOD_CALL_EXPR)
1424     {
1425       /* must be a member function.  */
1426       parms = tree_cons (NULL_TREE, xarg2, arg3);
1427       return build_method_call (xarg1, fnname, parms, NULL_TREE,
1428                                 LOOKUP_NORMAL);
1429     }
1430   else if (fields1)
1431     {
1432       parms = build_tree_list (NULL_TREE, xarg2);
1433       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
1434     }
1435   else
1436     {
1437       parms = tree_cons (NULL_TREE, xarg1,
1438                          build_tree_list (NULL_TREE, xarg2));
1439       rval = build_overload_call (fnname, parms, flags);
1440     }
1441
1442   return rval;
1443 }
1444 \f
1445 /* This function takes an identifier, ID, and attempts to figure out what
1446    it means. There are a number of possible scenarios, presented in increasing
1447    order of hair:
1448
1449    1) not in a class's scope
1450    2) in class's scope, member name of the class's method
1451    3) in class's scope, but not a member name of the class
1452    4) in class's scope, member name of a class's variable
1453
1454    NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
1455    VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
1456
1457    As a last ditch, try to look up the name as a label and return that
1458    address.
1459
1460    Values which are declared as being of REFERENCE_TYPE are
1461    automatically dereferenced here (as a hack to make the
1462    compiler faster).  */
1463
1464 tree
1465 hack_identifier (value, name)
1466      tree value, name;
1467 {
1468   tree type, context;
1469
1470   if (TREE_CODE (value) == ERROR_MARK)
1471     {
1472       if (current_class_name)
1473         {
1474           tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1);
1475           if (fields == error_mark_node)
1476             return error_mark_node;
1477           if (fields)
1478             {
1479               tree fndecl;
1480
1481               fndecl = TREE_VALUE (fields);
1482               my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251);
1483               if (DECL_CHAIN (fndecl) == NULL_TREE)
1484                 {
1485                   warning ("methods cannot be converted to function pointers");
1486                   return fndecl;
1487                 }
1488               else
1489                 {
1490                   error ("ambiguous request for method pointer `%s'",
1491                          IDENTIFIER_POINTER (name));
1492                   return error_mark_node;
1493                 }
1494             }
1495         }
1496       if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
1497         {
1498           return IDENTIFIER_LABEL_VALUE (name);
1499         }
1500       return error_mark_node;
1501     }
1502
1503   type = TREE_TYPE (value);
1504   if (TREE_CODE (value) == FIELD_DECL)
1505     {
1506       if (current_class_ptr == NULL_TREE)
1507         {
1508           error ("request for member `%s' in static member function",
1509                  IDENTIFIER_POINTER (DECL_NAME (value)));
1510           return error_mark_node;
1511         }
1512       TREE_USED (current_class_ptr) = 1;
1513
1514       /* Mark so that if we are in a constructor, and then find that
1515          this field was initialized by a base initializer,
1516          we can emit an error message.  */
1517       TREE_USED (value) = 1;
1518       value = build_component_ref (current_class_ref, name, NULL_TREE, 1);
1519     }
1520   else if (really_overloaded_fn (value))
1521     {
1522 #if 0
1523       tree t = get_first_fn (value);
1524       for (; t; t = DECL_CHAIN (t))
1525         {
1526           if (TREE_CODE (t) == TEMPLATE_DECL)
1527             continue;
1528
1529           assemble_external (t);
1530           TREE_USED (t) = 1;
1531         }
1532 #endif
1533     }
1534   else if (TREE_CODE (value) == TREE_LIST)
1535     {
1536       /* Ambiguous reference to base members, possibly other cases?.  */
1537       tree t = value;
1538       while (t && TREE_CODE (t) == TREE_LIST)
1539         {
1540           mark_used (TREE_VALUE (t));
1541           t = TREE_CHAIN (t);
1542         }
1543     }
1544   else
1545     mark_used (value);
1546
1547   if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL)
1548     {
1549       tree context = decl_function_context (value);
1550       if (context != NULL_TREE && context != current_function_decl
1551           && ! TREE_STATIC (value))
1552         {
1553           cp_error ("use of %s from containing function",
1554                       (TREE_CODE (value) == VAR_DECL
1555                        ? "`auto' variable" : "parameter"));
1556           cp_error_at ("  `%#D' declared here", value);
1557           value = error_mark_node;
1558         }
1559     }
1560
1561   if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
1562     {
1563       if (DECL_LANG_SPECIFIC (value)
1564           && DECL_CLASS_CONTEXT (value) != current_class_type)
1565         {
1566           tree path, access;
1567           register tree context
1568             = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
1569               ? DECL_CLASS_CONTEXT (value)
1570               : DECL_CONTEXT (value);
1571
1572           get_base_distance (context, current_class_type, 0, &path);
1573           if (path)
1574             {
1575               access = compute_access (path, value);
1576               if (access != access_public_node)
1577                 {
1578                   if (TREE_CODE (value) == VAR_DECL)
1579                     error ("static member `%s' is %s",
1580                            IDENTIFIER_POINTER (name),
1581                            TREE_PRIVATE (value) ? "private" :
1582                            "from a private base class");
1583                   else
1584                     error ("enum `%s' is from private base class",
1585                            IDENTIFIER_POINTER (name));
1586                   return error_mark_node;
1587                 }
1588             }
1589         }
1590       return value;
1591     }
1592   if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
1593     {
1594       if (type == 0)
1595         {
1596           error ("request for member `%s' is ambiguous in multiple inheritance lattice",
1597                  IDENTIFIER_POINTER (name));
1598           return error_mark_node;
1599         }
1600
1601       return value;
1602     }
1603
1604   if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl)
1605     value = convert_from_reference (value);
1606   return value;
1607 }
1608
1609 \f
1610 static char *
1611 thunk_printable_name (decl)
1612      tree decl;
1613 {
1614   return "<thunk function>";
1615 }
1616
1617 tree
1618 make_thunk (function, delta)
1619      tree function;
1620      int delta;
1621 {
1622   char buffer[250];
1623   tree thunk_fndecl, thunk_id;
1624   tree thunk;
1625   char *func_name;
1626   static int thunk_number = 0;
1627   tree func_decl;
1628   if (TREE_CODE (function) != ADDR_EXPR)
1629     abort ();
1630   func_decl = TREE_OPERAND (function, 0);
1631   if (TREE_CODE (func_decl) != FUNCTION_DECL)
1632     abort ();
1633   func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
1634   if (delta<=0)
1635     sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
1636   else
1637     sprintf (buffer, "__thunk_n%d_%s", delta, func_name);
1638   thunk_id = get_identifier (buffer);
1639   thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
1640   if (thunk && TREE_CODE (thunk) != THUNK_DECL)
1641     {
1642       cp_error ("implementation-reserved name `%D' used", thunk_id);
1643       IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
1644     }
1645   if (thunk == NULL_TREE)
1646     {
1647       thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
1648       DECL_RESULT (thunk)
1649         = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type)));
1650       TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type));
1651       TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type));
1652       make_function_rtl (thunk);
1653       comdat_linkage (thunk);
1654       TREE_SET_CODE (thunk, THUNK_DECL);
1655       DECL_INITIAL (thunk) = function;
1656       THUNK_DELTA (thunk) = delta;
1657       DECL_EXTERNAL (thunk) = 1;
1658       /* So that finish_file can write out any thunks that need to be: */
1659       pushdecl_top_level (thunk);
1660     }
1661   return thunk;
1662 }
1663
1664 void
1665 emit_thunk (thunk_fndecl)
1666   tree thunk_fndecl;
1667 {
1668   rtx insns;
1669   char buffer[250];
1670   tree argp;
1671   struct args_size stack_args_size;
1672   tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
1673   int delta = THUNK_DELTA (thunk_fndecl);
1674   char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
1675   int tem;
1676   int failure = 0;
1677   int save_ofp;
1678
1679   /* Used to remember which regs we need to emit a USE rtx for.  */
1680   rtx need_use[FIRST_PSEUDO_REGISTER];
1681   int need_use_count = 0;
1682
1683   /* rtx for the 'this' parameter.  */
1684   rtx this_rtx = 0, this_reg_rtx = 0, fixed_this_rtx;
1685
1686   char *(*save_decl_printable_name) () = decl_printable_name;
1687   /* Data on reg parms scanned so far.  */
1688   CUMULATIVE_ARGS args_so_far;
1689
1690   if (TREE_ASM_WRITTEN (thunk_fndecl))
1691     return;
1692
1693   TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1694
1695   TREE_ADDRESSABLE (function) = 1;
1696   mark_used (function);
1697
1698   decl_printable_name = thunk_printable_name;
1699   if (current_function_decl)
1700     abort ();
1701   current_function_decl = thunk_fndecl;
1702
1703   TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);
1704 #ifdef ASM_OUTPUT_MI_THUNK
1705   temporary_allocation ();
1706   assemble_start_function (thunk_fndecl, fnname);
1707   ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
1708   assemble_end_function (thunk_fndecl, fnname);
1709   permanent_allocation (1);
1710 #else
1711   save_ofp = flag_omit_frame_pointer;
1712   flag_omit_frame_pointer = 1;
1713   init_function_start (thunk_fndecl, input_filename, lineno);
1714   pushlevel (0);
1715   expand_start_bindings (1);
1716
1717   temporary_allocation ();
1718
1719   /* Start updating where the next arg would go.  */
1720   INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (function), NULL_RTX, 0);
1721   stack_args_size.constant = 0;
1722   stack_args_size.var = 0;
1723   /* SETUP for possible structure return address FIXME */
1724
1725   /* Now look through all the parameters, make sure that we
1726      don't clobber any registers used for parameters.
1727      Also, pick up an rtx for the first "this" parameter.  */
1728   for (argp = TYPE_ARG_TYPES (TREE_TYPE (function));
1729        argp != NULL_TREE;
1730        argp = TREE_CHAIN (argp))
1731
1732     {
1733       tree passed_type = TREE_VALUE (argp);
1734       register rtx entry_parm;
1735       int named = 1; /* FIXME */
1736       struct args_size stack_offset;
1737       struct args_size arg_size;
1738
1739       if (passed_type == void_type_node)
1740         break;
1741
1742       if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
1743            && contains_placeholder_p (TYPE_SIZE (passed_type)))
1744 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
1745           || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far,
1746                                              TYPE_MODE (passed_type),
1747                                              passed_type, named)
1748 #endif
1749           )
1750         passed_type = build_pointer_type (passed_type);
1751
1752       entry_parm = FUNCTION_ARG (args_so_far,
1753                                  TYPE_MODE (passed_type),
1754                                  passed_type,
1755                                  named);
1756       if (entry_parm != 0)
1757         need_use[need_use_count++] = entry_parm;
1758
1759       locate_and_pad_parm (TYPE_MODE (passed_type), passed_type,
1760 #ifdef STACK_PARMS_IN_REG_PARM_AREA
1761                            1,
1762 #else
1763                            entry_parm != 0,
1764 #endif
1765                            thunk_fndecl,
1766                            &stack_args_size, &stack_offset, &arg_size);
1767
1768 /*    REGNO (entry_parm);*/
1769       if (this_rtx == 0)
1770         {
1771           this_reg_rtx = entry_parm;
1772           if (!entry_parm)
1773             {
1774               rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
1775
1776               rtx internal_arg_pointer, stack_parm;
1777
1778               if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
1779                    || ! (fixed_regs[ARG_POINTER_REGNUM]
1780                          || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
1781                 internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
1782               else
1783                 internal_arg_pointer = virtual_incoming_args_rtx;
1784
1785               if (offset_rtx == const0_rtx)
1786                 entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),
1787                                       internal_arg_pointer);
1788               else
1789                 entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),
1790                                       gen_rtx (PLUS, Pmode,
1791                                                internal_arg_pointer, 
1792                                                offset_rtx));
1793             }
1794           
1795           this_rtx = entry_parm;
1796         }
1797
1798       FUNCTION_ARG_ADVANCE (args_so_far,
1799                             TYPE_MODE (passed_type),
1800                             passed_type,
1801                             named);
1802     }
1803
1804   fixed_this_rtx = plus_constant (this_rtx, delta);
1805   if (this_rtx != fixed_this_rtx)
1806     emit_move_insn (this_rtx, fixed_this_rtx);
1807
1808   if (this_reg_rtx)
1809     emit_insn (gen_rtx (USE, VOIDmode, this_reg_rtx));
1810
1811   emit_indirect_jump (XEXP (DECL_RTL (function), 0));
1812
1813   while (need_use_count > 0)
1814     emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count]));
1815
1816   expand_end_bindings (NULL, 1, 0);
1817   poplevel (0, 0, 1);
1818
1819   /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
1820      Note that that may have been done above, in save_for_inline_copying.
1821      The call to resume_temporary_allocation near the end of this function
1822      goes back to the usual state of affairs.  */
1823
1824   rtl_in_current_obstack ();
1825
1826   insns = get_insns ();
1827
1828   /* Copy any shared structure that should not be shared.  */
1829
1830   unshare_all_rtl (insns);
1831
1832   /* Instantiate all virtual registers.  */
1833
1834   instantiate_virtual_regs (current_function_decl, get_insns ());
1835
1836   /* We are no longer anticipating cse in this function, at least.  */
1837
1838   cse_not_expected = 1;
1839
1840   /* Now we choose between stupid (pcc-like) register allocation
1841      (if we got the -noreg switch and not -opt)
1842      and smart register allocation.  */
1843
1844   if (optimize > 0)                     /* Stupid allocation probably won't work */
1845     obey_regdecls = 0;          /* if optimizations being done.  */
1846
1847   regclass_init ();
1848
1849   regclass (insns, max_reg_num ());
1850   if (obey_regdecls)
1851     {
1852       stupid_life_analysis (insns, max_reg_num (), NULL);
1853       failure = reload (insns, 0, NULL);
1854     }
1855   else
1856     {
1857       /* Do control and data flow analysis,
1858          and write some of the results to dump file.  */
1859
1860       flow_analysis (insns, max_reg_num (), NULL);
1861       local_alloc ();
1862       failure = global_alloc (NULL);
1863     }
1864
1865   reload_completed = 1;
1866
1867 #ifdef LEAF_REGISTERS
1868   leaf_function = 0;
1869   if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
1870     leaf_function = 1;
1871 #endif
1872
1873   /* If a machine dependent reorganization is needed, call it.  */
1874 #ifdef MACHINE_DEPENDENT_REORG
1875    MACHINE_DEPENDENT_REORG (insns);
1876 #endif
1877
1878   /* Now turn the rtl into assembler code.  */
1879
1880   assemble_start_function (thunk_fndecl, fnname);
1881   final (insns, asm_out_file, optimize, 0);
1882   assemble_end_function (thunk_fndecl, fnname);
1883
1884   reload_completed = 0;
1885
1886   /* Cancel the effect of rtl_in_current_obstack.  */
1887
1888   permanent_allocation (1);
1889   flag_omit_frame_pointer = save_ofp;
1890 #endif /* ASM_OUTPUT_MI_THUNK */
1891   TREE_SET_CODE (thunk_fndecl, THUNK_DECL);
1892
1893   decl_printable_name = save_decl_printable_name;
1894   current_function_decl = 0;
1895 }
1896 \f
1897 /* Code for synthesizing methods which have default semantics defined.  */
1898
1899 /* For the anonymous union in TYPE, return the member that is at least as
1900    large as the rest of the members, so we can copy it.  */
1901
1902 static tree
1903 largest_union_member (type)
1904      tree type;
1905 {
1906   tree f, type_size = TYPE_SIZE (type);
1907
1908   for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
1909     if (simple_cst_equal (DECL_SIZE (f), type_size) == 1)
1910       return f;
1911
1912   /* We should always find one.  */
1913   my_friendly_abort (323);
1914   return NULL_TREE;
1915 }
1916
1917 /* Generate code for default X(X&) constructor.  */
1918
1919 void
1920 do_build_copy_constructor (fndecl)
1921      tree fndecl;
1922 {
1923   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
1924   tree t;
1925
1926   clear_last_expr ();
1927   push_momentary ();
1928
1929   if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
1930     parm = TREE_CHAIN (parm);
1931   parm = convert_from_reference (parm);
1932
1933   if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
1934     {
1935       t = build (INIT_EXPR, void_type_node, current_class_ref, parm);
1936       TREE_SIDE_EFFECTS (t) = 1;
1937       cplus_expand_expr_stmt (t);
1938     }
1939   else
1940     {
1941       tree fields = TYPE_FIELDS (current_class_type);
1942       int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
1943       tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
1944       int i;
1945
1946       for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
1947            t = TREE_CHAIN (t))
1948         {
1949           tree basetype = BINFO_TYPE (t);
1950           tree p = convert_to_reference
1951             (build_reference_type (basetype), parm,
1952              CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
1953           p = convert_from_reference (p);
1954
1955           if (p == error_mark_node)
1956             cp_error ("in default copy constructor");
1957           else 
1958             current_base_init_list = tree_cons (basetype,
1959                                                 p, current_base_init_list);
1960         }
1961         
1962       for (i = 0; i < n_bases; ++i)
1963         {
1964           tree p, basetype = TREE_VEC_ELT (binfos, i);
1965           if (TREE_VIA_VIRTUAL (basetype))
1966             continue; 
1967
1968           basetype = BINFO_TYPE (basetype);
1969           p = convert_to_reference
1970             (build_reference_type (basetype), parm,
1971              CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
1972
1973           if (p == error_mark_node) 
1974             cp_error ("in default copy constructor");
1975           else 
1976             {
1977               p = convert_from_reference (p);
1978               current_base_init_list = tree_cons (basetype,
1979                                                   p, current_base_init_list);
1980             }
1981         }
1982       for (; fields; fields = TREE_CHAIN (fields))
1983         {
1984           tree name, init, t;
1985           tree field = fields;
1986
1987           if (TREE_CODE (field) != FIELD_DECL)
1988             continue;
1989           if (DECL_NAME (field))
1990             {
1991               if (VFIELD_NAME_P (DECL_NAME (field)))
1992                 continue;
1993               if (VBASE_NAME_P (DECL_NAME (field)))
1994                 continue;
1995
1996               /* True for duplicate members.  */
1997               if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
1998                 continue;
1999             }
2000           else if ((t = TREE_TYPE (field)) != NULL_TREE
2001                    && TREE_CODE (t) == UNION_TYPE
2002                    && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
2003                    && TYPE_FIELDS (t) != NULL_TREE)
2004             field = largest_union_member (t);
2005           else
2006             continue;
2007
2008           init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
2009           init = build_tree_list (NULL_TREE, init);
2010
2011           current_member_init_list
2012             = tree_cons (DECL_NAME (field), init, current_member_init_list);
2013         }
2014       current_member_init_list = nreverse (current_member_init_list);
2015       current_base_init_list = nreverse (current_base_init_list);
2016       setup_vtbl_ptr ();
2017     }
2018
2019   pop_momentary ();
2020 }
2021
2022 void
2023 do_build_assign_ref (fndecl)
2024      tree fndecl;
2025 {
2026   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
2027
2028   clear_last_expr ();
2029   push_momentary ();
2030
2031   parm = convert_from_reference (parm);
2032
2033   if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))
2034     {
2035       tree t = build (MODIFY_EXPR, void_type_node, current_class_ref, parm);
2036       TREE_SIDE_EFFECTS (t) = 1;
2037       cplus_expand_expr_stmt (t);
2038     }
2039   else
2040     {
2041       tree fields = TYPE_FIELDS (current_class_type);
2042       int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
2043       tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
2044       int i;
2045
2046       for (i = 0; i < n_bases; ++i)
2047         {
2048           tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
2049           tree p = convert_to_reference
2050             (build_reference_type (basetype), parm,
2051              CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
2052           p = convert_from_reference (p);
2053           p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
2054                                  build_tree_list (NULL_TREE, p));
2055           expand_expr_stmt (p);
2056         }
2057       for (; fields; fields = TREE_CHAIN (fields))
2058         {
2059           tree comp, init, t;
2060           tree field = fields;
2061
2062           if (TREE_CODE (field) != FIELD_DECL)
2063             continue;
2064
2065           if (TREE_READONLY (field))
2066             {
2067               if (DECL_NAME (field))
2068                 cp_error ("non-static const member `%#D', can't use default assignment operator", field);
2069               else
2070                 cp_error ("non-static const member in type `%T', can't use default assignment operator", current_class_type);
2071               continue;
2072             }
2073           else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
2074             {
2075               if (DECL_NAME (field))
2076                 cp_error ("non-static reference member `%#D', can't use default assignment operator", field);
2077               else
2078                 cp_error ("non-static reference member in type `%T', can't use default assignment operator", current_class_type);
2079               continue;
2080             }
2081
2082           if (DECL_NAME (field))
2083             {
2084               if (VFIELD_NAME_P (DECL_NAME (field)))
2085                 continue;
2086               if (VBASE_NAME_P (DECL_NAME (field)))
2087                 continue;
2088
2089               /* True for duplicate members.  */
2090               if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
2091                 continue;
2092             }
2093           else if ((t = TREE_TYPE (field)) != NULL_TREE
2094                    && TREE_CODE (t) == UNION_TYPE
2095                    && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
2096                    && TYPE_FIELDS (t) != NULL_TREE)
2097             field = largest_union_member (t);
2098           else
2099             continue;
2100
2101           comp = build (COMPONENT_REF, TREE_TYPE (field), current_class_ref, field);
2102           init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
2103
2104           expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
2105         }
2106     }
2107   c_expand_return (current_class_ref);
2108   pop_momentary ();
2109 }
2110
2111 void
2112 synthesize_method (fndecl)
2113      tree fndecl;
2114 {
2115   int nested = (current_function_decl != NULL_TREE);
2116   tree context = hack_decl_function_context (fndecl);
2117   tree base = DECL_CLASS_CONTEXT (fndecl);
2118
2119   if (! context)
2120     push_to_top_level ();
2121   else if (nested)
2122     push_cp_function_context (context);
2123
2124   interface_unknown = 1;
2125   start_function (NULL_TREE, fndecl, NULL_TREE, 1);
2126   store_parm_decls ();
2127
2128   if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])
2129     do_build_assign_ref (fndecl);
2130   else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
2131     ;
2132   else
2133     {
2134       tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
2135       if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
2136         arg_chain = TREE_CHAIN (arg_chain);
2137       if (arg_chain != void_list_node)
2138         do_build_copy_constructor (fndecl);
2139       else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
2140         setup_vtbl_ptr ();
2141     }
2142
2143   finish_function (lineno, 0, nested);
2144
2145   /* Do we really *want* to inline this function?  */
2146   if (DECL_INLINE (fndecl))
2147     {
2148       /* Turn off DECL_INLINE for the moment so function_cannot_inline_p
2149          will check our size.  */
2150       DECL_INLINE (fndecl) = 0;
2151
2152       /* We say !at_eof because at the end of the file some of the rtl
2153          for fndecl may have been allocated on the temporary obstack.
2154          (The function_obstack is the temporary one if we're not in a
2155          function). */
2156       if ((! at_eof) && function_cannot_inline_p (fndecl) == 0)
2157         DECL_INLINE (fndecl) = 1;
2158     }
2159
2160   extract_interface_info ();
2161   if (! context)
2162     pop_from_top_level ();
2163   else if (nested)
2164     pop_cp_function_context (context);
2165 }