OSDN Git Service

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