OSDN Git Service

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