OSDN Git Service

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