OSDN Git Service

2003-07-01 Giovanni Bajo <giovannibajo@libero.it>
[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, 2002,
4    2003 Free Software Foundation, Inc.
5    This file is part of GCC.
6
7 GCC 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 GCC 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 GCC; 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 "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "cp-tree.h"
28 #include "real.h"
29 #include "toplev.h"
30 #include "flags.h"
31 #include "diagnostic.h"
32 #include "langhooks-def.h"
33
34 enum pad { none, before, after };
35
36 #define sorry_for_unsupported_tree(T)                                      \
37    sorry ("`%s' not supported by %s", tree_code_name[(int) TREE_CODE (T)], \
38              __FUNCTION__)
39
40 #define print_scope_operator(BUFFER)  output_add_string ((BUFFER), "::")
41 #define print_left_paren(BUFFER)      output_add_character ((BUFFER), '(')
42 #define print_right_paren(BUFFER)     output_add_character ((BUFFER), ')')
43 #define print_left_bracket(BUFFER)    output_add_character ((BUFFER), '[')
44 #define print_right_bracket(BUFFER)   output_add_character ((BUFFER), ']')
45 #define print_template_argument_list_start(BUFFER) \
46    print_non_consecutive_character ((BUFFER), '<')
47 #define print_template_argument_list_end(BUFFER)  \
48    print_non_consecutive_character ((BUFFER), '>')
49 #define print_tree_identifier(BUFFER, TID) \
50    output_add_string ((BUFFER), IDENTIFIER_POINTER (TID))
51 #define print_identifier(BUFFER, ID) output_add_string ((BUFFER), (ID))
52 #define separate_with_comma(BUFFER) output_add_string ((BUFFER), ", ")
53
54 /* The global buffer where we dump everything.  It is there only for
55    transitional purpose.  It is expected, in the near future, to be
56    completely removed.  */
57 static output_buffer scratch_buffer_rec;
58 static output_buffer *scratch_buffer = &scratch_buffer_rec;
59
60 # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
61
62 #define reinit_global_formatting_buffer() \
63    output_clear_message_text (scratch_buffer)
64
65 static const char *args_to_string (tree, int);
66 static const char *assop_to_string (enum tree_code);
67 static const char *code_to_string (enum tree_code);
68 static const char *cv_to_string (tree, int);
69 static const char *decl_to_string (tree, int);
70 static const char *expr_to_string (tree);
71 static const char *fndecl_to_string (tree, int);
72 static const char *op_to_string (enum tree_code);
73 static const char *parm_to_string (int);
74 static const char *type_to_string (tree, int);
75
76 static void dump_type (tree, int);
77 static void dump_typename (tree, int);
78 static void dump_simple_decl (tree, tree, int);
79 static void dump_decl (tree, int);
80 static void dump_template_decl (tree, int);
81 static void dump_function_decl (tree, int);
82 static void dump_expr (tree, int);
83 static void dump_unary_op (const char *, tree, int);
84 static void dump_binary_op (const char *, tree, int);
85 static void dump_aggr_type (tree, int);
86 static enum pad dump_type_prefix (tree, int);
87 static void dump_type_suffix (tree, int);
88 static void dump_function_name (tree, int);
89 static void dump_expr_list (tree, int);
90 static void dump_global_iord (tree);
91 static enum pad dump_qualifiers (tree, enum pad);
92 static void dump_char (int);
93 static void dump_parameters (tree, int);
94 static void dump_exception_spec (tree, int);
95 static const char *class_key_or_enum (tree);
96 static void dump_template_argument (tree, int);
97 static void dump_template_argument_list (tree, int);
98 static void dump_template_parameter (tree, int);
99 static void dump_template_bindings (tree, tree);
100 static void dump_scope (tree, int);
101 static void dump_template_parms (tree, int, int);
102
103 static const char *function_category (tree);
104 static void maybe_print_instantiation_context (diagnostic_context *);
105 static void print_instantiation_full_context (diagnostic_context *);
106 static void print_instantiation_partial_context (diagnostic_context *,
107                                                  tree, location_t);
108 static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
109 static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
110 static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
111
112 static bool cp_printer (output_buffer *, text_info *);
113 static void print_non_consecutive_character (output_buffer *, int);
114 static tree locate_error (const char *, va_list);
115 static location_t location_of (tree);
116
117 void
118 init_error (void)
119 {
120   diagnostic_starter (global_dc) = cp_diagnostic_starter;
121   diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer;
122   diagnostic_format_decoder (global_dc) = cp_printer;
123
124   init_output_buffer (scratch_buffer, /* prefix */NULL, /* line-width */0);
125 }
126
127 /* Dump a scope, if deemed necessary.  */
128
129 static void
130 dump_scope (tree scope, int flags)
131 {
132   int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF));
133
134   if (scope == NULL_TREE)
135     return;
136
137   if (TREE_CODE (scope) == NAMESPACE_DECL)
138     {
139       if (scope != global_namespace)
140         {
141           dump_decl (scope, f);
142           print_scope_operator (scratch_buffer);
143         }
144     }
145   else if (AGGREGATE_TYPE_P (scope))
146     {
147       dump_type (scope, f);
148       print_scope_operator (scratch_buffer);
149     }
150   else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
151     {
152       dump_function_decl (scope, f);
153       print_scope_operator (scratch_buffer);
154     }
155 }
156
157 /* Dump type qualifiers, providing padding as requested. Return an
158    indication of whether we dumped something.  */
159
160 static enum pad
161 dump_qualifiers (tree t, enum pad p)
162 {
163   static const int masks[] =
164     {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
165   static const char *const names[] =
166     {"const", "volatile", "__restrict"};
167   int ix;
168   int quals = TYPE_QUALS (t);
169   int do_after = p == after;
170
171   if (quals)
172     {
173       for (ix = 0; ix != 3; ix++)
174         if (masks[ix] & quals)
175           {
176             if (p == before)
177               output_add_space (scratch_buffer);
178             p = before;
179             print_identifier (scratch_buffer, names[ix]);
180           }
181       if (do_after)
182         output_add_space (scratch_buffer);
183     }
184   else
185     p = none;
186   return p;
187 }
188
189 /* Dump the template ARGument under control of FLAGS.  */
190
191 static void
192 dump_template_argument (tree arg, int flags)
193 {
194   if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
195     dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
196   else
197     dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
198 }
199
200 /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
201    of FLAGS.  */
202
203 static void
204 dump_template_argument_list (tree args, int flags)
205 {
206   int n = TREE_VEC_LENGTH (args);
207   int need_comma = 0;
208   int i;
209
210   for (i = 0; i< n; ++i)
211     {
212       if (need_comma)
213         separate_with_comma (scratch_buffer);
214       dump_template_argument (TREE_VEC_ELT (args, i), flags);
215       need_comma = 1;
216     }
217 }
218
219 /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS.  */
220
221 static void
222 dump_template_parameter (tree parm, int flags)
223 {
224   tree p = TREE_VALUE (parm);
225   tree a = TREE_PURPOSE (parm);
226
227   if (TREE_CODE (p) == TYPE_DECL)
228     {
229       if (flags & TFF_DECL_SPECIFIERS)
230         {
231           print_identifier (scratch_buffer, "class");
232           if (DECL_NAME (p))
233             {
234               output_add_space (scratch_buffer);
235               print_tree_identifier (scratch_buffer, DECL_NAME (p));
236             }
237         }
238       else if (DECL_NAME (p))
239         print_tree_identifier (scratch_buffer, DECL_NAME (p));
240       else
241         print_identifier (scratch_buffer, "{template default argument error}");
242     }
243   else
244     dump_decl (p, flags | TFF_DECL_SPECIFIERS);
245
246   if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
247     {
248       output_add_string (scratch_buffer, " = ");
249       if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
250         dump_type (a, flags & ~TFF_CHASE_TYPEDEF);
251       else
252         dump_expr (a, flags | TFF_EXPR_IN_PARENS);
253     }
254 }
255
256 /* Dump, under control of FLAGS, a template-parameter-list binding.
257    PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
258    TREE_VEC.  */
259
260 static void
261 dump_template_bindings (tree parms, tree args)
262 {
263   int need_comma = 0;
264
265   while (parms)
266     {
267       tree p = TREE_VALUE (parms);
268       int lvl = TMPL_PARMS_DEPTH (parms);
269       int arg_idx = 0;
270       int i;
271
272       for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
273         {
274           tree arg = NULL_TREE;
275
276           /* Don't crash if we had an invalid argument list.  */
277           if (TMPL_ARGS_DEPTH (args) >= lvl)
278             {
279               tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
280               if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
281                 arg = TREE_VEC_ELT (lvl_args, arg_idx);
282             }
283
284           if (need_comma)
285             separate_with_comma (scratch_buffer);
286           dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER);
287           output_add_string (scratch_buffer, " = ");
288           if (arg)
289             dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
290           else
291             print_identifier (scratch_buffer, "<missing>");
292
293           ++arg_idx;
294           need_comma = 1;
295         }
296
297       parms = TREE_CHAIN (parms);
298     }
299 }
300
301 /* Dump a human-readable equivalent of TYPE.  FLAGS controls the
302    format.  */
303
304 static void
305 dump_type (tree t, int flags)
306 {
307   if (t == NULL_TREE)
308     return;
309
310   if (TYPE_PTRMEMFUNC_P (t))
311     goto offset_type;
312
313   switch (TREE_CODE (t))
314     {
315     case UNKNOWN_TYPE:
316       print_identifier (scratch_buffer, "<unknown type>");
317       break;
318
319     case TREE_LIST:
320       /* A list of function parms.  */
321       dump_parameters (t, flags);
322       break;
323
324     case IDENTIFIER_NODE:
325       print_tree_identifier (scratch_buffer, t);
326       break;
327
328     case TREE_VEC:
329       dump_type (BINFO_TYPE (t), flags);
330       break;
331
332     case RECORD_TYPE:
333     case UNION_TYPE:
334     case ENUMERAL_TYPE:
335       dump_aggr_type (t, flags);
336       break;
337
338     case TYPE_DECL:
339       if (flags & TFF_CHASE_TYPEDEF)
340         {
341           dump_type (DECL_ORIGINAL_TYPE (t)
342                      ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
343           break;
344         }
345       /* else fallthrough */
346
347     case TEMPLATE_DECL:
348     case NAMESPACE_DECL:
349       dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
350       break;
351
352     case COMPLEX_TYPE:
353       output_add_string (scratch_buffer, "__complex__ ");
354       dump_type (TREE_TYPE (t), flags);
355       break;
356
357     case VECTOR_TYPE:
358       output_add_string (scratch_buffer, "__vector__ ");
359       {
360         /* The subtype of a VECTOR_TYPE is something like intQI_type_node,
361            which has no name and is not very useful for diagnostics.  So
362            look up the equivalent C type and print its name.  */
363         tree elt = TREE_TYPE (t);
364         elt = c_common_type_for_mode (TYPE_MODE (elt), TREE_UNSIGNED (elt));
365         dump_type (elt, flags);
366       }
367       break;
368
369     case INTEGER_TYPE:
370       if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
371         output_add_string (scratch_buffer, "unsigned ");
372       else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
373         output_add_string (scratch_buffer, "signed ");
374
375       /* fall through.  */
376     case REAL_TYPE:
377     case VOID_TYPE:
378     case BOOLEAN_TYPE:
379       {
380         tree type;
381         dump_qualifiers (t, after);
382         type = flags & TFF_CHASE_TYPEDEF ? TYPE_MAIN_VARIANT (t) : t;
383         if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
384           print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (type));
385         else
386           /* Types like intQI_type_node and friends have no names.
387              These don't come up in user error messages, but it's nice
388              to be able to print them from the debugger.  */
389           print_identifier (scratch_buffer, "<anonymous>");
390       }
391       break;
392
393     case TEMPLATE_TEMPLATE_PARM:
394       /* For parameters inside template signature.  */
395       if (TYPE_IDENTIFIER (t))
396         print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
397       else
398         print_identifier
399           (scratch_buffer, "<anonymous template template parameter>");
400       break;
401
402     case BOUND_TEMPLATE_TEMPLATE_PARM:
403       {
404         tree args = TYPE_TI_ARGS (t);
405         print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
406         print_template_argument_list_start (scratch_buffer);
407         dump_template_argument_list (args, flags);
408         print_template_argument_list_end (scratch_buffer);
409       }
410       break;
411
412     case TEMPLATE_TYPE_PARM:
413       dump_qualifiers (t, after);
414       if (TYPE_IDENTIFIER (t))
415         print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
416       else
417         print_identifier
418           (scratch_buffer, "<anonymous template type parameter>");
419       break;
420
421       /* This is not always necessary for pointers and such, but doing this
422          reduces code size.  */
423     case ARRAY_TYPE:
424     case POINTER_TYPE:
425     case REFERENCE_TYPE:
426     case OFFSET_TYPE:
427     offset_type:
428     case FUNCTION_TYPE:
429     case METHOD_TYPE:
430     {
431       dump_type_prefix (t, flags);
432       dump_type_suffix (t, flags);
433       break;
434     }
435     case TYPENAME_TYPE:
436       dump_qualifiers (t, after);
437       output_add_string (scratch_buffer, "typename ");
438       dump_typename (t, flags);
439       break;
440
441     case UNBOUND_CLASS_TEMPLATE:
442       dump_type (TYPE_CONTEXT (t), flags);
443       print_scope_operator (scratch_buffer);
444       print_identifier (scratch_buffer, "template ");
445       dump_type (DECL_NAME (TYPE_NAME (t)), flags);
446       break;
447
448     case TYPEOF_TYPE:
449       output_add_string (scratch_buffer, "__typeof (");
450       dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS);
451       print_right_paren (scratch_buffer);
452       break;
453
454     default:
455       sorry_for_unsupported_tree (t);
456       /* Fall through to error.  */
457
458     case ERROR_MARK:
459       print_identifier (scratch_buffer, "<type error>");
460       break;
461     }
462 }
463
464 /* Dump a TYPENAME_TYPE. We need to notice when the context is itself
465    a TYPENAME_TYPE.  */
466
467 static void
468 dump_typename (tree t, int flags)
469 {
470   tree ctx = TYPE_CONTEXT (t);
471
472   if (TREE_CODE (ctx) == TYPENAME_TYPE)
473     dump_typename (ctx, flags);
474   else
475     dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
476   print_scope_operator (scratch_buffer);
477   dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
478 }
479
480 /* Return the name of the supplied aggregate, or enumeral type.  */
481
482 static const char *
483 class_key_or_enum (tree t)
484 {
485   if (TREE_CODE (t) == ENUMERAL_TYPE)
486     return "enum";
487   else if (TREE_CODE (t) == UNION_TYPE)
488     return "union";
489   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
490     return "class";
491   else
492     return "struct";
493 }
494
495 /* Print out a class declaration T under the control of FLAGS,
496    in the form `class foo'.  */
497
498 static void
499 dump_aggr_type (tree t, int flags)
500 {
501   tree name;
502   const char *variety = class_key_or_enum (t);
503   int typdef = 0;
504   int tmplate = 0;
505
506   dump_qualifiers (t, after);
507
508   if (flags & TFF_CLASS_KEY_OR_ENUM)
509     {
510       print_identifier (scratch_buffer, variety);
511       output_add_space (scratch_buffer);
512     }
513
514   if (flags & TFF_CHASE_TYPEDEF)
515     t = TYPE_MAIN_VARIANT (t);
516
517   name = TYPE_NAME (t);
518
519   if (name)
520     {
521       typdef = !DECL_ARTIFICIAL (name);
522       tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
523                 && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
524                 && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
525                     || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
526                     || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
527                     || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
528       dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
529       if (tmplate)
530         {
531           /* Because the template names are mangled, we have to locate
532              the most general template, and use that name.  */
533           tree tpl = CLASSTYPE_TI_TEMPLATE (t);
534
535           while (DECL_TEMPLATE_INFO (tpl))
536             tpl = DECL_TI_TEMPLATE (tpl);
537           name = tpl;
538         }
539       name = DECL_NAME (name);
540     }
541
542   if (name == 0 || ANON_AGGRNAME_P (name))
543     {
544       if (flags & TFF_CLASS_KEY_OR_ENUM)
545         print_identifier (scratch_buffer, "<anonymous>");
546       else
547         output_printf (scratch_buffer, "<anonymous %s>", variety);
548     }
549   else
550     print_tree_identifier (scratch_buffer, name);
551   if (tmplate)
552     dump_template_parms (TYPE_TEMPLATE_INFO (t),
553                          !CLASSTYPE_USE_TEMPLATE (t),
554                          flags & ~TFF_TEMPLATE_HEADER);
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 (tree t, int flags)
573 {
574   enum pad padding = before;
575
576   if (TYPE_PTRMEMFUNC_P (t))
577     {
578       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
579       goto offset_type;
580     }
581
582   switch (TREE_CODE (t))
583     {
584     case POINTER_TYPE:
585     case REFERENCE_TYPE:
586       {
587         tree sub = TREE_TYPE (t);
588
589         padding = dump_type_prefix (sub, flags);
590         /* A tree for a member pointer looks like pointer to offset,
591            so let the OFFSET_TYPE case handle it.  */
592         if (!TYPE_PTRMEM_P (t))
593           {
594             if (TREE_CODE (sub) == ARRAY_TYPE)
595               {
596                 output_add_space (scratch_buffer);
597                 print_left_paren (scratch_buffer);
598               }
599             output_add_character
600               (scratch_buffer, "&*"[TREE_CODE (t) == POINTER_TYPE]);
601             padding = dump_qualifiers (t, before);
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             output_add_space (scratch_buffer);
613           dump_type (TYPE_OFFSET_BASETYPE (t), flags);
614           print_scope_operator (scratch_buffer);
615         }
616       output_add_character (scratch_buffer, '*');
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         output_add_space (scratch_buffer);
626       print_left_paren (scratch_buffer);
627       padding = none;
628       break;
629
630     case METHOD_TYPE:
631       padding = dump_type_prefix (TREE_TYPE (t), flags);
632       if (padding != none)
633         output_add_space (scratch_buffer);
634       print_left_paren (scratch_buffer);
635       padding = none;
636       dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
637       print_scope_operator (scratch_buffer);
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 BOUND_TEMPLATE_TEMPLATE_PARM:
653     case TREE_LIST:
654     case TYPE_DECL:
655     case TREE_VEC:
656     case UNION_TYPE:
657     case UNKNOWN_TYPE:
658     case VOID_TYPE:
659     case TYPENAME_TYPE:
660     case COMPLEX_TYPE:
661     case VECTOR_TYPE:
662     case TYPEOF_TYPE:
663       dump_type (t, flags);
664       padding = before;
665       break;
666
667     default:
668       sorry_for_unsupported_tree (t);
669       /* fall through.  */
670     case ERROR_MARK:
671       print_identifier (scratch_buffer, "<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 (tree t, int 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         print_right_paren (scratch_buffer);
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         print_right_paren (scratch_buffer);
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 & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
709
710         if (TREE_CODE (t) == METHOD_TYPE)
711           dump_qualifiers
712             (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
713         dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
714         dump_type_suffix (TREE_TYPE (t), flags);
715         break;
716       }
717
718     case ARRAY_TYPE:
719       print_left_bracket (scratch_buffer);
720       if (TYPE_DOMAIN (t))
721         {
722           if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0))
723             output_host_wide_integer
724               (scratch_buffer,
725                tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 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 & ~TFF_EXPR_IN_PARENS);
729           else
730             dump_expr (fold (cp_build_binary_op
731                              (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
732                               integer_one_node)),
733                        flags & ~TFF_EXPR_IN_PARENS);
734         }
735       print_right_bracket (scratch_buffer);
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 BOUND_TEMPLATE_TEMPLATE_PARM:
748     case TREE_LIST:
749     case TYPE_DECL:
750     case TREE_VEC:
751     case UNION_TYPE:
752     case UNKNOWN_TYPE:
753     case VOID_TYPE:
754     case TYPENAME_TYPE:
755     case COMPLEX_TYPE:
756     case VECTOR_TYPE:
757     case TYPEOF_TYPE:
758       break;
759
760     default:
761       sorry_for_unsupported_tree (t);
762     case ERROR_MARK:
763       /* Don't mark it here, we should have already done in
764          dump_type_prefix.  */
765       break;
766     }
767 }
768
769 static void
770 dump_global_iord (tree t)
771 {
772   const char *p = NULL;
773
774   if (DECL_GLOBAL_CTOR_P (t))
775     p = "initializers";
776   else if (DECL_GLOBAL_DTOR_P (t))
777     p = "destructors";
778   else
779     abort ();
780
781   output_printf (scratch_buffer, "(static %s for %s)", p, input_filename);
782 }
783
784 static void
785 dump_simple_decl (tree t, tree type, int flags)
786 {
787   if (flags & TFF_DECL_SPECIFIERS)
788     {
789       if (dump_type_prefix (type, flags) != none)
790         output_add_space (scratch_buffer);
791     }
792   if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
793     dump_scope (CP_DECL_CONTEXT (t), flags);
794   if (DECL_NAME (t))
795     dump_decl (DECL_NAME (t), flags);
796   else
797     print_identifier (scratch_buffer, "<anonymous>");
798   if (flags & TFF_DECL_SPECIFIERS)
799     dump_type_suffix (type, flags);
800 }
801
802 /* Dump a human readable string for the decl T under control of FLAGS.  */
803
804 static void
805 dump_decl (tree t, int flags)
806 {
807   if (t == NULL_TREE)
808     return;
809
810   switch (TREE_CODE (t))
811     {
812     case TYPE_DECL:
813       {
814         /* Don't say 'typedef class A' */
815         if (DECL_ARTIFICIAL (t))
816           {
817             if ((flags & TFF_DECL_SPECIFIERS)
818                 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
819               /* Say `class T' not just `T'.  */
820               output_add_string (scratch_buffer, "class ");
821
822             dump_type (TREE_TYPE (t), flags);
823             break;
824           }
825       }
826       if (flags & TFF_DECL_SPECIFIERS)
827         output_add_string (scratch_buffer, "typedef ");
828       dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
829                         ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
830                         flags);
831       break;
832
833     case VAR_DECL:
834       if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
835         {
836           output_add_string (scratch_buffer, "vtable for ");
837           my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
838           dump_type (DECL_CONTEXT (t), flags);
839           break;
840         }
841       /* else fall through */
842     case FIELD_DECL:
843     case PARM_DECL:
844       dump_simple_decl (t, TREE_TYPE (t), flags);
845       break;
846
847     case RESULT_DECL:
848       output_add_string (scratch_buffer, "<return value> ");
849       dump_simple_decl (t, TREE_TYPE (t), flags);
850       break;
851
852     case NAMESPACE_DECL:
853       dump_scope (CP_DECL_CONTEXT (t), flags);
854       if (DECL_NAME (t) == anonymous_namespace_name)
855         print_identifier (scratch_buffer, "<unnamed>");
856       else
857         print_tree_identifier (scratch_buffer, DECL_NAME (t));
858       break;
859
860     case SCOPE_REF:
861       dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS);
862       print_scope_operator (scratch_buffer); 
863       dump_decl (TREE_OPERAND (t, 1), flags);
864       break;
865
866     case ARRAY_REF:
867       dump_decl (TREE_OPERAND (t, 0), flags);
868       print_left_bracket (scratch_buffer);
869       dump_decl (TREE_OPERAND (t, 1), flags);
870       print_right_bracket (scratch_buffer);
871       break;
872
873       /* So that we can do dump_decl on an aggr type.  */
874     case RECORD_TYPE:
875     case UNION_TYPE:
876     case ENUMERAL_TYPE:
877       dump_type (t, flags);
878       break;
879
880     case BIT_NOT_EXPR:
881       /* This is a pseudo distructor call which has not been folded into
882          a PSEUDO_DTOR_EXPR yet.  */
883       output_add_character (scratch_buffer, '~');
884       dump_type (TREE_OPERAND (t, 0), flags);
885       break;
886
887     case TYPE_EXPR:
888       abort ();
889       break;
890
891       /* These special cases are duplicated here so that other functions
892          can feed identifiers to error and get them demangled properly.  */
893     case IDENTIFIER_NODE:
894       if (IDENTIFIER_TYPENAME_P (t))
895         {
896           output_add_string (scratch_buffer, "operator ");
897           /* Not exactly IDENTIFIER_TYPE_VALUE.  */
898           dump_type (TREE_TYPE (t), flags);
899           break;
900         }
901       else
902         print_tree_identifier (scratch_buffer, t);
903       break;
904
905     case OVERLOAD:
906       if (OVL_CHAIN (t))
907         {
908           t = OVL_CURRENT (t);
909           if (DECL_CLASS_SCOPE_P (t))
910             {
911               dump_type (DECL_CONTEXT (t), flags);
912               output_add_string (scratch_buffer, "::");
913             }
914           else if (DECL_CONTEXT (t))
915             {
916               dump_decl (DECL_CONTEXT (t), flags);
917               output_add_string (scratch_buffer, "::");
918             }
919           dump_decl (DECL_NAME (t), flags);
920           break;
921         }
922       
923       /* If there's only one function, just treat it like an ordinary
924          FUNCTION_DECL.  */
925       t = OVL_CURRENT (t);
926       /* Fall through.  */
927
928     case FUNCTION_DECL:
929       if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
930         dump_global_iord (t);
931       else if (! DECL_LANG_SPECIFIC (t))
932         print_identifier (scratch_buffer, "<internal>");
933       else
934         dump_function_decl (t, flags);
935       break;
936
937     case TEMPLATE_DECL:
938       dump_template_decl (t, flags);
939       break;
940
941     case TEMPLATE_ID_EXPR:
942       {
943         tree args;
944         tree name = TREE_OPERAND (t, 0);
945         if (is_overloaded_fn (name))
946           name = DECL_NAME (get_first_fn (name));
947         dump_decl (name, flags);
948         print_template_argument_list_start (scratch_buffer);
949         for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
950           {
951             dump_template_argument (TREE_VALUE (args), flags);
952             if (TREE_CHAIN (args))
953               separate_with_comma (scratch_buffer);
954           }
955         print_template_argument_list_end (scratch_buffer);
956       }
957       break;
958
959     case LOOKUP_EXPR:
960       dump_decl (TREE_OPERAND (t, 0), flags);
961       break;
962
963     case LABEL_DECL:
964       print_tree_identifier (scratch_buffer, DECL_NAME (t));
965       break;
966
967     case CONST_DECL:
968       if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
969           || (DECL_INITIAL (t) &&
970               TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
971         dump_simple_decl (t, TREE_TYPE (t), flags);
972       else if (DECL_NAME (t))
973         dump_decl (DECL_NAME (t), flags);
974       else if (DECL_INITIAL (t))
975         dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
976       else
977         print_identifier (scratch_buffer, "<enumerator>");
978       break;
979
980     case USING_DECL:
981       output_add_string (scratch_buffer, "using ");
982       dump_type (DECL_INITIAL (t), flags);
983       print_scope_operator (scratch_buffer);
984       dump_decl (DECL_NAME (t), flags);
985       break;
986
987     case BASELINK:
988       dump_decl (BASELINK_FUNCTIONS (t), flags);
989       break;
990
991     default:
992       sorry_for_unsupported_tree (t);
993       /* Fallthrough to error.  */
994
995     case ERROR_MARK:
996       print_identifier (scratch_buffer, "<declaration error>");
997       break;
998     }
999 }
1000
1001 /* Dump a template declaration T under control of FLAGS. This means the
1002    'template <...> leaders plus the 'class X' or 'void fn(...)' part.  */
1003
1004 static void
1005 dump_template_decl (tree t, int flags)
1006 {
1007   tree orig_parms = DECL_TEMPLATE_PARMS (t);
1008   tree parms;
1009   int i;
1010
1011   if (flags & TFF_TEMPLATE_HEADER)
1012     {
1013       for (parms = orig_parms = nreverse (orig_parms);
1014            parms;
1015            parms = TREE_CHAIN (parms))
1016         {
1017           tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
1018           int len = TREE_VEC_LENGTH (inner_parms);
1019
1020           output_add_string (scratch_buffer, "template<");
1021
1022           /* If we've shown the template prefix, we'd better show the
1023              parameters' and decl's type too.  */
1024             flags |= TFF_DECL_SPECIFIERS;
1025
1026           for (i = 0; i < len; i++)
1027             {
1028               if (i)
1029                 separate_with_comma (scratch_buffer);
1030               dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
1031             }
1032           print_template_argument_list_end (scratch_buffer);
1033           output_add_space (scratch_buffer);
1034         }
1035       nreverse(orig_parms);
1036
1037       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
1038         /* Say `template<arg> class TT' not just `template<arg> TT'.  */
1039         output_add_string (scratch_buffer, "class ");
1040     }
1041
1042   if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
1043     dump_type (TREE_TYPE (t),
1044                ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
1045                 | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
1046   else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
1047     dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
1048   else if (TREE_TYPE (t) == NULL_TREE)
1049     abort ();
1050   else
1051     switch (NEXT_CODE (t))
1052     {
1053       case METHOD_TYPE:
1054       case FUNCTION_TYPE:
1055         dump_function_decl (t, flags | TFF_TEMPLATE_NAME);
1056         break;
1057       default:
1058         /* This case can occur with some invalid code.  */
1059         dump_type (TREE_TYPE (t),
1060                    (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
1061                    | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0));
1062     }
1063 }
1064
1065 /* Pretty print a function decl. There are several ways we want to print a
1066    function declaration. The TFF_ bits in FLAGS tells us how to behave.
1067    As error can only apply the '#' flag once to give 0 and 1 for V, there
1068    is %D which doesn't print the throw specs, and %F which does.  */
1069
1070 static void
1071 dump_function_decl (tree t, int flags)
1072 {
1073   tree fntype;
1074   tree parmtypes;
1075   tree cname = NULL_TREE;
1076   tree template_args = NULL_TREE;
1077   tree template_parms = NULL_TREE;
1078   int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
1079
1080   if (TREE_CODE (t) == TEMPLATE_DECL)
1081     t = DECL_TEMPLATE_RESULT (t);
1082
1083   /* Pretty print template instantiations only.  */
1084   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t))
1085     {
1086       tree tmpl;
1087
1088       template_args = DECL_TI_ARGS (t);
1089       tmpl = most_general_template (t);
1090       if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
1091         {
1092           template_parms = DECL_TEMPLATE_PARMS (tmpl);
1093           t = tmpl;
1094         }
1095     }
1096
1097   fntype = TREE_TYPE (t);
1098   parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
1099
1100   if (DECL_CLASS_SCOPE_P (t))
1101     cname = DECL_CONTEXT (t);
1102   /* this is for partially instantiated template methods */
1103   else if (TREE_CODE (fntype) == METHOD_TYPE)
1104     cname = TREE_TYPE (TREE_VALUE (parmtypes));
1105
1106   if (!(flags & TFF_DECL_SPECIFIERS))
1107     /* OK */;
1108   else if (DECL_STATIC_FUNCTION_P (t))
1109     print_identifier (scratch_buffer, "static ");
1110   else if (DECL_VIRTUAL_P (t))
1111     print_identifier (scratch_buffer, "virtual ");
1112
1113   /* Print the return type?  */
1114   if (show_return)
1115     show_return = !DECL_CONV_FN_P (t)  && !DECL_CONSTRUCTOR_P (t)
1116                   && !DECL_DESTRUCTOR_P (t);
1117   if (show_return)
1118     {
1119       dump_type_prefix (TREE_TYPE (fntype), flags);
1120       output_add_space (scratch_buffer);
1121     }
1122
1123   /* Print the function name.  */
1124   if (cname)
1125     {
1126       dump_type (cname, flags);
1127       print_scope_operator (scratch_buffer);
1128     }
1129   else
1130     dump_scope (CP_DECL_CONTEXT (t), flags);
1131
1132   dump_function_name (t, flags);
1133
1134   if (1)
1135     {
1136       dump_parameters (parmtypes, flags);
1137
1138       if (TREE_CODE (fntype) == METHOD_TYPE)
1139         dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
1140                          before);
1141
1142       if (flags & TFF_EXCEPTION_SPECIFICATION)
1143         dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
1144
1145       if (show_return)
1146         dump_type_suffix (TREE_TYPE (fntype), flags);
1147     }
1148
1149   /* If T is a template instantiation, dump the parameter binding.  */
1150   if (template_parms != NULL_TREE && template_args != NULL_TREE)
1151     {
1152       output_add_string (scratch_buffer, " [with ");
1153       dump_template_bindings (template_parms, template_args);
1154       print_right_bracket (scratch_buffer);
1155     }
1156 }
1157
1158 /* Print a parameter list. If this is for a member function, the
1159    member object ptr (and any other hidden args) should have
1160    already been removed.  */
1161
1162 static void
1163 dump_parameters (tree parmtypes, int flags)
1164 {
1165   int first;
1166
1167   print_left_paren (scratch_buffer);
1168
1169   for (first = 1; parmtypes != void_list_node;
1170        parmtypes = TREE_CHAIN (parmtypes))
1171     {
1172       if (!first)
1173         separate_with_comma (scratch_buffer);
1174       first = 0;
1175       if (!parmtypes)
1176         {
1177           print_identifier (scratch_buffer, "...");
1178           break;
1179         }
1180       dump_type (TREE_VALUE (parmtypes), flags);
1181
1182       if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
1183         {
1184           output_add_string (scratch_buffer, " = ");
1185           dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
1186         }
1187     }
1188
1189   print_right_paren (scratch_buffer);
1190 }
1191
1192 /* Print an exception specification. T is the exception specification.  */
1193
1194 static void
1195 dump_exception_spec (tree t, int flags)
1196 {
1197   if (t)
1198     {
1199       output_add_string (scratch_buffer, " throw (");
1200       if (TREE_VALUE (t) != NULL_TREE)
1201         while (1)
1202           {
1203             dump_type (TREE_VALUE (t), flags);
1204             t = TREE_CHAIN (t);
1205             if (!t)
1206               break;
1207             separate_with_comma (scratch_buffer);
1208           }
1209       print_right_paren (scratch_buffer);
1210     }
1211 }
1212
1213 /* Handle the function name for a FUNCTION_DECL node, grokking operators
1214    and destructors properly.  */
1215
1216 static void
1217 dump_function_name (tree t, int flags)
1218 {
1219   tree name = DECL_NAME (t);
1220
1221   if (TREE_CODE (t) == TEMPLATE_DECL)
1222     t = DECL_TEMPLATE_RESULT (t);
1223
1224   /* Don't let the user see __comp_ctor et al.  */
1225   if (DECL_CONSTRUCTOR_P (t)
1226       || DECL_DESTRUCTOR_P (t))
1227     name = constructor_name (DECL_CONTEXT (t));
1228
1229   if (DECL_DESTRUCTOR_P (t))
1230     {
1231       output_add_character (scratch_buffer, '~');
1232       dump_decl (name, TFF_PLAIN_IDENTIFIER);
1233     }
1234   else if (DECL_CONV_FN_P (t))
1235     {
1236       /* This cannot use the hack that the operator's return
1237          type is stashed off of its name because it may be
1238          used for error reporting.  In the case of conflicting
1239          declarations, both will have the same name, yet
1240          the types will be different, hence the TREE_TYPE field
1241          of the first name will be clobbered by the second.  */
1242       output_add_string (scratch_buffer, "operator ");
1243       dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
1244     }
1245   else if (IDENTIFIER_OPNAME_P (name))
1246     print_tree_identifier (scratch_buffer, name);
1247   else
1248     dump_decl (name, flags);
1249
1250   if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
1251       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
1252       && (DECL_TEMPLATE_SPECIALIZATION (t)
1253           || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
1254           || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
1255           || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
1256     dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
1257 }
1258
1259 /* Dump the template parameters from the template info INFO under control of
1260    FLAGS. PRIMARY indicates whether this is a primary template decl, or
1261    specialization (partial or complete). For partial specializations we show
1262    the specialized parameter values. For a primary template we show no
1263    decoration.  */
1264
1265 static void
1266 dump_template_parms (tree info, int primary, int flags)
1267 {
1268   tree args = info ? TI_ARGS (info) : NULL_TREE;
1269
1270   if (primary && flags & TFF_TEMPLATE_NAME)
1271     return;
1272   flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
1273   print_template_argument_list_start (scratch_buffer);
1274
1275   /* Be careful only to print things when we have them, so as not
1276          to crash producing error messages.  */
1277   if (args && !primary)
1278     {
1279       int len = 0;
1280       int ix = 0;
1281       int need_comma = 0;
1282
1283       if (TREE_CODE (args) == TREE_VEC)
1284         {
1285           if (TREE_VEC_LENGTH (args) > 0
1286               && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
1287             args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
1288
1289           len = TREE_VEC_LENGTH (args);
1290         }
1291       else if (TREE_CODE (args) == TREE_LIST)
1292         len = -1;
1293       while (ix != len && args)
1294         {
1295           tree arg;
1296           if (len >= 0)
1297             {
1298               arg = TREE_VEC_ELT (args, ix);
1299               ix++;
1300             }
1301           else
1302             {
1303               arg = TREE_VALUE (args);
1304               args = TREE_CHAIN (args);
1305             }
1306           if (need_comma)
1307             separate_with_comma (scratch_buffer);
1308           
1309           if (!arg)
1310             print_identifier (scratch_buffer, "<template parameter error>");
1311           else
1312             dump_template_argument (arg, flags);
1313           need_comma = 1;
1314         }
1315     }
1316   else if (primary)
1317     {
1318       tree tpl = TI_TEMPLATE (info);
1319       tree parms = DECL_TEMPLATE_PARMS (tpl);
1320       int len, ix;
1321
1322       parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
1323       len = parms ? TREE_VEC_LENGTH (parms) : 0;
1324
1325       for (ix = 0; ix != len; ix++)
1326         {
1327           tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
1328
1329           if (ix)
1330             separate_with_comma (scratch_buffer);
1331
1332           dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS);
1333         }
1334     }
1335   print_template_argument_list_end (scratch_buffer);
1336 }
1337
1338 static void
1339 dump_char (int c)
1340 {
1341   switch (c)
1342     {
1343     case TARGET_NEWLINE:
1344       output_add_string (scratch_buffer, "\\n");
1345       break;
1346     case TARGET_TAB:
1347       output_add_string (scratch_buffer, "\\t");
1348       break;
1349     case TARGET_VT:
1350       output_add_string (scratch_buffer, "\\v");
1351       break;
1352     case TARGET_BS:
1353       output_add_string (scratch_buffer, "\\b");
1354       break;
1355     case TARGET_CR:
1356       output_add_string (scratch_buffer, "\\r");
1357       break;
1358     case TARGET_FF:
1359       output_add_string (scratch_buffer, "\\f");
1360       break;
1361     case TARGET_BELL:
1362       output_add_string (scratch_buffer, "\\a");
1363       break;
1364     case '\\':
1365       output_add_string (scratch_buffer, "\\\\");
1366       break;
1367     case '\'':
1368       output_add_string (scratch_buffer, "\\'");
1369       break;
1370     case '\"':
1371       output_add_string (scratch_buffer, "\\\"");
1372       break;
1373     default:
1374       if (ISPRINT (c))
1375         output_add_character (scratch_buffer, c);
1376       else
1377         output_formatted_scalar (scratch_buffer, "\\%03o", (unsigned) c);
1378       break;
1379     }
1380 }
1381
1382 /* Print out a list of initializers (subr of dump_expr) */
1383
1384 static void
1385 dump_expr_list (tree l, int flags)
1386 {
1387   while (l)
1388     {
1389       dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
1390       l = TREE_CHAIN (l);
1391       if (l)
1392         separate_with_comma (scratch_buffer);
1393     }
1394 }
1395
1396 /* Print out an expression E under control of FLAGS.  */
1397
1398 static void
1399 dump_expr (tree t, int flags)
1400 {
1401   if (t == 0)
1402     return;
1403   
1404   switch (TREE_CODE (t))
1405     {
1406     case VAR_DECL:
1407     case PARM_DECL:
1408     case FIELD_DECL:
1409     case CONST_DECL:
1410     case FUNCTION_DECL:
1411     case TEMPLATE_DECL:
1412     case NAMESPACE_DECL:
1413     case OVERLOAD:
1414     case IDENTIFIER_NODE:
1415       dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
1416       break;
1417
1418     case INTEGER_CST:
1419       {
1420         tree type = TREE_TYPE (t);
1421         my_friendly_assert (type != 0, 81);
1422
1423         /* If it's an enum, output its tag, rather than its value.  */
1424         if (TREE_CODE (type) == ENUMERAL_TYPE)
1425           {
1426             tree values = TYPE_VALUES (type);
1427
1428             for (; values;
1429                  values = TREE_CHAIN (values))
1430               if (tree_int_cst_equal (TREE_VALUE (values), t))
1431                 break;
1432
1433             if (values)
1434               print_tree_identifier (scratch_buffer, TREE_PURPOSE (values));
1435             else
1436               {
1437                 /* Value must have been cast.  */
1438                 print_left_paren (scratch_buffer);
1439                 dump_type (type, flags);
1440                 print_right_paren (scratch_buffer);
1441                 goto do_int;
1442               }
1443           }
1444         else if (type == boolean_type_node)
1445           {
1446             if (t == boolean_false_node || integer_zerop (t))
1447               print_identifier (scratch_buffer, "false");
1448             else if (t == boolean_true_node)
1449               print_identifier (scratch_buffer, "true");
1450           }
1451         else if (type == char_type_node)
1452           {
1453             output_add_character (scratch_buffer, '\'');
1454             if (host_integerp (t, TREE_UNSIGNED (type)))
1455               dump_char (tree_low_cst (t, TREE_UNSIGNED (type)));
1456             else
1457               output_printf (scratch_buffer, "\\x%x",
1458                              (unsigned int) TREE_INT_CST_LOW (t));
1459             output_add_character (scratch_buffer, '\'');
1460           }
1461         else
1462           {
1463             do_int:
1464             if (! host_integerp (t, 0))
1465               {
1466                 tree val = t;
1467
1468                 if (tree_int_cst_sgn (val) < 0)
1469                   {
1470                     output_add_character (scratch_buffer, '-');
1471                     val = build_int_2 (-TREE_INT_CST_LOW (val),
1472                                        ~TREE_INT_CST_HIGH (val)
1473                                        + !TREE_INT_CST_LOW (val));
1474                   }
1475                 sprintf (scratch_buffer->digit_buffer,
1476                          HOST_WIDE_INT_PRINT_DOUBLE_HEX,
1477                          TREE_INT_CST_HIGH (val), TREE_INT_CST_LOW (val));
1478                 output_add_string
1479                   (scratch_buffer, scratch_buffer->digit_buffer);
1480               }
1481             else
1482               output_host_wide_integer (scratch_buffer, TREE_INT_CST_LOW (t));
1483           }
1484       }
1485       break;
1486
1487     case REAL_CST:
1488       real_to_decimal (scratch_buffer->digit_buffer, &TREE_REAL_CST (t),
1489                        sizeof (scratch_buffer->digit_buffer), 0, 1);
1490       output_add_string (scratch_buffer, scratch_buffer->digit_buffer);
1491       break;
1492
1493     case PTRMEM_CST:
1494       output_add_character (scratch_buffer, '&');
1495       dump_type (PTRMEM_CST_CLASS (t), flags);
1496       print_scope_operator (scratch_buffer);
1497       print_tree_identifier
1498         (scratch_buffer, DECL_NAME (PTRMEM_CST_MEMBER (t)));
1499       break;
1500
1501     case STRING_CST:
1502       {
1503         const char *p = TREE_STRING_POINTER (t);
1504         int len = TREE_STRING_LENGTH (t) - 1;
1505         int i;
1506
1507         output_add_character (scratch_buffer, '\"');
1508         for (i = 0; i < len; i++)
1509           dump_char (p[i]);
1510         output_add_character (scratch_buffer, '\"');
1511       }
1512       break;
1513
1514     case COMPOUND_EXPR:
1515       print_left_paren (scratch_buffer);
1516       /* Within templates, a COMPOUND_EXPR has only one operand,
1517          containing a TREE_LIST of the two operands. */
1518       if (TREE_CODE (TREE_OPERAND (t, 0)) == TREE_LIST)
1519       {
1520         if (TREE_OPERAND (t, 1))
1521           abort();
1522         dump_expr_list (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1523       }
1524       else
1525       {
1526         dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1527         separate_with_comma (scratch_buffer);
1528         dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
1529       }
1530       print_right_paren (scratch_buffer);
1531       break;
1532
1533     case COND_EXPR:
1534       print_left_paren (scratch_buffer);
1535       dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1536       output_add_string (scratch_buffer, " ? ");
1537       dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
1538       output_add_string (scratch_buffer, " : ");
1539       dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
1540       print_right_paren (scratch_buffer);
1541       break;
1542
1543     case SAVE_EXPR:
1544       if (TREE_HAS_CONSTRUCTOR (t))
1545         {
1546           output_add_string (scratch_buffer, "new ");
1547           dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
1548         }
1549       else
1550         {
1551           dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1552         }
1553       break;
1554
1555     case AGGR_INIT_EXPR:
1556       {
1557         tree fn = NULL_TREE;
1558
1559         if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
1560           fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
1561
1562         if (fn && TREE_CODE (fn) == FUNCTION_DECL)
1563           {
1564             if (DECL_CONSTRUCTOR_P (fn))
1565               print_tree_identifier
1566                 (scratch_buffer, TYPE_IDENTIFIER (TREE_TYPE (t)));
1567             else
1568               dump_decl (fn, 0);
1569           }
1570         else
1571           dump_expr (TREE_OPERAND (t, 0), 0);
1572       }
1573       print_left_paren (scratch_buffer);
1574       if (TREE_OPERAND (t, 1))
1575         dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
1576       print_right_paren (scratch_buffer);
1577       break;
1578
1579     case CALL_EXPR:
1580       {
1581         tree fn = TREE_OPERAND (t, 0);
1582         tree args = TREE_OPERAND (t, 1);
1583
1584         if (TREE_CODE (fn) == ADDR_EXPR)
1585           fn = TREE_OPERAND (fn, 0);
1586
1587         if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
1588           {
1589             tree ob = TREE_VALUE (args);
1590             if (TREE_CODE (ob) == ADDR_EXPR)
1591               {
1592                 dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
1593                 output_add_character (scratch_buffer, '.');
1594               }
1595             else if (TREE_CODE (ob) != PARM_DECL
1596                      || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1597               {
1598                 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
1599                 output_add_string (scratch_buffer, "->");
1600               }
1601             args = TREE_CHAIN (args);
1602           }
1603         dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
1604         print_left_paren (scratch_buffer);
1605         dump_expr_list (args, flags);
1606         print_right_paren (scratch_buffer);
1607       }
1608       break;
1609
1610     case NEW_EXPR:
1611       {
1612         tree type = TREE_OPERAND (t, 1);
1613         tree init = TREE_OPERAND (t, 2);
1614         if (NEW_EXPR_USE_GLOBAL (t))
1615           print_scope_operator (scratch_buffer);
1616         output_add_string (scratch_buffer, "new ");
1617         if (TREE_OPERAND (t, 0))
1618           {
1619             print_left_paren (scratch_buffer);
1620             dump_expr_list (TREE_OPERAND (t, 0), flags);
1621             output_add_string (scratch_buffer, ") ");
1622           }
1623         if (TREE_CODE (type) == ARRAY_REF)
1624           type = build_cplus_array_type
1625             (TREE_OPERAND (type, 0),
1626              build_index_type (fold (build (MINUS_EXPR, integer_type_node,
1627                                             TREE_OPERAND (type, 1),
1628                                             integer_one_node))));
1629         dump_type (type, flags);
1630         if (init)
1631           {
1632             print_left_paren (scratch_buffer);
1633             if (TREE_CODE (init) == TREE_LIST)
1634               dump_expr_list (init, flags);
1635             else if (init == void_zero_node)
1636               /* This representation indicates an empty initializer,
1637                  e.g.: "new int()".  */
1638               ;
1639             else
1640               dump_expr (init, flags);
1641             print_right_paren (scratch_buffer);
1642           }
1643       }
1644       break;
1645
1646     case TARGET_EXPR:
1647       /* Note that this only works for G++ target exprs.  If somebody
1648          builds a general TARGET_EXPR, there's no way to represent that
1649          it initializes anything other that the parameter slot for the
1650          default argument.  Note we may have cleared out the first
1651          operand in expand_expr, so don't go killing ourselves.  */
1652       if (TREE_OPERAND (t, 1))
1653         dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
1654       break;
1655
1656     case INIT_EXPR:
1657     case MODIFY_EXPR:
1658     case PLUS_EXPR:
1659     case MINUS_EXPR:
1660     case MULT_EXPR:
1661     case TRUNC_DIV_EXPR:
1662     case TRUNC_MOD_EXPR:
1663     case MIN_EXPR:
1664     case MAX_EXPR:
1665     case LSHIFT_EXPR:
1666     case RSHIFT_EXPR:
1667     case BIT_IOR_EXPR:
1668     case BIT_XOR_EXPR:
1669     case BIT_AND_EXPR:
1670     case BIT_ANDTC_EXPR:
1671     case TRUTH_ANDIF_EXPR:
1672     case TRUTH_ORIF_EXPR:
1673     case LT_EXPR:
1674     case LE_EXPR:
1675     case GT_EXPR:
1676     case GE_EXPR:
1677     case EQ_EXPR:
1678     case NE_EXPR:
1679     case EXACT_DIV_EXPR:
1680       dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags);
1681       break;
1682
1683     case CEIL_DIV_EXPR:
1684     case FLOOR_DIV_EXPR:
1685     case ROUND_DIV_EXPR:
1686       dump_binary_op ("/", t, flags);
1687       break;
1688
1689     case CEIL_MOD_EXPR:
1690     case FLOOR_MOD_EXPR:
1691     case ROUND_MOD_EXPR:
1692       dump_binary_op ("%", t, flags);
1693       break;
1694
1695     case COMPONENT_REF:
1696       {
1697         tree ob = TREE_OPERAND (t, 0);
1698         if (TREE_CODE (ob) == INDIRECT_REF)
1699           {
1700             ob = TREE_OPERAND (ob, 0);
1701             if (TREE_CODE (ob) != PARM_DECL
1702                 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1703               {
1704                 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
1705                 output_add_string (scratch_buffer, "->");
1706               }
1707           }
1708         else
1709           {
1710             dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
1711             output_add_character (scratch_buffer, '.');
1712           }
1713         dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
1714       }
1715       break;
1716
1717     case ARRAY_REF:
1718       dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1719       print_left_bracket (scratch_buffer);
1720       dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
1721       print_right_bracket (scratch_buffer);
1722       break;
1723
1724     case CONVERT_EXPR:
1725       if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t)))
1726         {
1727           print_left_paren (scratch_buffer);
1728           dump_type (TREE_TYPE (t), flags);
1729           print_right_paren (scratch_buffer);
1730           dump_expr (TREE_OPERAND (t, 0), flags);
1731         }
1732       else
1733         dump_unary_op ("+", t, flags);
1734       break;
1735
1736     case ADDR_EXPR:
1737       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
1738           || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
1739           /* An ADDR_EXPR can have reference type.  In that case, we
1740              shouldn't print the `&' doing so indicates to the user
1741              that the expression has pointer type.  */
1742           || (TREE_TYPE (t)
1743               && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
1744         dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1745       else
1746         dump_unary_op ("&", t, flags);
1747       break;
1748
1749     case INDIRECT_REF:
1750       if (TREE_HAS_CONSTRUCTOR (t))
1751         {
1752           t = TREE_OPERAND (t, 0);
1753           my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1754           dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1755           print_left_paren (scratch_buffer);
1756           dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
1757           print_right_paren (scratch_buffer);
1758         }
1759       else
1760         {
1761           if (TREE_OPERAND (t,0) != NULL_TREE
1762               && TREE_TYPE (TREE_OPERAND (t, 0))
1763               && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
1764             dump_expr (TREE_OPERAND (t, 0), flags);
1765           else
1766             dump_unary_op ("*", t, flags);
1767         }
1768       break;
1769
1770     case NEGATE_EXPR:
1771     case BIT_NOT_EXPR:
1772     case TRUTH_NOT_EXPR:
1773     case PREDECREMENT_EXPR:
1774     case PREINCREMENT_EXPR:
1775       dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags);
1776       break;
1777
1778     case POSTDECREMENT_EXPR:
1779     case POSTINCREMENT_EXPR:
1780       print_left_paren (scratch_buffer);
1781       dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1782       print_identifier
1783         (scratch_buffer, operator_name_info[(int)TREE_CODE (t)].name);
1784       print_right_paren (scratch_buffer);
1785       break;
1786
1787     case NON_LVALUE_EXPR:
1788       /* FIXME: This is a KLUDGE workaround for a parsing problem.  There
1789          should be another level of INDIRECT_REF so that I don't have to do
1790          this.  */
1791       if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
1792         {
1793           tree next = TREE_TYPE (TREE_TYPE (t));
1794
1795           while (TREE_CODE (next) == POINTER_TYPE)
1796             next = TREE_TYPE (next);
1797
1798           if (TREE_CODE (next) == FUNCTION_TYPE)
1799             {
1800               if (flags & TFF_EXPR_IN_PARENS)
1801                 print_left_paren (scratch_buffer);
1802               output_add_character (scratch_buffer, '*');
1803               dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
1804               if (flags & TFF_EXPR_IN_PARENS)
1805                 print_right_paren (scratch_buffer);
1806               break;
1807             }
1808           /* else FALLTHRU */
1809         }
1810       dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
1811       break;
1812
1813     case NOP_EXPR:
1814       dump_expr (TREE_OPERAND (t, 0), flags);
1815       break;
1816
1817     case EXPR_WITH_FILE_LOCATION:
1818       dump_expr (EXPR_WFL_NODE (t), flags);
1819       break;
1820
1821     case CONSTRUCTOR:
1822       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
1823         {
1824           tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
1825
1826           if (integer_zerop (idx))
1827             {
1828               /* A NULL pointer-to-member constant.  */
1829               output_add_string (scratch_buffer, "((");
1830               dump_type (TREE_TYPE (t), flags);
1831               output_add_string (scratch_buffer, ") 0)");
1832               break;
1833             }
1834           else if (host_integerp (idx, 0))
1835             {
1836               tree virtuals;
1837               unsigned HOST_WIDE_INT n;
1838
1839               t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
1840               t = TYPE_METHOD_BASETYPE (t);
1841               virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
1842
1843               n = tree_low_cst (idx, 0);
1844
1845               /* Map vtable index back one, to allow for the null pointer to
1846                  member.  */
1847               --n;
1848
1849               while (n > 0 && virtuals)
1850                 {
1851                   --n;
1852                   virtuals = TREE_CHAIN (virtuals);
1853                 }
1854               if (virtuals)
1855                 {
1856                   dump_expr (BV_FN (virtuals),
1857                              flags | TFF_EXPR_IN_PARENS);
1858                   break;
1859                 }
1860             }
1861         }
1862       if (TREE_TYPE (t) && !CONSTRUCTOR_ELTS (t))
1863         {
1864           dump_type (TREE_TYPE (t), 0);
1865           output_add_character (scratch_buffer, '(');
1866           output_add_character (scratch_buffer, ')');
1867         }
1868       else
1869         {
1870           output_add_character (scratch_buffer, '{');
1871           dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
1872           output_add_character (scratch_buffer, '}');
1873         }
1874       
1875       break;
1876
1877     case OFFSET_REF:
1878       {
1879         tree ob = TREE_OPERAND (t, 0);
1880         if (is_dummy_object (ob))
1881           {
1882             t = TREE_OPERAND (t, 1);
1883             if (TREE_CODE (t) == FUNCTION_DECL)
1884               /* A::f */
1885               dump_expr (t, flags | TFF_EXPR_IN_PARENS);
1886             else if (BASELINK_P (t))
1887               dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)), 
1888                          flags | TFF_EXPR_IN_PARENS);
1889             else
1890               dump_decl (t, flags);
1891           }
1892         else
1893           {
1894             if (TREE_CODE (ob) == INDIRECT_REF)
1895               {
1896                 dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
1897                 output_add_string (scratch_buffer, "->*");
1898               }
1899             else
1900               {
1901                 dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
1902                 output_add_string (scratch_buffer, ".*");
1903               }
1904             dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
1905           }
1906         break;
1907       }
1908
1909     case TEMPLATE_PARM_INDEX:
1910       dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
1911       break;
1912
1913     case SCOPE_REF:
1914       dump_type (TREE_OPERAND (t, 0), flags);
1915       print_scope_operator (scratch_buffer);
1916       dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
1917       break;
1918
1919     case CAST_EXPR:
1920       if (TREE_OPERAND (t, 0) == NULL_TREE
1921           || TREE_CHAIN (TREE_OPERAND (t, 0)))
1922         {
1923           dump_type (TREE_TYPE (t), flags);
1924           print_left_paren (scratch_buffer);
1925           dump_expr_list (TREE_OPERAND (t, 0), flags);
1926           print_right_paren (scratch_buffer);
1927         }
1928       else
1929         {
1930           print_left_paren (scratch_buffer);
1931           dump_type (TREE_TYPE (t), flags);
1932           output_add_string (scratch_buffer, ")(");
1933           dump_expr_list (TREE_OPERAND (t, 0), flags);
1934           print_right_paren (scratch_buffer);
1935         }
1936       break;
1937
1938     case STATIC_CAST_EXPR:
1939       output_add_string (scratch_buffer, "static_cast<");
1940       goto cast;
1941     case REINTERPRET_CAST_EXPR:
1942       output_add_string (scratch_buffer, "reinterpret_cast<");
1943       goto cast;
1944     case CONST_CAST_EXPR:
1945       output_add_string (scratch_buffer, "const_cast<");
1946       goto cast;
1947     case DYNAMIC_CAST_EXPR:
1948       output_add_string (scratch_buffer, "dynamic_cast<");
1949     cast:
1950       dump_type (TREE_TYPE (t), flags);
1951       output_add_string (scratch_buffer, ">(");
1952       dump_expr (TREE_OPERAND (t, 0), flags);
1953       print_right_paren (scratch_buffer);
1954       break;
1955
1956     case LOOKUP_EXPR:
1957       print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0));
1958       break;
1959
1960     case ARROW_EXPR:
1961       dump_expr (TREE_OPERAND (t, 0), flags);
1962       output_add_string (scratch_buffer, "->");
1963       break;
1964
1965     case SIZEOF_EXPR:
1966     case ALIGNOF_EXPR:
1967       if (TREE_CODE (t) == SIZEOF_EXPR)
1968         output_add_string (scratch_buffer, "sizeof (");
1969       else
1970         {
1971           my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
1972           output_add_string (scratch_buffer, "__alignof__ (");
1973         }
1974       if (TYPE_P (TREE_OPERAND (t, 0)))
1975         dump_type (TREE_OPERAND (t, 0), flags);
1976       else
1977         dump_expr (TREE_OPERAND (t, 0), flags);
1978       print_right_paren (scratch_buffer);
1979       break;
1980
1981     case DEFAULT_ARG:
1982       print_identifier (scratch_buffer, "<unparsed>");
1983       break;
1984
1985     case TRY_CATCH_EXPR:
1986     case WITH_CLEANUP_EXPR:
1987     case CLEANUP_POINT_EXPR:
1988       dump_expr (TREE_OPERAND (t, 0), flags);
1989       break;
1990
1991     case PSEUDO_DTOR_EXPR:
1992       dump_expr (TREE_OPERAND (t, 2), flags);
1993       output_add_character (scratch_buffer, '.');
1994       dump_type (TREE_OPERAND (t, 0), flags);
1995       output_add_string (scratch_buffer, "::~");
1996       dump_type (TREE_OPERAND (t, 1), flags);
1997       break;
1998
1999     case TEMPLATE_ID_EXPR:
2000       dump_decl (t, flags);
2001       break;
2002
2003     case STMT_EXPR:
2004       /* We don't yet have a way of dumping statements in a
2005          human-readable format.  */
2006       output_add_string (scratch_buffer, "({...})");
2007       break;
2008
2009     case BIND_EXPR:
2010       output_add_character (scratch_buffer, '{');
2011       dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
2012       output_add_character (scratch_buffer, '}');
2013       break;
2014
2015     case LOOP_EXPR:
2016       output_add_string (scratch_buffer, "while (1) { ");
2017       dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
2018       output_add_character (scratch_buffer, '}');
2019       break;
2020
2021     case EXIT_EXPR:
2022       output_add_string (scratch_buffer, "if (");
2023       dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
2024       output_add_string (scratch_buffer, ") break; ");
2025       break;
2026
2027     case BASELINK:
2028       dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS);
2029       break;
2030
2031       /* else fall through */
2032
2033       /*  This list is incomplete, but should suffice for now.
2034           It is very important that `sorry' does not call
2035           `report_error_function'.  That could cause an infinite loop.  */
2036     default:
2037       sorry_for_unsupported_tree (t);
2038       /* fall through to ERROR_MARK...  */
2039     case ERROR_MARK:
2040       print_identifier (scratch_buffer, "<expression error>");
2041       break;
2042     }
2043 }
2044
2045 static void
2046 dump_binary_op (const char *opstring, tree t, int flags)
2047 {
2048   print_left_paren (scratch_buffer);
2049   dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
2050   output_add_space (scratch_buffer);
2051   if (opstring)
2052     print_identifier (scratch_buffer, opstring);
2053   else
2054     print_identifier (scratch_buffer, "<unknown operator>");
2055   output_add_space (scratch_buffer);
2056   dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
2057   print_right_paren (scratch_buffer);
2058 }
2059
2060 static void
2061 dump_unary_op (const char *opstring, tree t, int flags)
2062 {
2063   if (flags & TFF_EXPR_IN_PARENS)
2064     print_left_paren (scratch_buffer);
2065   print_identifier (scratch_buffer, opstring);
2066   dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
2067   if (flags & TFF_EXPR_IN_PARENS)
2068     print_right_paren (scratch_buffer);
2069 }
2070
2071 /* Exported interface to stringifying types, exprs and decls under TFF_*
2072    control.  */
2073
2074 const char *
2075 type_as_string (tree typ, int flags)
2076 {
2077   reinit_global_formatting_buffer ();
2078
2079   dump_type (typ, flags);
2080
2081   return output_finalize_message (scratch_buffer);
2082 }
2083
2084 const char *
2085 expr_as_string (tree decl, int flags)
2086 {
2087   reinit_global_formatting_buffer ();
2088
2089   dump_expr (decl, flags);
2090
2091   return output_finalize_message (scratch_buffer);
2092 }
2093
2094 const char *
2095 decl_as_string (tree decl, int flags)
2096 {
2097   reinit_global_formatting_buffer ();
2098
2099   dump_decl (decl, flags);
2100
2101   return output_finalize_message (scratch_buffer);
2102 }
2103
2104 const char *
2105 context_as_string (tree context, int flags)
2106 {
2107   reinit_global_formatting_buffer ();
2108
2109   dump_scope (context, flags);
2110
2111   return output_finalize_message (scratch_buffer);
2112 }
2113
2114 /* Generate the three forms of printable names for cxx_printable_name.  */
2115
2116 const char *
2117 lang_decl_name (tree decl, int v)
2118 {
2119   if (v >= 2)
2120     return decl_as_string (decl, TFF_DECL_SPECIFIERS);
2121
2122   reinit_global_formatting_buffer ();
2123
2124   if (v == 1 && DECL_CLASS_SCOPE_P (decl))
2125     {
2126       dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
2127       print_scope_operator (scratch_buffer);
2128     }
2129
2130   if (TREE_CODE (decl) == FUNCTION_DECL)
2131     dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
2132   else
2133     dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
2134
2135   return output_finalize_message (scratch_buffer);
2136 }
2137
2138 static location_t
2139 location_of (tree t)
2140 {
2141   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
2142     t = DECL_CONTEXT (t);
2143   else if (TYPE_P (t))
2144     t = TYPE_MAIN_DECL (t);
2145   else if (TREE_CODE (t) == OVERLOAD)
2146     t = OVL_FUNCTION (t);
2147   
2148   return DECL_SOURCE_LOCATION (t);
2149 }
2150
2151 /* Now the interfaces from error et al to dump_type et al. Each takes an
2152    on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_
2153    function.  */
2154
2155 static const char *
2156 decl_to_string (tree decl, int verbose)
2157 {
2158   int flags = 0;
2159
2160   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
2161       || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
2162     flags = TFF_CLASS_KEY_OR_ENUM;
2163   if (verbose)
2164     flags |= TFF_DECL_SPECIFIERS | TFF_FUNCTION_DEFAULT_ARGUMENTS;
2165   else if (TREE_CODE (decl) == FUNCTION_DECL)
2166     flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
2167   flags |= TFF_TEMPLATE_HEADER;
2168
2169   reinit_global_formatting_buffer ();
2170
2171   dump_decl (decl, flags);
2172
2173   return output_finalize_message (scratch_buffer);
2174 }
2175
2176 static const char *
2177 expr_to_string (tree decl)
2178 {
2179   reinit_global_formatting_buffer ();
2180
2181   dump_expr (decl, 0);
2182
2183   return output_finalize_message (scratch_buffer);
2184 }
2185
2186 static const char *
2187 fndecl_to_string (tree fndecl, int verbose)
2188 {
2189   int flags;
2190
2191   flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS;
2192   if (verbose)
2193     flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
2194   reinit_global_formatting_buffer ();
2195
2196   dump_decl (fndecl, flags);
2197
2198   return output_finalize_message (scratch_buffer);
2199 }
2200
2201
2202 static const char *
2203 code_to_string (enum tree_code c)
2204 {
2205   return tree_code_name [c];
2206 }
2207
2208 const char *
2209 language_to_string (enum languages c)
2210 {
2211   switch (c)
2212     {
2213     case lang_c:
2214       return "C";
2215
2216     case lang_cplusplus:
2217       return "C++";
2218
2219     case lang_java:
2220       return "Java";
2221
2222     default:
2223       abort ();
2224       return 0;
2225     }
2226 }
2227
2228 /* Return the proper printed version of a parameter to a C++ function.  */
2229
2230 static const char *
2231 parm_to_string (int p)
2232 {
2233   if (p < 0)
2234     output_add_string (scratch_buffer, "'this'");
2235   else
2236     output_decimal (scratch_buffer, p + 1);
2237
2238   return output_finalize_message (scratch_buffer);
2239 }
2240
2241 static const char *
2242 op_to_string (enum tree_code p)
2243 {
2244   tree id;
2245
2246   id = operator_name_info[(int) p].identifier;
2247   return id ? IDENTIFIER_POINTER (id) : "<unknown>";
2248 }
2249
2250 static const char *
2251 type_to_string (tree typ, int verbose)
2252 {
2253   int flags;
2254
2255   flags = 0;
2256   if (verbose)
2257     flags |= TFF_CLASS_KEY_OR_ENUM;
2258   flags |= TFF_TEMPLATE_HEADER;
2259
2260   reinit_global_formatting_buffer ();
2261
2262   dump_type (typ, flags);
2263
2264   return output_finalize_message (scratch_buffer);
2265 }
2266
2267 static const char *
2268 assop_to_string (enum tree_code p)
2269 {
2270   tree id;
2271
2272   id = assignment_operator_name_info[(int) p].identifier;
2273   return id ? IDENTIFIER_POINTER (id) : "{unknown}";
2274 }
2275
2276 static const char *
2277 args_to_string (tree p, int verbose)
2278 {
2279   int flags = 0;
2280   if (verbose)
2281     flags |= TFF_CLASS_KEY_OR_ENUM;
2282
2283   if (p == NULL_TREE)
2284     return "";
2285
2286   if (TYPE_P (TREE_VALUE (p)))
2287     return type_as_string (p, flags);
2288
2289   reinit_global_formatting_buffer ();
2290   for (; p; p = TREE_CHAIN (p))
2291     {
2292       if (TREE_VALUE (p) == null_node)
2293         print_identifier (scratch_buffer, "NULL");
2294       else
2295         dump_type (error_type (TREE_VALUE (p)), flags);
2296       if (TREE_CHAIN (p))
2297         separate_with_comma (scratch_buffer);
2298     }
2299   return output_finalize_message (scratch_buffer);
2300 }
2301
2302 static const char *
2303 cv_to_string (tree p, int v)
2304 {
2305   reinit_global_formatting_buffer ();
2306
2307   dump_qualifiers (p, v ? before : none);
2308
2309   return output_finalize_message (scratch_buffer);
2310 }
2311
2312 /* Langhook for print_error_function.  */
2313 void
2314 cxx_print_error_function (diagnostic_context *context, const char *file)
2315 {
2316   lhd_print_error_function (context, file);
2317   output_set_prefix (&context->buffer, file);
2318   maybe_print_instantiation_context (context);
2319 }
2320
2321 static void
2322 cp_diagnostic_starter (diagnostic_context *context,
2323                        diagnostic_info *diagnostic)
2324 {
2325   diagnostic_report_current_module (context);
2326   cp_print_error_function (context, diagnostic);
2327   maybe_print_instantiation_context (context);
2328   output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
2329 }
2330
2331 static void
2332 cp_diagnostic_finalizer (diagnostic_context *context,
2333                          diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
2334 {
2335   output_destroy_prefix (&context->buffer);
2336 }
2337
2338 /* Print current function onto BUFFER, in the process of reporting
2339    a diagnostic message.  Called from cp_diagnostic_starter.  */
2340 static void
2341 cp_print_error_function (diagnostic_context *context,
2342                          diagnostic_info *diagnostic)
2343 {
2344   if (diagnostic_last_function_changed (context))
2345     {
2346       const char *old_prefix = output_prefix (&context->buffer);
2347       char *new_prefix = diagnostic->location.file
2348         ? file_name_as_prefix (diagnostic->location.file)
2349         : NULL;
2350
2351       output_set_prefix (&context->buffer, new_prefix);
2352
2353       if (current_function_decl == NULL)
2354         output_add_string (&context->buffer, "At global scope:");
2355       else
2356         output_printf (&context->buffer, "In %s `%s':",
2357                        function_category (current_function_decl),
2358                        cxx_printable_name (current_function_decl, 2));
2359       output_add_newline (&context->buffer);
2360
2361       diagnostic_set_last_function (context);
2362       output_destroy_prefix (&context->buffer);
2363       context->buffer.state.prefix = old_prefix;
2364     }
2365 }
2366
2367 /* Returns a description of FUNCTION using standard terminology.  */
2368 static const char *
2369 function_category (tree fn)
2370 {
2371   if (DECL_FUNCTION_MEMBER_P (fn))
2372     {
2373       if (DECL_STATIC_FUNCTION_P (fn))
2374         return "static member function";
2375       else if (DECL_COPY_CONSTRUCTOR_P (fn))
2376         return "copy constructor";
2377       else if (DECL_CONSTRUCTOR_P (fn))
2378         return "constructor";
2379       else if (DECL_DESTRUCTOR_P (fn))
2380         return "destructor";
2381       else
2382         return "member function";
2383     }
2384   else
2385     return "function";
2386 }
2387
2388 /* Report the full context of a current template instantiation,
2389    onto BUFFER.  */
2390 static void
2391 print_instantiation_full_context (diagnostic_context *context)
2392 {
2393   tree p = current_instantiation ();
2394   location_t location = input_location;
2395   
2396   if (p)
2397     {
2398       if (current_function_decl != TINST_DECL (p)
2399           && current_function_decl != NULL_TREE)
2400         /* We can get here during the processing of some synthesized
2401            method.  Then, TINST_DECL (p) will be the function that's causing
2402            the synthesis.  */
2403         ;
2404       else
2405         {
2406           if (current_function_decl == TINST_DECL (p))
2407             /* Avoid redundancy with the the "In function" line.  */;
2408           else
2409             output_verbatim (&context->buffer,
2410                              "%s: In instantiation of `%s':\n", location.file,
2411                              decl_as_string (TINST_DECL (p),
2412                                              TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
2413
2414           location.line = TINST_LINE (p);
2415           location.file = TINST_FILE (p);
2416           p = TREE_CHAIN (p);
2417         }
2418     }
2419
2420   print_instantiation_partial_context (context, p, location);
2421 }
2422
2423 /* Same as above but less verbose.  */
2424 static void
2425 print_instantiation_partial_context (diagnostic_context *context,
2426                                      tree t, location_t loc)
2427 {
2428   for (; t; t = TREE_CHAIN (t))
2429     {
2430       output_verbatim
2431         (&context->buffer, "%s:%d:   instantiated from `%s'\n",
2432          loc.file, loc.line,
2433          decl_as_string (TINST_DECL (t),
2434                          TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
2435       loc.line = TINST_LINE (t);
2436       loc.file = TINST_FILE (t);
2437     }
2438   output_verbatim (&context->buffer, "%s:%d:   instantiated from here\n",
2439                    loc.file, loc.line);
2440 }
2441
2442 /* Called from cp_thing to print the template context for an error.  */
2443 static void
2444 maybe_print_instantiation_context (diagnostic_context *context)
2445 {
2446   if (!problematic_instantiation_changed () || current_instantiation () == 0)
2447     return;
2448
2449   record_last_problematic_instantiation ();
2450   print_instantiation_full_context (context);
2451 }
2452
2453 /* Report the bare minimum context of a template instantiation.  */
2454 void
2455 print_instantiation_context (void)
2456 {
2457   print_instantiation_partial_context
2458     (global_dc, current_instantiation (), input_location);
2459   diagnostic_flush_buffer (global_dc);
2460 }
2461 \f
2462 /* Called from output_format -- during diagnostic message processing --
2463    to handle C++ specific format specifier with the following meanings:
2464    %A   function argument-list.
2465    %C   tree code.
2466    %D   declaration.
2467    %E   expression.
2468    %F   function declaration.
2469    %L   language as used in extern "lang".
2470    %O   binary operator.
2471    %P   function parameter whose position is indicated by an integer.
2472    %Q   assignment operator.
2473    %T   type.
2474    %V   cv-qualifier.  */
2475 static bool
2476 cp_printer (output_buffer *buffer, text_info *text)
2477 {
2478   int verbose = 0;
2479   const char *result;
2480 #define next_tree    va_arg (*text->args_ptr, tree)
2481 #define next_tcode   va_arg (*text->args_ptr, enum tree_code)
2482 #define next_lang    va_arg (*text->args_ptr, enum languages)
2483 #define next_int     va_arg (*text->args_ptr, int)
2484
2485   if (*text->format_spec == '+')
2486     ++text->format_spec;
2487   if (*text->format_spec == '#')
2488     {
2489       verbose = 1;
2490       ++text->format_spec;
2491     }
2492
2493   switch (*text->format_spec)
2494     {
2495     case 'A': result = args_to_string (next_tree, verbose);     break;
2496     case 'C': result = code_to_string (next_tcode);             break;
2497     case 'D': result = decl_to_string (next_tree, verbose);     break;
2498     case 'E': result = expr_to_string (next_tree);              break;
2499     case 'F': result = fndecl_to_string (next_tree, verbose);   break;
2500     case 'L': result = language_to_string (next_lang);          break;
2501     case 'O': result = op_to_string (next_tcode);               break;
2502     case 'P': result = parm_to_string (next_int);               break;
2503     case 'Q': result = assop_to_string (next_tcode);            break;
2504     case 'T': result = type_to_string (next_tree, verbose);     break;
2505     case 'V': result = cv_to_string (next_tree, verbose);       break;
2506  
2507     default:
2508       return false;
2509     }
2510
2511   output_add_string (buffer, result);
2512   return true;
2513 #undef next_tree
2514 #undef next_tcode
2515 #undef next_lang
2516 #undef next_int
2517 }
2518
2519 static void
2520 print_non_consecutive_character (output_buffer *buffer, int c)
2521 {
2522   const char *p = output_last_position (buffer);
2523
2524   if (p != NULL && *p == c)
2525     output_add_space (buffer);
2526   output_add_character (buffer, c);
2527 }
2528
2529 /* These are temporary wrapper functions which handle the historic
2530    behavior of cp_*_at.  */
2531
2532 static tree
2533 locate_error (const char *msgid, va_list ap)
2534 {
2535   tree here = 0, t;
2536   int plus = 0;
2537   const char *f;
2538
2539   for (f = msgid; *f; f++)
2540     {
2541       plus = 0;
2542       if (*f == '%')
2543         {
2544           f++;
2545           if (*f == '+')
2546             f++, plus = 1;
2547           if (*f == '#')
2548             f++;
2549
2550           switch (*f)
2551             {
2552               /* Just ignore these possibilities.  */
2553             case '%':                                           break;
2554             case 'd':   (void) va_arg (ap, int);                break;
2555             case 's':   (void) va_arg (ap, char *);             break;
2556             case 'L':   (void) va_arg (ap, enum languages);     break;
2557             case 'C':
2558             case 'O':
2559             case 'Q':   (void) va_arg (ap, enum tree_code);     break;
2560
2561               /* These take a tree, which may be where the error is
2562                  located.  */
2563             case 'A':
2564             case 'D':
2565             case 'E':
2566             case 'F':
2567             case 'P':
2568             case 'T':
2569             case 'V':
2570               t = va_arg (ap, tree);
2571               if (!here || plus)
2572                 here = t;
2573               break;
2574
2575             default:
2576               errorcount = 0;  /* damn ICE suppression */
2577               internal_error ("unexpected letter `%c' in locate_error\n", *f);
2578             }
2579         }
2580     }
2581
2582   if (here == 0)
2583     here = va_arg (ap, tree);
2584
2585   return here;
2586 }
2587
2588
2589 void
2590 cp_error_at (const char *msgid, ...)
2591 {
2592   tree here;
2593   diagnostic_info diagnostic;
2594   va_list ap;
2595
2596   va_start (ap, msgid);
2597   here = locate_error (msgid, ap);
2598   va_end (ap);
2599
2600   va_start (ap, msgid);
2601   diagnostic_set_info (&diagnostic, msgid, &ap,
2602                        location_of (here), DK_ERROR);
2603   report_diagnostic (&diagnostic);
2604   va_end (ap);
2605 }
2606
2607 void
2608 cp_warning_at (const char *msgid, ...)
2609 {
2610   tree here;
2611   diagnostic_info diagnostic;
2612   va_list ap;
2613
2614   va_start (ap, msgid);
2615   here = locate_error (msgid, ap);
2616   va_end (ap);
2617
2618   va_start (ap, msgid);
2619   diagnostic_set_info (&diagnostic, msgid, &ap,
2620                        location_of (here), DK_WARNING);
2621   report_diagnostic (&diagnostic);
2622   va_end (ap);
2623 }
2624
2625 void
2626 cp_pedwarn_at (const char *msgid, ...)
2627 {
2628   tree here;
2629   diagnostic_info diagnostic;
2630   va_list ap;
2631
2632   va_start (ap, msgid);
2633   here = locate_error (msgid, ap);
2634   va_end (ap);
2635
2636   va_start (ap, msgid);
2637   diagnostic_set_info (&diagnostic, msgid, &ap,
2638                        location_of (here), pedantic_error_kind());
2639   report_diagnostic (&diagnostic);
2640   va_end (ap);
2641 }