OSDN Git Service

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