OSDN Git Service

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