OSDN Git Service

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