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