OSDN Git Service

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