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