OSDN Git Service

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