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