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