OSDN Git Service

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