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