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