OSDN Git Service

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