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