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