OSDN Git Service

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