OSDN Git Service

f76b4da772ca0d2aeac29fd9f21264a509b5d20d
[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, 94-97, 1998, 1999 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 const char *cp_printer ();
30
31 #define obstack_chunk_alloc xmalloc
32 #define obstack_chunk_free free
33
34 /* Obstack where we build text strings for overloading, etc.  */
35 static struct obstack scratch_obstack;
36 static char *scratch_firstobj;
37
38 # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
39 # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
40 # define OB_PUTC2(C1,C2)        \
41   (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
42 # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
43 # define OB_PUTID(ID)  \
44   (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),     \
45                  IDENTIFIER_LENGTH (ID)))
46 # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
47 # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
48 # define OB_PUTI(CST) do { sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(CST)); \
49                            OB_PUTCP (digit_buffer); } while (0)
50
51 # define OB_END_TEMPLATE_ID()                                               \
52   (((obstack_next_free (&scratch_obstack) != obstack_base (&scratch_obstack) \
53     && obstack_next_free (&scratch_obstack)[-1] == '>')                     \
54    ? OB_PUTC (' ') : (void)0), OB_PUTC ('>'))
55
56 # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
57
58 enum pad { none, before, after };
59
60 static const char *args_to_string               PROTO((tree, int));
61 static const char *assop_to_string              PROTO((enum tree_code, int));
62 static const char *code_to_string               PROTO((enum tree_code, int));
63 static const char *cv_to_string                 PROTO((tree, int));
64 static const char *decl_to_string               PROTO((tree, int));
65 static const char *expr_to_string               PROTO((tree, int));
66 static const char *fndecl_to_string             PROTO((tree, int));
67 static const char *language_to_string           PROTO((enum languages, int));
68 static const char *op_to_string                 PROTO((enum tree_code, int));
69 static const char *parm_to_string               PROTO((int, int));
70 static const char *type_to_string               PROTO((tree, int));
71
72 static void dump_type PROTO((tree, enum tree_string_flags));
73 static void dump_simple_decl PROTO((tree, tree, enum tree_string_flags));
74 static void dump_decl PROTO((tree, enum tree_string_flags));
75 static void dump_template_decl PROTO((tree, enum tree_string_flags));
76 static void dump_function_decl PROTO((tree, enum tree_string_flags));
77 static void dump_expr PROTO((tree, enum tree_string_flags));
78 static void dump_unary_op PROTO((const char *, tree, enum tree_string_flags));
79 static void dump_binary_op PROTO((const char *, tree, enum tree_string_flags));
80 static void dump_aggr_type PROTO((tree, enum tree_string_flags));
81 static enum pad dump_type_prefix PROTO((tree, enum tree_string_flags));
82 static void dump_type_suffix PROTO((tree, enum tree_string_flags));
83 static void dump_function_name PROTO((tree, enum tree_string_flags));
84 static void dump_expr_list PROTO((tree, enum tree_string_flags));
85 static void dump_global_iord PROTO((tree));
86 static enum pad dump_qualifiers PROTO((tree, enum pad));
87 static void dump_char PROTO((int));
88 static void dump_parameters PROTO((tree, enum tree_string_flags));
89 static void dump_exception_spec PROTO((tree, enum tree_string_flags));
90 static const char *aggr_variety PROTO((tree));
91 static tree ident_fndecl PROTO((tree));
92 static void dump_template_argument PROTO((tree, enum tree_string_flags));
93 static void dump_template_argument_list PROTO((tree, enum tree_string_flags));
94 static void dump_template_parameter PROTO((tree, enum tree_string_flags));
95 static void dump_template_bindings PROTO((tree, tree));
96 static void dump_scope PROTO((tree, enum tree_string_flags));
97 static void dump_template_parms PROTO((tree, int, enum tree_string_flags));
98
99 #define A args_to_string
100 #define C code_to_string
101 #define D decl_to_string
102 #define E expr_to_string
103 #define F fndecl_to_string
104 #define L language_to_string
105 #define O op_to_string
106 #define P parm_to_string
107 #define Q assop_to_string
108 #define T type_to_string
109 #define V cv_to_string
110
111 #define o (cp_printer *) 0
112 cp_printer * cp_printers[256] =
113 {
114 /*0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
115   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */
116   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
117   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
118   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
119   o, A, o, C, D, E, F, o, o, o, o, o, L, o, o, O, /* 0x40 */
120   P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
121   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
122   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
123 };
124 #undef C
125 #undef D
126 #undef E
127 #undef F
128 #undef L
129 #undef O
130 #undef P
131 #undef Q
132 #undef T
133 #undef V
134 #undef o
135
136 void
137 init_error ()
138 {
139   gcc_obstack_init (&scratch_obstack);
140   scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
141 }
142
143 /* Dump a scope, if deemed necessary.  */
144
145 static void
146 dump_scope (scope, flags)
147      tree scope;
148      enum tree_string_flags flags;
149 {
150   if (scope == NULL_TREE)
151     return;
152   
153   if (TREE_CODE (scope) == NAMESPACE_DECL)
154     {
155       if (scope != global_namespace)
156         {
157           dump_decl (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
158                              | TS_FUNC_NORETURN | TS_DECL_TYPE);
159           OB_PUTS ("::");
160         }
161       else if (flags & TS_PEDANTIC_NAME)
162         OB_PUTS ("::");
163     }
164   else if (AGGREGATE_TYPE_P (scope))
165     {
166       dump_type (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
167                            | TS_FUNC_NORETURN | TS_DECL_TYPE);
168       OB_PUTS ("::");
169     }
170   else if ((flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE))
171             && TREE_CODE (scope) == FUNCTION_DECL)
172     {
173       dump_function_decl (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
174                            | TS_FUNC_NORETURN | TS_DECL_TYPE);
175       OB_PUTS ("::");
176     }
177 }
178
179 /* Dump type qualifiers, providing padding as requested. Return an
180    indication of whether we dumped something.  */
181
182 static enum pad
183 dump_qualifiers (t, p)
184      tree t;
185      enum pad p;
186 {
187   static const int masks[] =
188     {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
189   static const char *const names[] =
190     {"const", "volatile", "__restrict"};
191   int ix;
192   int quals = TYPE_QUALS (t);
193   int do_after = p == after;
194   
195   if (quals)
196     {
197       for (ix = 0; ix != 3; ix++)
198         if (masks[ix] & quals)
199           {
200             if (p == before)
201               OB_PUTC (' ');
202             p = before;
203             OB_PUTCP (names[ix]);
204           }
205       if (do_after)
206         OB_PUTC (' ');
207     }
208   else
209     p = none;
210   return p;
211 }
212
213 /* This must be large enough to hold any printed integer or floating-point
214    value.  */
215 static char digit_buffer[128];
216
217 /* Dump the template ARGument under control of FLAGS.  */
218
219 static void
220 dump_template_argument (arg, flags)
221      tree arg;
222      enum tree_string_flags flags;
223 {
224   if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
225       || TREE_CODE (arg) == TEMPLATE_DECL)
226     dump_type (arg, flags & ~TS_AGGR_TAGS);
227   else
228     dump_expr (arg, (flags | TS_EXPR_PARENS) & ~TS_AGGR_TAGS);
229 }
230
231 /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
232    of FLAGS.  */
233
234 static void
235 dump_template_argument_list (args, flags)
236      tree args;
237      enum tree_string_flags flags;
238 {
239   int n = TREE_VEC_LENGTH (args);
240   int need_comma = 0;
241   int i;
242
243   for (i = 0; i< n; ++i)
244     {
245       if (need_comma)
246         OB_PUTS (", ");
247       dump_template_argument (TREE_VEC_ELT (args, i), flags);
248       need_comma = 1;
249     }
250 }
251
252 /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS.  */
253
254 static void
255 dump_template_parameter (parm, flags)
256      tree parm;
257      enum tree_string_flags flags;
258 {
259   tree p = TREE_VALUE (parm);
260   tree a = TREE_PURPOSE (parm);
261
262   if (TREE_CODE (p) == TYPE_DECL)
263     {
264       if (flags & TS_DECL_TYPE)
265         {
266           OB_PUTS ("class");
267           if (DECL_NAME (p))
268             {
269               OB_PUTC (' ');
270               OB_PUTID (DECL_NAME (p));
271             }
272         }
273       else if (DECL_NAME (p))
274         OB_PUTID (DECL_NAME (p));
275       else
276         OB_PUTS ("{template default argument error}");
277     }
278   else
279     dump_decl (p, flags | TS_DECL_TYPE);
280
281   if ((flags & TS_PARM_DEFAULTS) && a != NULL_TREE)
282     {
283       OB_PUTS (" = ");
284       if (TREE_CODE (a) == TYPE_DECL || TREE_CODE (a) == TEMPLATE_DECL)
285         dump_type (a, flags & ~TS_CHASE_TYPEDEFS);
286       else
287         dump_expr (a, flags | TS_EXPR_PARENS);
288     }
289 }
290
291 /* Dump, under control of FLAGS, a template-parameter-list binding.
292    PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
293    TREE_VEC.  */
294
295 static void
296 dump_template_bindings (parms, args)
297      tree parms, args;
298 {
299   int need_comma = 0;
300
301   while (parms)
302     {
303       tree p = TREE_VALUE (parms);
304       int lvl = TMPL_PARMS_DEPTH (parms);
305       int arg_idx = 0;
306       int i;
307
308       for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
309         {
310           tree arg = TMPL_ARG (args, lvl, arg_idx);
311
312           if (need_comma)
313             OB_PUTS (", ");
314           dump_template_parameter (TREE_VEC_ELT (p, i), TS_PLAIN);
315           OB_PUTS (" = ");
316           if (arg)
317             dump_template_argument (arg, TS_PLAIN);
318           else
319             OB_PUTS ("{missing}");
320           
321           ++arg_idx;
322           need_comma = 1;
323         }
324
325       parms = TREE_CHAIN (parms);
326     }
327 }
328
329 /* Dump into the obstack a human-readable equivalent of TYPE.  FLAGS
330    controls the format.  */
331
332 static void
333 dump_type (t, flags)
334      tree t;
335      enum tree_string_flags flags;
336 {
337   if (t == NULL_TREE)
338     return;
339   
340   if (TYPE_PTRMEMFUNC_P (t))
341     goto offset_type;
342
343   switch (TREE_CODE (t))
344     {
345     case UNKNOWN_TYPE:
346       OB_PUTS ("{unknown type}");
347       break;
348
349     case TREE_LIST:
350       /* A list of function parms.  */
351       dump_parameters (t, flags);
352       break;
353
354     case IDENTIFIER_NODE:
355       OB_PUTID (t);
356       break;
357
358     case TREE_VEC:
359       dump_type (BINFO_TYPE (t), flags);
360       break;
361
362     case RECORD_TYPE:
363     case UNION_TYPE:
364     case ENUMERAL_TYPE:
365       dump_aggr_type (t, flags);
366       break;
367
368     case TYPE_DECL:
369       if (flags & TS_CHASE_TYPEDEFS)
370         {
371           dump_type (DECL_ORIGINAL_TYPE (t)
372                      ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
373           break;
374         }
375       /* else fallthrough */
376     
377     case TEMPLATE_DECL:
378     case NAMESPACE_DECL:
379       dump_decl (t, flags & ~TS_DECL_TYPE);
380       break;
381     
382     case COMPLEX_TYPE:
383       OB_PUTS ("complex ");
384       dump_type (TREE_TYPE (t), flags);
385       break;
386
387     case INTEGER_TYPE:
388       if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
389         OB_PUTS ("unsigned ");
390       else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
391         OB_PUTS ("signed ");
392
393       /* fall through.  */
394     case REAL_TYPE:
395     case VOID_TYPE:
396     case BOOLEAN_TYPE:
397       {
398         tree type;
399         dump_qualifiers (t, after);
400         type = flags & TS_CHASE_TYPEDEFS ? TYPE_MAIN_VARIANT (t) : t;
401         if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
402           OB_PUTID (TYPE_IDENTIFIER (type));
403         else
404           /* Types like intQI_type_node and friends have no names.
405              These don't come up in user error messages, but it's nice
406              to be able to print them from the debugger.  */
407           OB_PUTS ("{anonymous}");
408       }
409       break;
410
411     case TEMPLATE_TEMPLATE_PARM:
412       if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
413         {
414           /* For parameters inside template signature. */
415           if (TYPE_IDENTIFIER (t))
416             OB_PUTID (TYPE_IDENTIFIER (t));
417           else
418             OB_PUTS ("{anonymous template template parameter}");
419         }
420       else
421         {
422           tree args = TYPE_TI_ARGS (t);
423           OB_PUTID (TYPE_IDENTIFIER (t));
424           OB_PUTC ('<');
425           dump_template_argument_list (args, flags);
426           OB_END_TEMPLATE_ID ();
427         }
428       break;
429
430     case TEMPLATE_TYPE_PARM:
431       dump_qualifiers (t, after);
432       if (TYPE_IDENTIFIER (t))
433         OB_PUTID (TYPE_IDENTIFIER (t));
434       else
435         OB_PUTS ("{anonymous template type parameter}");
436       break;
437
438       /* This is not always necessary for pointers and such, but doing this
439          reduces code size.  */
440     case ARRAY_TYPE:
441     case POINTER_TYPE:
442     case REFERENCE_TYPE:
443     case OFFSET_TYPE:
444     offset_type:
445     case FUNCTION_TYPE:
446     case METHOD_TYPE:
447     {
448       dump_type_prefix (t, flags);
449       dump_type_suffix (t, flags);
450       break;
451     }
452     case TYPENAME_TYPE:
453       OB_PUTS ("typename ");
454       dump_type (TYPE_CONTEXT (t), flags);
455       OB_PUTS ("::");
456       dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
457       break;
458
459     case TYPEOF_TYPE:
460       OB_PUTS ("__typeof (");
461       dump_expr (TYPE_FIELDS (t), flags & ~TS_EXPR_PARENS);
462       OB_PUTC (')');
463       break;
464
465     default:
466       sorry ("`%s' not supported by dump_type",
467              tree_code_name[(int) TREE_CODE (t)]);
468       /* Fall through to error. */
469
470     case ERROR_MARK:
471       OB_PUTS ("{type error}");
472       break;
473     }
474 }
475
476 /* Return the name of the supplied aggregate, or enumeral type.  */
477
478 static const char *
479 aggr_variety (t)
480      tree t;
481 {
482   if (TREE_CODE (t) == ENUMERAL_TYPE)
483     return "enum";
484   else if (TREE_CODE (t) == UNION_TYPE)
485     return "union";
486   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
487     return "class";
488   else
489     return "struct";
490 }
491
492 /* Print out a class declaration T under the control of FLAGS,
493    in the form `class foo'.  */
494
495 static void
496 dump_aggr_type (t, flags)
497      tree t;
498      enum tree_string_flags flags;
499 {
500   tree name;
501   const char *variety = aggr_variety (t);
502   int typdef = 0;
503   int tmplate = 0;
504
505   dump_qualifiers (t, after);
506
507   if (flags & TS_AGGR_TAGS)
508     {
509       OB_PUTCP (variety);
510       OB_PUTC (' ');
511     }
512   
513   if (flags & TS_CHASE_TYPEDEFS)
514     t = TYPE_MAIN_VARIANT (t);
515
516   name = TYPE_NAME (t);
517
518   if (name)
519     {
520       typdef = !DECL_ARTIFICIAL (name);
521       tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
522                 && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
523                 && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
524                     || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
525                     || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
526                     || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
527       dump_scope (CP_DECL_CONTEXT (name), flags | TS_FUNC_SCOPE);
528       if (tmplate)
529         {
530           /* Because the template names are mangled, we have to locate
531              the most general template, and use that name.  */
532           tree tpl = CLASSTYPE_TI_TEMPLATE (t);
533           
534           while (DECL_TEMPLATE_INFO (tpl))
535             tpl = DECL_TI_TEMPLATE (tpl);
536           name = tpl;
537         }
538       name = DECL_NAME (name);
539     }
540
541   if (name == 0 || ANON_AGGRNAME_P (name))
542     {
543       OB_PUTS ("{anonymous");
544       if (!(flags & TS_AGGR_TAGS))
545         {
546           OB_PUTC (' ');
547           OB_PUTCP (variety);
548         }
549       OB_PUTC ('}');
550     }
551   else
552     OB_PUTID (name);
553   if (tmplate)
554     dump_template_parms (TYPE_TEMPLATE_INFO (t),
555                          !CLASSTYPE_USE_TEMPLATE (t),
556                          flags & ~TS_TEMPLATE_PREFIX);
557 }
558
559 /* Dump into the obstack the initial part of the output for a given type.
560    This is necessary when dealing with things like functions returning
561    functions.  Examples:
562
563    return type of `int (* fee ())()': pointer -> function -> int.  Both
564    pointer (and reference and offset) and function (and member) types must
565    deal with prefix and suffix.
566
567    Arrays must also do this for DECL nodes, like int a[], and for things like
568    int *[]&.  
569    
570    Return indicates how you should pad an object name after this. I.e. you
571    want to pad non-*, non-& cores, but not pad * or & types.  */
572
573 static enum pad
574 dump_type_prefix (t, flags)
575      tree t;
576      enum tree_string_flags flags;
577 {
578   enum pad padding = before;
579   
580   if (TYPE_PTRMEMFUNC_P (t))
581     {
582       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
583       goto offset_type;
584     }
585   
586   switch (TREE_CODE (t))
587     {
588     case POINTER_TYPE:
589     case REFERENCE_TYPE:
590       {
591         tree sub = TREE_TYPE (t);
592         
593         padding = dump_type_prefix (sub, flags);
594         /* A tree for a member pointer looks like pointer to offset,
595            so let the OFFSET_TYPE case handle it.  */
596         if (!TYPE_PTRMEM_P (t))
597           {
598             if (padding != none)
599               OB_PUTC (' ');
600             if (TREE_CODE (sub) == ARRAY_TYPE)
601               OB_PUTC ('(');
602             OB_PUTC ("&*"[TREE_CODE (t) == POINTER_TYPE]);
603             padding = dump_qualifiers (t, none);
604           }
605       }
606       break;
607
608     case OFFSET_TYPE:
609     offset_type:
610       padding = dump_type_prefix (TREE_TYPE (t), flags);
611       if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
612         {
613           if (padding != none)
614             OB_PUTC (' ');
615           dump_type (TYPE_OFFSET_BASETYPE (t), flags);
616           OB_PUTS ("::");
617         }
618       OB_PUTC ('*');
619       padding = dump_qualifiers (t, none);
620       break;
621
622       /* Can only be reached through function pointer -- this would not be
623          correct if FUNCTION_DECLs used it.  */
624     case FUNCTION_TYPE:
625       padding = dump_type_prefix (TREE_TYPE (t), flags);
626       if (padding != none)
627         OB_PUTC (' ');
628       OB_PUTC ('(');
629       padding = none;
630       break;
631
632     case METHOD_TYPE:
633       padding = dump_type_prefix (TREE_TYPE (t), flags);
634       if (padding != none)
635         OB_PUTC (' ');
636       OB_PUTC ('(');
637       padding = none;
638       dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
639       OB_PUTS ("::");
640       break;
641
642     case ARRAY_TYPE:
643       padding = dump_type_prefix (TREE_TYPE (t), flags);
644       break;
645
646     case ENUMERAL_TYPE:
647     case IDENTIFIER_NODE:
648     case INTEGER_TYPE:
649     case BOOLEAN_TYPE:
650     case REAL_TYPE:
651     case RECORD_TYPE:
652     case TEMPLATE_TYPE_PARM:
653     case TEMPLATE_TEMPLATE_PARM:
654     case TREE_LIST:
655     case TYPE_DECL:
656     case TREE_VEC:
657     case UNION_TYPE:
658     case UNKNOWN_TYPE:
659     case VOID_TYPE:
660     case TYPENAME_TYPE:
661     case COMPLEX_TYPE:
662       dump_type (t, flags);
663       padding = before;
664       break;
665       
666     default:
667       sorry ("`%s' not supported by dump_type_prefix",
668              tree_code_name[(int) TREE_CODE (t)]);
669
670     case ERROR_MARK:
671       OB_PUTS ("{typeprefixerror}");
672       break;
673     }
674   return padding;
675 }
676
677 /* Dump the suffix of type T, under control of FLAGS.  This is the part
678    which appears after the identifier (or function parms).  */
679
680 static void
681 dump_type_suffix (t, flags)
682      tree t;
683      enum tree_string_flags flags;
684 {
685   if (TYPE_PTRMEMFUNC_P (t))
686     t = TYPE_PTRMEMFUNC_FN_TYPE (t);
687
688   switch (TREE_CODE (t))
689     {
690     case POINTER_TYPE:
691     case REFERENCE_TYPE:
692     case OFFSET_TYPE:
693       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
694         OB_PUTC (')');
695       dump_type_suffix (TREE_TYPE (t), flags);
696       break;
697
698       /* Can only be reached through function pointer */
699     case FUNCTION_TYPE:
700     case METHOD_TYPE:
701       {
702         tree arg;
703         OB_PUTC (')');
704         arg = TYPE_ARG_TYPES (t);
705         if (TREE_CODE (t) == METHOD_TYPE)
706           arg = TREE_CHAIN (arg);
707
708         /* Function pointers don't have default args.  Not in standard C++,
709            anyway; they may in g++, but we'll just pretend otherwise.  */
710         dump_parameters (arg, flags & ~TS_PARM_DEFAULTS);
711
712         if (TREE_CODE (t) == METHOD_TYPE)
713           dump_qualifiers
714             (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
715         dump_type_suffix (TREE_TYPE (t), flags);
716         dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
717         break;
718       }
719
720     case ARRAY_TYPE:
721       OB_PUTC ('[');
722       if (TYPE_DOMAIN (t))
723         {
724           if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
725             OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
726           else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
727             dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0),
728                        flags & ~TS_EXPR_PARENS);
729           else
730             dump_expr (fold (build_binary_op
731                              (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
732                               integer_one_node)),
733                        flags & ~TS_EXPR_PARENS);
734         }
735       OB_PUTC (']');
736       dump_type_suffix (TREE_TYPE (t), flags);
737       break;
738       
739     case ENUMERAL_TYPE:
740     case IDENTIFIER_NODE:
741     case INTEGER_TYPE:
742     case BOOLEAN_TYPE:
743     case REAL_TYPE:
744     case RECORD_TYPE:
745     case TEMPLATE_TYPE_PARM:
746     case TEMPLATE_TEMPLATE_PARM:
747     case TREE_LIST:
748     case TYPE_DECL:
749     case TREE_VEC:
750     case UNION_TYPE:
751     case UNKNOWN_TYPE:
752     case VOID_TYPE:
753     case TYPENAME_TYPE:
754     case COMPLEX_TYPE:
755       break;
756
757     default:
758       sorry ("`%s' not supported by dump_type_suffix",
759              tree_code_name[(int) TREE_CODE (t)]);
760
761     case ERROR_MARK:
762       /* Don't mark it here, we should have already done in
763          dump_type_prefix.  */
764       break;
765     }
766 }
767
768 /* Return a function declaration which corresponds to the IDENTIFIER_NODE
769    argument.  */
770
771 static tree
772 ident_fndecl (t)
773      tree t;
774 {
775   tree n = lookup_name (t, 0);
776
777   if (n == NULL_TREE)
778     return NULL_TREE;
779
780   if (TREE_CODE (n) == FUNCTION_DECL)
781     return n;
782   else if (TREE_CODE (n) == TREE_LIST
783            && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL)
784     return TREE_VALUE (n);
785
786   my_friendly_abort (66);
787   return NULL_TREE;
788 }
789
790 #ifndef NO_DOLLAR_IN_LABEL
791 #  define GLOBAL_THING "_GLOBAL_$"
792 #else
793 #  ifndef NO_DOT_IN_LABEL
794 #    define GLOBAL_THING "_GLOBAL_."
795 #  else
796 #    define GLOBAL_THING "_GLOBAL__"
797 #  endif
798 #endif
799
800 #define GLOBAL_IORD_P(NODE) \
801   ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
802
803 static void
804 dump_global_iord (t)
805      tree t;
806 {
807   const char *name = IDENTIFIER_POINTER (t);
808
809   OB_PUTS ("(static ");
810   if (name [sizeof (GLOBAL_THING) - 1] == 'I')
811     OB_PUTS ("initializers");
812   else if (name [sizeof (GLOBAL_THING) - 1] == 'D')
813     OB_PUTS ("destructors");
814   else
815     my_friendly_abort (352);
816   
817   OB_PUTS (" for ");
818   OB_PUTCP (input_filename);
819   OB_PUTC (')');
820 }
821
822 static void
823 dump_simple_decl (t, type, flags)
824      tree t;
825      tree type;
826      enum tree_string_flags flags;
827 {
828   if (flags & TS_DECL_TYPE)
829     {
830       if (dump_type_prefix (type, flags) != none)
831         OB_PUTC (' ');
832     }
833   if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
834     dump_scope (CP_DECL_CONTEXT (t), flags);
835   if (DECL_NAME (t))
836     dump_decl (DECL_NAME (t), flags);
837   else
838     OB_PUTS ("{anonymous}");
839   if (flags & TS_DECL_TYPE)
840     dump_type_suffix (type, flags);
841 }
842
843 /* Dump a human readable string for the decl T under control of FLAGS.  */
844
845 static void
846 dump_decl (t, flags)
847      tree t;
848      enum tree_string_flags flags;
849 {
850   if (t == NULL_TREE)
851     return;
852
853   switch (TREE_CODE (t))
854     {
855     case TYPE_DECL:
856       {
857         /* Don't say 'typedef class A' */
858         if (DECL_ARTIFICIAL (t))
859           {
860             if ((flags & TS_DECL_TYPE)
861                 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
862               /* Say `class T' not just `T'. */
863               OB_PUTS ("class ");
864
865             dump_type (TREE_TYPE (t), flags);
866             break;
867           }
868       }
869       if (flags & TS_DECORATE)
870         OB_PUTS ("typedef ");
871       dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) 
872                         ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
873                         flags);
874       break;
875       
876     case VAR_DECL:
877       if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
878         {
879           OB_PUTS ("vtable for ");
880           if (TYPE_P (DECL_CONTEXT (t)))
881             dump_type (DECL_CONTEXT (t), flags);
882           else
883             /* This case can arise with -fno-vtable-thunks.  See
884                expand_upcast_fixups.  It's not clear what to print
885                here.  */
886             OB_PUTS ("{unknown type}");
887           break;
888         }
889       /* else fall through */
890     case FIELD_DECL:
891     case PARM_DECL:
892       dump_simple_decl (t, TREE_TYPE (t), flags);
893       break;
894
895     case RESULT_DECL:
896       OB_PUTS ("{return} ");
897       dump_simple_decl (t, TREE_TYPE (t), flags);
898       break;
899
900     case NAMESPACE_DECL:
901       dump_scope (CP_DECL_CONTEXT (t), flags);
902       if (DECL_NAME (t) == anonymous_namespace_name)
903         OB_PUTS ("{unnamed}");
904       else
905         OB_PUTID (DECL_NAME (t));
906       break;
907
908     case SCOPE_REF:
909       dump_decl (TREE_OPERAND (t, 0), flags & ~TS_DECL_TYPE);
910       OB_PUTS ("::");
911       dump_decl (TREE_OPERAND (t, 1), flags);
912       break;      
913
914     case ARRAY_REF:
915       dump_decl (TREE_OPERAND (t, 0), flags);
916       OB_PUTC ('[');
917       dump_decl (TREE_OPERAND (t, 1), flags);
918       OB_PUTC (']');
919       break;
920
921       /* So that we can do dump_decl on an aggr type.  */
922     case RECORD_TYPE:
923     case UNION_TYPE:
924     case ENUMERAL_TYPE:
925       dump_type (t, flags);
926       break;
927
928     case TYPE_EXPR:
929       my_friendly_abort (69);
930       break;
931
932       /* These special cases are duplicated here so that other functions
933          can feed identifiers to cp_error and get them demangled properly.  */
934     case IDENTIFIER_NODE:
935       { tree f;
936         if (DESTRUCTOR_NAME_P (t)
937             && (f = ident_fndecl (t))
938             && DECL_LANGUAGE (f) == lang_cplusplus)
939           {
940             OB_PUTC ('~');
941             dump_decl (DECL_NAME (f), flags);
942           }
943         else if (IDENTIFIER_TYPENAME_P (t))
944           {
945             OB_PUTS ("operator ");
946             /* Not exactly IDENTIFIER_TYPE_VALUE.  */
947             dump_type (TREE_TYPE (t), flags);
948             break;
949           }
950         else if (IDENTIFIER_OPNAME_P (t))
951           {
952             const char *name_string = operator_name_string (t);
953             OB_PUTS ("operator");
954             if (ISALPHA (name_string[0]))
955               OB_PUTC (' ');
956             OB_PUTCP (name_string);
957           }
958         else
959           OB_PUTID (t);
960       }
961       break;
962
963     case OVERLOAD:
964       t = OVL_CURRENT (t);
965       /* Fall through.  */
966
967     case FUNCTION_DECL:
968       if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
969         dump_global_iord (DECL_ASSEMBLER_NAME (t));
970       else if (! DECL_LANG_SPECIFIC (t))
971         OB_PUTS ("{internal}");
972       else if (flags & TS_PEDANTIC_NAME)
973         dump_function_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
974       else
975         dump_function_decl (t, flags);
976       break;
977
978     case TEMPLATE_DECL:
979       if (flags & TS_PEDANTIC_NAME)
980         dump_template_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
981       else
982         dump_template_decl (t, flags);
983       break;
984
985     case TEMPLATE_ID_EXPR:
986       {
987         tree args;
988         tree name = TREE_OPERAND (t, 0);
989         if (is_overloaded_fn (name))
990           name = DECL_NAME (get_first_fn (name));
991         dump_decl (name, flags);
992         OB_PUTC ('<');
993         for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
994           {
995             dump_template_argument (TREE_VALUE (args), flags);
996             if (TREE_CHAIN (args))
997               OB_PUTS (", ");
998           }
999         OB_END_TEMPLATE_ID ();
1000       }
1001       break;
1002
1003     case LOOKUP_EXPR:
1004       dump_decl (TREE_OPERAND (t, 0), flags);
1005       break;
1006
1007     case LABEL_DECL:
1008       OB_PUTID (DECL_NAME (t));
1009       break;
1010
1011     case CONST_DECL:
1012       if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
1013           || (DECL_INITIAL (t) &&
1014               TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
1015         dump_simple_decl (t, TREE_TYPE (t), flags);
1016       else if (DECL_NAME (t))
1017         dump_decl (DECL_NAME (t), flags);
1018       else if (DECL_INITIAL (t))
1019         dump_expr (DECL_INITIAL (t), flags | TS_EXPR_PARENS);
1020       else
1021         OB_PUTS ("enumerator");
1022       break;
1023
1024     case USING_DECL:
1025       OB_PUTS ("using ");
1026       dump_type (DECL_INITIAL (t), flags);
1027       OB_PUTS ("::");
1028       OB_PUTID (DECL_NAME (t));
1029       break;
1030
1031     default:
1032       sorry ("`%s' not supported by dump_decl",
1033              tree_code_name[(int) TREE_CODE (t)]);
1034       /* Fallthrough to error.  */
1035
1036     case ERROR_MARK:
1037       OB_PUTS ("{declaration error}");
1038       break;
1039     }
1040 }
1041
1042 /* Dump a template declaration T under control of FLAGS. This means the
1043    'template <...> leaders plus the 'class X' or 'void fn(...)' part.  */
1044
1045 static void
1046 dump_template_decl (t, flags)
1047      tree t;
1048      enum tree_string_flags flags;
1049 {
1050   tree orig_parms = DECL_TEMPLATE_PARMS (t);
1051   tree parms;
1052   int i; 
1053   
1054   if (flags & TS_TEMPLATE_PREFIX)
1055     {
1056       for (parms = orig_parms = nreverse (orig_parms); 
1057            parms;
1058            parms = TREE_CHAIN (parms))
1059         {
1060           tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
1061           int len = TREE_VEC_LENGTH (inner_parms);
1062           
1063           OB_PUTS ("template <");
1064           for (i = 0; i < len; i++)
1065             {
1066               if (i)
1067                 OB_PUTS (", ");
1068               dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
1069             }
1070           OB_END_TEMPLATE_ID ();
1071           OB_PUTC (' ');
1072         }
1073       nreverse(orig_parms);
1074       /* If we've shown the template<args> prefix, we'd better show the
1075          decl's type too.  */
1076       flags |= TS_DECL_TYPE;
1077     }
1078   if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
1079     dump_type (TREE_TYPE (t),
1080                ((flags & ~TS_AGGR_TAGS) | TS_TEMPLATE_PLAIN
1081                 | (flags & TS_DECL_TYPE ? TS_AGGR_TAGS : 0)));
1082   else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
1083     dump_decl (DECL_TEMPLATE_RESULT (t), flags | TS_TEMPLATE_PLAIN);
1084   else if (TREE_TYPE (t) == NULL_TREE)
1085     my_friendly_abort (353);
1086   else
1087     switch (NEXT_CODE (t))
1088     {
1089       case METHOD_TYPE:
1090       case FUNCTION_TYPE:
1091         dump_function_decl (t, flags | TS_TEMPLATE_PLAIN);
1092         break;
1093       default:
1094         /* This case can occur with some illegal code.  */
1095         dump_type (TREE_TYPE (t),
1096                    (flags & ~TS_AGGR_TAGS) | TS_TEMPLATE_PLAIN
1097                    | (flags & TS_DECL_TYPE ? TS_AGGR_TAGS : 0));
1098     }
1099 }
1100
1101 /* Pretty print a function decl. There are several ways we want to print a
1102    function declaration. The TS_FUNC bits in FLAGS tells us how to behave.
1103    As cp_error can only apply the '#' flag once to give 0 and 1 for V, there
1104    is %D which doesn't print the throw specs, and %F which does. */
1105
1106 static void
1107 dump_function_decl (t, flags)
1108      tree t;
1109      enum tree_string_flags flags;
1110 {
1111   tree fntype;
1112   tree parmtypes;
1113   tree cname = NULL_TREE;
1114   tree template_args = NULL_TREE;
1115   tree template_parms = NULL_TREE;
1116   int show_return = !(flags & TS_FUNC_NORETURN) && (flags & TS_DECL_TYPE);
1117
1118   if (TREE_CODE (t) == TEMPLATE_DECL)
1119     t = DECL_TEMPLATE_RESULT (t);
1120
1121   /* Pretty print template instantiations only.  */
1122   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t))
1123     {
1124       template_args = DECL_TI_ARGS (t);
1125       t = most_general_template (t);
1126       if (TREE_CODE (t) == TEMPLATE_DECL)
1127         template_parms = DECL_TEMPLATE_PARMS (t);
1128     }
1129
1130   fntype = TREE_TYPE (t);
1131   parmtypes = TYPE_ARG_TYPES (fntype);
1132
1133   /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT.  */
1134   if (DECL_CLASS_SCOPE_P (t))
1135     cname = DECL_CLASS_CONTEXT (t);
1136   /* this is for partially instantiated template methods */
1137   else if (TREE_CODE (fntype) == METHOD_TYPE)
1138     cname = TREE_TYPE (TREE_VALUE (parmtypes));
1139
1140   if (!(flags & TS_DECORATE))
1141     /* OK */;
1142   else if (DECL_STATIC_FUNCTION_P (t))
1143     OB_PUTS ("static ");
1144   else if (TYPE_POLYMORPHIC_P (t))
1145     OB_PUTS ("virtual ");
1146   
1147   /* Print the return type?  */
1148   if (show_return)
1149     show_return = !DECL_CONV_FN_P (t)  && !DECL_CONSTRUCTOR_P (t)
1150                   && !DECL_DESTRUCTOR_P (t);
1151   if (show_return)
1152     {
1153       if (dump_type_prefix (TREE_TYPE (fntype), flags) != none)
1154         OB_PUTC (' ');
1155     }
1156
1157   /* Print the function name.  */
1158   if (cname)
1159     {
1160       dump_type (cname, flags);
1161       OB_PUTS ("::");
1162     }
1163   else
1164     dump_scope (CP_DECL_CONTEXT (t), flags);
1165
1166   dump_function_name (t, flags);
1167   
1168   if (!(flags & TS_DECL_TYPE))
1169     return;
1170   if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
1171     /* Skip "this" parameter.  */
1172     parmtypes = TREE_CHAIN (parmtypes);
1173     
1174   if (DECL_DESTRUCTOR_P (t) || DECL_CONSTRUCTOR_FOR_VBASE_P (t))
1175     /* Skip past "in_charge" identifier.  */
1176     parmtypes = TREE_CHAIN (parmtypes);
1177   
1178   dump_parameters (parmtypes, flags);
1179   
1180   if (show_return)
1181     dump_type_suffix (TREE_TYPE (fntype), flags);
1182
1183   if (TREE_CODE (fntype) == METHOD_TYPE)
1184     dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
1185                      before);
1186   
1187   if (flags & TS_FUNC_THROW)
1188     dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
1189
1190   /* If T is a template instantiation, dump the parameter binding.  */
1191   if (template_parms != NULL_TREE && template_args != NULL_TREE)
1192     {
1193       OB_PUTS (" [with ");
1194       dump_template_bindings (template_parms, template_args);
1195       OB_PUTC (']');
1196     }
1197 }
1198
1199 /* Print a parameter list. If this is for a member function, the
1200    member object ptr (and any other hidden args) should have
1201    already been removed. */
1202
1203 static void
1204 dump_parameters (parmtypes, flags)
1205      tree parmtypes;
1206      enum tree_string_flags flags;
1207 {
1208   int first;
1209   OB_PUTS (" (");
1210
1211   for (first = 1; parmtypes != void_list_node;
1212        parmtypes = TREE_CHAIN (parmtypes))
1213     {
1214       if (!first)
1215         OB_PUTS (", ");
1216       first = 0;
1217       if (!parmtypes)
1218         {
1219           OB_PUTS ("...");
1220           break;
1221         }
1222       dump_type (TREE_VALUE (parmtypes), flags);
1223       
1224       if ((flags & TS_PARM_DEFAULTS) && TREE_PURPOSE (parmtypes))
1225         {
1226           OB_PUTS (" = ");
1227           dump_expr (TREE_PURPOSE (parmtypes), flags | TS_EXPR_PARENS);
1228         }
1229     }
1230
1231   OB_PUTC (')');
1232 }
1233
1234 /* Print an exception specification. T is the exception specification. */
1235
1236 static void
1237 dump_exception_spec (t, flags)
1238      tree t;
1239      enum tree_string_flags flags;
1240 {
1241   if (t)
1242     {
1243       OB_PUTS (" throw (");
1244       if (TREE_VALUE (t) != NULL_TREE)
1245         while (1)
1246           {
1247             dump_type (TREE_VALUE (t), flags);
1248             t = TREE_CHAIN (t);
1249             if (!t)
1250               break;
1251             OB_PUTS (", ");
1252           }
1253       OB_PUTC (')');
1254     }
1255 }
1256
1257 /* Handle the function name for a FUNCTION_DECL node, grokking operators
1258    and destructors properly.  */
1259
1260 static void
1261 dump_function_name (t, flags)
1262      tree t;
1263      enum tree_string_flags flags;
1264 {
1265   tree name = DECL_NAME (t);
1266
1267   if (DECL_DESTRUCTOR_P (t))
1268     {
1269       OB_PUTC ('~');
1270       dump_decl (name, TS_PLAIN);
1271     }
1272   else if (DECL_CONV_FN_P (t))
1273     {
1274       /* This cannot use the hack that the operator's return
1275          type is stashed off of its name because it may be
1276          used for error reporting.  In the case of conflicting
1277          declarations, both will have the same name, yet
1278          the types will be different, hence the TREE_TYPE field
1279          of the first name will be clobbered by the second.  */
1280       OB_PUTS ("operator ");
1281       dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
1282     }
1283   else if (IDENTIFIER_OPNAME_P (name))
1284     {
1285       const char *name_string = operator_name_string (name);
1286       OB_PUTS ("operator");
1287       if (ISALPHA (name_string[0]))
1288         OB_PUTC (' ');
1289       OB_PUTCP (name_string);
1290     }
1291   else
1292     dump_decl (name, flags);
1293
1294   if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
1295       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
1296       && (DECL_TEMPLATE_SPECIALIZATION (t) 
1297           || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
1298           || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
1299           || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
1300     dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
1301 }
1302
1303 /* Dump the template parameters from the template info INFO under control of
1304    FLAGS. PRIMARY indicates whether this is a primary template decl, or
1305    specialization (partial or complete). For partial specializations we show
1306    the specialized parameter values. For a primary template we show no
1307    decoration.  */
1308
1309 static void
1310 dump_template_parms (info, primary, flags)
1311      tree info;
1312      int primary;
1313      enum tree_string_flags flags;
1314 {
1315   tree args = info ? TI_ARGS (info) : NULL_TREE;
1316   
1317   if (primary && flags & TS_TEMPLATE_PLAIN)
1318     return;
1319   flags &= ~(TS_AGGR_TAGS | TS_TEMPLATE_PLAIN);
1320   OB_PUTC ('<');
1321
1322   /* Be careful only to print things when we have them, so as not
1323          to crash producing error messages.  */
1324   if (args && !primary)
1325     {
1326       int len = 0;
1327       int ix = 0;
1328       int need_comma = 0;
1329       
1330       if (TREE_CODE (args) == TREE_VEC)
1331         {
1332           if (TREE_VEC_LENGTH (args) > 0
1333               && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
1334             args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
1335           
1336           len = TREE_VEC_LENGTH (args);
1337         }
1338       else if (TREE_CODE (args) == TREE_LIST)
1339         len = -1;
1340       while (ix != len && args)
1341         {
1342           tree arg;
1343           if (len >= 0)
1344             {
1345               arg = TREE_VEC_ELT (args, ix);
1346               ix++;
1347             }
1348           else
1349             {
1350               arg = TREE_VALUE (args);
1351               args = TREE_CHAIN (args);
1352             }
1353           if (need_comma)
1354             OB_PUTS (", ");
1355               
1356           if (!arg)
1357             OB_PUTS ("{template parameter error}");
1358           else
1359             dump_template_argument (arg, flags);
1360           need_comma = 1;
1361         }
1362     }
1363   else if (primary)
1364     {
1365       tree tpl = TI_TEMPLATE (info);
1366       tree parms = DECL_TEMPLATE_PARMS (tpl);
1367       int len, ix;
1368       
1369       parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
1370       len = parms ? TREE_VEC_LENGTH (parms) : 0;
1371       
1372       for (ix = 0; ix != len; ix++)
1373         {
1374           tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
1375
1376           if (ix)
1377             OB_PUTS (", ");
1378           
1379           dump_decl (parm, flags & ~TS_DECL_TYPE);
1380         }
1381     }
1382   OB_END_TEMPLATE_ID ();
1383 }
1384
1385 static void
1386 dump_char (c)
1387      int c;
1388 {
1389   switch (c)
1390     {
1391     case TARGET_NEWLINE:
1392       OB_PUTS ("\\n");
1393       break;
1394     case TARGET_TAB:
1395       OB_PUTS ("\\t");
1396       break;
1397     case TARGET_VT:
1398       OB_PUTS ("\\v");
1399       break;
1400     case TARGET_BS:
1401       OB_PUTS ("\\b");
1402       break;
1403     case TARGET_CR:
1404       OB_PUTS ("\\r");
1405       break;
1406     case TARGET_FF:
1407       OB_PUTS ("\\f");
1408       break;
1409     case TARGET_BELL:
1410       OB_PUTS ("\\a");
1411       break;
1412     case '\\':
1413       OB_PUTS ("\\\\");
1414       break;
1415     case '\'':
1416       OB_PUTS ("\\'");
1417       break;
1418     case '\"':
1419       OB_PUTS ("\\\"");
1420       break;
1421     default:
1422       if (ISPRINT (c))
1423         OB_PUTC (c);
1424       else
1425         {
1426           sprintf (digit_buffer, "\\%03o", (int) c);
1427           OB_PUTCP (digit_buffer);
1428         }
1429     }
1430 }
1431
1432 /* Print out a list of initializers (subr of dump_expr) */
1433
1434 static void
1435 dump_expr_list (l, flags)
1436      tree l;
1437      enum tree_string_flags flags;
1438 {
1439   while (l)
1440     {
1441       dump_expr (TREE_VALUE (l), flags | TS_EXPR_PARENS);
1442       l = TREE_CHAIN (l);
1443       if (l)
1444         OB_PUTS (", ");
1445     }
1446 }
1447
1448 /* Print out an expression E under control of FLAGS. */
1449
1450 static void
1451 dump_expr (t, flags)
1452      tree t;
1453      enum tree_string_flags flags;
1454 {
1455   switch (TREE_CODE (t))
1456     {
1457     case VAR_DECL:
1458     case PARM_DECL:
1459     case FIELD_DECL:
1460     case CONST_DECL:
1461     case FUNCTION_DECL:
1462     case TEMPLATE_DECL:
1463     case NAMESPACE_DECL:
1464     case OVERLOAD:
1465       dump_decl (t, flags & ~TS_DECL_TYPE);
1466       break;
1467
1468     case INTEGER_CST:
1469       {
1470         tree type = TREE_TYPE (t);
1471         my_friendly_assert (type != 0, 81);
1472
1473         /* If it's an enum, output its tag, rather than its value.  */
1474         if (TREE_CODE (type) == ENUMERAL_TYPE)
1475           {
1476             const char *p = enum_name_string (t, type);
1477             OB_PUTCP (p);
1478           }
1479         else if (type == boolean_type_node)
1480           {
1481             if (t == boolean_false_node
1482                 || (TREE_INT_CST_LOW (t) == 0
1483                     && TREE_INT_CST_HIGH (t) == 0))
1484               OB_PUTS ("false");
1485             else if (t == boolean_true_node)
1486               OB_PUTS ("true");
1487           }
1488         else if (type == char_type_node)
1489           {
1490             OB_PUTC ('\'');
1491             dump_char (TREE_INT_CST_LOW (t));
1492             OB_PUTC ('\'');
1493           }
1494         else if (TREE_INT_CST_HIGH (t)
1495                  != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1)))
1496           {
1497             tree val = t;
1498             if (TREE_INT_CST_HIGH (val) < 0)
1499               {
1500                 OB_PUTC ('-');
1501                 val = build_int_2 (~TREE_INT_CST_LOW (val),
1502                                    -TREE_INT_CST_HIGH (val));
1503               }
1504             /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
1505                systems?  */
1506             {
1507               static char format[10]; /* "%x%09999x\0" */
1508               if (!format[0])
1509                 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
1510               sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
1511                        TREE_INT_CST_LOW (val));
1512               OB_PUTCP (digit_buffer);
1513             }
1514           }
1515         else
1516           OB_PUTI (TREE_INT_CST_LOW (t));
1517       }
1518       break;
1519
1520     case REAL_CST:
1521 #ifndef REAL_IS_NOT_DOUBLE
1522       sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
1523 #else
1524       {
1525         const unsigned char *p = (const unsigned char *) &TREE_REAL_CST (t);
1526         size_t i;
1527         strcpy (digit_buffer, "0x");
1528         for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
1529           sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
1530       }
1531 #endif
1532       OB_PUTCP (digit_buffer);
1533       break;
1534
1535     case PTRMEM_CST:
1536       OB_PUTC ('&');
1537       dump_type (PTRMEM_CST_CLASS (t), flags);
1538       OB_PUTS ("::");
1539       OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t)));
1540       break;
1541
1542     case STRING_CST:
1543       {
1544         const char *p = TREE_STRING_POINTER (t);
1545         int len = TREE_STRING_LENGTH (t) - 1;
1546         int i;
1547
1548         OB_PUTC ('\"');
1549         for (i = 0; i < len; i++)
1550           dump_char (p[i]);
1551         OB_PUTC ('\"');
1552       }
1553       break;
1554
1555     case COMPOUND_EXPR:
1556       OB_PUTC ('(');
1557       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1558       OB_PUTS (", ");
1559       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1560       OB_PUTC (')');
1561       break;
1562
1563     case COND_EXPR:
1564       OB_PUTC ('(');
1565       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1566       OB_PUTS (" ? ");
1567       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1568       OB_PUTS (" : ");
1569       dump_expr (TREE_OPERAND (t, 2), flags | TS_EXPR_PARENS);
1570       OB_PUTC (')');
1571       break;
1572
1573     case SAVE_EXPR:
1574       if (TREE_HAS_CONSTRUCTOR (t))
1575         {
1576           OB_PUTS ("new ");
1577           dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
1578         }
1579       else
1580         {
1581           dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1582         }
1583       break;
1584
1585     case AGGR_INIT_EXPR:
1586       {
1587         tree fn = NULL_TREE;
1588         
1589         if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
1590           fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
1591
1592         if (fn && TREE_CODE (fn) == FUNCTION_DECL)
1593           {
1594             if (DECL_CONSTRUCTOR_P (fn))
1595               OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
1596             else
1597               dump_decl (fn, 0);
1598           }
1599         else
1600           dump_expr (TREE_OPERAND (t, 0), 0);
1601       }
1602       OB_PUTC ('(');
1603       if (TREE_OPERAND (t, 1))
1604         dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
1605       OB_PUTC (')');
1606       break;
1607
1608     case CALL_EXPR:
1609       {
1610         tree fn = TREE_OPERAND (t, 0);
1611         tree args = TREE_OPERAND (t, 1);
1612         
1613         if (TREE_CODE (fn) == ADDR_EXPR)
1614           fn = TREE_OPERAND (fn, 0);
1615
1616         if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
1617           {
1618             tree ob = TREE_VALUE (args);
1619             if (TREE_CODE (ob) == ADDR_EXPR)
1620               {
1621                 dump_expr (TREE_OPERAND (ob, 0), flags | TS_EXPR_PARENS);
1622                 OB_PUTC ('.');
1623               }
1624             else if (TREE_CODE (ob) != PARM_DECL
1625                      || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1626               {
1627                 dump_expr (ob, flags | TS_EXPR_PARENS);
1628                 OB_PUTS ("->");
1629               }
1630             args = TREE_CHAIN (args);
1631           }
1632         dump_expr (fn, flags | TS_EXPR_PARENS);
1633         OB_PUTC ('(');
1634         dump_expr_list (args, flags);
1635         OB_PUTC (')');
1636       }
1637       break;
1638
1639     case NEW_EXPR:
1640       {
1641         tree type = TREE_OPERAND (t, 1);
1642         if (NEW_EXPR_USE_GLOBAL (t))
1643           OB_PUTS ("::");
1644         OB_PUTS ("new ");
1645         if (TREE_OPERAND (t, 0))
1646           {
1647             OB_PUTC ('(');
1648             dump_expr_list (TREE_OPERAND (t, 0), flags);
1649             OB_PUTS (") ");
1650           }
1651         if (TREE_CODE (type) == ARRAY_REF)
1652           type = build_cplus_array_type
1653             (TREE_OPERAND (type, 0),
1654              build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1),
1655                                            integer_one_node)));
1656         dump_type (type, flags);
1657         if (TREE_OPERAND (t, 2))
1658           {
1659             OB_PUTC ('(');
1660             dump_expr_list (TREE_OPERAND (t, 2), flags);
1661             OB_PUTC (')');
1662           }
1663       }
1664       break;
1665
1666     case TARGET_EXPR:
1667       /* Note that this only works for G++ target exprs.  If somebody
1668          builds a general TARGET_EXPR, there's no way to represent that
1669          it initializes anything other that the parameter slot for the
1670          default argument.  Note we may have cleared out the first
1671          operand in expand_expr, so don't go killing ourselves.  */
1672       if (TREE_OPERAND (t, 1))
1673         dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1674       break;
1675
1676     case INIT_EXPR:
1677     case MODIFY_EXPR:
1678     case PLUS_EXPR:
1679     case MINUS_EXPR:
1680     case MULT_EXPR:
1681     case TRUNC_DIV_EXPR:
1682     case TRUNC_MOD_EXPR:
1683     case MIN_EXPR:
1684     case MAX_EXPR:
1685     case LSHIFT_EXPR:
1686     case RSHIFT_EXPR:
1687     case BIT_IOR_EXPR:
1688     case BIT_XOR_EXPR:
1689     case BIT_AND_EXPR:
1690     case BIT_ANDTC_EXPR:
1691     case TRUTH_ANDIF_EXPR:
1692     case TRUTH_ORIF_EXPR:
1693     case LT_EXPR:
1694     case LE_EXPR:
1695     case GT_EXPR:
1696     case GE_EXPR:
1697     case EQ_EXPR:
1698     case NE_EXPR:
1699     case EXACT_DIV_EXPR:
1700       dump_binary_op (opname_tab[(int) TREE_CODE (t)], t, flags);
1701       break;
1702
1703     case CEIL_DIV_EXPR:
1704     case FLOOR_DIV_EXPR:
1705     case ROUND_DIV_EXPR:
1706       dump_binary_op ("/", t, flags);
1707       break;
1708
1709     case CEIL_MOD_EXPR:
1710     case FLOOR_MOD_EXPR:
1711     case ROUND_MOD_EXPR:
1712       dump_binary_op ("%", t, flags);
1713       break;
1714
1715     case COMPONENT_REF:
1716       {
1717         tree ob = TREE_OPERAND (t, 0);
1718         if (TREE_CODE (ob) == INDIRECT_REF)
1719           {
1720             ob = TREE_OPERAND (ob, 0);
1721             if (TREE_CODE (ob) != PARM_DECL
1722                 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1723               {
1724                 dump_expr (ob, flags | TS_EXPR_PARENS);
1725                 OB_PUTS ("->");
1726               }
1727           }
1728         else
1729           {
1730             dump_expr (ob, flags | TS_EXPR_PARENS);
1731             OB_PUTC ('.');
1732           }
1733         dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS);
1734       }
1735       break;
1736
1737     case ARRAY_REF:
1738       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1739       OB_PUTC ('[');
1740       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1741       OB_PUTC (']');
1742       break;
1743
1744     case CONVERT_EXPR:
1745       if (same_type_p (TREE_TYPE (t), void_type_node))
1746         {
1747           OB_PUTS ("(void)");
1748           dump_expr (TREE_OPERAND (t, 0), flags);
1749         }
1750       else
1751         dump_unary_op ("+", t, flags);
1752       break;
1753
1754     case ADDR_EXPR:
1755       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
1756           || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
1757         dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1758       else
1759         dump_unary_op ("&", t, flags);
1760       break;
1761
1762     case INDIRECT_REF:
1763       if (TREE_HAS_CONSTRUCTOR (t))
1764         {
1765           t = TREE_OPERAND (t, 0);
1766           my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1767           dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1768           OB_PUTC ('(');
1769           dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
1770           OB_PUTC (')');
1771         }
1772       else
1773         {
1774           if (TREE_OPERAND (t,0) != NULL_TREE
1775               && TREE_TYPE (TREE_OPERAND (t, 0))
1776               && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
1777             dump_expr (TREE_OPERAND (t, 0), flags);
1778           else
1779             dump_unary_op ("*", t, flags);
1780         }
1781       break;
1782
1783     case NEGATE_EXPR:
1784     case BIT_NOT_EXPR:
1785     case TRUTH_NOT_EXPR:
1786     case PREDECREMENT_EXPR:
1787     case PREINCREMENT_EXPR:
1788       dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, flags);
1789       break;
1790
1791     case POSTDECREMENT_EXPR:
1792     case POSTINCREMENT_EXPR:
1793       OB_PUTC ('(');
1794       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1795       OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
1796       OB_PUTC (')');
1797       break;
1798
1799     case NON_LVALUE_EXPR:
1800       /* FIXME: This is a KLUDGE workaround for a parsing problem.  There
1801          should be another level of INDIRECT_REF so that I don't have to do
1802          this.  */
1803       if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
1804         {
1805           tree next = TREE_TYPE (TREE_TYPE (t));
1806
1807           while (TREE_CODE (next) == POINTER_TYPE)
1808             next = TREE_TYPE (next);
1809           
1810           if (TREE_CODE (next) == FUNCTION_TYPE)
1811             {
1812               if (flags & TS_EXPR_PARENS)
1813                 OB_PUTC ('(');
1814               OB_PUTC ('*');
1815               dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
1816               if (flags & TS_EXPR_PARENS)
1817                 OB_PUTC (')');
1818               break;
1819             }
1820           /* else FALLTHRU */
1821         }
1822       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1823       break;
1824
1825     case NOP_EXPR:
1826       dump_expr (TREE_OPERAND (t, 0), flags);
1827       break;
1828
1829     case EXPR_WITH_FILE_LOCATION:
1830       dump_expr (EXPR_WFL_NODE (t), flags);
1831       break;
1832
1833     case CONSTRUCTOR:
1834       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
1835         {
1836           tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
1837
1838           if (integer_all_onesp (idx))
1839             {
1840               tree pfn = PFN_FROM_PTRMEMFUNC (t);
1841               dump_unary_op ("&", pfn, flags | TS_EXPR_PARENS);
1842               break;
1843             }
1844           else if (TREE_CODE (idx) == INTEGER_CST
1845                    && tree_int_cst_equal (idx, integer_zero_node))
1846             {
1847               /* A NULL pointer-to-member constant.  */
1848               OB_PUTS ("((");
1849               dump_type (TREE_TYPE (t), flags);
1850               OB_PUTS (") 0)");
1851               break;
1852             }
1853           else if (TREE_CODE (idx) == INTEGER_CST
1854                    && TREE_INT_CST_HIGH (idx) == 0)
1855             {
1856               tree virtuals;
1857               unsigned HOST_WIDE_INT n;
1858
1859               t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
1860               t = TYPE_METHOD_BASETYPE (t);
1861               virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
1862               
1863               n = TREE_INT_CST_LOW (idx);
1864
1865               /* Map vtable index back one, to allow for the null pointer to
1866                  member.  */
1867               --n;
1868
1869               while (n > 0 && virtuals)
1870                 {
1871                   --n;
1872                   virtuals = TREE_CHAIN (virtuals);
1873                 }
1874               if (virtuals)
1875                 {
1876                   dump_expr (TREE_VALUE (virtuals),
1877                              flags | TS_EXPR_PARENS);
1878                   break;
1879                 }
1880             }
1881         }
1882       OB_PUTC ('{');
1883       dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
1884       OB_PUTC ('}');
1885       break;
1886
1887     case OFFSET_REF:
1888       {
1889         tree ob = TREE_OPERAND (t, 0);
1890         if (is_dummy_object (ob))
1891           {
1892             t = TREE_OPERAND (t, 1);
1893             if (TREE_CODE (t) == FUNCTION_DECL)
1894               /* A::f */
1895               dump_expr (t, flags | TS_EXPR_PARENS);
1896             else if (BASELINK_P (t))
1897               dump_expr (OVL_CURRENT (TREE_VALUE (t)), flags | TS_EXPR_PARENS);
1898             else
1899               dump_decl (t, flags);
1900           }
1901         else
1902           {
1903             if (TREE_CODE (ob) == INDIRECT_REF)
1904               {
1905                 dump_expr (TREE_OPERAND (ob, 0), flags | TS_EXPR_PARENS);
1906                 OB_PUTS (" ->* ");
1907               }
1908             else
1909               {
1910                 dump_expr (ob, flags | TS_EXPR_PARENS);
1911                 OB_PUTS (" .* ");
1912               }
1913             dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1914           }
1915         break;
1916       }
1917
1918     case TEMPLATE_PARM_INDEX:
1919       dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TS_DECL_TYPE);
1920       break;
1921
1922     case IDENTIFIER_NODE:
1923       OB_PUTID (t);
1924       break;
1925
1926     case SCOPE_REF:
1927       dump_type (TREE_OPERAND (t, 0), flags);
1928       OB_PUTS ("::");
1929       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1930       break;
1931
1932     case CAST_EXPR:
1933       if (TREE_OPERAND (t, 0) == NULL_TREE
1934           || TREE_CHAIN (TREE_OPERAND (t, 0)))
1935         {
1936           dump_type (TREE_TYPE (t), flags);
1937           OB_PUTC ('(');
1938           dump_expr_list (TREE_OPERAND (t, 0), flags);
1939           OB_PUTC (')');
1940         }
1941       else
1942         {
1943           OB_PUTC ('(');
1944           dump_type (TREE_TYPE (t), flags);
1945           OB_PUTC (')');
1946           OB_PUTC ('(');
1947           dump_expr_list (TREE_OPERAND (t, 0), flags);
1948           OB_PUTC (')');
1949         }
1950       break;
1951
1952     case LOOKUP_EXPR:
1953       OB_PUTID (TREE_OPERAND (t, 0));
1954       break;
1955
1956     case ARROW_EXPR:
1957       dump_expr (TREE_OPERAND (t, 0), flags);
1958       OB_PUTS ("->");
1959       break;
1960
1961     case SIZEOF_EXPR:
1962     case ALIGNOF_EXPR:
1963       if (TREE_CODE (t) == SIZEOF_EXPR)
1964         OB_PUTS ("sizeof (");
1965       else 
1966         {
1967           my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
1968           OB_PUTS ("__alignof__ (");
1969         }
1970       if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
1971         dump_type (TREE_OPERAND (t, 0), flags);
1972       else
1973         dump_unary_op ("*", t, flags | TS_EXPR_PARENS);
1974       OB_PUTC (')');
1975       break;
1976
1977     case DEFAULT_ARG:
1978       OB_PUTS ("{unparsed}");
1979       break;
1980
1981     case TRY_CATCH_EXPR:
1982     case WITH_CLEANUP_EXPR:
1983     case CLEANUP_POINT_EXPR:
1984       dump_expr (TREE_OPERAND (t, 0), flags);
1985       break;
1986
1987     case PSEUDO_DTOR_EXPR:
1988       dump_expr (TREE_OPERAND (t, 2), flags);
1989       OB_PUTS (".");
1990       dump_type (TREE_OPERAND (t, 0), flags);
1991       OB_PUTS ("::~");
1992       dump_type (TREE_OPERAND (t, 1), flags);
1993       break;
1994
1995     case TEMPLATE_ID_EXPR:
1996       dump_decl (t, flags);
1997       break;
1998
1999     case STMT_EXPR:
2000       /* We don't yet have a way of dumping statements in a
2001          human-readable format.  */
2002       OB_PUTS ("{ ... }");
2003       break;
2004
2005     case BIND_EXPR:
2006       OB_PUTS ("{ ");
2007       dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS);
2008       OB_PUTS ("} ");
2009       break;
2010       
2011     case LOOP_EXPR:
2012       OB_PUTS ("while (1) { ");
2013       dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
2014       OB_PUTS ("} ");
2015       break;
2016
2017     case EXIT_EXPR:
2018       OB_PUTS ("if (");
2019       dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
2020       OB_PUTS (") break; ");
2021       break;
2022
2023     case TREE_LIST:
2024       if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
2025         {
2026           OB_PUTID (DECL_NAME (TREE_VALUE (t)));
2027           break;
2028         }
2029       /* else fall through */   
2030
2031       /*  This list is incomplete, but should suffice for now.
2032           It is very important that `sorry' does not call
2033           `report_error_function'.  That could cause an infinite loop.  */
2034     default:
2035       sorry ("`%s' not supported by dump_expr",
2036              tree_code_name[(int) TREE_CODE (t)]);
2037
2038       /* fall through to ERROR_MARK...  */
2039     case ERROR_MARK:
2040       OB_PUTCP ("{expression error}");
2041       break;
2042     }
2043 }
2044
2045 static void
2046 dump_binary_op (opstring, t, flags)
2047      const char *opstring;
2048      tree t;
2049      enum tree_string_flags flags;
2050 {
2051   OB_PUTC ('(');
2052   dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
2053   OB_PUTC (' ');
2054   if (opstring)
2055     OB_PUTCP (opstring);
2056   else
2057     OB_PUTS ("<unknown operator>");
2058   OB_PUTC (' ');
2059   dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
2060   OB_PUTC (')');
2061 }
2062
2063 static void
2064 dump_unary_op (opstring, t, flags)
2065      const char *opstring;
2066      tree t;
2067      enum tree_string_flags flags;
2068 {
2069   if (flags & TS_EXPR_PARENS)
2070     OB_PUTC ('(');
2071   OB_PUTCP (opstring);
2072   dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
2073   if (flags & TS_EXPR_PARENS)
2074     OB_PUTC (')');
2075 }
2076
2077 /* Exported interface to stringifying types, exprs and decls under TS_*
2078    control.  */
2079
2080 const char *
2081 type_as_string (typ, flags)
2082      tree typ;
2083      enum tree_string_flags flags;
2084 {
2085   OB_INIT ();
2086
2087   dump_type (typ, flags);
2088
2089   OB_FINISH ();
2090
2091   return (char *)obstack_base (&scratch_obstack);
2092 }
2093
2094 const char *
2095 expr_as_string (decl, flags)
2096      tree decl;
2097      enum tree_string_flags flags;
2098 {
2099   OB_INIT ();
2100
2101   dump_expr (decl, flags);
2102
2103   OB_FINISH ();
2104
2105   return (char *)obstack_base (&scratch_obstack);
2106 }
2107
2108 const char *
2109 decl_as_string (decl, flags)
2110      tree decl;
2111      enum tree_string_flags flags;
2112 {
2113   OB_INIT ();
2114
2115   dump_decl (decl, flags);
2116
2117   OB_FINISH ();
2118
2119   return (char *)obstack_base (&scratch_obstack);
2120 }
2121
2122 const char *
2123 context_as_string (context, flags)
2124      tree context;
2125      enum tree_string_flags flags;
2126 {
2127   OB_INIT ();
2128   
2129   dump_scope (context, flags);
2130   
2131   OB_FINISH ();
2132
2133   return (char *)obstack_base (&scratch_obstack);
2134 }
2135
2136 /* Generate the three forms of printable names for lang_printable_name.  */
2137
2138 const char *
2139 lang_decl_name (decl, v)
2140      tree decl;
2141      int v;
2142 {
2143   if (v >= 2)
2144     return decl_as_string (decl, TS_DECL_TYPE);
2145
2146   OB_INIT ();
2147
2148   if (v == 1 && DECL_CLASS_SCOPE_P (decl))
2149     {
2150       tree cname;
2151       if (TREE_CODE (decl) == FUNCTION_DECL)
2152         cname = DECL_CLASS_CONTEXT (decl);
2153       else
2154         cname = DECL_CONTEXT (decl);
2155       dump_type (cname, TS_PLAIN);
2156       OB_PUTS ("::");
2157     }
2158
2159   if (TREE_CODE (decl) == FUNCTION_DECL)
2160     dump_function_name (decl, TS_PLAIN);
2161   else
2162     dump_decl (DECL_NAME (decl), TS_PLAIN);
2163
2164   OB_FINISH ();
2165
2166   return (char *)obstack_base (&scratch_obstack);
2167 }
2168
2169 const char *
2170 cp_file_of (t)
2171      tree t;
2172 {
2173   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
2174     return DECL_SOURCE_FILE (DECL_CONTEXT (t));
2175   else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
2176     return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));
2177   else if (TREE_CODE (t) == OVERLOAD)
2178     return DECL_SOURCE_FILE (OVL_FUNCTION (t));
2179   else
2180     return DECL_SOURCE_FILE (t);
2181 }
2182
2183 int
2184 cp_line_of (t)
2185      tree t;
2186 {
2187   int line = 0;
2188   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
2189     line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
2190   if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
2191       && TYPE_MAIN_DECL (TREE_TYPE (t)))
2192     t = TREE_TYPE (t);
2193
2194   if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
2195     line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));
2196   else if (TREE_CODE (t) == OVERLOAD)
2197     line = DECL_SOURCE_LINE (OVL_FUNCTION (t));
2198   else
2199     line = DECL_SOURCE_LINE (t);
2200
2201   if (line == 0)
2202     return lineno;
2203
2204   return line;
2205 }
2206
2207 /* Now the interfaces from cp_error et al to dump_type et al. Each takes an
2208    on/off VERBOSE flag and supply the appropriate TS_ flags to a dump_
2209    function.  */
2210
2211 static const char *
2212 decl_to_string (decl, verbose)
2213      tree decl;
2214      int verbose;
2215 {
2216   enum tree_string_flags flags = 0;
2217
2218   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
2219       || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
2220     flags = TS_AGGR_TAGS;
2221   if (verbose)
2222     flags |= TS_DECL_TYPE | TS_DECORATE | TS_PARM_DEFAULTS;
2223   else if (TREE_CODE (decl) == FUNCTION_DECL)
2224     flags |= TS_DECL_TYPE | TS_FUNC_NORETURN;
2225   flags |= TS_TEMPLATE_PREFIX;
2226   
2227   OB_INIT ();
2228
2229   dump_decl (decl, flags);
2230
2231   OB_FINISH ();
2232
2233   return (char *)obstack_base (&scratch_obstack);
2234 }
2235
2236 static const char *
2237 expr_to_string (decl, verbose)
2238      tree decl;
2239      int verbose ATTRIBUTE_UNUSED;
2240 {
2241   OB_INIT ();
2242
2243   dump_expr (decl, 0);
2244
2245   OB_FINISH ();
2246
2247   return (char *)obstack_base (&scratch_obstack);
2248 }
2249
2250 static const char *
2251 fndecl_to_string (fndecl, verbose)
2252      tree fndecl;
2253      int verbose;
2254 {
2255   enum tree_string_flags flags;
2256   
2257   flags = TS_FUNC_THROW | TS_DECL_TYPE;
2258   if (verbose)
2259     flags |= TS_PARM_DEFAULTS;
2260   OB_INIT ();
2261
2262   dump_decl (fndecl, flags);
2263   
2264   OB_FINISH ();
2265
2266   return (char *)obstack_base (&scratch_obstack);
2267 }
2268
2269
2270 static const char *
2271 code_to_string (c, v)
2272      enum tree_code c;
2273      int v ATTRIBUTE_UNUSED;
2274 {
2275   return tree_code_name [c];
2276 }
2277
2278 static const char *
2279 language_to_string (c, v)
2280      enum languages c;
2281      int v ATTRIBUTE_UNUSED;
2282 {
2283   switch (c)
2284     {
2285     case lang_c:
2286       return "C";
2287
2288     case lang_cplusplus:
2289       return "C++";
2290
2291     case lang_java:
2292       return "Java";
2293
2294     default:
2295       my_friendly_abort (355);
2296       return 0;
2297     }
2298 }
2299
2300 /* Return the proper printed version of a parameter to a C++ function.  */
2301
2302 static const char *
2303 parm_to_string (p, v)
2304      int p;
2305      int v ATTRIBUTE_UNUSED;
2306 {
2307   if (p < 0)
2308     return "`this'";
2309
2310   sprintf (digit_buffer, "%d", p+1);
2311   return digit_buffer;
2312 }
2313
2314 static const char *
2315 op_to_string (p, v)
2316      enum tree_code p;
2317      int v ATTRIBUTE_UNUSED;
2318 {
2319   static char buf[] = "operator                ";
2320
2321   if (p == 0)
2322     return "{unknown}";
2323   
2324   strcpy (buf + 8, opname_tab [p]);
2325   return buf;
2326 }
2327
2328 static const char *
2329 type_to_string (typ, verbose)
2330      tree typ;
2331      int verbose;
2332 {
2333   enum tree_string_flags flags;
2334   
2335   flags = 0;
2336   if (verbose)
2337     flags |= TS_AGGR_TAGS;
2338   flags |= TS_TEMPLATE_PREFIX;
2339   
2340   OB_INIT ();
2341
2342   dump_type (typ, flags);
2343
2344   OB_FINISH ();
2345
2346   return (char *)obstack_base (&scratch_obstack);
2347 }
2348
2349 static const char *
2350 assop_to_string (p, v)
2351      enum tree_code p;
2352      int v ATTRIBUTE_UNUSED;
2353 {
2354   static char buf[] = "operator                ";
2355
2356   if (p == 0)
2357     return "{unknown}";
2358   
2359   strcpy (buf + 9, assignop_tab [p]);
2360   return buf;
2361 }
2362
2363 static const char *
2364 args_to_string (p, verbose)
2365      tree p;
2366      int verbose;
2367 {
2368   enum tree_string_flags flags = 0;
2369   if (verbose)
2370     flags |= TS_AGGR_TAGS;
2371   
2372   if (p == NULL_TREE)
2373     return "";
2374
2375   if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't')
2376     return type_as_string (p, flags);
2377
2378   OB_INIT ();
2379   for (; p; p = TREE_CHAIN (p))
2380     {
2381       if (TREE_VALUE (p) == null_node)
2382         OB_PUTS ("NULL");
2383       else
2384         dump_type (error_type (TREE_VALUE (p)), flags);
2385       if (TREE_CHAIN (p))
2386         OB_PUTS (", ");
2387     }
2388   OB_FINISH ();
2389   return (char *)obstack_base (&scratch_obstack);
2390 }
2391
2392 static const char *
2393 cv_to_string (p, v)
2394      tree p;
2395      int v ATTRIBUTE_UNUSED;
2396 {
2397   OB_INIT ();
2398
2399   dump_qualifiers (p, before);
2400
2401   OB_FINISH ();
2402
2403   return (char *)obstack_base (&scratch_obstack);
2404 }