OSDN Git Service

* decl2.c (arg_assoc_type): Handle VECTOR_TYPE.
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
1 /* Call-backs for C++ error reporting.
2    This code is non-reentrant.
3    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
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 "obstack.h"
27 #include "toplev.h"
28 #include "diagnostic.h"
29
30 enum pad { none, before, after };
31
32 /* These constants can used as bit flags in the process of tree formatting.
33
34    TFF_PLAIN_IDENTIFER: unqualified part of a name.
35    TFF_NAMESPACE_SCOPE: the complete qualified-id form of a name.
36    TFF_CLASS_SCOPE: if possible, include the class-name part of a
37         qualified-id.  This flag may be implied in some circumstances by
38         TFF_NAMESPACE_SCOPE.
39    TFF_SCOPE: the combinaison of the two above.
40    TFF_CHASE_TYPDEF: print the original type-id instead of the typedef-name.
41    TFF_DECL_SPECIFIERS: print decl-specifiers.
42    TFF_CLASS_KEY_OR_ENUM: precede a class-type name (resp. enum name) with
43        a class-key (resp. `enum').
44    TFF_RETURN_TYPE: include function return type.
45    TFF_FUNCTION_DEFAULT_ARGUMENTS: include function default parameter values.
46    TFF_EXCEPTION_SPECIFICATION: show function exception specification.
47    TFF_TEMPLATE_HEADER: show the template<...> hearder in a
48        template-declaration.
49    TFF_TEMPLATE_DEFAULT_ARGUMENTS: show template paramter default values.  */
50
51 #define TFF_PLAIN_IDENTIFIER               (0)
52 #define TFF_NAMESPACE_SCOPE                (1)
53 #define TFF_CLASS_SCOPE                    (1 << 1)
54 #define TFF_CHASE_NAMESPACE_ALIAS          (1 << 2)
55 #define TFF_CHASE_TYPEDEF                  (1 << 3)
56 #define TFF_DECL_SPECIFIERS                (1 << 4)
57 #define TFF_CLASS_KEY_OR_ENUM              (1 << 5)
58 #define TFF_RETURN_TYPE                    (1 << 6)
59 #define TFF_FUNCTION_DEFAULT_ARGUMENTS     (1 << 7)
60 #define TFF_EXCEPTION_SPECIFICATION        (1 << 8)
61 #define TFF_TEMPLATE_HEADER                (1 << 9)
62 #define TFF_TEMPLATE_DEFAULT_ARGUMENTS     (1 << 10)
63 #define TFF_SCOPE (TFF_NAMESPACE_SCOPE | TFF_CLASS_SCOPE)
64
65 /* This data structure bundles altogether, all the information necessary
66    for pretty-printing a C++ source-level entity represented by a tree.  */
67 typedef struct
68 {
69   tree decl;
70   int flags;
71   enum pad pad;
72 } tree_formatting_info, *tfi_t;
73
74 #define tree_being_formatted(TFI) (TFI)->decl
75 #define tree_formatting_flags(TFI) (TFI)->flags
76 #define put_whitespace(TFI) (TFI)->pad
77
78 #define sorry_for_unsupported_tree(T)                                      \
79    sorry ("`%s' not supported by %s", tree_code_name[(int) TREE_CODE (T)], \
80              __FUNCTION__)
81
82 #define print_scope_operator(BUFFER)  output_add_string (BUFFER, "::")
83 #define print_left_paren(BUFFER)      output_add_character (BUFFER, '(')
84 #define print_right_paren(BUFFER)     output_add_character (BUFFER, ')')
85 #define print_left_bracket(BUFFER)    output_add_character (BUFFER, '[')
86 #define print_right_bracket(BUFFER)   output_add_character (BUFFER, ']')
87 #define print_template_argument_list_start(BUFFER) \
88    print_non_consecutive_character (BUFFER, '<')
89 #define print_template_argument_list_end(BUFFER)  \
90    print_non_consecutive_character (BUFFER, '>')
91 #define print_whitespace(BUFFER, TFI)        \
92    do {                                      \
93      output_add_space (BUFFER);              \
94      put_whitespace (TFI) = none;            \
95    } while (0)
96 #define print_tree_identifier(BUFFER, TID) \
97    output_add_string (BUFFER, IDENTIFIER_POINTER (TID))
98 #define print_identifier(BUFFER, ID) output_add_string (BUFFER, ID)
99 #define separate_with_comma(BUFFER) output_add_string (BUFFER, ", ")
100
101 /* The global buffer where we dump everything.  It is there only for
102    transitional purpose.  It is expected, in the near future, to be
103    completely removed.  */
104 static output_buffer scratch_buffer_rec;
105 static output_buffer *scratch_buffer = &scratch_buffer_rec;
106
107 # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
108
109 #define reinit_global_formatting_buffer() \
110    output_clear_message_text (scratch_buffer)
111
112 static const char *args_to_string               PARAMS ((tree, int));
113 static const char *assop_to_string              PARAMS ((enum tree_code, int));
114 static const char *code_to_string               PARAMS ((enum tree_code, int));
115 static const char *cv_to_string                 PARAMS ((tree, int));
116 static const char *decl_to_string               PARAMS ((tree, int));
117 static const char *expr_to_string               PARAMS ((tree, int));
118 static const char *fndecl_to_string             PARAMS ((tree, int));
119 static const char *op_to_string                 PARAMS ((enum tree_code, int));
120 static const char *parm_to_string               PARAMS ((int, int));
121 static const char *type_to_string               PARAMS ((tree, int));
122
123 static void dump_type PARAMS ((tree, enum tree_string_flags));
124 static void dump_typename PARAMS ((tree, enum tree_string_flags));
125 static void dump_simple_decl PARAMS ((tree, tree, enum tree_string_flags));
126 static void dump_decl PARAMS ((tree, enum tree_string_flags));
127 static void dump_template_decl PARAMS ((tree, enum tree_string_flags));
128 static void dump_function_decl PARAMS ((tree, enum tree_string_flags));
129 static void dump_expr PARAMS ((tree, enum tree_string_flags));
130 static void dump_unary_op PARAMS ((const char *, tree, enum tree_string_flags));
131 static void dump_binary_op PARAMS ((const char *, tree, enum tree_string_flags));
132 static void dump_aggr_type PARAMS ((tree, enum tree_string_flags));
133 static enum pad dump_type_prefix PARAMS ((tree, enum tree_string_flags));
134 static void dump_type_suffix PARAMS ((tree, enum tree_string_flags));
135 static void dump_function_name PARAMS ((tree, enum tree_string_flags));
136 static void dump_expr_list PARAMS ((tree, enum tree_string_flags));
137 static void dump_global_iord PARAMS ((tree));
138 static enum pad dump_qualifiers PARAMS ((tree, enum pad));
139 static void dump_char PARAMS ((int));
140 static void dump_parameters PARAMS ((tree, enum tree_string_flags));
141 static void dump_exception_spec PARAMS ((tree, enum tree_string_flags));
142 static const char *class_key_or_enum PARAMS ((tree));
143 static tree ident_fndecl PARAMS ((tree));
144 static void dump_template_argument PARAMS ((tree, enum tree_string_flags));
145 static void dump_template_argument_list PARAMS ((tree, enum tree_string_flags));
146 static void dump_template_parameter PARAMS ((tree, enum tree_string_flags));
147 static void dump_template_bindings PARAMS ((tree, tree));
148 static void dump_scope PARAMS ((tree, enum tree_string_flags));
149 static void dump_template_parms PARAMS ((tree, int, enum tree_string_flags));
150
151 static const char *function_category PARAMS ((tree));
152 static void lang_print_error_function PARAMS ((const char *));
153 static void maybe_print_instantiation_context PARAMS ((output_buffer *));
154 static void print_instantiation_full_context PARAMS ((output_buffer *));
155 static void print_instantiation_partial_context PARAMS ((output_buffer *, tree,
156                                                          const char *, int));
157 static void cp_diagnostic_starter PARAMS ((output_buffer *,
158                                            diagnostic_context *));
159 static void cp_diagnostic_finalizer PARAMS ((output_buffer *,
160                                              diagnostic_context *));
161 static void cp_print_error_function PARAMS ((output_buffer *,
162                                              diagnostic_context *));
163
164 static int cp_tree_printer PARAMS ((output_buffer *));
165 static void print_function_argument_list PARAMS ((output_buffer *, tfi_t));
166 static void print_declaration PARAMS ((output_buffer *, tfi_t));
167 static void print_expression PARAMS ((output_buffer *, tfi_t));
168 static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT));
169 static void print_function_declaration PARAMS ((output_buffer *, tfi_t));
170 static void print_function_parameter PARAMS ((output_buffer *, int));
171 static void print_type_id PARAMS ((output_buffer *, tfi_t));
172 static void print_cv_qualifier_seq PARAMS ((output_buffer *, tfi_t));
173 static void print_type_specifier_seq PARAMS ((output_buffer *, tfi_t));
174 static void print_simple_type_specifier PARAMS ((output_buffer *, tfi_t));
175 static void print_elaborated_type_specifier PARAMS ((output_buffer *, tfi_t));
176 static void print_rest_of_abstract_declarator PARAMS ((output_buffer *,
177                                                        tfi_t));
178 static void print_parameter_declaration_clause PARAMS ((output_buffer *,
179                                                         tfi_t));
180 static void print_exception_specification PARAMS ((output_buffer *, tfi_t));
181 static void print_nested_name_specifier PARAMS ((output_buffer *, tfi_t));
182 static void print_template_id PARAMS ((output_buffer *, tfi_t));
183 static tree typedef_original_name PARAMS ((tree));
184 static void print_non_consecutive_character PARAMS ((output_buffer *, int));
185
186 #define A args_to_string
187 #define C code_to_string
188 #define D decl_to_string
189 #define E expr_to_string
190 #define F fndecl_to_string
191 #define L language_to_string
192 #define O op_to_string
193 #define P parm_to_string
194 #define Q assop_to_string
195 #define T type_to_string
196 #define V cv_to_string
197
198 #define o (cp_printer *) 0
199 cp_printer * cp_printers[256] =
200 {
201 /*0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
202   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */
203   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
204   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
205   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
206   o, A, o, C, D, E, F, o, o, o, o, o, L, o, o, O, /* 0x40 */
207   P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
208   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
209   o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
210 };
211 #undef C
212 #undef D
213 #undef E
214 #undef F
215 #undef L
216 #undef O
217 #undef P
218 #undef Q
219 #undef T
220 #undef V
221 #undef o
222
223 void
224 init_error ()
225 {
226   init_output_buffer (scratch_buffer, /* prefix */NULL, /* line-width */0);
227   
228   print_error_function = lang_print_error_function;
229   lang_diagnostic_starter = cp_diagnostic_starter;
230   lang_diagnostic_finalizer = cp_diagnostic_finalizer;
231
232   lang_printer = cp_tree_printer;
233 }
234
235 /* Dump a scope, if deemed necessary.  */
236
237 static void
238 dump_scope (scope, flags)
239      tree scope;
240      enum tree_string_flags flags;
241 {
242   if (scope == NULL_TREE)
243     return;
244
245   if (TREE_CODE (scope) == NAMESPACE_DECL)
246     {
247       if (scope != global_namespace)
248         {
249           dump_decl (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
250                              | TS_FUNC_NORETURN | TS_DECL_TYPE);
251           print_scope_operator (scratch_buffer);
252         }
253       else if (flags & TS_PEDANTIC_NAME)
254         print_scope_operator (scratch_buffer);
255     }
256   else if (AGGREGATE_TYPE_P (scope))
257     {
258       dump_type (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
259                            | TS_FUNC_NORETURN | TS_DECL_TYPE);
260       print_scope_operator (scratch_buffer);
261     }
262   else if ((flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE))
263             && TREE_CODE (scope) == FUNCTION_DECL)
264     {
265       dump_function_decl (scope, (flags & (TS_PEDANTIC_NAME | TS_FUNC_SCOPE | TS_CHASE_TYPEDEFS))
266                            | TS_FUNC_NORETURN | TS_DECL_TYPE);
267       print_scope_operator (scratch_buffer);
268     }
269 }
270
271 /* Dump type qualifiers, providing padding as requested. Return an
272    indication of whether we dumped something.  */
273
274 static enum pad
275 dump_qualifiers (t, p)
276      tree t;
277      enum pad p;
278 {
279   static const int masks[] =
280     {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
281   static const char *const names[] =
282     {"const", "volatile", "__restrict"};
283   int ix;
284   int quals = TYPE_QUALS (t);
285   int do_after = p == after;
286
287   if (quals)
288     {
289       for (ix = 0; ix != 3; ix++)
290         if (masks[ix] & quals)
291           {
292             if (p == before)
293               output_add_space (scratch_buffer);
294             p = before;
295             print_identifier (scratch_buffer, names[ix]);
296           }
297       if (do_after)
298         output_add_space (scratch_buffer);
299     }
300   else
301     p = none;
302   return p;
303 }
304
305 /* This must be large enough to hold any printed integer or floating-point
306    value.  */
307 static char digit_buffer[128];
308
309 /* Dump the template ARGument under control of FLAGS.  */
310
311 static void
312 dump_template_argument (arg, flags)
313      tree arg;
314      enum tree_string_flags flags;
315 {
316   if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
317     dump_type (arg, flags & ~TS_AGGR_TAGS);
318   else
319     dump_expr (arg, (flags | TS_EXPR_PARENS) & ~TS_AGGR_TAGS);
320 }
321
322 /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
323    of FLAGS.  */
324
325 static void
326 dump_template_argument_list (args, flags)
327      tree args;
328      enum tree_string_flags flags;
329 {
330   int n = TREE_VEC_LENGTH (args);
331   int need_comma = 0;
332   int i;
333
334   for (i = 0; i< n; ++i)
335     {
336       if (need_comma)
337         separate_with_comma (scratch_buffer);
338       dump_template_argument (TREE_VEC_ELT (args, i), flags);
339       need_comma = 1;
340     }
341 }
342
343 /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS.  */
344
345 static void
346 dump_template_parameter (parm, flags)
347      tree parm;
348      enum tree_string_flags flags;
349 {
350   tree p = TREE_VALUE (parm);
351   tree a = TREE_PURPOSE (parm);
352
353   if (TREE_CODE (p) == TYPE_DECL)
354     {
355       if (flags & TS_DECL_TYPE)
356         {
357           print_identifier (scratch_buffer, "class");
358           if (DECL_NAME (p))
359             {
360               output_add_space (scratch_buffer);
361               print_tree_identifier (scratch_buffer, DECL_NAME (p));
362             }
363         }
364       else if (DECL_NAME (p))
365         print_tree_identifier (scratch_buffer, DECL_NAME (p));
366       else
367         print_identifier (scratch_buffer, "{template default argument error}");
368     }
369   else
370     dump_decl (p, flags | TS_DECL_TYPE);
371
372   if ((flags & TS_PARM_DEFAULTS) && a != NULL_TREE)
373     {
374       output_add_string (scratch_buffer, " = ");
375       if (TREE_CODE (a) == TYPE_DECL || TREE_CODE (a) == TEMPLATE_DECL)
376         dump_type (a, flags & ~TS_CHASE_TYPEDEFS);
377       else
378         dump_expr (a, flags | TS_EXPR_PARENS);
379     }
380 }
381
382 /* Dump, under control of FLAGS, a template-parameter-list binding.
383    PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
384    TREE_VEC.  */
385
386 static void
387 dump_template_bindings (parms, args)
388      tree parms, args;
389 {
390   int need_comma = 0;
391
392   while (parms)
393     {
394       tree p = TREE_VALUE (parms);
395       int lvl = TMPL_PARMS_DEPTH (parms);
396       int arg_idx = 0;
397       int i;
398
399       for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
400         {
401           tree arg = NULL_TREE;
402
403           /* Don't crash if we had an invalid argument list.  */
404           if (TMPL_ARGS_DEPTH (args) >= lvl)
405             {
406               tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
407               if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
408                 arg = TREE_VEC_ELT (lvl_args, arg_idx);
409             }
410
411           if (need_comma)
412             separate_with_comma (scratch_buffer);
413           dump_template_parameter (TREE_VEC_ELT (p, i), TS_PLAIN);
414           output_add_string (scratch_buffer, " = ");
415           if (arg)
416             dump_template_argument (arg, TS_PLAIN);
417           else
418             print_identifier (scratch_buffer, "<missing>");
419
420           ++arg_idx;
421           need_comma = 1;
422         }
423
424       parms = TREE_CHAIN (parms);
425     }
426 }
427
428 /* Dump into the obstack a human-readable equivalent of TYPE.  FLAGS
429    controls the format.  */
430
431 static void
432 dump_type (t, flags)
433      tree t;
434      enum tree_string_flags flags;
435 {
436   if (t == NULL_TREE)
437     return;
438
439   if (TYPE_PTRMEMFUNC_P (t))
440     goto offset_type;
441
442   switch (TREE_CODE (t))
443     {
444     case UNKNOWN_TYPE:
445       print_identifier (scratch_buffer, "<unknown type>");
446       break;
447
448     case TREE_LIST:
449       /* A list of function parms.  */
450       dump_parameters (t, flags);
451       break;
452
453     case IDENTIFIER_NODE:
454       print_tree_identifier (scratch_buffer, t);
455       break;
456
457     case TREE_VEC:
458       dump_type (BINFO_TYPE (t), flags);
459       break;
460
461     case RECORD_TYPE:
462     case UNION_TYPE:
463     case ENUMERAL_TYPE:
464       dump_aggr_type (t, flags);
465       break;
466
467     case TYPE_DECL:
468       if (flags & TS_CHASE_TYPEDEFS)
469         {
470           dump_type (DECL_ORIGINAL_TYPE (t)
471                      ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
472           break;
473         }
474       /* else fallthrough */
475
476     case TEMPLATE_DECL:
477     case NAMESPACE_DECL:
478       dump_decl (t, flags & ~TS_DECL_TYPE);
479       break;
480
481     case COMPLEX_TYPE:
482       output_add_string (scratch_buffer, "__complex__ ");
483       dump_type (TREE_TYPE (t), flags);
484       break;
485
486     case INTEGER_TYPE:
487       if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
488         output_add_string (scratch_buffer, "unsigned ");
489       else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
490         output_add_string (scratch_buffer, "signed ");
491
492       /* fall through.  */
493     case REAL_TYPE:
494     case VOID_TYPE:
495     case BOOLEAN_TYPE:
496       {
497         tree type;
498         dump_qualifiers (t, after);
499         type = flags & TS_CHASE_TYPEDEFS ? TYPE_MAIN_VARIANT (t) : t;
500         if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
501           print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (type));
502         else
503           /* Types like intQI_type_node and friends have no names.
504              These don't come up in user error messages, but it's nice
505              to be able to print them from the debugger.  */
506           print_identifier (scratch_buffer, "<anonymous>");
507       }
508       break;
509
510     case TEMPLATE_TEMPLATE_PARM:
511       /* For parameters inside template signature. */
512       if (TYPE_IDENTIFIER (t))
513         print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
514       else
515         print_identifier
516           (scratch_buffer, "<anonymous template template parameter>");
517       break;
518
519     case BOUND_TEMPLATE_TEMPLATE_PARM:
520       {
521         tree args = TYPE_TI_ARGS (t);
522         print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
523         print_template_argument_list_start (scratch_buffer);
524         dump_template_argument_list (args, flags);
525         print_template_argument_list_end (scratch_buffer);
526       }
527       break;
528
529     case TEMPLATE_TYPE_PARM:
530       dump_qualifiers (t, after);
531       if (TYPE_IDENTIFIER (t))
532         print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
533       else
534         print_identifier
535           (scratch_buffer, "<anonymous template type parameter>");
536       break;
537
538       /* This is not always necessary for pointers and such, but doing this
539          reduces code size.  */
540     case ARRAY_TYPE:
541     case POINTER_TYPE:
542     case VECTOR_TYPE:
543     case REFERENCE_TYPE:
544     case OFFSET_TYPE:
545     offset_type:
546     case FUNCTION_TYPE:
547     case METHOD_TYPE:
548     {
549       dump_type_prefix (t, flags);
550       dump_type_suffix (t, flags);
551       break;
552     }
553     case TYPENAME_TYPE:
554       output_add_string (scratch_buffer, "typename ");
555       dump_typename (t, flags);
556       break;
557
558     case TYPEOF_TYPE:
559       output_add_string (scratch_buffer, "__typeof (");
560       dump_expr (TYPE_FIELDS (t), flags & ~TS_EXPR_PARENS);
561       print_left_paren (scratch_buffer);
562       break;
563
564     default:
565       sorry_for_unsupported_tree (t);
566       /* Fall through to error. */
567
568     case ERROR_MARK:
569       print_identifier (scratch_buffer, "<type error>");
570       break;
571     }
572 }
573
574 /* Dump a TYPENAME_TYPE. We need to notice when the context is itself
575    a TYPENAME_TYPE.  */
576
577 static void
578 dump_typename (t, flags)
579      tree t;
580      enum tree_string_flags flags;
581 {
582   tree ctx = TYPE_CONTEXT (t);
583
584   if (TREE_CODE (ctx) == TYPENAME_TYPE)
585     dump_typename (ctx, flags);
586   else
587     dump_type (ctx, flags & ~TS_AGGR_TAGS);
588   print_scope_operator (scratch_buffer);
589   dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
590 }
591
592 /* Return the name of the supplied aggregate, or enumeral type.  */
593
594 static const char *
595 class_key_or_enum (t)
596      tree t;
597 {
598   if (TREE_CODE (t) == ENUMERAL_TYPE)
599     return "enum";
600   else if (TREE_CODE (t) == UNION_TYPE)
601     return "union";
602   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
603     return "class";
604   else
605     return "struct";
606 }
607
608 /* Print out a class declaration T under the control of FLAGS,
609    in the form `class foo'.  */
610
611 static void
612 dump_aggr_type (t, flags)
613      tree t;
614      enum tree_string_flags flags;
615 {
616   tree name;
617   const char *variety = class_key_or_enum (t);
618   int typdef = 0;
619   int tmplate = 0;
620
621   dump_qualifiers (t, after);
622
623   if (flags & TS_AGGR_TAGS)
624     {
625       print_identifier (scratch_buffer, variety);
626       output_add_space (scratch_buffer);
627     }
628
629   if (flags & TS_CHASE_TYPEDEFS)
630     t = TYPE_MAIN_VARIANT (t);
631
632   name = TYPE_NAME (t);
633
634   if (name)
635     {
636       typdef = !DECL_ARTIFICIAL (name);
637       tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
638                 && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
639                 && (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
640                     || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
641                     || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
642                     || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
643       dump_scope (CP_DECL_CONTEXT (name), flags | TS_FUNC_SCOPE);
644       if (tmplate)
645         {
646           /* Because the template names are mangled, we have to locate
647              the most general template, and use that name.  */
648           tree tpl = CLASSTYPE_TI_TEMPLATE (t);
649
650           while (DECL_TEMPLATE_INFO (tpl))
651             tpl = DECL_TI_TEMPLATE (tpl);
652           name = tpl;
653         }
654       name = DECL_NAME (name);
655     }
656
657   if (name == 0 || ANON_AGGRNAME_P (name))
658     {
659       if (flags & TS_AGGR_TAGS)
660         print_identifier (scratch_buffer, "<anonymous>");
661       else
662         output_printf (scratch_buffer, "<anonymous %s>", variety);
663     }
664   else
665     print_tree_identifier (scratch_buffer, name);
666   if (tmplate)
667     dump_template_parms (TYPE_TEMPLATE_INFO (t),
668                          !CLASSTYPE_USE_TEMPLATE (t),
669                          flags & ~TS_TEMPLATE_PREFIX);
670 }
671
672 /* Dump into the obstack the initial part of the output for a given type.
673    This is necessary when dealing with things like functions returning
674    functions.  Examples:
675
676    return type of `int (* fee ())()': pointer -> function -> int.  Both
677    pointer (and reference and offset) and function (and member) types must
678    deal with prefix and suffix.
679
680    Arrays must also do this for DECL nodes, like int a[], and for things like
681    int *[]&.
682
683    Return indicates how you should pad an object name after this. I.e. you
684    want to pad non-*, non-& cores, but not pad * or & types.  */
685
686 static enum pad
687 dump_type_prefix (t, flags)
688      tree t;
689      enum tree_string_flags flags;
690 {
691   enum pad padding = before;
692
693   if (TYPE_PTRMEMFUNC_P (t))
694     {
695       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
696       goto offset_type;
697     }
698
699   switch (TREE_CODE (t))
700     {
701     case VECTOR_TYPE:
702       padding = dump_type_prefix (TREE_TYPE (t), flags);
703       if (padding != none)
704         output_add_space (scratch_buffer);
705       output_add_string (scratch_buffer, "vector");
706       dump_qualifiers (t, before);
707       padding = before;
708       break;
709
710     case POINTER_TYPE:
711     case REFERENCE_TYPE:
712       {
713         tree sub = TREE_TYPE (t);
714
715         padding = dump_type_prefix (sub, flags);
716         /* A tree for a member pointer looks like pointer to offset,
717            so let the OFFSET_TYPE case handle it.  */
718         if (!TYPE_PTRMEM_P (t))
719           {
720             if (padding != none)
721               output_add_space (scratch_buffer);
722             if (TREE_CODE (sub) == ARRAY_TYPE)
723               print_left_paren (scratch_buffer);
724             output_add_character
725               (scratch_buffer, "&*"[TREE_CODE (t) == POINTER_TYPE]);
726             padding = dump_qualifiers (t, none);
727           }
728       }
729       break;
730
731     case OFFSET_TYPE:
732     offset_type:
733       padding = dump_type_prefix (TREE_TYPE (t), flags);
734       if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
735         {
736           if (padding != none)
737             output_add_space (scratch_buffer);
738           dump_type (TYPE_OFFSET_BASETYPE (t), flags);
739           print_scope_operator (scratch_buffer);
740         }
741       output_add_character (scratch_buffer, '*');
742       padding = dump_qualifiers (t, none);
743       break;
744
745       /* Can only be reached through function pointer -- this would not be
746          correct if FUNCTION_DECLs used it.  */
747     case FUNCTION_TYPE:
748       padding = dump_type_prefix (TREE_TYPE (t), flags);
749       if (padding != none)
750         output_add_space (scratch_buffer);
751       print_left_paren (scratch_buffer);
752       padding = none;
753       break;
754
755     case METHOD_TYPE:
756       padding = dump_type_prefix (TREE_TYPE (t), flags);
757       if (padding != none)
758         output_add_space (scratch_buffer);
759       print_left_paren (scratch_buffer);
760       padding = none;
761       dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
762       print_scope_operator (scratch_buffer);
763       break;
764
765     case ARRAY_TYPE:
766       padding = dump_type_prefix (TREE_TYPE (t), flags);
767       break;
768
769     case ENUMERAL_TYPE:
770     case IDENTIFIER_NODE:
771     case INTEGER_TYPE:
772     case BOOLEAN_TYPE:
773     case REAL_TYPE:
774     case RECORD_TYPE:
775     case TEMPLATE_TYPE_PARM:
776     case TEMPLATE_TEMPLATE_PARM:
777     case BOUND_TEMPLATE_TEMPLATE_PARM:
778     case TREE_LIST:
779     case TYPE_DECL:
780     case TREE_VEC:
781     case UNION_TYPE:
782     case UNKNOWN_TYPE:
783     case VOID_TYPE:
784     case TYPENAME_TYPE:
785     case COMPLEX_TYPE:
786       dump_type (t, flags);
787       padding = before;
788       break;
789
790     default:
791       sorry_for_unsupported_tree (t);
792       /* fall through.  */
793     case ERROR_MARK:
794       print_identifier (scratch_buffer, "<typeprefixerror>");
795       break;
796     }
797   return padding;
798 }
799
800 /* Dump the suffix of type T, under control of FLAGS.  This is the part
801    which appears after the identifier (or function parms).  */
802
803 static void
804 dump_type_suffix (t, flags)
805      tree t;
806      enum tree_string_flags flags;
807 {
808   if (TYPE_PTRMEMFUNC_P (t))
809     t = TYPE_PTRMEMFUNC_FN_TYPE (t);
810
811   switch (TREE_CODE (t))
812     {
813     case POINTER_TYPE:
814     case REFERENCE_TYPE:
815     case OFFSET_TYPE:
816     case VECTOR_TYPE:
817       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
818         print_right_paren (scratch_buffer);
819       dump_type_suffix (TREE_TYPE (t), flags);
820       break;
821
822       /* Can only be reached through function pointer */
823     case FUNCTION_TYPE:
824     case METHOD_TYPE:
825       {
826         tree arg;
827         print_right_paren (scratch_buffer);
828         arg = TYPE_ARG_TYPES (t);
829         if (TREE_CODE (t) == METHOD_TYPE)
830           arg = TREE_CHAIN (arg);
831
832         /* Function pointers don't have default args.  Not in standard C++,
833            anyway; they may in g++, but we'll just pretend otherwise.  */
834         dump_parameters (arg, flags & ~TS_PARM_DEFAULTS);
835
836         if (TREE_CODE (t) == METHOD_TYPE)
837           dump_qualifiers
838             (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
839         dump_type_suffix (TREE_TYPE (t), flags);
840         dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
841         break;
842       }
843
844     case ARRAY_TYPE:
845       print_left_bracket (scratch_buffer);
846       if (TYPE_DOMAIN (t))
847         {
848           if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0))
849             print_integer
850               (scratch_buffer,
851                tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1);
852           else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
853             dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0),
854                        flags & ~TS_EXPR_PARENS);
855           else
856             dump_expr (fold (cp_build_binary_op
857                              (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
858                               integer_one_node)),
859                        flags & ~TS_EXPR_PARENS);
860         }
861       print_right_bracket (scratch_buffer);
862       dump_type_suffix (TREE_TYPE (t), flags);
863       break;
864
865     case ENUMERAL_TYPE:
866     case IDENTIFIER_NODE:
867     case INTEGER_TYPE:
868     case BOOLEAN_TYPE:
869     case REAL_TYPE:
870     case RECORD_TYPE:
871     case TEMPLATE_TYPE_PARM:
872     case TEMPLATE_TEMPLATE_PARM:
873     case BOUND_TEMPLATE_TEMPLATE_PARM:
874     case TREE_LIST:
875     case TYPE_DECL:
876     case TREE_VEC:
877     case UNION_TYPE:
878     case UNKNOWN_TYPE:
879     case VOID_TYPE:
880     case TYPENAME_TYPE:
881     case COMPLEX_TYPE:
882       break;
883
884     default:
885       sorry_for_unsupported_tree (t);
886     case ERROR_MARK:
887       /* Don't mark it here, we should have already done in
888          dump_type_prefix.  */
889       break;
890     }
891 }
892
893 /* Return a function declaration which corresponds to the IDENTIFIER_NODE
894    argument.  */
895
896 static tree
897 ident_fndecl (t)
898      tree t;
899 {
900   tree n = lookup_name (t, 0);
901
902   if (n == NULL_TREE)
903     return NULL_TREE;
904
905   if (TREE_CODE (n) == FUNCTION_DECL)
906     return n;
907   else if (TREE_CODE (n) == TREE_LIST
908            && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL)
909     return TREE_VALUE (n);
910
911   my_friendly_abort (66);
912   return NULL_TREE;
913 }
914
915 #ifndef NO_DOLLAR_IN_LABEL
916 #  define GLOBAL_THING "_GLOBAL_$"
917 #else
918 #  ifndef NO_DOT_IN_LABEL
919 #    define GLOBAL_THING "_GLOBAL_."
920 #  else
921 #    define GLOBAL_THING "_GLOBAL__"
922 #  endif
923 #endif
924
925 #define GLOBAL_IORD_P(NODE) \
926   ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
927
928 static void
929 dump_global_iord (t)
930      tree t;
931 {
932   const char *name = IDENTIFIER_POINTER (t);
933   const char *p = NULL;
934
935   if (name [sizeof (GLOBAL_THING) - 1] == 'I')
936     p = "initializers";
937   else if (name [sizeof (GLOBAL_THING) - 1] == 'D')
938     p = "destructors";
939   else
940     my_friendly_abort (352);
941
942   output_printf (scratch_buffer, "(static %s for %s)", p, input_filename);
943 }
944
945 static void
946 dump_simple_decl (t, type, flags)
947      tree t;
948      tree type;
949      enum tree_string_flags flags;
950 {
951   if (flags & TS_DECL_TYPE)
952     {
953       if (dump_type_prefix (type, flags) != none)
954         output_add_space (scratch_buffer);
955     }
956   if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
957     dump_scope (CP_DECL_CONTEXT (t), flags);
958   if (DECL_NAME (t))
959     dump_decl (DECL_NAME (t), flags);
960   else
961     print_identifier (scratch_buffer, "<anonymous>");
962   if (flags & TS_DECL_TYPE)
963     dump_type_suffix (type, flags);
964 }
965
966 /* Dump a human readable string for the decl T under control of FLAGS.  */
967
968 static void
969 dump_decl (t, flags)
970      tree t;
971      enum tree_string_flags flags;
972 {
973   if (t == NULL_TREE)
974     return;
975
976   switch (TREE_CODE (t))
977     {
978     case TYPE_DECL:
979       {
980         /* Don't say 'typedef class A' */
981         if (DECL_ARTIFICIAL (t))
982           {
983             if ((flags & TS_DECL_TYPE)
984                 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
985               /* Say `class T' not just `T'. */
986               output_add_string (scratch_buffer, "class ");
987
988             dump_type (TREE_TYPE (t), flags);
989             break;
990           }
991       }
992       if (flags & TS_DECORATE)
993         output_add_string (scratch_buffer, "typedef ");
994       dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
995                         ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
996                         flags);
997       break;
998
999     case VAR_DECL:
1000       if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
1001         {
1002           output_add_string (scratch_buffer, "vtable for ");
1003           if (TYPE_P (DECL_CONTEXT (t)))
1004             dump_type (DECL_CONTEXT (t), flags);
1005           else
1006             /* This case can arise with -fno-vtable-thunks.  See
1007                expand_upcast_fixups.  It's not clear what to print
1008                here.  */
1009             print_identifier (scratch_buffer, "<unknown type>");
1010           break;
1011         }
1012       /* else fall through */
1013     case FIELD_DECL:
1014     case PARM_DECL:
1015       dump_simple_decl (t, TREE_TYPE (t), flags);
1016       break;
1017
1018     case RESULT_DECL:
1019       output_add_string (scratch_buffer, "<return value> ");
1020       dump_simple_decl (t, TREE_TYPE (t), flags);
1021       break;
1022
1023     case NAMESPACE_DECL:
1024       dump_scope (CP_DECL_CONTEXT (t), flags);
1025       if (DECL_NAME (t) == anonymous_namespace_name)
1026         print_identifier (scratch_buffer, "<unnamed>");
1027       else
1028         print_tree_identifier (scratch_buffer, DECL_NAME (t));
1029       break;
1030
1031     case SCOPE_REF:
1032       dump_decl (TREE_OPERAND (t, 0), flags & ~TS_DECL_TYPE);
1033       print_scope_operator (scratch_buffer); 
1034       dump_decl (TREE_OPERAND (t, 1), flags);
1035       break;
1036
1037     case ARRAY_REF:
1038       dump_decl (TREE_OPERAND (t, 0), flags);
1039       print_left_bracket (scratch_buffer);
1040       dump_decl (TREE_OPERAND (t, 1), flags);
1041       print_right_bracket (scratch_buffer);
1042       break;
1043
1044       /* So that we can do dump_decl on an aggr type.  */
1045     case RECORD_TYPE:
1046     case UNION_TYPE:
1047     case ENUMERAL_TYPE:
1048       dump_type (t, flags);
1049       break;
1050
1051     case TYPE_EXPR:
1052       my_friendly_abort (69);
1053       break;
1054
1055       /* These special cases are duplicated here so that other functions
1056          can feed identifiers to cp_error and get them demangled properly.  */
1057     case IDENTIFIER_NODE:
1058       { tree f;
1059         if (DESTRUCTOR_NAME_P (t)
1060             && (f = ident_fndecl (t))
1061             && DECL_LANGUAGE (f) == lang_cplusplus)
1062           {
1063             output_add_character (scratch_buffer, '~');
1064             dump_decl (DECL_NAME (f), flags);
1065           }
1066         else if (IDENTIFIER_TYPENAME_P (t))
1067           {
1068             output_add_string (scratch_buffer, "operator ");
1069             /* Not exactly IDENTIFIER_TYPE_VALUE.  */
1070             dump_type (TREE_TYPE (t), flags);
1071             break;
1072           }
1073         else
1074           print_tree_identifier (scratch_buffer, t);
1075       }
1076       break;
1077
1078     case OVERLOAD:
1079       t = OVL_CURRENT (t);
1080       /* Fall through.  */
1081
1082     case FUNCTION_DECL:
1083       if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
1084         dump_global_iord (DECL_ASSEMBLER_NAME (t));
1085       else if (! DECL_LANG_SPECIFIC (t))
1086         print_identifier (scratch_buffer, "<internal>");
1087       else if (flags & TS_PEDANTIC_NAME)
1088         dump_function_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
1089       else
1090         dump_function_decl (t, flags);
1091       break;
1092
1093     case TEMPLATE_DECL:
1094       if (flags & TS_PEDANTIC_NAME)
1095         dump_template_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
1096       else
1097         dump_template_decl (t, flags);
1098       break;
1099
1100     case TEMPLATE_ID_EXPR:
1101       {
1102         tree args;
1103         tree name = TREE_OPERAND (t, 0);
1104         if (is_overloaded_fn (name))
1105           name = DECL_NAME (get_first_fn (name));
1106         dump_decl (name, flags);
1107         print_template_argument_list_start (scratch_buffer);
1108         for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
1109           {
1110             dump_template_argument (TREE_VALUE (args), flags);
1111             if (TREE_CHAIN (args))
1112               separate_with_comma (scratch_buffer);
1113           }
1114         print_template_argument_list_end (scratch_buffer);
1115       }
1116       break;
1117
1118     case LOOKUP_EXPR:
1119       dump_decl (TREE_OPERAND (t, 0), flags);
1120       break;
1121
1122     case LABEL_DECL:
1123       print_tree_identifier (scratch_buffer, DECL_NAME (t));
1124       break;
1125
1126     case CONST_DECL:
1127       if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
1128           || (DECL_INITIAL (t) &&
1129               TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
1130         dump_simple_decl (t, TREE_TYPE (t), flags);
1131       else if (DECL_NAME (t))
1132         dump_decl (DECL_NAME (t), flags);
1133       else if (DECL_INITIAL (t))
1134         dump_expr (DECL_INITIAL (t), flags | TS_EXPR_PARENS);
1135       else
1136         print_identifier (scratch_buffer, "enumerator");
1137       break;
1138
1139     case USING_DECL:
1140       output_add_string (scratch_buffer, "using ");
1141       dump_type (DECL_INITIAL (t), flags);
1142       print_scope_operator (scratch_buffer);
1143       print_tree_identifier (scratch_buffer, DECL_NAME (t));
1144       break;
1145
1146     default:
1147       sorry_for_unsupported_tree (t);
1148       /* Fallthrough to error.  */
1149
1150     case ERROR_MARK:
1151       print_identifier (scratch_buffer, "<declaration error>");
1152       break;
1153     }
1154 }
1155
1156 /* Dump a template declaration T under control of FLAGS. This means the
1157    'template <...> leaders plus the 'class X' or 'void fn(...)' part.  */
1158
1159 static void
1160 dump_template_decl (t, flags)
1161      tree t;
1162      enum tree_string_flags flags;
1163 {
1164   tree orig_parms = DECL_TEMPLATE_PARMS (t);
1165   tree parms;
1166   int i;
1167
1168   if (flags & TS_TEMPLATE_PREFIX)
1169     {
1170       for (parms = orig_parms = nreverse (orig_parms);
1171            parms;
1172            parms = TREE_CHAIN (parms))
1173         {
1174           tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
1175           int len = TREE_VEC_LENGTH (inner_parms);
1176
1177           output_add_string (scratch_buffer, "template<");
1178           for (i = 0; i < len; i++)
1179             {
1180               if (i)
1181                 separate_with_comma (scratch_buffer);
1182               dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
1183             }
1184           print_template_argument_list_end (scratch_buffer);
1185           separate_with_comma (scratch_buffer);
1186         }
1187       nreverse(orig_parms);
1188       /* If we've shown the template<args> prefix, we'd better show the
1189          decl's type too.  */
1190       flags |= TS_DECL_TYPE;
1191     }
1192   if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
1193     dump_type (TREE_TYPE (t),
1194                ((flags & ~TS_AGGR_TAGS) | TS_TEMPLATE_PLAIN
1195                 | (flags & TS_DECL_TYPE ? TS_AGGR_TAGS : 0)));
1196   else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
1197     dump_decl (DECL_TEMPLATE_RESULT (t), flags | TS_TEMPLATE_PLAIN);
1198   else if (TREE_TYPE (t) == NULL_TREE)
1199     my_friendly_abort (353);
1200   else
1201     switch (NEXT_CODE (t))
1202     {
1203       case METHOD_TYPE:
1204       case FUNCTION_TYPE:
1205         dump_function_decl (t, flags | TS_TEMPLATE_PLAIN);
1206         break;
1207       default:
1208         /* This case can occur with some illegal code.  */
1209         dump_type (TREE_TYPE (t),
1210                    (flags & ~TS_AGGR_TAGS) | TS_TEMPLATE_PLAIN
1211                    | (flags & TS_DECL_TYPE ? TS_AGGR_TAGS : 0));
1212     }
1213 }
1214
1215 /* Pretty print a function decl. There are several ways we want to print a
1216    function declaration. The TS_FUNC bits in FLAGS tells us how to behave.
1217    As cp_error can only apply the '#' flag once to give 0 and 1 for V, there
1218    is %D which doesn't print the throw specs, and %F which does. */
1219
1220 static void
1221 dump_function_decl (t, flags)
1222      tree t;
1223      enum tree_string_flags flags;
1224 {
1225   tree fntype;
1226   tree parmtypes;
1227   tree cname = NULL_TREE;
1228   tree template_args = NULL_TREE;
1229   tree template_parms = NULL_TREE;
1230   int show_return = !(flags & TS_FUNC_NORETURN) && (flags & TS_DECL_TYPE);
1231
1232   if (TREE_CODE (t) == TEMPLATE_DECL)
1233     t = DECL_TEMPLATE_RESULT (t);
1234
1235   /* Pretty print template instantiations only.  */
1236   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t))
1237     {
1238       tree tmpl;
1239
1240       template_args = DECL_TI_ARGS (t);
1241       tmpl = most_general_template (t);
1242       if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
1243         {
1244           template_parms = DECL_TEMPLATE_PARMS (tmpl);
1245           t = tmpl;
1246         }
1247     }
1248
1249   fntype = TREE_TYPE (t);
1250   parmtypes = TYPE_ARG_TYPES (fntype);
1251
1252   if (DECL_CLASS_SCOPE_P (t))
1253     cname = DECL_CONTEXT (t);
1254   /* this is for partially instantiated template methods */
1255   else if (TREE_CODE (fntype) == METHOD_TYPE)
1256     cname = TREE_TYPE (TREE_VALUE (parmtypes));
1257
1258   if (!(flags & TS_DECORATE))
1259     /* OK */;
1260   else if (DECL_STATIC_FUNCTION_P (t))
1261     print_identifier (scratch_buffer, "static ");
1262   else if (TYPE_POLYMORPHIC_P (t))
1263     print_identifier (scratch_buffer, "virtual ");
1264
1265   /* Print the return type?  */
1266   if (show_return)
1267     show_return = !DECL_CONV_FN_P (t)  && !DECL_CONSTRUCTOR_P (t)
1268                   && !DECL_DESTRUCTOR_P (t);
1269   if (show_return)
1270     {
1271       if (dump_type_prefix (TREE_TYPE (fntype), flags) != none)
1272         output_add_space (scratch_buffer);
1273     }
1274
1275   /* Print the function name.  */
1276   if (cname)
1277     {
1278       dump_type (cname, flags);
1279       print_scope_operator (scratch_buffer);
1280     }
1281   else
1282     dump_scope (CP_DECL_CONTEXT (t), flags);
1283
1284   dump_function_name (t, flags);
1285
1286   if (!(flags & TS_DECL_TYPE))
1287     return;
1288   if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
1289     /* Skip "this" parameter.  */
1290     parmtypes = TREE_CHAIN (parmtypes);
1291
1292   /* Skip past the "in_charge" parameter.  */
1293   if (DECL_HAS_IN_CHARGE_PARM_P (t))
1294     parmtypes = TREE_CHAIN (parmtypes);
1295
1296   dump_parameters (parmtypes, flags);
1297
1298   if (show_return)
1299     dump_type_suffix (TREE_TYPE (fntype), flags);
1300
1301   if (TREE_CODE (fntype) == METHOD_TYPE)
1302     dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
1303                      before);
1304
1305   if (flags & TS_FUNC_THROW)
1306     dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
1307
1308   /* If T is a template instantiation, dump the parameter binding.  */
1309   if (template_parms != NULL_TREE && template_args != NULL_TREE)
1310     {
1311       output_add_string (scratch_buffer, " [with ");
1312       dump_template_bindings (template_parms, template_args);
1313       print_right_bracket (scratch_buffer);
1314     }
1315 }
1316
1317 /* Print a parameter list. If this is for a member function, the
1318    member object ptr (and any other hidden args) should have
1319    already been removed. */
1320
1321 static void
1322 dump_parameters (parmtypes, flags)
1323      tree parmtypes;
1324      enum tree_string_flags flags;
1325 {
1326   int first;
1327
1328   print_left_paren (scratch_buffer);
1329
1330   for (first = 1; parmtypes != void_list_node;
1331        parmtypes = TREE_CHAIN (parmtypes))
1332     {
1333       if (!first)
1334         separate_with_comma (scratch_buffer);
1335       first = 0;
1336       if (!parmtypes)
1337         {
1338           print_identifier (scratch_buffer, "...");
1339           break;
1340         }
1341       dump_type (TREE_VALUE (parmtypes), flags);
1342
1343       if ((flags & TS_PARM_DEFAULTS) && TREE_PURPOSE (parmtypes))
1344         {
1345           output_add_string (scratch_buffer, " = ");
1346           dump_expr (TREE_PURPOSE (parmtypes), flags | TS_EXPR_PARENS);
1347         }
1348     }
1349
1350   print_right_paren (scratch_buffer);
1351 }
1352
1353 /* Print an exception specification. T is the exception specification. */
1354
1355 static void
1356 dump_exception_spec (t, flags)
1357      tree t;
1358      enum tree_string_flags flags;
1359 {
1360   if (t)
1361     {
1362       output_add_string (scratch_buffer, " throw (");
1363       if (TREE_VALUE (t) != NULL_TREE)
1364         while (1)
1365           {
1366             dump_type (TREE_VALUE (t), flags);
1367             t = TREE_CHAIN (t);
1368             if (!t)
1369               break;
1370             separate_with_comma (scratch_buffer);
1371           }
1372       print_right_paren (scratch_buffer);
1373     }
1374 }
1375
1376 /* Handle the function name for a FUNCTION_DECL node, grokking operators
1377    and destructors properly.  */
1378
1379 static void
1380 dump_function_name (t, flags)
1381      tree t;
1382      enum tree_string_flags flags;
1383 {
1384   tree name = DECL_NAME (t);
1385
1386   if (DECL_DESTRUCTOR_P (t))
1387     {
1388       output_add_character (scratch_buffer, '~');
1389       dump_decl (name, TS_PLAIN);
1390     }
1391   else if (DECL_CONV_FN_P (t))
1392     {
1393       /* This cannot use the hack that the operator's return
1394          type is stashed off of its name because it may be
1395          used for error reporting.  In the case of conflicting
1396          declarations, both will have the same name, yet
1397          the types will be different, hence the TREE_TYPE field
1398          of the first name will be clobbered by the second.  */
1399       output_add_string (scratch_buffer, "operator ");
1400       dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
1401     }
1402   else if (IDENTIFIER_OPNAME_P (name))
1403     print_tree_identifier (scratch_buffer, name);
1404   else
1405     dump_decl (name, flags);
1406
1407   if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
1408       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
1409       && (DECL_TEMPLATE_SPECIALIZATION (t)
1410           || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
1411           || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
1412           || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
1413     dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
1414 }
1415
1416 /* Dump the template parameters from the template info INFO under control of
1417    FLAGS. PRIMARY indicates whether this is a primary template decl, or
1418    specialization (partial or complete). For partial specializations we show
1419    the specialized parameter values. For a primary template we show no
1420    decoration.  */
1421
1422 static void
1423 dump_template_parms (info, primary, flags)
1424      tree info;
1425      int primary;
1426      enum tree_string_flags flags;
1427 {
1428   tree args = info ? TI_ARGS (info) : NULL_TREE;
1429
1430   if (primary && flags & TS_TEMPLATE_PLAIN)
1431     return;
1432   flags &= ~(TS_AGGR_TAGS | TS_TEMPLATE_PLAIN);
1433   print_template_argument_list_start (scratch_buffer);
1434
1435   /* Be careful only to print things when we have them, so as not
1436          to crash producing error messages.  */
1437   if (args && !primary)
1438     {
1439       int len = 0;
1440       int ix = 0;
1441       int need_comma = 0;
1442
1443       if (TREE_CODE (args) == TREE_VEC)
1444         {
1445           if (TREE_VEC_LENGTH (args) > 0
1446               && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
1447             args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
1448
1449           len = TREE_VEC_LENGTH (args);
1450         }
1451       else if (TREE_CODE (args) == TREE_LIST)
1452         len = -1;
1453       while (ix != len && args)
1454         {
1455           tree arg;
1456           if (len >= 0)
1457             {
1458               arg = TREE_VEC_ELT (args, ix);
1459               ix++;
1460             }
1461           else
1462             {
1463               arg = TREE_VALUE (args);
1464               args = TREE_CHAIN (args);
1465             }
1466           if (need_comma)
1467             separate_with_comma (scratch_buffer);
1468           
1469           if (!arg)
1470             print_identifier (scratch_buffer, "<template parameter error>");
1471           else
1472             dump_template_argument (arg, flags);
1473           need_comma = 1;
1474         }
1475     }
1476   else if (primary)
1477     {
1478       tree tpl = TI_TEMPLATE (info);
1479       tree parms = DECL_TEMPLATE_PARMS (tpl);
1480       int len, ix;
1481
1482       parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
1483       len = parms ? TREE_VEC_LENGTH (parms) : 0;
1484
1485       for (ix = 0; ix != len; ix++)
1486         {
1487           tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
1488
1489           if (ix)
1490             separate_with_comma (scratch_buffer);
1491
1492           dump_decl (parm, flags & ~TS_DECL_TYPE);
1493         }
1494     }
1495   print_template_argument_list_end (scratch_buffer);
1496 }
1497
1498 static void
1499 dump_char (c)
1500      int c;
1501 {
1502   switch (c)
1503     {
1504     case TARGET_NEWLINE:
1505       output_add_string (scratch_buffer, "\\n");
1506       break;
1507     case TARGET_TAB:
1508       output_add_string (scratch_buffer, "\\t");
1509       break;
1510     case TARGET_VT:
1511       output_add_string (scratch_buffer, "\\v");
1512       break;
1513     case TARGET_BS:
1514       output_add_string (scratch_buffer, "\\b");
1515       break;
1516     case TARGET_CR:
1517       output_add_string (scratch_buffer, "\\r");
1518       break;
1519     case TARGET_FF:
1520       output_add_string (scratch_buffer, "\\f");
1521       break;
1522     case TARGET_BELL:
1523       output_add_string (scratch_buffer, "\\a");
1524       break;
1525     case '\\':
1526       output_add_string (scratch_buffer, "\\\\");
1527       break;
1528     case '\'':
1529       output_add_string (scratch_buffer, "\\'");
1530       break;
1531     case '\"':
1532       output_add_string (scratch_buffer, "\\\"");
1533       break;
1534     default:
1535       if (ISPRINT (c))
1536         output_add_character (scratch_buffer, c);
1537       else
1538         {
1539           sprintf (digit_buffer, "\\%03o", (int) c);
1540           output_add_string (scratch_buffer, digit_buffer);
1541         }
1542     }
1543 }
1544
1545 /* Print out a list of initializers (subr of dump_expr) */
1546
1547 static void
1548 dump_expr_list (l, flags)
1549      tree l;
1550      enum tree_string_flags flags;
1551 {
1552   while (l)
1553     {
1554       dump_expr (TREE_VALUE (l), flags | TS_EXPR_PARENS);
1555       l = TREE_CHAIN (l);
1556       if (l)
1557         separate_with_comma (scratch_buffer);
1558     }
1559 }
1560
1561 /* Print out an expression E under control of FLAGS. */
1562
1563 static void
1564 dump_expr (t, flags)
1565      tree t;
1566      enum tree_string_flags flags;
1567 {
1568   switch (TREE_CODE (t))
1569     {
1570     case VAR_DECL:
1571     case PARM_DECL:
1572     case FIELD_DECL:
1573     case CONST_DECL:
1574     case FUNCTION_DECL:
1575     case TEMPLATE_DECL:
1576     case NAMESPACE_DECL:
1577     case OVERLOAD:
1578       dump_decl (t, flags & ~TS_DECL_TYPE);
1579       break;
1580
1581     case INTEGER_CST:
1582       {
1583         tree type = TREE_TYPE (t);
1584         my_friendly_assert (type != 0, 81);
1585
1586         /* If it's an enum, output its tag, rather than its value.  */
1587         if (TREE_CODE (type) == ENUMERAL_TYPE)
1588           {
1589             tree values = TYPE_VALUES (type);
1590
1591             for (; values;
1592                  values = TREE_CHAIN (values))
1593               if (tree_int_cst_equal (TREE_VALUE (values), t))
1594                 break;
1595
1596             if (values)
1597               print_tree_identifier (scratch_buffer, TREE_PURPOSE (values));
1598             else
1599               {
1600                 /* Value must have been cast.  */
1601                 print_left_paren (scratch_buffer);
1602                 dump_type (type, flags);
1603                 print_right_paren (scratch_buffer);
1604                 goto do_int;
1605               }
1606           }
1607         else if (type == boolean_type_node)
1608           {
1609             if (t == boolean_false_node || integer_zerop (t))
1610               print_identifier (scratch_buffer, "false");
1611             else if (t == boolean_true_node)
1612               print_identifier (scratch_buffer, "true");
1613           }
1614         else if (type == char_type_node)
1615           {
1616             output_add_character (scratch_buffer, '\'');
1617             dump_char (tree_low_cst (t, 0));
1618             output_add_character (scratch_buffer, '\'');
1619           }
1620         else
1621           {
1622             do_int:
1623             if (! host_integerp (t, 0))
1624               {
1625                 tree val = t;
1626
1627                 if (tree_int_cst_sgn (val) < 0)
1628                   {
1629                     output_add_character (scratch_buffer, '-');
1630                     val = build_int_2 (-TREE_INT_CST_LOW (val),
1631                                        ~TREE_INT_CST_HIGH (val)
1632                                        + !TREE_INT_CST_LOW (val));
1633                   }
1634                 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
1635                    systems?  */
1636                 {
1637                   static char format[10]; /* "%x%09999x\0" */
1638                   if (!format[0])
1639                     sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
1640                   sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
1641                            TREE_INT_CST_LOW (val));
1642                   output_add_string (scratch_buffer, digit_buffer);
1643                 }
1644               }
1645             else
1646               print_integer (scratch_buffer, TREE_INT_CST_LOW (t));
1647           }
1648       }
1649       break;
1650
1651     case REAL_CST:
1652 #ifndef REAL_IS_NOT_DOUBLE
1653       sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
1654 #else
1655       {
1656         const unsigned char *p = (const unsigned char *) &TREE_REAL_CST (t);
1657         size_t i;
1658         strcpy (digit_buffer, "0x");
1659         for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
1660           sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
1661       }
1662 #endif
1663       output_add_string (scratch_buffer, digit_buffer);
1664       break;
1665
1666     case PTRMEM_CST:
1667       output_add_character (scratch_buffer, '&');
1668       dump_type (PTRMEM_CST_CLASS (t), flags);
1669       print_scope_operator (scratch_buffer);
1670       print_tree_identifier
1671         (scratch_buffer, DECL_NAME (PTRMEM_CST_MEMBER (t)));
1672       break;
1673
1674     case STRING_CST:
1675       {
1676         const char *p = TREE_STRING_POINTER (t);
1677         int len = TREE_STRING_LENGTH (t) - 1;
1678         int i;
1679
1680         output_add_character (scratch_buffer, '\"');
1681         for (i = 0; i < len; i++)
1682           dump_char (p[i]);
1683         output_add_character (scratch_buffer, '\"');
1684       }
1685       break;
1686
1687     case COMPOUND_EXPR:
1688       print_left_paren (scratch_buffer);
1689       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1690       separate_with_comma (scratch_buffer);
1691       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1692       print_right_paren (scratch_buffer);
1693       break;
1694
1695     case COND_EXPR:
1696       print_left_paren (scratch_buffer);
1697       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1698       output_add_string (scratch_buffer, " ? ");
1699       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1700       output_add_string (scratch_buffer, " : ");
1701       dump_expr (TREE_OPERAND (t, 2), flags | TS_EXPR_PARENS);
1702       print_right_paren (scratch_buffer);
1703       break;
1704
1705     case SAVE_EXPR:
1706       if (TREE_HAS_CONSTRUCTOR (t))
1707         {
1708           output_add_string (scratch_buffer, "new ");
1709           dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
1710         }
1711       else
1712         {
1713           dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1714         }
1715       break;
1716
1717     case AGGR_INIT_EXPR:
1718       {
1719         tree fn = NULL_TREE;
1720
1721         if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
1722           fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
1723
1724         if (fn && TREE_CODE (fn) == FUNCTION_DECL)
1725           {
1726             if (DECL_CONSTRUCTOR_P (fn))
1727               print_tree_identifier
1728                 (scratch_buffer, TYPE_IDENTIFIER (TREE_TYPE (t)));
1729             else
1730               dump_decl (fn, 0);
1731           }
1732         else
1733           dump_expr (TREE_OPERAND (t, 0), 0);
1734       }
1735       print_left_paren (scratch_buffer);
1736       if (TREE_OPERAND (t, 1))
1737         dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
1738       print_right_paren (scratch_buffer);
1739       break;
1740
1741     case CALL_EXPR:
1742       {
1743         tree fn = TREE_OPERAND (t, 0);
1744         tree args = TREE_OPERAND (t, 1);
1745
1746         if (TREE_CODE (fn) == ADDR_EXPR)
1747           fn = TREE_OPERAND (fn, 0);
1748
1749         if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
1750           {
1751             tree ob = TREE_VALUE (args);
1752             if (TREE_CODE (ob) == ADDR_EXPR)
1753               {
1754                 dump_expr (TREE_OPERAND (ob, 0), flags | TS_EXPR_PARENS);
1755                 output_add_character (scratch_buffer, '.');
1756               }
1757             else if (TREE_CODE (ob) != PARM_DECL
1758                      || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1759               {
1760                 dump_expr (ob, flags | TS_EXPR_PARENS);
1761                 output_add_string (scratch_buffer, "->");
1762               }
1763             args = TREE_CHAIN (args);
1764           }
1765         dump_expr (fn, flags | TS_EXPR_PARENS);
1766         print_left_paren (scratch_buffer);
1767         dump_expr_list (args, flags);
1768         print_right_paren (scratch_buffer);
1769       }
1770       break;
1771
1772     case NEW_EXPR:
1773       {
1774         tree type = TREE_OPERAND (t, 1);
1775         if (NEW_EXPR_USE_GLOBAL (t))
1776           print_scope_operator (scratch_buffer);
1777         output_add_string (scratch_buffer, "new ");
1778         if (TREE_OPERAND (t, 0))
1779           {
1780             print_left_paren (scratch_buffer);
1781             dump_expr_list (TREE_OPERAND (t, 0), flags);
1782             output_add_string (scratch_buffer, ") ");
1783           }
1784         if (TREE_CODE (type) == ARRAY_REF)
1785           type = build_cplus_array_type
1786             (TREE_OPERAND (type, 0),
1787              build_index_type (fold (build (MINUS_EXPR, integer_type_node,
1788                                             TREE_OPERAND (type, 1),
1789                                             integer_one_node))));
1790         dump_type (type, flags);
1791         if (TREE_OPERAND (t, 2))
1792           {
1793             print_left_paren (scratch_buffer);
1794             dump_expr_list (TREE_OPERAND (t, 2), flags);
1795             print_right_paren (scratch_buffer);
1796           }
1797       }
1798       break;
1799
1800     case TARGET_EXPR:
1801       /* Note that this only works for G++ target exprs.  If somebody
1802          builds a general TARGET_EXPR, there's no way to represent that
1803          it initializes anything other that the parameter slot for the
1804          default argument.  Note we may have cleared out the first
1805          operand in expand_expr, so don't go killing ourselves.  */
1806       if (TREE_OPERAND (t, 1))
1807         dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1808       break;
1809
1810     case INIT_EXPR:
1811     case MODIFY_EXPR:
1812     case PLUS_EXPR:
1813     case MINUS_EXPR:
1814     case MULT_EXPR:
1815     case TRUNC_DIV_EXPR:
1816     case TRUNC_MOD_EXPR:
1817     case MIN_EXPR:
1818     case MAX_EXPR:
1819     case LSHIFT_EXPR:
1820     case RSHIFT_EXPR:
1821     case BIT_IOR_EXPR:
1822     case BIT_XOR_EXPR:
1823     case BIT_AND_EXPR:
1824     case BIT_ANDTC_EXPR:
1825     case TRUTH_ANDIF_EXPR:
1826     case TRUTH_ORIF_EXPR:
1827     case LT_EXPR:
1828     case LE_EXPR:
1829     case GT_EXPR:
1830     case GE_EXPR:
1831     case EQ_EXPR:
1832     case NE_EXPR:
1833     case EXACT_DIV_EXPR:
1834       dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags);
1835       break;
1836
1837     case CEIL_DIV_EXPR:
1838     case FLOOR_DIV_EXPR:
1839     case ROUND_DIV_EXPR:
1840       dump_binary_op ("/", t, flags);
1841       break;
1842
1843     case CEIL_MOD_EXPR:
1844     case FLOOR_MOD_EXPR:
1845     case ROUND_MOD_EXPR:
1846       dump_binary_op ("%", t, flags);
1847       break;
1848
1849     case COMPONENT_REF:
1850       {
1851         tree ob = TREE_OPERAND (t, 0);
1852         if (TREE_CODE (ob) == INDIRECT_REF)
1853           {
1854             ob = TREE_OPERAND (ob, 0);
1855             if (TREE_CODE (ob) != PARM_DECL
1856                 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1857               {
1858                 dump_expr (ob, flags | TS_EXPR_PARENS);
1859                 output_add_string (scratch_buffer, "->");
1860               }
1861           }
1862         else
1863           {
1864             dump_expr (ob, flags | TS_EXPR_PARENS);
1865             output_add_character (scratch_buffer, '.');
1866           }
1867         dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS);
1868       }
1869       break;
1870
1871     case ARRAY_REF:
1872       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1873       print_left_bracket (scratch_buffer);
1874       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
1875       print_right_bracket (scratch_buffer);
1876       break;
1877
1878     case CONVERT_EXPR:
1879       if (VOID_TYPE_P (TREE_TYPE (t)))
1880         {
1881           print_left_paren (scratch_buffer);
1882           dump_type (TREE_TYPE (t), flags);
1883           print_right_paren (scratch_buffer);
1884           dump_expr (TREE_OPERAND (t, 0), flags);
1885         }
1886       else
1887         dump_unary_op ("+", t, flags);
1888       break;
1889
1890     case ADDR_EXPR:
1891       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
1892           || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
1893           /* An ADDR_EXPR can have reference type.  In that case, we
1894              shouldn't print the `&' doing so indicates to the user
1895              that the expression has pointer type.  */
1896           || (TREE_TYPE (t)
1897               && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
1898         dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1899       else
1900         dump_unary_op ("&", t, flags);
1901       break;
1902
1903     case INDIRECT_REF:
1904       if (TREE_HAS_CONSTRUCTOR (t))
1905         {
1906           t = TREE_OPERAND (t, 0);
1907           my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1908           dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1909           print_left_paren (scratch_buffer);
1910           dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
1911           print_right_paren (scratch_buffer);
1912         }
1913       else
1914         {
1915           if (TREE_OPERAND (t,0) != NULL_TREE
1916               && TREE_TYPE (TREE_OPERAND (t, 0))
1917               && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
1918             dump_expr (TREE_OPERAND (t, 0), flags);
1919           else
1920             dump_unary_op ("*", t, flags);
1921         }
1922       break;
1923
1924     case NEGATE_EXPR:
1925     case BIT_NOT_EXPR:
1926     case TRUTH_NOT_EXPR:
1927     case PREDECREMENT_EXPR:
1928     case PREINCREMENT_EXPR:
1929       dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags);
1930       break;
1931
1932     case POSTDECREMENT_EXPR:
1933     case POSTINCREMENT_EXPR:
1934       print_left_paren (scratch_buffer);
1935       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1936       print_identifier
1937         (scratch_buffer, operator_name_info[(int)TREE_CODE (t)].name);
1938       print_right_paren (scratch_buffer);
1939       break;
1940
1941     case NON_LVALUE_EXPR:
1942       /* FIXME: This is a KLUDGE workaround for a parsing problem.  There
1943          should be another level of INDIRECT_REF so that I don't have to do
1944          this.  */
1945       if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
1946         {
1947           tree next = TREE_TYPE (TREE_TYPE (t));
1948
1949           while (TREE_CODE (next) == POINTER_TYPE)
1950             next = TREE_TYPE (next);
1951
1952           if (TREE_CODE (next) == FUNCTION_TYPE)
1953             {
1954               if (flags & TS_EXPR_PARENS)
1955                 print_left_paren (scratch_buffer);
1956               output_add_character (scratch_buffer, '*');
1957               dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
1958               if (flags & TS_EXPR_PARENS)
1959                 print_right_paren (scratch_buffer);
1960               break;
1961             }
1962           /* else FALLTHRU */
1963         }
1964       dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
1965       break;
1966
1967     case NOP_EXPR:
1968       dump_expr (TREE_OPERAND (t, 0), flags);
1969       break;
1970
1971     case EXPR_WITH_FILE_LOCATION:
1972       dump_expr (EXPR_WFL_NODE (t), flags);
1973       break;
1974
1975     case CONSTRUCTOR:
1976       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
1977         {
1978           tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
1979
1980           if (integer_all_onesp (idx))
1981             {
1982               tree pfn = PFN_FROM_PTRMEMFUNC (t);
1983               dump_unary_op ("&", pfn, flags | TS_EXPR_PARENS);
1984               break;
1985             }
1986           else if (TREE_CODE (idx) == INTEGER_CST
1987                    && tree_int_cst_equal (idx, integer_zero_node))
1988             {
1989               /* A NULL pointer-to-member constant.  */
1990               output_add_string (scratch_buffer, "((");
1991               dump_type (TREE_TYPE (t), flags);
1992               output_add_string (scratch_buffer, ") 0)");
1993               break;
1994             }
1995           else if (host_integerp (idx, 0))
1996             {
1997               tree virtuals;
1998               unsigned HOST_WIDE_INT n;
1999
2000               t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
2001               t = TYPE_METHOD_BASETYPE (t);
2002               virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
2003
2004               n = tree_low_cst (idx, 0) - first_vfun_index (t);
2005
2006               /* Map vtable index back one, to allow for the null pointer to
2007                  member.  */
2008               --n;
2009
2010               while (n > 0 && virtuals)
2011                 {
2012                   --n;
2013                   virtuals = TREE_CHAIN (virtuals);
2014                 }
2015               if (virtuals)
2016                 {
2017                   dump_expr (BV_FN (virtuals),
2018                              flags | TS_EXPR_PARENS);
2019                   break;
2020                 }
2021             }
2022         }
2023       output_add_character (scratch_buffer, '{');
2024       dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
2025       output_add_character (scratch_buffer, '}');
2026       break;
2027
2028     case OFFSET_REF:
2029       {
2030         tree ob = TREE_OPERAND (t, 0);
2031         if (is_dummy_object (ob))
2032           {
2033             t = TREE_OPERAND (t, 1);
2034             if (TREE_CODE (t) == FUNCTION_DECL)
2035               /* A::f */
2036               dump_expr (t, flags | TS_EXPR_PARENS);
2037             else if (BASELINK_P (t))
2038               dump_expr (OVL_CURRENT (TREE_VALUE (t)), flags | TS_EXPR_PARENS);
2039             else
2040               dump_decl (t, flags);
2041           }
2042         else
2043           {
2044             if (TREE_CODE (ob) == INDIRECT_REF)
2045               {
2046                 dump_expr (TREE_OPERAND (ob, 0), flags | TS_EXPR_PARENS);
2047                 output_add_string (scratch_buffer, "->*");
2048               }
2049             else
2050               {
2051                 dump_expr (ob, flags | TS_EXPR_PARENS);
2052                 output_add_string (scratch_buffer, ".*");
2053               }
2054             dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
2055           }
2056         break;
2057       }
2058
2059     case TEMPLATE_PARM_INDEX:
2060       dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TS_DECL_TYPE);
2061       break;
2062
2063     case IDENTIFIER_NODE:
2064       print_tree_identifier (scratch_buffer, t);
2065       break;
2066
2067     case SCOPE_REF:
2068       dump_type (TREE_OPERAND (t, 0), flags);
2069       print_scope_operator (scratch_buffer);
2070       dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
2071       break;
2072
2073     case CAST_EXPR:
2074       if (TREE_OPERAND (t, 0) == NULL_TREE
2075           || TREE_CHAIN (TREE_OPERAND (t, 0)))
2076         {
2077           dump_type (TREE_TYPE (t), flags);
2078           print_left_paren (scratch_buffer);
2079           dump_expr_list (TREE_OPERAND (t, 0), flags);
2080           print_right_paren (scratch_buffer);
2081         }
2082       else
2083         {
2084           print_left_paren (scratch_buffer);
2085           dump_type (TREE_TYPE (t), flags);
2086           output_add_string (scratch_buffer, ")(");
2087           dump_expr_list (TREE_OPERAND (t, 0), flags);
2088           print_right_paren (scratch_buffer);
2089         }
2090       break;
2091
2092     case LOOKUP_EXPR:
2093       print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0));
2094       break;
2095
2096     case ARROW_EXPR:
2097       dump_expr (TREE_OPERAND (t, 0), flags);
2098       output_add_string (scratch_buffer, "->");
2099       break;
2100
2101     case SIZEOF_EXPR:
2102     case ALIGNOF_EXPR:
2103       if (TREE_CODE (t) == SIZEOF_EXPR)
2104         output_add_string (scratch_buffer, "sizeof (");
2105       else
2106         {
2107           my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
2108           output_add_string (scratch_buffer, "__alignof__ (");
2109         }
2110       if (TYPE_P (TREE_OPERAND (t, 0)))
2111         dump_type (TREE_OPERAND (t, 0), flags);
2112       else
2113         dump_unary_op ("*", t, flags | TS_EXPR_PARENS);
2114       print_right_paren (scratch_buffer);
2115       break;
2116
2117     case DEFAULT_ARG:
2118       print_identifier (scratch_buffer, "<unparsed>");
2119       break;
2120
2121     case TRY_CATCH_EXPR:
2122     case WITH_CLEANUP_EXPR:
2123     case CLEANUP_POINT_EXPR:
2124       dump_expr (TREE_OPERAND (t, 0), flags);
2125       break;
2126
2127     case PSEUDO_DTOR_EXPR:
2128       dump_expr (TREE_OPERAND (t, 2), flags);
2129       output_add_character (scratch_buffer, '.');
2130       dump_type (TREE_OPERAND (t, 0), flags);
2131       output_add_string (scratch_buffer, "::~");
2132       dump_type (TREE_OPERAND (t, 1), flags);
2133       break;
2134
2135     case TEMPLATE_ID_EXPR:
2136       dump_decl (t, flags);
2137       break;
2138
2139     case STMT_EXPR:
2140       /* We don't yet have a way of dumping statements in a
2141          human-readable format.  */
2142       output_add_string (scratch_buffer, "({...})");
2143       break;
2144
2145     case BIND_EXPR:
2146       output_add_character (scratch_buffer, '}');
2147       dump_expr (TREE_OPERAND (t, 1), flags & ~TS_EXPR_PARENS);
2148       output_add_character (scratch_buffer, '}');
2149       break;
2150
2151     case LOOP_EXPR:
2152       output_add_string (scratch_buffer, "while (1) { ");
2153       dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
2154       output_add_character (scratch_buffer, '}');
2155       break;
2156
2157     case EXIT_EXPR:
2158       output_add_string (scratch_buffer, "if (");
2159       dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
2160       output_add_string (scratch_buffer, ") break; ");
2161       break;
2162
2163     case TREE_LIST:
2164       if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
2165         {
2166           print_tree_identifier (scratch_buffer, DECL_NAME (TREE_VALUE (t)));
2167           break;
2168         }
2169       /* else fall through */
2170
2171       /*  This list is incomplete, but should suffice for now.
2172           It is very important that `sorry' does not call
2173           `report_error_function'.  That could cause an infinite loop.  */
2174     default:
2175       sorry_for_unsupported_tree (t);
2176       /* fall through to ERROR_MARK...  */
2177     case ERROR_MARK:
2178       print_identifier (scratch_buffer, "<expression error>");
2179       break;
2180     }
2181 }
2182
2183 static void
2184 dump_binary_op (opstring, t, flags)
2185      const char *opstring;
2186      tree t;
2187      enum tree_string_flags flags;
2188 {
2189   print_left_paren (scratch_buffer);
2190   dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
2191   output_add_space (scratch_buffer);
2192   if (opstring)
2193     print_identifier (scratch_buffer, opstring);
2194   else
2195     print_identifier (scratch_buffer, "<unknown operator>");
2196   output_add_space (scratch_buffer);
2197   dump_expr (TREE_OPERAND (t, 1), flags | TS_EXPR_PARENS);
2198   print_right_paren (scratch_buffer);
2199 }
2200
2201 static void
2202 dump_unary_op (opstring, t, flags)
2203      const char *opstring;
2204      tree t;
2205      enum tree_string_flags flags;
2206 {
2207   if (flags & TS_EXPR_PARENS)
2208     print_left_paren (scratch_buffer);
2209   print_identifier (scratch_buffer, opstring);
2210   dump_expr (TREE_OPERAND (t, 0), flags & ~TS_EXPR_PARENS);
2211   if (flags & TS_EXPR_PARENS)
2212     print_right_paren (scratch_buffer);
2213 }
2214
2215 /* Exported interface to stringifying types, exprs and decls under TS_*
2216    control.  */
2217
2218 const char *
2219 type_as_string (typ, flags)
2220      tree typ;
2221      enum tree_string_flags flags;
2222 {
2223   reinit_global_formatting_buffer ();
2224
2225   dump_type (typ, flags);
2226
2227   return output_finalize_message (scratch_buffer);
2228 }
2229
2230 const char *
2231 expr_as_string (decl, flags)
2232      tree decl;
2233      enum tree_string_flags flags;
2234 {
2235   reinit_global_formatting_buffer ();
2236
2237   dump_expr (decl, flags);
2238
2239   return output_finalize_message (scratch_buffer);
2240 }
2241
2242 const char *
2243 decl_as_string (decl, flags)
2244      tree decl;
2245      enum tree_string_flags flags;
2246 {
2247   reinit_global_formatting_buffer ();
2248
2249   dump_decl (decl, flags);
2250
2251   return output_finalize_message (scratch_buffer);
2252 }
2253
2254 const char *
2255 context_as_string (context, flags)
2256      tree context;
2257      enum tree_string_flags flags;
2258 {
2259   reinit_global_formatting_buffer ();
2260
2261   dump_scope (context, flags);
2262
2263   return output_finalize_message (scratch_buffer);
2264 }
2265
2266 /* Generate the three forms of printable names for lang_printable_name.  */
2267
2268 const char *
2269 lang_decl_name (decl, v)
2270      tree decl;
2271      int v;
2272 {
2273   if (v >= 2)
2274     return decl_as_string (decl, TS_DECL_TYPE);
2275
2276   reinit_global_formatting_buffer ();
2277
2278   if (v == 1 && DECL_CLASS_SCOPE_P (decl))
2279     {
2280       dump_type (CP_DECL_CONTEXT (decl), TS_PLAIN);
2281       print_scope_operator (scratch_buffer);
2282     }
2283
2284   if (TREE_CODE (decl) == FUNCTION_DECL)
2285     dump_function_name (decl, TS_PLAIN);
2286   else
2287     dump_decl (DECL_NAME (decl), TS_PLAIN);
2288
2289   return output_finalize_message (scratch_buffer);
2290 }
2291
2292 const char *
2293 cp_file_of (t)
2294      tree t;
2295 {
2296   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
2297     return DECL_SOURCE_FILE (DECL_CONTEXT (t));
2298   else if (TYPE_P (t))
2299     return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));
2300   else if (TREE_CODE (t) == OVERLOAD)
2301     return DECL_SOURCE_FILE (OVL_FUNCTION (t));
2302   else
2303     return DECL_SOURCE_FILE (t);
2304 }
2305
2306 int
2307 cp_line_of (t)
2308      tree t;
2309 {
2310   int line = 0;
2311   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
2312     line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
2313   if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
2314       && TYPE_MAIN_DECL (TREE_TYPE (t)))
2315     t = TREE_TYPE (t);
2316
2317   if (TYPE_P (t))
2318     line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));
2319   else if (TREE_CODE (t) == OVERLOAD)
2320     line = DECL_SOURCE_LINE (OVL_FUNCTION (t));
2321   else
2322     line = DECL_SOURCE_LINE (t);
2323
2324   if (line == 0)
2325     return lineno;
2326
2327   return line;
2328 }
2329
2330 /* Now the interfaces from cp_error et al to dump_type et al. Each takes an
2331    on/off VERBOSE flag and supply the appropriate TS_ flags to a dump_
2332    function.  */
2333
2334 static const char *
2335 decl_to_string (decl, verbose)
2336      tree decl;
2337      int verbose;
2338 {
2339   enum tree_string_flags flags = 0;
2340
2341   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
2342       || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
2343     flags = TS_AGGR_TAGS;
2344   if (verbose)
2345     flags |= TS_DECL_TYPE | TS_DECORATE | TS_PARM_DEFAULTS;
2346   else if (TREE_CODE (decl) == FUNCTION_DECL)
2347     flags |= TS_DECL_TYPE | TS_FUNC_NORETURN;
2348   flags |= TS_TEMPLATE_PREFIX;
2349
2350   reinit_global_formatting_buffer ();
2351
2352   dump_decl (decl, flags);
2353
2354   return output_finalize_message (scratch_buffer);
2355 }
2356
2357 static const char *
2358 expr_to_string (decl, verbose)
2359      tree decl;
2360      int verbose ATTRIBUTE_UNUSED;
2361 {
2362   reinit_global_formatting_buffer ();
2363
2364   dump_expr (decl, 0);
2365
2366   return output_finalize_message (scratch_buffer);
2367 }
2368
2369 static const char *
2370 fndecl_to_string (fndecl, verbose)
2371      tree fndecl;
2372      int verbose;
2373 {
2374   enum tree_string_flags flags;
2375
2376   flags = TS_FUNC_THROW | TS_DECL_TYPE;
2377   if (verbose)
2378     flags |= TS_PARM_DEFAULTS;
2379   reinit_global_formatting_buffer ();
2380
2381   dump_decl (fndecl, flags);
2382
2383   return output_finalize_message (scratch_buffer);
2384 }
2385
2386
2387 static const char *
2388 code_to_string (c, v)
2389      enum tree_code c;
2390      int v ATTRIBUTE_UNUSED;
2391 {
2392   return tree_code_name [c];
2393 }
2394
2395 const char *
2396 language_to_string (c, v)
2397      enum languages c;
2398      int v ATTRIBUTE_UNUSED;
2399 {
2400   switch (c)
2401     {
2402     case lang_c:
2403       return "C";
2404
2405     case lang_cplusplus:
2406       return "C++";
2407
2408     case lang_java:
2409       return "Java";
2410
2411     default:
2412       my_friendly_abort (355);
2413       return 0;
2414     }
2415 }
2416
2417 /* Return the proper printed version of a parameter to a C++ function.  */
2418
2419 static const char *
2420 parm_to_string (p, v)
2421      int p;
2422      int v ATTRIBUTE_UNUSED;
2423 {
2424   if (p < 0)
2425     return "`this'";
2426
2427   sprintf (digit_buffer, "%d", p+1);
2428   return digit_buffer;
2429 }
2430
2431 static const char *
2432 op_to_string (p, v)
2433      enum tree_code p;
2434      int v ATTRIBUTE_UNUSED;
2435 {
2436   tree id;
2437
2438   id = operator_name_info[(int) p].identifier;
2439   return id ? IDENTIFIER_POINTER (id) : "{unknown}";
2440 }
2441
2442 static const char *
2443 type_to_string (typ, verbose)
2444      tree typ;
2445      int verbose;
2446 {
2447   enum tree_string_flags flags;
2448
2449   flags = 0;
2450   if (verbose)
2451     flags |= TS_AGGR_TAGS;
2452   flags |= TS_TEMPLATE_PREFIX;
2453
2454   reinit_global_formatting_buffer ();
2455
2456   dump_type (typ, flags);
2457
2458   return output_finalize_message (scratch_buffer);
2459 }
2460
2461 static const char *
2462 assop_to_string (p, v)
2463      enum tree_code p;
2464      int v ATTRIBUTE_UNUSED;
2465 {
2466   tree id;
2467
2468   id = assignment_operator_name_info[(int) p].identifier;
2469   return id ? IDENTIFIER_POINTER (id) : "{unknown}";
2470 }
2471
2472 static const char *
2473 args_to_string (p, verbose)
2474      tree p;
2475      int verbose;
2476 {
2477   enum tree_string_flags flags = 0;
2478   if (verbose)
2479     flags |= TS_AGGR_TAGS;
2480
2481   if (p == NULL_TREE)
2482     return "";
2483
2484   if (TYPE_P (TREE_VALUE (p)))
2485     return type_as_string (p, flags);
2486
2487   reinit_global_formatting_buffer ();
2488   for (; p; p = TREE_CHAIN (p))
2489     {
2490       if (TREE_VALUE (p) == null_node)
2491         print_identifier (scratch_buffer, "NULL");
2492       else
2493         dump_type (error_type (TREE_VALUE (p)), flags);
2494       if (TREE_CHAIN (p))
2495         separate_with_comma (scratch_buffer);
2496     }
2497   return output_finalize_message (scratch_buffer);
2498 }
2499
2500 static const char *
2501 cv_to_string (p, v)
2502      tree p;
2503      int v ATTRIBUTE_UNUSED;
2504 {
2505   reinit_global_formatting_buffer ();
2506
2507   dump_qualifiers (p, before);
2508
2509   return output_finalize_message (scratch_buffer);
2510 }
2511
2512 static void
2513 lang_print_error_function (file)
2514      const char *file;
2515 {
2516   output_state os;
2517
2518   default_print_error_function (file);
2519   os = output_buffer_state (diagnostic_buffer);
2520   output_set_prefix (diagnostic_buffer, file);
2521   maybe_print_instantiation_context (diagnostic_buffer);
2522   output_buffer_state (diagnostic_buffer) = os;
2523 }
2524
2525 static void
2526 cp_diagnostic_starter (buffer, dc)
2527      output_buffer *buffer;
2528      diagnostic_context *dc;
2529 {
2530   report_problematic_module (buffer);
2531   cp_print_error_function (buffer, dc);
2532   maybe_print_instantiation_context (buffer);
2533   output_set_prefix (buffer,
2534                      context_as_prefix (diagnostic_file_location (dc),
2535                                         diagnostic_line_location (dc),
2536                                         diagnostic_is_warning (dc)));
2537 }
2538
2539 static void
2540 cp_diagnostic_finalizer (buffer, dc)
2541      output_buffer *buffer;
2542      diagnostic_context *dc __attribute__ ((__unused__));
2543 {
2544   output_destroy_prefix (buffer);
2545 }
2546
2547 /* Print current function onto BUFFER, in the process of reporting
2548    a diagnostic message.  Called from cp_diagnostic_starter.  */
2549 static void
2550 cp_print_error_function (buffer, dc)
2551      output_buffer *buffer;
2552      diagnostic_context *dc;
2553 {
2554   if (error_function_changed ())
2555     {
2556       char *prefix = diagnostic_file_location (dc)
2557         ? file_name_as_prefix (diagnostic_file_location (dc))
2558         : NULL;
2559       output_state os;
2560
2561       os = output_buffer_state (buffer);
2562       output_set_prefix (buffer, prefix);
2563
2564       if (current_function_decl == NULL)
2565         output_add_string (buffer, "At global scope:");
2566       else
2567         output_printf
2568           (buffer, "In %s `%s':", function_category (current_function_decl),
2569            (*decl_printable_name) (current_function_decl, 2));
2570       output_add_newline (buffer);
2571
2572       record_last_error_function ();
2573       output_destroy_prefix (buffer);
2574       output_buffer_state (buffer) = os;
2575     }
2576 }
2577
2578 /* Returns a description of FUNCTION using standard terminology.  */
2579 static const char *
2580 function_category (fn)
2581      tree fn;
2582 {
2583   if (DECL_FUNCTION_MEMBER_P (fn))
2584     {
2585       if (DECL_STATIC_FUNCTION_P (fn))
2586         return "static member function";
2587       else if (DECL_COPY_CONSTRUCTOR_P (fn))
2588         return "copy constructor";
2589       else if (DECL_CONSTRUCTOR_P (fn))
2590         return "constructor";
2591       else if (DECL_DESTRUCTOR_P (fn))
2592         return "destructor";
2593       else
2594         return "member function";
2595     }
2596   else
2597     return "function";
2598 }
2599
2600 /* Report the full context of a current template instantiation,
2601    onto BUFFER.  */
2602 static void
2603 print_instantiation_full_context (buffer)
2604      output_buffer *buffer;
2605 {
2606   tree p = current_instantiation ();
2607   int line = lineno;
2608   const char *file = input_filename;
2609
2610   if (p)
2611     {
2612       if (current_function_decl != TINST_DECL (p)
2613           && current_function_decl != NULL_TREE)
2614         /* We can get here during the processing of some synthesized
2615            method.  Then, TINST_DECL (p) will be the function that's causing
2616            the synthesis.  */
2617         ;
2618       else
2619         {
2620           if (current_function_decl == TINST_DECL (p))
2621             /* Avoid redundancy with the the "In function" line.  */;
2622           else
2623             output_verbatim (buffer, "%s: In instantiation of `%s':\n", file,
2624                              decl_as_string (TINST_DECL (p),
2625                                              TS_DECL_TYPE | TS_FUNC_NORETURN));
2626
2627           line = TINST_LINE (p);
2628           file = TINST_FILE (p);
2629           p = TREE_CHAIN (p);
2630         }
2631     }
2632
2633   print_instantiation_partial_context (buffer, p, file, line);
2634 }
2635
2636 /* Same as above but less verbose.  */
2637 static void
2638 print_instantiation_partial_context (buffer, t, file, line)
2639      output_buffer *buffer;
2640      tree t;
2641      const char *file;
2642      int line;
2643 {
2644   for (; t; t = TREE_CHAIN (t))
2645     {
2646       output_verbatim
2647         (buffer, "%s:%d:   instantiated from `%s'\n", file, line,
2648          decl_as_string (TINST_DECL (t), TS_DECL_TYPE | TS_FUNC_NORETURN));
2649       line = TINST_LINE (t);
2650       file = TINST_FILE (t);
2651     }
2652   output_verbatim (buffer, "%s:%d:   instantiated from here\n", file, line);
2653 }
2654
2655 /* Called from cp_thing to print the template context for an error.  */
2656 static void
2657 maybe_print_instantiation_context (buffer)
2658      output_buffer *buffer;
2659 {
2660   if (!problematic_instantiation_changed () || current_instantiation () == 0)
2661     return;
2662
2663   record_last_problematic_instantiation ();
2664   print_instantiation_full_context (buffer);
2665 }
2666
2667 /* Report the bare minimum context of a template instantiation.  */
2668 void
2669 print_instantiation_context ()
2670 {
2671   print_instantiation_partial_context
2672     (diagnostic_buffer, current_instantiation (), input_filename, lineno);
2673   flush_diagnostic_buffer ();
2674 }
2675 \f
2676 /* Called from output_format -- during diagnostic message processing --
2677    to handle C++ specific format specifier with the following meanings:
2678    %A   function argument-list.
2679    %D   declaration.
2680    %E   expression.
2681    %F   function declaration.
2682    %P   function parameter whose position is indicated by an integer.
2683    %T   type.
2684    %V   cv-qualifier.  */
2685 static int
2686 cp_tree_printer (buffer)
2687      output_buffer *buffer;
2688 {
2689   int be_verbose = 0;
2690   tree_formatting_info tfi;
2691
2692   bzero (&tfi, sizeof (tree_formatting_info));
2693
2694   if (*output_buffer_text_cursor (buffer) == '+')
2695     ++output_buffer_text_cursor (buffer);
2696   if (*output_buffer_text_cursor (buffer) == '#')
2697     {
2698       be_verbose = 1;
2699       ++output_buffer_text_cursor (buffer);
2700     }
2701
2702   switch (*output_buffer_text_cursor (buffer))
2703     {
2704     case 'A':
2705       tree_being_formatted (&tfi) =
2706         va_arg (output_buffer_format_args (buffer), tree);
2707       if (be_verbose)
2708         tree_formatting_flags (&tfi) = TFF_SCOPE
2709           | TFF_FUNCTION_DEFAULT_ARGUMENTS;
2710       print_function_argument_list (buffer, &tfi);
2711       break;
2712
2713     case 'D':
2714       tree_being_formatted (&tfi) =
2715         va_arg (output_buffer_format_args (buffer), tree);
2716       if (be_verbose)
2717         tree_formatting_flags (&tfi) = TFF_SCOPE | TFF_DECL_SPECIFIERS
2718           | TFF_CLASS_KEY_OR_ENUM | TFF_RETURN_TYPE
2719           | TFF_FUNCTION_DEFAULT_ARGUMENTS | TFF_TEMPLATE_DEFAULT_ARGUMENTS
2720           | TFF_EXCEPTION_SPECIFICATION | TFF_CHASE_NAMESPACE_ALIAS;
2721       print_declaration (buffer, &tfi);
2722       break;
2723
2724     case 'E':
2725       tree_being_formatted (&tfi) =
2726         va_arg (output_buffer_format_args (buffer), tree);
2727       if (be_verbose)
2728         tree_formatting_flags (&tfi) = TFF_SCOPE;
2729       print_expression (buffer, &tfi);
2730       break;
2731
2732     case 'F':
2733       tree_being_formatted (&tfi) =
2734         va_arg (output_buffer_format_args (buffer), tree);
2735       if (be_verbose)
2736         tree_formatting_flags (&tfi) = TFF_SCOPE | TFF_DECL_SPECIFIERS
2737           | TFF_RETURN_TYPE | TFF_FUNCTION_DEFAULT_ARGUMENTS
2738           | TFF_EXCEPTION_SPECIFICATION;
2739       print_function_declaration (buffer, &tfi);
2740       break;
2741
2742     case 'P':
2743       print_function_parameter
2744         (buffer, va_arg (output_buffer_format_args (buffer), int));
2745       break;
2746
2747     case 'T':
2748       tree_being_formatted (&tfi) =
2749         va_arg (output_buffer_format_args (buffer), tree);
2750       if (be_verbose)
2751         tree_formatting_flags (&tfi) = TFF_SCOPE | TFF_CLASS_KEY_OR_ENUM
2752           | TFF_RETURN_TYPE | TFF_EXCEPTION_SPECIFICATION;
2753       print_type_id (buffer, &tfi);
2754       break;
2755
2756     case 'V':
2757       tree_being_formatted (&tfi) =
2758         va_arg (output_buffer_format_args (buffer), tree);
2759       print_cv_qualifier_seq (buffer, &tfi);
2760       break;
2761
2762     default:
2763       return 0;
2764     }
2765
2766   return 1;
2767 }
2768
2769 /* Print a function argument-list represented by tree_being_formatted (TFI)
2770    onto BUFFER.  */
2771 static void
2772 print_function_argument_list (buffer, tfi)
2773      output_buffer *buffer __attribute__ ((__unused__));
2774      tfi_t tfi __attribute__  ((__unused__));
2775 {
2776 }
2777
2778 /* Print a declaration represented by tree_being_formatted (TFI)
2779    onto buffer.  */
2780 static void
2781 print_declaration (buffer, tfi)
2782      output_buffer *buffer __attribute__ ((__unused__));
2783      tfi_t tfi __attribute__ ((__unused__));
2784 {
2785 }
2786
2787 /* Print an expression represented by tree_being_formatted (TFI)
2788    onto BUFFER.  */
2789 static void
2790 print_expression (buffer, tfi)
2791      output_buffer *buffer __attribute__ ((__unused__));
2792      tfi_t tfi __attribute__ ((__unused__));
2793 {
2794 }
2795
2796 static void
2797 print_integer (buffer, i)
2798      output_buffer *buffer;
2799      HOST_WIDE_INT i;
2800 {
2801   sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) i);
2802   output_add_string (buffer, digit_buffer);
2803 }
2804
2805 /* Print a function declaration represented by tree_being_formatted (TFI)
2806    onto BUFFER.  */
2807 static void
2808 print_function_declaration (buffer, tfi)
2809      output_buffer *buffer __attribute__ ((__unused__));
2810      tfi_t tfi __attribute__ ((__unused__));
2811 {
2812 }
2813
2814 /* Print the N'th function parameter onto BUFFER.  A negative value of N
2815    means the implicit "this" parameter of a member function.  */
2816 static void
2817 print_function_parameter (buffer, n)
2818      output_buffer *buffer;
2819      int n;
2820 {
2821   if (n < 0)
2822     print_identifier (buffer, "this");
2823   else
2824     output_decimal (buffer, n + 1);
2825 }
2826 \f
2827 /* Print a type represented by tree_being_formatted (TFI) onto BUFFER.  */
2828 static void
2829 print_type_id (buffer, tfi)
2830      output_buffer *buffer;
2831      tfi_t tfi;
2832 {
2833   tree t = tree_being_formatted (tfi);
2834   int flags = tree_formatting_flags (tfi);
2835   if (t == NULL_TREE)
2836     return;
2837
2838   if (flags & TFF_CHASE_TYPEDEF)
2839     tree_being_formatted (tfi) =
2840       typedef_original_name (tree_being_formatted (tfi));
2841
2842   /* A type-id is of the form:
2843      type-id:
2844         type-specifier-seq abstract-declarator(opt)  */
2845   print_type_specifier_seq (buffer, tfi);
2846
2847   if (TYPE_PTRMEMFUNC_P (t))
2848     goto ptr_mem_fun;
2849
2850   /* For types with abstract-declarator, print_type_specifier_seq prints
2851      the start of the abstract-declarator.  Fiinish the job.  */
2852   switch (TREE_CODE (t))
2853     {
2854     case ARRAY_TYPE:
2855     case POINTER_TYPE:
2856     case REFERENCE_TYPE:
2857     case OFFSET_TYPE:
2858     case METHOD_TYPE:
2859     case FUNCTION_TYPE:
2860     ptr_mem_fun:
2861       print_rest_of_abstract_declarator (buffer, tfi);
2862
2863     default:
2864       break;
2865     }
2866
2867   tree_being_formatted (tfi) = t;
2868 }
2869
2870 /* Print the type-specifier-seq part of a type-id.  If appropriate, print
2871  also the prefix of the abstract-declarator.  */
2872 static void
2873 print_type_specifier_seq (buffer, tfi)
2874      output_buffer *buffer;
2875      tfi_t tfi;
2876 {
2877   int flags = tree_formatting_flags (tfi);
2878   tree t = tree_being_formatted (tfi);
2879   enum tree_code code = TREE_CODE (t);
2880
2881   /* A type-speficier-seq is:
2882          type-specifier type-specifier-seq(opt)
2883      where
2884          type-specifier:
2885              simple-type-specifier
2886              class-specifier
2887              enum-specifier
2888              elaborated-type-specifier
2889              cv-qualifier
2890
2891      We do not, however, pretty-print class-specifier nor enum-specifier.  */
2892
2893   switch (code)
2894     {
2895     case UNKNOWN_TYPE:
2896     case IDENTIFIER_NODE:
2897     case VOID_TYPE:
2898     case INTEGER_TYPE:
2899     case REAL_TYPE:
2900     case COMPLEX_TYPE:
2901     case ENUMERAL_TYPE:
2902     case BOOLEAN_TYPE:
2903     case UNION_TYPE:
2904     case TYPE_DECL:
2905     case TEMPLATE_DECL:
2906     case TEMPLATE_TYPE_PARM:
2907     case TYPEOF_TYPE:
2908     case TEMPLATE_TEMPLATE_PARM:
2909     case TYPENAME_TYPE:
2910     class_type:
2911       print_cv_qualifier_seq (buffer, tfi);
2912       if ((flags & TFF_DECL_SPECIFIERS)
2913           && (code ==  TYPENAME_TYPE || IS_AGGR_TYPE (t)))
2914         print_elaborated_type_specifier (buffer, tfi);
2915       else
2916         print_simple_type_specifier (buffer, tfi);
2917       break;
2918
2919       /* Because the abstract-declarator can modify the type-specifier-seq
2920          in a highly non linear manner, we pretty-print its prefix here.
2921          The suffix part is handled by print_rest_of_abstract_declarator.  */
2922
2923       /* A RECORD_TYPE is also used to represent a pointer to member
2924          function.  */
2925     case RECORD_TYPE:
2926       if (TYPE_PTRMEMFUNC_P (t))
2927         {
2928           /* Print the return type.  */
2929           tree_being_formatted (tfi) =
2930             TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t));
2931           print_type_id (buffer, tfi);
2932           print_whitespace (buffer, tfi);
2933
2934           /* Then the beginning of the abstract-declarator part.  */
2935           tree_being_formatted (tfi) =
2936             TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (t));
2937           print_left_paren (buffer);
2938           print_nested_name_specifier (buffer, tfi);
2939         }
2940       else
2941         goto class_type;
2942       break;
2943
2944     case POINTER_TYPE:
2945       if (TYPE_PTRMEM_P (t))
2946         goto ptr_data_member;
2947       else
2948         goto non_ptr_data_member;
2949       break;
2950
2951     case ARRAY_TYPE:
2952     case REFERENCE_TYPE:
2953     case FUNCTION_TYPE:
2954     case METHOD_TYPE:
2955     non_ptr_data_member:
2956       tree_being_formatted (tfi) = TREE_TYPE (t);
2957       print_type_specifier_seq (buffer, tfi);
2958       if (code == POINTER_TYPE || code == REFERENCE_TYPE)
2959         {
2960           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2961             print_left_paren (buffer);
2962         }
2963       else if (code == FUNCTION_TYPE || code == METHOD_TYPE)
2964         {
2965           print_whitespace (buffer, tfi);
2966           print_left_paren (buffer);
2967           if (code == METHOD_TYPE)
2968             {
2969               tree_being_formatted (tfi) = TYPE_METHOD_BASETYPE (t);
2970               print_nested_name_specifier (buffer, tfi);
2971               tree_being_formatted (tfi) = t;
2972             }
2973         }
2974       tree_being_formatted (tfi) = t;
2975       break;
2976
2977     ptr_data_member:
2978     case OFFSET_TYPE:
2979       /* Firstly, the type of the member.  */
2980       tree_being_formatted (tfi) = TREE_TYPE (t);
2981       print_type_id (buffer, tfi);
2982       print_whitespace (buffer, tfi);
2983
2984       /* Then, the containing class.  */
2985       tree_being_formatted (tfi) = TYPE_OFFSET_BASETYPE (t);
2986       print_nested_name_specifier (buffer, tfi);
2987       tree_being_formatted (tfi) = t;
2988       break;
2989
2990     default:
2991       sorry_for_unsupported_tree (t);
2992       /* fall throught  */
2993
2994     case ERROR_MARK:
2995       print_identifier (buffer, "{type-specifier-seq error}");
2996       break;
2997     }
2998
2999   tree_being_formatted (tfi) = t;
3000 }
3001
3002 /* Print the simpe-type-specifier component of a type-specifier.  */
3003 static void
3004 print_simple_type_specifier (buffer, tfi)
3005      output_buffer *buffer;
3006      tfi_t tfi;
3007 {
3008   int flags = tree_formatting_flags (tfi);
3009   tree t = tree_being_formatted (tfi);
3010   enum tree_code code = TREE_CODE (t);
3011
3012   switch (code)
3013     {
3014     case UNKNOWN_TYPE:
3015       print_identifier (buffer, "{unknown type}");
3016       break;
3017
3018     case IDENTIFIER_NODE:
3019       print_tree_identifier (buffer, t);
3020       break;
3021
3022     case COMPLEX_TYPE:
3023       print_identifier (buffer, "__complex__ ");
3024       tree_being_formatted (tfi) = TREE_TYPE (t);
3025       print_type_id (buffer, tfi);
3026       break;
3027
3028     case TYPENAME_TYPE:
3029       tree_being_formatted (tfi) = TYPE_CONTEXT (t);
3030       print_nested_name_specifier (buffer, tfi);
3031       tree_being_formatted (tfi) = TYPENAME_TYPE_FULLNAME (t);
3032       tree_formatting_flags (tfi) |= ~TFF_CHASE_TYPEDEF;
3033       print_type_id (buffer, tfi);
3034       break;
3035
3036     case TYPEOF_TYPE:
3037       print_identifier (buffer, "__typeof__");
3038       tree_being_formatted (tfi) = TYPE_FIELDS (t);
3039       print_left_paren (buffer);
3040       print_expression (buffer, tfi);
3041       print_right_paren (buffer);
3042       break;
3043
3044     case INTEGER_TYPE:
3045       if (TREE_UNSIGNED (t))
3046         {
3047           if (TYPE_MAIN_VARIANT (t) == integer_type_node)
3048             /* We don't want pedantry like `unsigned int'.  */;
3049           else if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)))
3050             {
3051               print_identifier (buffer, "unsigned");
3052               print_whitespace (buffer, tfi);
3053             }
3054         }
3055       else if (TYPE_MAIN_VARIANT (t) == char_type_node)
3056         {
3057           print_identifier (buffer, "signed");
3058           print_whitespace (buffer, tfi);
3059         }
3060     case REAL_TYPE:
3061     case BOOLEAN_TYPE:
3062     case VOID_TYPE:
3063       {
3064         tree s = (flags & TFF_CHASE_TYPEDEF) ? TYPE_MAIN_VARIANT (t) : t;
3065
3066         if (TYPE_NAME (s) && TYPE_IDENTIFIER (s))
3067           print_tree_identifier (buffer, TYPE_IDENTIFIER (s));
3068         else
3069           /* Types like intQI_type_node and friends have no names.
3070              These don't come up in user error messages, but it's nice
3071              to be able to print them from the debugger.  */
3072           print_identifier (buffer, "{anonymous}");
3073       }
3074       break;
3075
3076     case TEMPLATE_TEMPLATE_PARM:
3077       if (TYPE_IDENTIFIER (t))
3078         print_tree_identifier (buffer, TYPE_IDENTIFIER (t));
3079       else
3080         print_identifier (buffer, "{anonymous template template parameter}");
3081       break;
3082
3083     case TYPE_DECL:
3084       if (flags & TFF_CHASE_TYPEDEF)
3085         print_type_id (buffer, tfi);
3086       else
3087         print_tree_identifier (buffer, DECL_NAME (t));
3088       break;
3089
3090     case BOUND_TEMPLATE_TEMPLATE_PARM:
3091     case TEMPLATE_DECL:
3092       print_template_id (buffer, tfi);
3093       break;
3094
3095     case TEMPLATE_TYPE_PARM:
3096       if (TYPE_IDENTIFIER (t))
3097         print_tree_identifier (buffer, TYPE_IDENTIFIER (t));
3098       else
3099         print_identifier (buffer, "{anonymous template type parameter}");
3100       break;
3101
3102     default:
3103       break;
3104     }
3105
3106   tree_being_formatted (tfi) = t;
3107   tree_formatting_flags (tfi) = flags;
3108 }
3109
3110 /* Print the elaborated-type-specifier form of a type-specifier.  */
3111 static void
3112 print_elaborated_type_specifier (buffer, tfi)
3113      output_buffer *buffer;
3114      tfi_t tfi;
3115 {
3116   int flags = tree_formatting_flags (tfi);
3117   tree t = tree_being_formatted (tfi);
3118
3119   switch (TREE_CODE (t))
3120     {
3121     case TYPENAME_TYPE:
3122       print_identifier (buffer, "typename");
3123       print_whitespace (buffer, tfi);
3124       tree_formatting_flags (tfi) |= ~TFF_DECL_SPECIFIERS;
3125       print_simple_type_specifier (buffer, tfi);
3126       break;
3127
3128     case UNION_TYPE:
3129     case RECORD_TYPE:
3130       {
3131         tree name = NULL_TREE;
3132
3133         if (flags & TFF_CHASE_TYPEDEF)
3134           tree_being_formatted (tfi) = typedef_original_name (t);
3135
3136         print_identifier
3137           (buffer, class_key_or_enum (tree_being_formatted (tfi)));
3138         print_whitespace (buffer, tfi);
3139
3140         name = TYPE_NAME (tree_being_formatted (tfi));
3141         if (name)
3142           {
3143             if (flags & TFF_SCOPE)
3144               {
3145                 tree_being_formatted (tfi) = CP_DECL_CONTEXT (name);
3146                 print_nested_name_specifier (buffer, tfi);
3147               }
3148             print_tree_identifier (buffer, DECL_NAME (name));
3149           }
3150         else
3151           print_identifier (buffer, "{anonymous}");
3152       }
3153       break;
3154
3155     default:
3156       sorry_for_unsupported_tree (t);
3157       break;
3158     }
3159
3160   tree_being_formatted (tfi) = t;
3161   tree_formatting_flags (tfi) = flags;
3162 }
3163
3164 /* Finish the job of printing the abstract-declarator part of a
3165    type-id.  */
3166 static void
3167 print_rest_of_abstract_declarator (buffer, tfi)
3168      output_buffer *buffer;
3169      tfi_t tfi;
3170 {
3171   tree t = tree_being_formatted (tfi);
3172   enum tree_code code = TREE_CODE (t);
3173
3174   /* An abstract-declarator has the form:
3175
3176      abstract-declarator:
3177           ptr-operator abstract-declarator(opt)
3178           direct-abstract-declarator
3179
3180      direct-abstract-declarator:
3181           direct-abstract-declarator(opt)
3182               ( parameter-declaration-clause ) cv-qualifier-seq(opt)
3183                     exception-specification(opt)
3184           direct-abstract-declarator(opt) [ constant-expression(opt) ]
3185           ( direct-abstract-declarator )   */
3186
3187   switch (code)
3188     {
3189     case ARRAY_TYPE:
3190       print_left_bracket (buffer);
3191       if (TYPE_DOMAIN (t))
3192         {
3193           tree s = TYPE_DOMAIN (t);
3194
3195           if (host_integerp (TYPE_MAX_VALUE (s), 0))
3196             output_decimal (buffer, tree_low_cst (TYPE_MAX_VALUE (s), 0) + 1);
3197           else if (TREE_CODE (TYPE_MAX_VALUE (s)) == MINUS_EXPR)
3198             {
3199               tree_being_formatted (tfi) =
3200                 TREE_OPERAND (TYPE_MAX_VALUE (s), 0);
3201               print_expression (buffer, tfi);
3202               tree_being_formatted (tfi) = t;
3203             }
3204           else
3205             {
3206               tree_being_formatted (tfi) = fold
3207                 (cp_build_binary_op (PLUS_EXPR, TYPE_MAX_VALUE (s),
3208                                      integer_one_node));
3209               print_expression (buffer, tfi);
3210               tree_being_formatted (tfi) = t;
3211             }
3212         }
3213       print_right_bracket (buffer);
3214       put_whitespace (tfi) = none;
3215       tree_being_formatted (tfi) = TREE_TYPE (t);
3216       print_rest_of_abstract_declarator (buffer, tfi);
3217       tree_being_formatted (tfi) = t;
3218       break;
3219
3220     case POINTER_TYPE:
3221     case REFERENCE_TYPE:
3222     case OFFSET_TYPE:
3223       if (code == POINTER_TYPE || code == REFERENCE_TYPE)
3224         {
3225           output_add_character (buffer, "&*"[code == POINTER_TYPE]);
3226           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
3227             print_right_paren (buffer);
3228         }
3229       put_whitespace (tfi) = before;
3230       print_cv_qualifier_seq (buffer, tfi);
3231       tree_being_formatted (tfi) = TREE_TYPE (t);
3232       print_rest_of_abstract_declarator (buffer, tfi);
3233       tree_being_formatted (tfi) = t;
3234       break;
3235
3236     case FUNCTION_TYPE:
3237     case METHOD_TYPE:
3238       print_right_paren (buffer);
3239       print_whitespace (buffer, tfi);
3240
3241       /* Skip the `this' implicit parameter if present.  */
3242       tree_being_formatted (tfi) = TYPE_ARG_TYPES (t);
3243       if (code == METHOD_TYPE)
3244         tree_being_formatted (tfi) = TREE_CHAIN (tree_being_formatted (tfi));
3245
3246       /* Print the parameter-list.  */
3247       print_left_paren (buffer);
3248       print_parameter_declaration_clause (buffer, tfi);
3249       print_right_paren (buffer);
3250
3251       print_whitespace (buffer, tfi);
3252
3253       if (code == METHOD_TYPE)
3254         {
3255           tree_being_formatted (tfi) =
3256             TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)));
3257           print_cv_qualifier_seq (buffer, tfi);
3258         }
3259
3260       /* Finish the abstract-declarator.  */
3261       tree_being_formatted (tfi) = TREE_TYPE (t);
3262       print_rest_of_abstract_declarator (buffer, tfi);
3263
3264       /* Print the exception-specification for documentaion purpose.  */
3265       tree_being_formatted (tfi) = TYPE_RAISES_EXCEPTIONS (t);
3266       print_exception_specification (buffer, tfi);
3267       tree_being_formatted (tfi) = t;
3268       break;
3269
3270       /* These types don't have abstract-declarator.  */
3271     case UNKNOWN_TYPE:
3272     case IDENTIFIER_NODE:
3273     case VOID_TYPE:
3274     case INTEGER_TYPE:
3275     case REAL_TYPE:
3276     case COMPLEX_TYPE:
3277     case ENUMERAL_TYPE:
3278     case BOOLEAN_TYPE:
3279     case UNION_TYPE:
3280     case TYPE_DECL:
3281     case TEMPLATE_DECL:
3282     case TEMPLATE_TYPE_PARM:
3283     case TYPEOF_TYPE:
3284     case TEMPLATE_TEMPLATE_PARM:
3285     case TYPENAME_TYPE:
3286       break;
3287
3288     default:
3289       sorry_for_unsupported_tree (t);
3290       /* fall throught.  */
3291     case ERROR_MARK:
3292       break;
3293     }
3294 }
3295
3296 /* Print the cv-quafilers of tree_being_formatted (TFI) onto BUFFER.  */
3297 static void
3298 print_cv_qualifier_seq (buffer, tfi)
3299      output_buffer *buffer;
3300      tree_formatting_info *tfi;
3301 {
3302   int cv = TYPE_QUALS (tree_being_formatted (tfi));
3303   int pad_after = after == put_whitespace (tfi);
3304   static const int mask[]
3305     = {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
3306   static const char *const qualifier[]
3307     = { "const", "volatile", "__restrict__" };
3308
3309   if (cv != 0)
3310     {
3311       int i;
3312       for (i = 0; i != 3; ++i)
3313         if (mask[i] & cv)
3314           {
3315             if (put_whitespace (tfi) == before)
3316               output_add_space (buffer);
3317             print_identifier (buffer, qualifier[i]);
3318             put_whitespace (tfi) = before;
3319           }
3320
3321       if (pad_after)
3322         {
3323           output_add_space (buffer);
3324           put_whitespace (tfi) = none;
3325         }
3326     }
3327 }
3328
3329 static void
3330 print_parameter_declaration_clause (buffer, tfi)
3331      output_buffer *buffer __attribute__ ((__unused__));
3332      tfi_t tfi __attribute__ ((__unused__));
3333 {
3334 }
3335
3336 static void
3337 print_exception_specification (buffer, tfi)
3338      output_buffer *buffer __attribute__ ((__unused__));
3339      tfi_t tfi __attribute__ ((__unused__));
3340 {
3341 }
3342
3343 static void
3344 print_nested_name_specifier (buffer, tfi)
3345      output_buffer *buffer;
3346      tfi_t tfi;
3347 {
3348   int flags = tree_formatting_flags (tfi);
3349   tree t = tree_being_formatted (tfi);
3350   /* A nested-name-specifier is:
3351         class-or-namespace-name :: nested-name-specifier(opt)
3352         class-or-namespace-name :: template nested-name-specifier
3353
3354      The latter form being the correct syntax for a name  designating
3355      a template member, where the preceding class-or-namespace-name part
3356      is name-dependent.  For the time being, we do not do such a
3357      sophisticated pretty-printing.
3358
3359      class-or-namespace-name:
3360         class-name
3361         namespace-name  */
3362
3363   if (t == NULL_TREE || t == global_namespace)
3364     return;
3365
3366   if (CLASS_TYPE_P (t) && !(flags & TFF_CLASS_SCOPE))
3367     return;
3368
3369   if (TREE_CODE (t) == NAMESPACE_DECL && !(flags & TFF_NAMESPACE_SCOPE))
3370     return;
3371
3372   tree_being_formatted (tfi) = DECL_CONTEXT (t);
3373   print_nested_name_specifier (buffer, tfi);
3374   print_scope_operator (buffer);
3375   if (TREE_CODE (t) == NAMESPACE_DECL)
3376     print_tree_identifier (buffer, DECL_NAME (t));
3377   else if (CLASS_TYPE_P (t))
3378     {
3379       if (!DECL_USE_TEMPLATE (t))
3380         print_tree_identifier (buffer, TYPE_IDENTIFIER (t));
3381       else
3382         {
3383           tree_being_formatted (tfi) = t;
3384           print_template_id (buffer, tfi);
3385         }
3386     }
3387
3388   tree_being_formatted (tfi) = t;
3389 }
3390
3391 static void
3392 print_template_id (buffer, tfi)
3393      output_buffer *buffer;
3394      tfi_t tfi __attribute__ ((__unused__));
3395 {
3396   print_template_argument_list_start (buffer);
3397   /* ... */
3398   print_template_argument_list_end (buffer);
3399 }
3400
3401 static tree
3402 typedef_original_name (t)
3403      tree t;
3404 {
3405   return DECL_ORIGINAL_TYPE (t) ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t);
3406 }
3407
3408 static void
3409 print_non_consecutive_character (buffer, c)
3410      output_buffer *buffer;
3411      int c;
3412 {
3413   const char *p = output_last_position (buffer);
3414
3415   if (p != NULL && *p == c)
3416     output_add_space (buffer);
3417   output_add_character (buffer, c);
3418 }