OSDN Git Service

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