OSDN Git Service

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