OSDN Git Service

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