OSDN Git Service

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