OSDN Git Service

* pt.c (check_explicit_specialization): Complain about using a
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
1 /* Call-backs for C++ error reporting.
2    This code is non-reentrant.
3    Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
4
5    This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include <stdio.h>
24 #include "tree.h"
25 #include "cp-tree.h"
26 #include "obstack.h"
27 #include <ctype.h>
28
29 typedef char* cp_printer ();
30
31 #define A args_as_string
32 #define C code_as_string
33 #define D decl_as_string
34 #define E expr_as_string
35 #define L language_as_string
36 #define O op_as_string
37 #define P parm_as_string
38 #define Q assop_as_string
39 #define T type_as_string
40 #define V cv_as_string
41
42 #define _ (cp_printer *) 0
43 cp_printer * cp_printers[256] =
44
45 /*0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
46   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */
47   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */
48   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */
49   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */
50   _, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */
51   P, Q, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
52   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */
53   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */
54 };
55 #undef C
56 #undef D
57 #undef E
58 #undef L
59 #undef O
60 #undef P
61 #undef Q
62 #undef T
63 #undef V
64 #undef _
65
66 #define obstack_chunk_alloc xmalloc
67 #define obstack_chunk_free free
68
69 /* Obstack where we build text strings for overloading, etc.  */
70 static struct obstack scratch_obstack;
71 static char *scratch_firstobj;
72
73 # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
74 # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
75 # define OB_PUTC2(C1,C2)        \
76   (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
77 # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
78 # define OB_PUTID(ID)  \
79   (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),     \
80                  IDENTIFIER_LENGTH (ID)))
81 # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
82 # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
83 # define OB_PUTI(CST) do { sprintf (digit_buffer, "%d", (CST)); \
84                            OB_PUTCP (digit_buffer); } while (0)
85 # define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));
86
87 # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
88
89 enum pad { none, before, after };
90
91 static void dump_type PROTO((tree, int));
92 static void dump_decl PROTO((tree, int));
93 static void dump_function_decl PROTO((tree, int));
94 static void dump_expr PROTO((tree, int));
95 static void dump_unary_op PROTO((char *, tree, int));
96 static void dump_binary_op PROTO((char *, tree));
97 static void dump_aggr_type PROTO((tree, int));
98 static void dump_type_prefix PROTO((tree, int));
99 static void dump_type_suffix PROTO((tree, int));
100 static void dump_function_name PROTO((tree));
101 static void dump_expr_list PROTO((tree));
102 static void dump_global_iord PROTO((tree));
103 static void dump_readonly_or_volatile PROTO((tree, enum pad));
104 static void dump_char PROTO((int));
105 static char *aggr_variety PROTO((tree));
106 static tree ident_fndecl PROTO((tree));
107
108 void
109 init_error ()
110 {
111   gcc_obstack_init (&scratch_obstack);
112   scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
113 }
114
115 static void
116 dump_readonly_or_volatile (t, p)
117      tree t;
118      enum pad p;
119 {
120   if (TYPE_READONLY (t) || TYPE_VOLATILE (t))
121     {
122       if (p == before) OB_PUTC (' ');
123       if (TYPE_READONLY (t))
124         OB_PUTS ("const");
125       if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
126         OB_PUTC (' ');
127       if (TYPE_VOLATILE (t))
128         OB_PUTS ("volatile");
129       if (p == after) OB_PUTC (' ');
130     }
131 }
132
133 /* This must be large enough to hold any printed integer or floating-point
134    value.  */
135 static char digit_buffer[128];
136
137 /* Dump into the obstack a human-readable equivalent of TYPE.  */
138
139 static void
140 dump_type (t, v)
141      tree t;
142      int v;                     /* verbose? */
143 {
144   if (t == NULL_TREE)
145     return;
146   
147   if (TYPE_PTRMEMFUNC_P (t))
148     goto offset_type;
149
150   switch (TREE_CODE (t))
151     {
152     case ERROR_MARK:
153       OB_PUTS ("{error}");
154       break;
155
156     case UNKNOWN_TYPE:
157       OB_PUTS ("{unknown type}");
158       break;
159
160     case TREE_LIST:
161       /* i.e. function taking no arguments */
162       if (t != void_list_node)
163         {
164           dump_type (TREE_VALUE (t), v);
165           /* Can this happen other than for default arguments? */
166           if (TREE_PURPOSE (t) && v)
167             {
168               OB_PUTS (" = ");
169               dump_expr (TREE_PURPOSE (t), 0);
170             }
171           if (TREE_CHAIN (t))
172             {
173               if (TREE_CHAIN (t) != void_list_node)
174                 {
175                   OB_PUTC2 (',', ' ');
176                   dump_type (TREE_CHAIN (t), v);
177                 }
178             }
179           else OB_PUTS (" ...");
180         }
181       break;
182
183     case IDENTIFIER_NODE:
184       OB_PUTID (t);
185       break;
186
187     case TREE_VEC:
188       dump_type (BINFO_TYPE (t), v);
189       break;
190
191     case RECORD_TYPE:
192     case UNION_TYPE:
193     case ENUMERAL_TYPE:
194       if (TYPE_LANG_SPECIFIC (t)
195           && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
196         {
197           if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
198             dump_readonly_or_volatile (t, after);
199           dump_type (SIGNATURE_TYPE (t), v);
200           if (IS_SIGNATURE_POINTER (t))
201             OB_PUTC ('*');
202           else
203             OB_PUTC ('&');
204         }
205       else
206         dump_aggr_type (t, v);
207       break;
208
209     case TYPE_DECL:
210       dump_decl (t, v);
211       break;
212
213     case COMPLEX_TYPE:
214       OB_PUTS ("complex ");
215       dump_type (TREE_TYPE (t), v);
216       break;
217
218     case INTEGER_TYPE:
219       if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
220         OB_PUTS ("unsigned ");
221       else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
222         OB_PUTS ("signed ");
223
224       /* fall through.  */
225     case REAL_TYPE:
226     case VOID_TYPE:
227     case BOOLEAN_TYPE:
228       dump_readonly_or_volatile (t, after);
229       OB_PUTID (TYPE_IDENTIFIER (t));
230       break;
231
232     case TEMPLATE_TYPE_PARM:
233       dump_readonly_or_volatile (t, after);
234       if (TYPE_IDENTIFIER (t))
235         OB_PUTID (TYPE_IDENTIFIER (t));
236       else
237         OB_PUTS ("{anonymous template type parm}");
238       break;
239
240       /* This is not always necessary for pointers and such, but doing this
241          reduces code size.  */
242     case ARRAY_TYPE:
243     case POINTER_TYPE:
244     case REFERENCE_TYPE:
245     case OFFSET_TYPE:
246     offset_type:
247     case FUNCTION_TYPE:
248     case METHOD_TYPE:
249       dump_type_prefix (t, v);
250       dump_type_suffix (t, v);
251       break;
252
253     case TYPENAME_TYPE:
254       OB_PUTS ("typename ");
255       dump_type (TYPE_CONTEXT (t), 0);
256       OB_PUTS ("::");
257       OB_PUTID (TYPE_IDENTIFIER (t));
258       break;
259
260     default:
261       sorry ("`%s' not supported by dump_type",
262              tree_code_name[(int) TREE_CODE (t)]);
263     }
264 }
265
266 static char *
267 aggr_variety (t)
268      tree t;
269 {
270   if (TREE_CODE (t) == ENUMERAL_TYPE)
271     return "enum";
272   else if (TREE_CODE (t) == UNION_TYPE)
273     return "union";
274   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
275     return "class";
276   else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t))
277     return "signature";
278   else
279     return "struct";
280 }
281
282 /* Print out a class declaration, in the form `class foo'.  */
283
284 static void
285 dump_aggr_type (t, v)
286      tree t;
287      int v;                     /* verbose? */
288 {
289   tree name;
290   char *variety = aggr_variety (t);
291
292   dump_readonly_or_volatile (t, after);
293
294   if (v > 0)
295     {
296       OB_PUTCP (variety);
297       OB_PUTC (' ');
298     }
299   
300   name = TYPE_NAME (t);
301
302   if (name && DECL_CONTEXT (name))
303     {
304       /* FUNCTION_DECL or RECORD_TYPE */
305       dump_decl (DECL_CONTEXT (name), 0);
306       OB_PUTC2 (':', ':');
307     }
308
309   /* kludge around weird behavior on g++.brendan/line1.C */
310   if (name && TREE_CODE (name) != IDENTIFIER_NODE)
311     name = DECL_NAME (name);
312
313   if (name == 0 || ANON_AGGRNAME_P (name))
314     {
315       OB_PUTS ("{anonymous");
316       if (!v)
317         {
318           OB_PUTC (' ');
319           OB_PUTCP (variety);
320         }
321       OB_PUTC ('}');
322     }
323   else
324     OB_PUTID (name);
325 }
326
327 /* Dump into the obstack the initial part of the output for a given type.
328    This is necessary when dealing with things like functions returning
329    functions.  Examples:
330
331    return type of `int (* fee ())()': pointer -> function -> int.  Both
332    pointer (and reference and offset) and function (and member) types must
333    deal with prefix and suffix.
334
335    Arrays must also do this for DECL nodes, like int a[], and for things like
336    int *[]&.  */
337
338 static void
339 dump_type_prefix (t, v)
340      tree t;
341      int v;                     /* verbosity */
342 {
343   if (TYPE_PTRMEMFUNC_P (t))
344     {
345       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
346       goto offset_type;
347     }
348   
349   switch (TREE_CODE (t))
350     {
351     case POINTER_TYPE:
352       {
353         tree sub = TREE_TYPE (t);
354         
355         dump_type_prefix (sub, v);
356         /* A tree for a member pointer looks like pointer to offset,
357            so let the OFFSET_TYPE case handle it.  */
358         if (TREE_CODE (sub) != OFFSET_TYPE)
359           {
360             switch (TREE_CODE (sub))
361               {
362                 /* We don't want int ( *)() */
363               case FUNCTION_TYPE:
364               case METHOD_TYPE:
365                 break;
366                 
367               case ARRAY_TYPE:
368                 OB_PUTC2 (' ', '(');
369                 break;
370
371               case POINTER_TYPE:
372                 /* We don't want "char * *" */
373                 if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
374                   break;
375                 /* But we do want "char *const *" */
376                 
377               default:
378                 OB_PUTC (' ');
379               }
380             OB_PUTC ('*');
381             dump_readonly_or_volatile (t, none);
382           }
383       }
384       break;
385
386     case REFERENCE_TYPE:
387       {
388         tree sub = TREE_TYPE (t);
389         dump_type_prefix (sub, v);
390
391         switch (TREE_CODE (sub))
392           {
393           case ARRAY_TYPE:
394             OB_PUTC2 (' ', '(');
395             break;
396
397           case POINTER_TYPE:
398             /* We don't want "char * &" */
399             if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
400               break;
401             /* But we do want "char *const &" */
402
403           default:
404             OB_PUTC (' ');
405           }
406       }
407       OB_PUTC ('&');
408       dump_readonly_or_volatile (t, none);
409       break;
410
411     case OFFSET_TYPE:
412     offset_type:
413       dump_type_prefix (TREE_TYPE (t), v);
414       if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
415         {
416           OB_PUTC (' ');
417           dump_type (TYPE_OFFSET_BASETYPE (t), 0);
418           OB_PUTC2 (':', ':');
419         }
420       OB_PUTC ('*');
421       dump_readonly_or_volatile (t, none);
422       break;
423
424       /* Can only be reached through function pointer -- this would not be
425          correct if FUNCTION_DECLs used it.  */
426     case FUNCTION_TYPE:
427       dump_type_prefix (TREE_TYPE (t), v);
428       OB_PUTC2 (' ', '(');
429       break;
430
431     case METHOD_TYPE:
432       dump_type_prefix (TREE_TYPE (t), v);
433       OB_PUTC2 (' ', '(');
434       dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0);
435       OB_PUTC2 (':', ':');
436       break;
437
438     case ARRAY_TYPE:
439       dump_type_prefix (TREE_TYPE (t), v);
440       break;
441
442     case ENUMERAL_TYPE:
443     case ERROR_MARK:
444     case IDENTIFIER_NODE:
445     case INTEGER_TYPE:
446     case BOOLEAN_TYPE:
447     case REAL_TYPE:
448     case RECORD_TYPE:
449     case TEMPLATE_TYPE_PARM:
450     case TREE_LIST:
451     case TYPE_DECL:
452     case TREE_VEC:
453     case UNION_TYPE:
454     case UNKNOWN_TYPE:
455     case VOID_TYPE:
456     case TYPENAME_TYPE:
457     case COMPLEX_TYPE:
458       dump_type (t, v);
459       break;
460       
461     default:
462       sorry ("`%s' not supported by dump_type_prefix",
463              tree_code_name[(int) TREE_CODE (t)]);
464     }
465 }
466
467 static void
468 dump_type_suffix (t, v)
469      tree t;
470      int v;                     /* verbose? */
471 {
472   if (TYPE_PTRMEMFUNC_P (t))
473     t = TYPE_PTRMEMFUNC_FN_TYPE (t);
474
475   switch (TREE_CODE (t))
476     {
477     case POINTER_TYPE:
478     case REFERENCE_TYPE:
479     case OFFSET_TYPE:
480       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
481         OB_PUTC (')');
482       dump_type_suffix (TREE_TYPE (t), v);
483       break;
484
485       /* Can only be reached through function pointer */
486     case FUNCTION_TYPE:
487     case METHOD_TYPE:
488       {
489         tree arg;
490         OB_PUTC2 (')', '(');
491         arg = TYPE_ARG_TYPES (t);
492         if (TREE_CODE (t) == METHOD_TYPE)
493           arg = TREE_CHAIN (arg);
494
495         if (arg)
496           dump_type (arg, v);
497         else
498           OB_PUTS ("...");
499         OB_PUTC (')');
500         if (TREE_CODE (t) == METHOD_TYPE)
501           dump_readonly_or_volatile
502             (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
503         dump_type_suffix (TREE_TYPE (t), v);
504         break;
505       }
506
507     case ARRAY_TYPE:
508       OB_PUTC ('[');
509       if (TYPE_DOMAIN (t))
510         {
511           if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
512             OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
513           else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
514             dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0);
515           else
516             dump_expr (fold (build_binary_op
517                              (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
518                               integer_one_node, 1)), 0);
519         }
520       OB_PUTC (']');
521       dump_type_suffix (TREE_TYPE (t), v);
522       break;
523       
524     case ENUMERAL_TYPE:
525     case ERROR_MARK:
526     case IDENTIFIER_NODE:
527     case INTEGER_TYPE:
528     case BOOLEAN_TYPE:
529     case REAL_TYPE:
530     case RECORD_TYPE:
531     case TEMPLATE_TYPE_PARM:
532     case TREE_LIST:
533     case TYPE_DECL:
534     case TREE_VEC:
535     case UNION_TYPE:
536     case UNKNOWN_TYPE:
537     case VOID_TYPE:
538     case TYPENAME_TYPE:
539     case COMPLEX_TYPE:
540       break;
541
542     default:
543       sorry ("`%s' not supported by dump_type_suffix",
544              tree_code_name[(int) TREE_CODE (t)]);
545     }
546 }
547
548 /* Return a function declaration which corresponds to the IDENTIFIER_NODE
549    argument.  */
550
551 static tree
552 ident_fndecl (t)
553      tree t;
554 {
555   tree n = lookup_name (t, 0);
556
557   if (n == NULL_TREE)
558     return NULL_TREE;
559
560   if (TREE_CODE (n) == FUNCTION_DECL)
561     return n;
562   else if (TREE_CODE (n) == TREE_LIST
563            && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL)
564     return TREE_VALUE (n);
565
566   my_friendly_abort (66);
567   return NULL_TREE;
568 }
569
570 #ifndef NO_DOLLAR_IN_LABEL
571 #  define GLOBAL_THING "_GLOBAL_$"
572 #else
573 #  ifndef NO_DOT_IN_LABEL
574 #    define GLOBAL_THING "_GLOBAL_."
575 #  else
576 #    define GLOBAL_THING "_GLOBAL__"
577 #  endif
578 #endif
579
580 #define GLOBAL_IORD_P(NODE) \
581   ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
582
583 static void
584 dump_global_iord (t)
585      tree t;
586 {
587   char *name = IDENTIFIER_POINTER (t);
588
589   OB_PUTS ("(static ");
590   if (name [sizeof (GLOBAL_THING) - 1] == 'I')
591     OB_PUTS ("initializers");
592   else if (name [sizeof (GLOBAL_THING) - 1] == 'D')
593     OB_PUTS ("destructors");
594   else
595     my_friendly_abort (352);
596   
597   OB_PUTS (" for ");
598   OB_PUTCP (input_filename);
599   OB_PUTC (')');
600 }
601
602 static void
603 dump_decl (t, v)
604      tree t;
605      int v;                     /* verbosity */
606 {
607   if (t == NULL_TREE)
608     return;
609
610   switch (TREE_CODE (t))
611     {
612     case ERROR_MARK:
613       OB_PUTS (" /* decl error */ ");
614       break;
615
616     case TYPE_DECL:
617       {
618         /* Don't say 'typedef class A' */
619         if (DECL_ARTIFICIAL (t))
620           {
621             dump_type (TREE_TYPE (t), v);
622             break;
623           }
624       }
625       if (v > 0)
626         OB_PUTS ("typedef ");
627       goto general;
628       break;
629       
630     case VAR_DECL:
631       if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
632         {
633           OB_PUTS ("vtable for ");
634           dump_type (DECL_CONTEXT (t), v);
635           break;
636         }
637       /* else fall through */
638     case FIELD_DECL:
639     case PARM_DECL:
640     general:
641       if (v > 0)
642         {
643           dump_type_prefix (TREE_TYPE (t), v);
644           OB_PUTC (' ');
645           dump_readonly_or_volatile (t, after);
646         }
647       /* DECL_CLASS_CONTEXT isn't being set in some cases.  Hmm...  */
648       if (DECL_CONTEXT (t)
649           && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')
650         {
651           dump_type (DECL_CONTEXT (t), 0);
652           OB_PUTC2 (':', ':');
653         }
654       if (DECL_NAME (t))
655         dump_decl (DECL_NAME (t), v);
656       else
657         OB_PUTS ("{anon}");
658       if (v > 0)
659         dump_type_suffix (TREE_TYPE (t), v);
660       break;
661
662     case NAMESPACE_DECL:
663       OB_PUTID (DECL_NAME (t));
664       break;
665
666     case ARRAY_REF:
667       dump_decl (TREE_OPERAND (t, 0), v);
668       OB_PUTC ('[');
669       dump_decl (TREE_OPERAND (t, 1), v);
670       OB_PUTC (']');
671       break;
672
673       /* So that we can do dump_decl in dump_aggr_type and have it work for
674          both class and function scope.  */
675     case RECORD_TYPE:
676     case UNION_TYPE:
677     case ENUMERAL_TYPE:
678       dump_type (t, v);
679       break;
680
681     case TYPE_EXPR:
682       my_friendly_abort (69);
683       break;
684
685       /* These special cases are duplicated here so that other functions
686          can feed identifiers to cp_error and get them demangled properly.  */
687     case IDENTIFIER_NODE:
688       { tree f;
689         if (DESTRUCTOR_NAME_P (t)
690             && (f = ident_fndecl (t))
691             && DECL_LANGUAGE (f) == lang_cplusplus)
692           {
693             OB_PUTC ('~');
694             dump_decl (DECL_NAME (f), 0);
695           }
696         else if (IDENTIFIER_TYPENAME_P (t))
697           {
698             OB_PUTS ("operator ");
699             /* Not exactly IDENTIFIER_TYPE_VALUE.  */
700             dump_type (TREE_TYPE (t), 0);
701             break;
702           }
703         else if (IDENTIFIER_OPNAME_P (t))
704           {
705             char *name_string = operator_name_string (t);
706             OB_PUTS ("operator ");
707             OB_PUTCP (name_string);
708           }
709         else
710           OB_PUTID (t);
711       }
712       break;
713
714     case FUNCTION_DECL:
715       if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
716         dump_global_iord (DECL_ASSEMBLER_NAME (t));
717       else if (! DECL_LANG_SPECIFIC (t))
718         OB_PUTS ("{internal}");
719       else
720         dump_function_decl (t, v);
721       break;
722
723     case TEMPLATE_DECL:
724       {
725         tree orig_args = DECL_TEMPLATE_PARMS (t);
726         tree args;
727         int i; 
728         for (args = orig_args = nreverse (orig_args); 
729              args;
730              args = TREE_CHAIN (args))
731           {
732             int len = TREE_VEC_LENGTH (TREE_VALUE (args));
733
734             OB_PUTS ("template <");
735             for (i = 0; i < len; i++)
736               {
737                 tree arg = TREE_VEC_ELT (TREE_VALUE (args), i);
738                 tree defval = TREE_PURPOSE (arg);
739                 arg = TREE_VALUE (arg);
740                 if (TREE_CODE (arg) == TYPE_DECL)
741                   {
742                     OB_PUTS ("class ");
743                     OB_PUTID (DECL_NAME (arg));
744                   }
745                 else
746                   dump_decl (arg, 1);
747                 
748                 if (defval)
749                   {
750                     OB_PUTS (" = ");
751                     dump_decl (defval, 1);
752                   }
753                 
754                 OB_PUTC2 (',', ' ');
755               }
756             if (len != 0)
757               OB_UNPUT (2);
758             OB_PUTC2 ('>', ' ');
759           }
760         nreverse(orig_args);
761
762         if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
763           dump_type (TREE_TYPE (t), v);
764         else if (TREE_TYPE (t) == NULL_TREE)
765            my_friendly_abort (353);
766         else switch (NEXT_CODE (t))
767           {
768           case METHOD_TYPE:
769           case FUNCTION_TYPE:
770             dump_function_decl (t, v);
771             break;
772
773           default:
774             my_friendly_abort (353);
775           }
776       }
777       break;
778
779     case TEMPLATE_ID_EXPR:
780       {
781         tree args;
782         dump_type (TREE_OPERAND (t, 0), v);
783         OB_PUTC ('<');
784         for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
785           {
786             if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't')
787               dump_type (TREE_VALUE (args), 0);
788             else
789               dump_expr (TREE_VALUE (args), 0);
790             if (TREE_CHAIN (args))
791               OB_PUTC2 (',', ' ');
792           }
793         OB_PUTC ('>');
794       }
795       break;
796
797     case LABEL_DECL:
798       OB_PUTID (DECL_NAME (t));
799       break;
800
801     case CONST_DECL:
802       if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
803           || (DECL_INITIAL (t) &&
804               TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_CONST_PARM))
805         goto general;
806       else if (DECL_INITIAL (t))
807         dump_expr (DECL_INITIAL (t), 0);
808       else
809         OB_PUTS ("enumerator");
810       break;
811
812     case USING_DECL:
813       OB_PUTS ("using ");
814       dump_type (DECL_INITIAL (t), 0);
815       OB_PUTS ("::");
816       OB_PUTID (DECL_NAME (t));
817       break;
818
819     default:
820       sorry ("`%s' not supported by dump_decl",
821              tree_code_name[(int) TREE_CODE (t)]);
822     }
823 }
824
825 /* Pretty printing for announce_function.  T is the declaration of the
826    function we are interested in seeing.  V is non-zero if we should print
827    the type that this function returns.  */
828
829 static void
830 dump_function_decl (t, v)
831      tree t;
832      int v;
833 {
834   tree name;
835   tree fntype;
836   tree parmtypes;
837   tree cname = NULL_TREE;
838
839   if (TREE_CODE (t) == TEMPLATE_DECL)
840     t = DECL_TEMPLATE_RESULT (t);
841
842   name = DECL_ASSEMBLER_NAME (t);
843   fntype = TREE_TYPE (t);
844   parmtypes = TYPE_ARG_TYPES (fntype);
845
846   /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT.  */
847   if (DECL_CONTEXT (t))
848     cname = DECL_CLASS_CONTEXT (t);
849   /* this is for partially instantiated template methods */
850   else if (TREE_CODE (fntype) == METHOD_TYPE)
851     cname = TREE_TYPE (TREE_VALUE (parmtypes));
852
853   v = (v > 0);
854   
855   if (v)
856     {
857       if (DECL_STATIC_FUNCTION_P (t))
858         OB_PUTS ("static ");
859     
860       if (! IDENTIFIER_TYPENAME_P (name)
861           && ! DECL_CONSTRUCTOR_P (t)
862           && ! DESTRUCTOR_NAME_P (name))
863         {
864           dump_type_prefix (TREE_TYPE (fntype), 1);
865           OB_PUTC (' ');
866         }
867     }
868
869   if (cname)
870     {
871       dump_type (cname, 0);
872       OB_PUTC2 (':', ':');
873       if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
874         parmtypes = TREE_CHAIN (parmtypes);
875       if (DECL_CONSTRUCTOR_FOR_VBASE_P (t))
876         /* Skip past "in_charge" identifier.  */
877         parmtypes = TREE_CHAIN (parmtypes);
878     }
879
880   if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus)
881     parmtypes = TREE_CHAIN (parmtypes);
882   
883   dump_function_name (t);
884   
885   OB_PUTC ('(');
886
887   if (parmtypes)
888     dump_type (parmtypes, v);
889   else
890     OB_PUTS ("...");
891
892   OB_PUTC (')');
893
894   if (v && ! IDENTIFIER_TYPENAME_P (name))
895     dump_type_suffix (TREE_TYPE (fntype), 1);
896
897   if (TREE_CODE (fntype) == METHOD_TYPE)
898     {
899       if (IS_SIGNATURE (cname))
900         /* We look at the type pointed to by the `optr' field of `this.'  */
901         dump_readonly_or_volatile
902           (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
903       else
904         dump_readonly_or_volatile
905           (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
906     }
907 }
908
909 /* Handle the function name for a FUNCTION_DECL node, grokking operators
910    and destructors properly.  */
911
912 static void
913 dump_function_name (t)
914      tree t;
915 {
916   tree name = DECL_NAME (t);
917
918   /* There ought to be a better way to find out whether or not something is
919      a destructor.  */
920   if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))
921       && DECL_LANGUAGE (t) == lang_cplusplus)
922     {
923       OB_PUTC ('~');
924       dump_decl (name, 0);
925     }
926   else if (IDENTIFIER_TYPENAME_P (name))
927     {
928       /* This cannot use the hack that the operator's return
929          type is stashed off of its name because it may be
930          used for error reporting.  In the case of conflicting
931          declarations, both will have the same name, yet
932          the types will be different, hence the TREE_TYPE field
933          of the first name will be clobbered by the second.  */
934       OB_PUTS ("operator ");
935       dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
936     }
937   else if (IDENTIFIER_OPNAME_P (name))
938     {
939       char *name_string = operator_name_string (name);
940       OB_PUTS ("operator ");
941       OB_PUTCP (name_string);
942     }
943   else
944     dump_decl (name, 0);
945
946   if (DECL_LANG_SPECIFIC (t)
947       && (DECL_TEMPLATE_SPECIALIZATION (t) || DECL_IMPLICIT_INSTANTIATION (t))
948       && (DECL_CLASS_CONTEXT (t) == NULL_TREE || is_member_template (t)))
949     {
950       tree args = DECL_TEMPLATE_INFO (t) 
951         ? DECL_TI_ARGS (t) : NULL_TREE; 
952
953       OB_PUTC ('<');
954
955       /* Be careful only to print things when we have them, so as not
956          to crash producing error messages.  */
957       if (args)
958         {
959           if (TREE_CODE (args) == TREE_LIST)
960             {
961               tree arg;
962               int need_comma = 0;
963
964               for (arg = args; arg; arg = TREE_CHAIN (arg))
965                 {
966                   tree a = TREE_VALUE (arg);
967
968                   if (need_comma)
969                     OB_PUTS (", ");
970
971                   if (a)
972                     {
973                       if (TREE_CODE_CLASS (TREE_CODE (a)) == 't')
974                         dump_type (a, 0);
975                       else
976                         dump_expr (a, 0);
977                     }
978                   
979                   need_comma = 1;
980                 }
981             }
982           else if (TREE_CODE (args) == TREE_VEC)
983             {
984               int i;
985               int need_comma = 0;
986
987               if (TREE_VEC_LENGTH (args) > 0
988                   && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
989                 args = TREE_VEC_ELT (args, 0);
990
991               for (i = 0; i < TREE_VEC_LENGTH (args); i++)
992                 {
993                   tree a = TREE_VEC_ELT (args, i);
994
995                   if (need_comma)
996                     OB_PUTS (", ");
997
998                   if (a)
999                     {
1000                       if (TREE_CODE_CLASS (TREE_CODE (a)) == 't')
1001                         dump_type (a, 0);
1002                       else
1003                         dump_expr (a, 0);
1004                     }
1005                   
1006                   need_comma = 1;
1007                 }
1008             }
1009         }
1010       OB_PUTC ('>');
1011     }
1012 }
1013
1014 static void
1015 dump_char (c)
1016      int c;
1017 {
1018   switch (c)
1019     {
1020     case TARGET_NEWLINE:
1021       OB_PUTS ("\\n");
1022       break;
1023     case TARGET_TAB:
1024       OB_PUTS ("\\t");
1025       break;
1026     case TARGET_VT:
1027       OB_PUTS ("\\v");
1028       break;
1029     case TARGET_BS:
1030       OB_PUTS ("\\b");
1031       break;
1032     case TARGET_CR:
1033       OB_PUTS ("\\r");
1034       break;
1035     case TARGET_FF:
1036       OB_PUTS ("\\f");
1037       break;
1038     case TARGET_BELL:
1039       OB_PUTS ("\\a");
1040       break;
1041     case '\\':
1042       OB_PUTS ("\\\\");
1043       break;
1044     case '\'':
1045       OB_PUTS ("\\'");
1046       break;
1047     case '\"':
1048       OB_PUTS ("\\\"");
1049       break;
1050     default:
1051       if (isprint (c))
1052         OB_PUTC (c);
1053       else
1054         {
1055           sprintf (digit_buffer, "\\%03o", (int) c);
1056           OB_PUTCP (digit_buffer);
1057         }
1058     }
1059 }
1060
1061 /* Print out a list of initializers (subr of dump_expr) */
1062
1063 static void
1064 dump_expr_list (l)
1065      tree l;
1066 {
1067   while (l)
1068     {
1069       dump_expr (TREE_VALUE (l), 0);
1070       if (TREE_CHAIN (l))
1071         OB_PUTC2 (',', ' ');
1072       l = TREE_CHAIN (l);
1073     }
1074 }
1075
1076 /* Print out an expression */
1077
1078 static void
1079 dump_expr (t, nop)
1080      tree t;
1081      int nop;                   /* suppress parens */
1082 {
1083   switch (TREE_CODE (t))
1084     {
1085     case VAR_DECL:
1086     case PARM_DECL:
1087     case FIELD_DECL:
1088     case CONST_DECL:
1089     case FUNCTION_DECL:
1090     case TEMPLATE_DECL:
1091       dump_decl (t, -1);
1092       break;
1093
1094     case INTEGER_CST:
1095       {
1096         tree type = TREE_TYPE (t);
1097         my_friendly_assert (type != 0, 81);
1098
1099         /* If it's an enum, output its tag, rather than its value.  */
1100         if (TREE_CODE (type) == ENUMERAL_TYPE)
1101           {
1102             char *p = enum_name_string (t, type);
1103             OB_PUTCP (p);
1104           }
1105         else if (type == boolean_type_node)
1106           {
1107             if (t == boolean_false_node
1108                 || (TREE_INT_CST_LOW (t) == 0
1109                     && TREE_INT_CST_HIGH (t) == 0))
1110               OB_PUTS ("false");
1111             else if (t == boolean_true_node)
1112               OB_PUTS ("true");
1113           }
1114         else if (type == char_type_node)
1115           {
1116             OB_PUTC ('\'');
1117             dump_char (TREE_INT_CST_LOW (t));
1118             OB_PUTC ('\'');
1119           }
1120         else if (TREE_INT_CST_HIGH (t)
1121                  != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1)))
1122           {
1123             tree val = t;
1124             if (TREE_INT_CST_HIGH (val) < 0)
1125               {
1126                 OB_PUTC ('-');
1127                 val = build_int_2 (~TREE_INT_CST_LOW (val),
1128                                    -TREE_INT_CST_HIGH (val));
1129               }
1130             /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
1131                systems?  */
1132             {
1133               static char format[10]; /* "%x%09999x\0" */
1134               if (!format[0])
1135                 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
1136               sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
1137                        TREE_INT_CST_LOW (val));
1138               OB_PUTCP (digit_buffer);
1139             }
1140           }
1141         else
1142           OB_PUTI (TREE_INT_CST_LOW (t));
1143       }
1144       break;
1145
1146     case REAL_CST:
1147 #ifndef REAL_IS_NOT_DOUBLE
1148       sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
1149 #else
1150       {
1151         unsigned char *p = (unsigned char *) &TREE_REAL_CST (t);
1152         int i;
1153         strcpy (digit_buffer, "0x");
1154         for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
1155           sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
1156       }
1157 #endif
1158       OB_PUTCP (digit_buffer);
1159       break;
1160
1161     case STRING_CST:
1162       {
1163         char *p = TREE_STRING_POINTER (t);
1164         int len = TREE_STRING_LENGTH (t) - 1;
1165         int i;
1166
1167         OB_PUTC ('\"');
1168         for (i = 0; i < len; i++)
1169           dump_char (p[i]);
1170         OB_PUTC ('\"');
1171       }
1172       break;
1173
1174     case COMPOUND_EXPR:
1175       dump_binary_op (",", t);
1176       break;
1177
1178     case COND_EXPR:
1179       OB_PUTC ('(');
1180       dump_expr (TREE_OPERAND (t, 0), 0);
1181       OB_PUTS (" ? ");
1182       dump_expr (TREE_OPERAND (t, 1), 0);
1183       OB_PUTS (" : ");
1184       dump_expr (TREE_OPERAND (t, 2), 0);
1185       OB_PUTC (')');
1186       break;
1187
1188     case SAVE_EXPR:
1189       if (TREE_HAS_CONSTRUCTOR (t))
1190         {
1191           OB_PUTS ("new ");
1192           dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
1193           PARM_DECL_EXPR (t) = 1;
1194         }
1195       else
1196         {
1197           dump_expr (TREE_OPERAND (t, 0), 0);
1198         }
1199       break;
1200
1201     case NEW_EXPR:
1202       OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
1203       OB_PUTC ('(');
1204       if (TREE_OPERAND (t, 1))
1205         dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
1206       OB_PUTC (')');
1207       break;
1208
1209     case CALL_EXPR:
1210       {
1211         tree fn = TREE_OPERAND (t, 0);
1212         tree args = TREE_OPERAND (t, 1);
1213         
1214         if (TREE_CODE (fn) == ADDR_EXPR)
1215           fn = TREE_OPERAND (fn, 0);
1216
1217         if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
1218           {
1219             tree ob = TREE_VALUE (args);
1220             if (TREE_CODE (ob) == ADDR_EXPR)
1221               {
1222                 dump_expr (TREE_OPERAND (ob, 0), 0);
1223                 OB_PUTC ('.');
1224               }
1225             else if (TREE_CODE (ob) != PARM_DECL
1226                      || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1227               {
1228                 dump_expr (ob, 0);
1229                 OB_PUTC2 ('-', '>');
1230               }
1231             args = TREE_CHAIN (args);
1232           }
1233         dump_expr (fn, 0);
1234         OB_PUTC ('(');
1235         dump_expr_list (args);
1236         OB_PUTC (')');
1237       }
1238       break;
1239
1240     case TARGET_EXPR:
1241       /* Note that this only works for G++ target exprs.  If somebody
1242          builds a general TARGET_EXPR, there's no way to represent that
1243          it initializes anything other that the parameter slot for the
1244          default argument.  Note we may have cleared out the first
1245          operand in expand_expr, so don't go killing ourselves.  */
1246       if (TREE_OPERAND (t, 1))
1247         dump_expr (TREE_OPERAND (t, 1), 0);
1248       break;
1249
1250     case MODIFY_EXPR:
1251     case PLUS_EXPR:
1252     case MINUS_EXPR:
1253     case MULT_EXPR:
1254     case TRUNC_DIV_EXPR:
1255     case TRUNC_MOD_EXPR:
1256     case MIN_EXPR:
1257     case MAX_EXPR:
1258     case LSHIFT_EXPR:
1259     case RSHIFT_EXPR:
1260     case BIT_IOR_EXPR:
1261     case BIT_XOR_EXPR:
1262     case BIT_AND_EXPR:
1263     case BIT_ANDTC_EXPR:
1264     case TRUTH_ANDIF_EXPR:
1265     case TRUTH_ORIF_EXPR:
1266     case LT_EXPR:
1267     case LE_EXPR:
1268     case GT_EXPR:
1269     case GE_EXPR:
1270     case EQ_EXPR:
1271     case NE_EXPR:
1272       dump_binary_op (opname_tab[(int) TREE_CODE (t)], t);
1273       break;
1274
1275     case CEIL_DIV_EXPR:
1276     case FLOOR_DIV_EXPR:
1277     case ROUND_DIV_EXPR:
1278       dump_binary_op ("/", t);
1279       break;
1280
1281     case CEIL_MOD_EXPR:
1282     case FLOOR_MOD_EXPR:
1283     case ROUND_MOD_EXPR:
1284       dump_binary_op ("%", t);
1285       break;
1286
1287     case COMPONENT_REF:
1288       {
1289         tree ob = TREE_OPERAND (t, 0);
1290         if (TREE_CODE (ob) == INDIRECT_REF)
1291           {
1292             ob = TREE_OPERAND (ob, 0);
1293             if (TREE_CODE (ob) != PARM_DECL
1294                 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1295               {
1296                 dump_expr (ob, 0);
1297                 OB_PUTC2 ('-', '>');
1298               }
1299           }
1300         else
1301           {
1302             dump_expr (ob, 0);
1303             OB_PUTC ('.');
1304           }
1305         dump_expr (TREE_OPERAND (t, 1), 1);
1306       }
1307       break;
1308
1309     case ARRAY_REF:
1310       dump_expr (TREE_OPERAND (t, 0), 0);
1311       OB_PUTC ('[');
1312       dump_expr (TREE_OPERAND (t, 1), 0);
1313       OB_PUTC (']');
1314       break;
1315
1316     case CONVERT_EXPR:
1317       dump_unary_op ("+", t, nop);
1318       break;
1319
1320     case ADDR_EXPR:
1321       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
1322           || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
1323         dump_expr (TREE_OPERAND (t, 0), 0);
1324       else
1325         dump_unary_op ("&", t, nop);
1326       break;
1327
1328     case INDIRECT_REF:
1329       if (TREE_HAS_CONSTRUCTOR (t))
1330         {
1331           t = TREE_OPERAND (t, 0);
1332           my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1333           dump_expr (TREE_OPERAND (t, 0), 0);
1334           OB_PUTC ('(');
1335           dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
1336           OB_PUTC (')');
1337         }
1338       else
1339         {
1340           if (TREE_OPERAND (t,0) != NULL_TREE
1341               && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
1342             dump_expr (TREE_OPERAND (t, 0), nop);
1343           else
1344             dump_unary_op ("*", t, nop);
1345         }
1346       break;
1347
1348     case NEGATE_EXPR:
1349     case BIT_NOT_EXPR:
1350     case TRUTH_NOT_EXPR:
1351     case PREDECREMENT_EXPR:
1352     case PREINCREMENT_EXPR:
1353       dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, nop);
1354       break;
1355
1356     case POSTDECREMENT_EXPR:
1357     case POSTINCREMENT_EXPR:
1358       OB_PUTC ('(');
1359       dump_expr (TREE_OPERAND (t, 0), 0);
1360       OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
1361       OB_PUTC (')');
1362       break;
1363
1364     case NON_LVALUE_EXPR:
1365       /* FIXME: This is a KLUDGE workaround for a parsing problem.  There
1366          should be another level of INDIRECT_REF so that I don't have to do
1367          this.  */
1368       if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
1369         {
1370           tree next = TREE_TYPE (TREE_TYPE (t));
1371
1372           while (TREE_CODE (next) == POINTER_TYPE)
1373             next = TREE_TYPE (next);
1374           
1375           if (TREE_CODE (next) == FUNCTION_TYPE)
1376             {
1377               if (!nop) OB_PUTC ('(');
1378               OB_PUTC ('*');
1379               dump_expr (TREE_OPERAND (t, 0), 1);
1380               if (!nop) OB_PUTC (')');
1381               break;
1382             }
1383           /* else FALLTHRU */
1384         }
1385       dump_expr (TREE_OPERAND (t, 0), 0);
1386       break;
1387
1388     case NOP_EXPR:
1389       dump_expr (TREE_OPERAND (t, 0), nop);
1390       break;
1391
1392     case CONSTRUCTOR:
1393       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
1394         {
1395           tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
1396
1397           if (integer_all_onesp (idx))
1398             {
1399               tree pfn = PFN_FROM_PTRMEMFUNC (t);
1400               dump_expr (pfn, 0);
1401               break;
1402             }
1403           if (TREE_CODE (idx) == INTEGER_CST
1404               && TREE_INT_CST_HIGH (idx) == 0)
1405             {
1406               tree virtuals;
1407               unsigned HOST_WIDE_INT n;
1408
1409               t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
1410               t = TYPE_METHOD_BASETYPE (t);
1411               virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
1412               
1413               n = TREE_INT_CST_LOW (idx);
1414
1415               /* Map vtable index back one, to allow for the null pointer to
1416                  member.  */
1417               --n;
1418
1419               while (n > 0 && virtuals)
1420                 {
1421                   --n;
1422                   virtuals = TREE_CHAIN (virtuals);
1423                 }
1424               if (virtuals)
1425                 {
1426                   dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
1427                   break;
1428                 }
1429             }
1430         }
1431       OB_PUTC ('{');
1432       dump_expr_list (CONSTRUCTOR_ELTS (t));
1433       OB_PUTC ('}');
1434       break;
1435
1436     case OFFSET_REF:
1437       {
1438         tree ob = TREE_OPERAND (t, 0);
1439         if (TREE_CODE (ob) == NOP_EXPR
1440             && TREE_OPERAND (ob, 0) == error_mark_node
1441             && TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
1442             /* A::f */
1443           dump_expr (TREE_OPERAND (t, 1), 0);
1444         else
1445           {
1446             dump_expr (TREE_OPERAND (t, 0), 0);
1447             OB_PUTS (" .* ");
1448             dump_expr (TREE_OPERAND (t, 1), 0);
1449           }
1450         break;
1451       }
1452
1453     case TEMPLATE_CONST_PARM:
1454       {
1455         int l = current_template_parms ? 
1456           list_length (current_template_parms) : 0;
1457
1458         if (l >= TEMPLATE_CONST_LEVEL (t))
1459           {
1460             int i;
1461             tree parms = current_template_parms;
1462             tree r;
1463             
1464             for (i = 0; i < l - TEMPLATE_CONST_LEVEL (t); ++i)
1465               {
1466                 parms = TREE_CHAIN (parms);
1467                 my_friendly_assert (parms != NULL_TREE, 0);
1468               }
1469             
1470             r = TREE_VEC_ELT (TREE_VALUE (parms),
1471                               TEMPLATE_CONST_IDX (t));
1472             dump_decl (TREE_VALUE (r), -1);
1473           }
1474         else
1475           {
1476             OB_PUTS ("<tparm ");
1477             OB_PUTI (TEMPLATE_CONST_IDX (t));
1478             OB_PUTS (">");
1479           }
1480       }
1481       break;
1482
1483     case IDENTIFIER_NODE:
1484       OB_PUTID (t);
1485       break;
1486
1487     case SCOPE_REF:
1488       dump_type (TREE_OPERAND (t, 0), 0);
1489       OB_PUTS ("::");
1490       dump_expr (TREE_OPERAND (t, 1), 0);
1491       break;
1492
1493     case CAST_EXPR:
1494       if (TREE_OPERAND (t, 0) == NULL_TREE
1495           || TREE_CHAIN (TREE_OPERAND (t, 0)))
1496         {
1497           dump_type (TREE_TYPE (t), 0);
1498           OB_PUTC ('(');
1499           dump_expr_list (TREE_OPERAND (t, 0));
1500           OB_PUTC (')');
1501         }
1502       else
1503         {
1504           OB_PUTC ('(');
1505           dump_type (TREE_TYPE (t), 0);
1506           OB_PUTC (')');
1507           OB_PUTC ('(');
1508           dump_expr_list (TREE_OPERAND (t, 0));
1509           OB_PUTC (')');
1510         }
1511       break;
1512
1513     case LOOKUP_EXPR:
1514       OB_PUTID (TREE_OPERAND (t, 0));
1515       break;
1516
1517     case SIZEOF_EXPR:
1518       OB_PUTS ("sizeof (");
1519       if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
1520         dump_type (TREE_OPERAND (t, 0), 0);
1521       else
1522         dump_unary_op ("*", t, 0);
1523       OB_PUTC (')');
1524       break;
1525
1526     case DEFAULT_ARG:
1527       OB_PUTS ("{unparsed}");
1528       break;
1529
1530     case TREE_LIST:
1531       if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
1532         {
1533           OB_PUTID (DECL_NAME (TREE_VALUE (t)));
1534           break;
1535         }
1536       /* else fall through */   
1537
1538       /*  This list is incomplete, but should suffice for now.
1539           It is very important that `sorry' does not call
1540           `report_error_function'.  That could cause an infinite loop.  */
1541     default:
1542       sorry ("`%s' not supported by dump_expr",
1543              tree_code_name[(int) TREE_CODE (t)]);
1544
1545       /* fall through to ERROR_MARK...  */
1546     case ERROR_MARK:
1547     error:
1548       OB_PUTCP ("{error}");
1549       break;
1550     }
1551 }
1552
1553 static void
1554 dump_binary_op (opstring, t)
1555      char *opstring;
1556      tree t;
1557 {
1558   OB_PUTC ('(');
1559   dump_expr (TREE_OPERAND (t, 0), 1);
1560   OB_PUTC (' ');
1561   OB_PUTCP (opstring);
1562   OB_PUTC (' ');
1563   dump_expr (TREE_OPERAND (t, 1), 1);
1564   OB_PUTC (')');
1565 }
1566
1567 static void
1568 dump_unary_op (opstring, t, nop)
1569      char *opstring;
1570      tree t;
1571      int nop;
1572 {
1573   if (!nop) OB_PUTC ('(');
1574   OB_PUTCP (opstring);
1575   dump_expr (TREE_OPERAND (t, 0), 1);
1576   if (!nop) OB_PUTC (')');
1577 }
1578
1579 char *
1580 fndecl_as_string (fndecl, print_ret_type_p)
1581      tree fndecl;
1582      int print_ret_type_p;
1583 {
1584   return decl_as_string (fndecl, print_ret_type_p);
1585 }
1586
1587 /* Same, but handtype a _TYPE.
1588    Called from convert_to_reference, mangle_class_name_for_template,
1589    build_unary_op, and GNU_xref_decl.  */
1590
1591 char *
1592 type_as_string (typ, v)
1593      tree typ;
1594      int v;
1595 {
1596   OB_INIT ();
1597
1598   dump_type (typ, v);
1599
1600   OB_FINISH ();
1601
1602   return (char *)obstack_base (&scratch_obstack);
1603 }
1604
1605 char *
1606 expr_as_string (decl, v)
1607      tree decl;
1608      int v;
1609 {
1610   OB_INIT ();
1611
1612   dump_expr (decl, 1);
1613
1614   OB_FINISH ();
1615
1616   return (char *)obstack_base (&scratch_obstack);
1617 }
1618
1619 /* A cross between type_as_string and fndecl_as_string.
1620    Only called from substitute_nice_name.  */
1621
1622 char *
1623 decl_as_string (decl, v)
1624      tree decl;
1625      int v;
1626 {
1627   OB_INIT ();
1628
1629   dump_decl (decl, v);
1630
1631   OB_FINISH ();
1632
1633   return (char *)obstack_base (&scratch_obstack);
1634 }
1635
1636 /* Generate the three forms of printable names for lang_printable_name.  */
1637
1638 char *
1639 lang_decl_name (decl, v)
1640      tree decl;
1641      int v;
1642 {
1643   if (v >= 2)
1644     return decl_as_string (decl, 1);
1645
1646   OB_INIT ();
1647
1648   if (v == 1 && DECL_CONTEXT (decl)
1649       && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
1650     {
1651       tree cname;
1652       if (TREE_CODE (decl) == FUNCTION_DECL)
1653         cname = DECL_CLASS_CONTEXT (decl);
1654       else
1655         cname = DECL_CONTEXT (decl);
1656       dump_type (cname, 0);
1657       OB_PUTC2 (':', ':');
1658     }
1659
1660   if (TREE_CODE (decl) == FUNCTION_DECL)
1661     dump_function_name (decl);
1662   else
1663     dump_decl (DECL_NAME (decl), 0);
1664
1665   OB_FINISH ();
1666
1667   return (char *)obstack_base (&scratch_obstack);
1668 }
1669   
1670
1671 char *
1672 cp_file_of (t)
1673      tree t;
1674 {
1675   if (TREE_CODE (t) == PARM_DECL)
1676     return DECL_SOURCE_FILE (DECL_CONTEXT (t));
1677   else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
1678     return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));
1679   else
1680     return DECL_SOURCE_FILE (t);
1681 }
1682
1683 int
1684 cp_line_of (t)
1685      tree t;
1686 {
1687   int line = 0;
1688   if (TREE_CODE (t) == PARM_DECL)
1689     line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
1690   if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
1691     t = TREE_TYPE (t);
1692
1693   if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
1694     line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));
1695   else
1696     line = DECL_SOURCE_LINE (t);
1697
1698   if (line == 0)
1699     return lineno;
1700
1701   return line;
1702 }
1703
1704 char *
1705 code_as_string (c, v)
1706      enum tree_code c;
1707      int v;
1708 {
1709   return tree_code_name [c];
1710 }
1711
1712 char *
1713 language_as_string (c, v)
1714      enum languages c;
1715      int v;
1716 {
1717   switch (c)
1718     {
1719     case lang_c:
1720       return "C";
1721
1722     case lang_cplusplus:
1723       return "C++";
1724
1725     default:
1726       my_friendly_abort (355);
1727       return 0;
1728     }
1729 }
1730
1731 /* Return the proper printed version of a parameter to a C++ function.  */
1732
1733 char *
1734 parm_as_string (p, v)
1735      int p, v;
1736 {
1737   if (p < 0)
1738     return "`this'";
1739
1740   sprintf (digit_buffer, "%d", p+1);
1741   return digit_buffer;
1742 }
1743
1744 char *
1745 op_as_string (p, v)
1746      enum tree_code p;
1747      int v;
1748 {
1749   static char buf[] = "operator                ";
1750
1751   if (p == 0)
1752     return "{unknown}";
1753   
1754   strcpy (buf + 9, opname_tab [p]);
1755   return buf;
1756 }
1757
1758 char *
1759 assop_as_string (p, v)
1760      enum tree_code p;
1761      int v;
1762 {
1763   static char buf[] = "operator                ";
1764
1765   if (p == 0)
1766     return "{unknown}";
1767   
1768   strcpy (buf + 9, assignop_tab [p]);
1769   return buf;
1770 }
1771
1772 char *
1773 args_as_string (p, v)
1774      tree p;
1775      int v;
1776 {
1777   if (p == NULL_TREE)
1778     return "";
1779
1780   if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't')
1781     return type_as_string (p, v);
1782
1783   OB_INIT ();
1784   for (; p; p = TREE_CHAIN (p))
1785     {
1786       if (TREE_VALUE (p) == null_node)
1787         OB_PUTS ("NULL");
1788       else
1789         dump_type (error_type (TREE_VALUE (p)), v);
1790       if (TREE_CHAIN (p))
1791         OB_PUTS (", ");
1792     }
1793   OB_FINISH ();
1794   return (char *)obstack_base (&scratch_obstack);
1795 }
1796
1797 char *
1798 cv_as_string (p, v)
1799      tree p;
1800      int v;
1801 {
1802   OB_INIT ();
1803
1804   dump_readonly_or_volatile (p, before);
1805
1806   OB_FINISH ();
1807
1808   return (char *)obstack_base (&scratch_obstack);
1809 }