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