OSDN Git Service

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