OSDN Git Service

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