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