OSDN Git Service

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