OSDN Git Service

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