]> gcc.gnu.org Git - gcc.git/blame - gcc/cp/error.c
59th Cygnus<->FSF merge
[gcc.git] / gcc / cp / error.c
CommitLineData
8d08fdba
MS
1/* Call-backs for C++ error reporting.
2 This code is non-reentrant.
3 Copyright (C) 1993 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include "config.h"
22#include "tree.h"
23#include "cp-tree.h"
24#include "obstack.h"
25#include <ctype.h>
26
27typedef char* cp_printer ();
28
29#define A args_as_string
30#define C code_as_string
31#define D decl_as_string
32#define E expr_as_string
33#define L language_as_string
34#define O op_as_string
35#define P parm_as_string
36#define T type_as_string
37
38#define _ (cp_printer *) 0
39cp_printer * cp_printers[256] =
40{
41/*0 1 2 3 4 5 6 7 8 9 A B C D E F */
42 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */
43 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */
44 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */
45 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */
46 _, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */
47 P, _, _, _, T, _, _, _, _, _, _, _, _, _, _, _, /* 0x50 */
48 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */
49 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */
50};
51#undef C
52#undef D
53#undef E
54#undef L
55#undef O
56#undef P
57#undef T
58#undef _
59
60#define obstack_chunk_alloc xmalloc
61#define obstack_chunk_free free
62
63/* Obstack where we build text strings for overloading, etc. */
64static struct obstack scratch_obstack;
65static char *scratch_firstobj;
66
67# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
68# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
69# define OB_PUTC2(C1,C2) \
70 (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
71# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
72# define OB_PUTID(ID) \
73 (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \
74 IDENTIFIER_LENGTH (ID)))
75# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
76# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
77# define OB_PUTI(CST) do { sprintf (digit_buffer, "%d", (CST)); \
78 OB_PUTCP (digit_buffer); } while (0)
51c184be 79# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));
8d08fdba
MS
80
81# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
82
83static void dump_type (), dump_decl (), dump_function_decl ();
84static void dump_expr (), dump_unary_op (), dump_binary_op ();
85static void dump_aggr_type (), dump_type_prefix (), dump_type_suffix ();
86static void dump_function_name ();
87
88void
89init_error ()
90{
91 gcc_obstack_init (&scratch_obstack);
92 scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
93}
94
8d08fdba
MS
95enum pad { none, before, after };
96
97static void
98dump_readonly_or_volatile (t, p)
99 tree t;
100 enum pad p;
101{
102 if (TYPE_READONLY (t) || TYPE_VOLATILE (t))
103 {
104 if (p == before) OB_PUTC (' ');
105 if (TYPE_READONLY (t))
106 OB_PUTS ("const");
00595019
MS
107 if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
108 OB_PUTC (' ');
8d08fdba
MS
109 if (TYPE_VOLATILE (t))
110 OB_PUTS ("volatile");
111 if (p == after) OB_PUTC (' ');
112 }
113}
114
115/* This must be large enough to hold any printed integer or floating-point
116 value. */
117static char digit_buffer[128];
118
119/* Dump into the obstack a human-readable equivalent of TYPE. */
120static void
121dump_type (t, v)
122 tree t;
123 int v; /* verbose? */
124{
125 if (t == NULL_TREE)
126 return;
127
128 if (TYPE_PTRMEMFUNC_P (t))
129 goto offset_type;
130
131 switch (TREE_CODE (t))
132 {
133 case ERROR_MARK:
51c184be 134 OB_PUTS ("{error}");
8d08fdba
MS
135 break;
136
137 case UNKNOWN_TYPE:
51c184be 138 OB_PUTS ("{unknown type}");
8d08fdba
MS
139 break;
140
141 case TREE_LIST:
142 /* i.e. function taking no arguments */
143 if (t != void_list_node)
144 {
145 dump_type (TREE_VALUE (t), v);
146 /* Can this happen other than for default arguments? */
147 if (TREE_PURPOSE (t) && v)
148 {
149 OB_PUTS (" = ");
150 dump_expr (TREE_PURPOSE (t));
151 }
152 if (TREE_CHAIN (t))
153 {
154 if (TREE_CHAIN (t) != void_list_node)
155 {
156 OB_PUTC2 (',', ' ');
157 dump_type (TREE_CHAIN (t), v);
158 }
159 }
160 else OB_PUTS (" ...");
161 }
162 break;
163
164 case IDENTIFIER_NODE:
165 OB_PUTID (t);
166 break;
167
168 case TREE_VEC:
169 dump_type (BINFO_TYPE (t), v);
170 break;
171
172 case RECORD_TYPE:
173 case UNION_TYPE:
174 case ENUMERAL_TYPE:
175 if (TYPE_LANG_SPECIFIC (t)
176 && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
177 {
178 if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
179 dump_readonly_or_volatile (t);
180 dump_type (SIGNATURE_TYPE (t), v);
181 if (IS_SIGNATURE_POINTER (t))
182 OB_PUTC ('*');
183 else
184 OB_PUTC ('&');
185 }
186 else
187 dump_aggr_type (t, v);
188 break;
189
190 case TYPE_DECL:
7177d104 191 dump_decl (t, v);
8d08fdba
MS
192 break;
193
194 case INTEGER_TYPE:
195 if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
196 OB_PUTS ("unsigned ");
197 else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
198 OB_PUTS ("signed ");
199
200 /* fall through. */
201 case REAL_TYPE:
202 case VOID_TYPE:
2986ae00 203 case BOOLEAN_TYPE:
8d08fdba
MS
204 dump_readonly_or_volatile (t, after);
205 OB_PUTID (TYPE_IDENTIFIER (t));
206 break;
207
208 case TEMPLATE_TYPE_PARM:
8d08fdba 209 OB_PUTID (TYPE_IDENTIFIER (t));
8d08fdba
MS
210 break;
211
212 case UNINSTANTIATED_P_TYPE:
213 OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));
214 OB_PUTS ("<...>");
215 break;
216
217 /* This is not always necessary for pointers and such, but doing this
218 reduces code size. */
219 case ARRAY_TYPE:
220 case POINTER_TYPE:
221 case REFERENCE_TYPE:
222 case OFFSET_TYPE:
223 offset_type:
224 case FUNCTION_TYPE:
225 case METHOD_TYPE:
226 dump_type_prefix (t, v);
227 dump_type_suffix (t, v);
228 break;
229
230 default:
51c184be
MS
231 sorry ("`%s' not supported by dump_type",
232 tree_code_name[(int) TREE_CODE (t)]);
8d08fdba
MS
233 }
234}
235
51c184be
MS
236static char *
237aggr_variety (t)
8d08fdba 238 tree t;
8d08fdba 239{
8d08fdba 240 if (TREE_CODE (t) == ENUMERAL_TYPE)
51c184be 241 return "enum";
8d08fdba 242 else if (TREE_CODE (t) == UNION_TYPE)
51c184be 243 return "union";
8d08fdba 244 else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
51c184be 245 return "class";
8d08fdba 246 else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t))
51c184be 247 return "signature";
8d08fdba 248 else
51c184be
MS
249 return "struct";
250}
251
252/* Print out a class declaration, in the form `class foo'. */
253static void
254dump_aggr_type (t, v)
255 tree t;
256 int v; /* verbose? */
257{
258 tree name;
259 char *variety = aggr_variety (t);
8d08fdba
MS
260
261 dump_readonly_or_volatile (t, after);
262
263 if (v > 0)
264 {
265 OB_PUTCP (variety);
266 OB_PUTC (' ');
267 }
268
269 name = TYPE_NAME (t);
270
271 if (DECL_CONTEXT (name))
272 {
273 /* FUNCTION_DECL or RECORD_TYPE */
274 dump_decl (DECL_CONTEXT (name), 0);
275 OB_PUTC2 (':', ':');
276 }
277
278 /* kludge around wierd behavior on g++.brendan/line1.C */
279 if (TREE_CODE (name) != IDENTIFIER_NODE)
280 name = DECL_NAME (name);
281
282 if (ANON_AGGRNAME_P (name))
283 {
51c184be 284 OB_PUTS ("{anonymous");
8d08fdba
MS
285 if (!v)
286 {
287 OB_PUTC (' ');
288 OB_PUTCP (variety);
289 }
51c184be 290 OB_PUTC ('}');
8d08fdba
MS
291 }
292 else
293 OB_PUTID (name);
294}
295
296/* Dump into the obstack the initial part of the output for a given type.
297 This is necessary when dealing with things like functions returning
298 functions. Examples:
299
300 return type of `int (* fee ())()': pointer -> function -> int. Both
301 pointer (and reference and offset) and function (and member) types must
302 deal with prefix and suffix.
303
304 Arrays must also do this for DECL nodes, like int a[], and for things like
305 int *[]&. */
306
307static void
308dump_type_prefix (t, v)
309 tree t;
310 int v; /* verbosity */
311{
312 if (TYPE_PTRMEMFUNC_P (t))
313 {
314 t = TYPE_PTRMEMFUNC_FN_TYPE (t);
315 goto offset_type;
316 }
317
318 switch (TREE_CODE (t))
319 {
320 case POINTER_TYPE:
321 {
322 tree sub = TREE_TYPE (t);
323
324 dump_type_prefix (sub, v);
325 /* A tree for a member pointer looks like pointer to offset,
326 so let the OFFSET_TYPE case handle it. */
327 if (TREE_CODE (sub) != OFFSET_TYPE)
328 {
329 switch (TREE_CODE (sub))
330 {
331 /* We don't want int ( *)() */
332 case FUNCTION_TYPE:
333 case METHOD_TYPE:
334 break;
335
39211cd5
MS
336 case ARRAY_TYPE:
337 OB_PUTC2 (' ', '(');
338 break;
339
8d08fdba
MS
340 case POINTER_TYPE:
341 /* We don't want "char * *" */
342 if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
343 break;
344 /* But we do want "char *const *" */
345
346 default:
347 OB_PUTC (' ');
348 }
349 OB_PUTC ('*');
350 dump_readonly_or_volatile (t, none);
351 }
352 }
353 break;
354
355 case REFERENCE_TYPE:
356 {
357 tree sub = TREE_TYPE (t);
358 dump_type_prefix (sub, v);
359
360 switch (TREE_CODE (sub))
361 {
2986ae00
MS
362 case ARRAY_TYPE:
363 OB_PUTC2 (' ', '(');
364 break;
365
8d08fdba
MS
366 case POINTER_TYPE:
367 /* We don't want "char * &" */
368 if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
369 break;
370 /* But we do want "char *const &" */
371
372 default:
373 OB_PUTC (' ');
374 }
375 }
376 OB_PUTC ('&');
377 dump_readonly_or_volatile (t, none);
378 break;
379
380 case OFFSET_TYPE:
381 offset_type:
382 dump_type_prefix (TREE_TYPE (t), v);
51c184be
MS
383 if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
384 {
385 OB_PUTC (' ');
386 dump_type (TYPE_OFFSET_BASETYPE (t), 0);
387 OB_PUTC2 (':', ':');
388 }
8d08fdba
MS
389 OB_PUTC ('*');
390 dump_readonly_or_volatile (t, none);
391 break;
392
393 /* Can only be reached through function pointer -- this would not be
394 correct if FUNCTION_DECLs used it. */
395 case FUNCTION_TYPE:
396 dump_type_prefix (TREE_TYPE (t), v);
397 OB_PUTC2 (' ', '(');
398 break;
399
400 case METHOD_TYPE:
401 dump_type_prefix (TREE_TYPE (t), v);
402 OB_PUTC2 (' ', '(');
403 dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0);
404 OB_PUTC2 (':', ':');
405 break;
406
407 case ARRAY_TYPE:
408 dump_type_prefix (TREE_TYPE (t), v);
409 break;
410
411 case ENUMERAL_TYPE:
412 case ERROR_MARK:
413 case IDENTIFIER_NODE:
414 case INTEGER_TYPE:
2986ae00 415 case BOOLEAN_TYPE:
8d08fdba
MS
416 case REAL_TYPE:
417 case RECORD_TYPE:
418 case TEMPLATE_TYPE_PARM:
419 case TREE_LIST:
420 case TYPE_DECL:
421 case TREE_VEC:
422 case UNINSTANTIATED_P_TYPE:
423 case UNION_TYPE:
424 case UNKNOWN_TYPE:
425 case VOID_TYPE:
426 dump_type (t, v);
427 break;
428
429 default:
51c184be
MS
430 sorry ("`%s' not supported by dump_type_prefix",
431 tree_code_name[(int) TREE_CODE (t)]);
8d08fdba
MS
432 }
433}
434
435static void
436dump_type_suffix (t, v)
437 tree t;
438 int v; /* verbose? */
439{
440 if (TYPE_PTRMEMFUNC_P (t))
441 t = TYPE_PTRMEMFUNC_FN_TYPE (t);
442
443 switch (TREE_CODE (t))
444 {
445 case POINTER_TYPE:
446 case REFERENCE_TYPE:
447 case OFFSET_TYPE:
39211cd5
MS
448 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
449 OB_PUTC (')');
8d08fdba
MS
450 dump_type_suffix (TREE_TYPE (t), v);
451 break;
452
453 /* Can only be reached through function pointer */
454 case FUNCTION_TYPE:
455 case METHOD_TYPE:
456 {
457 tree arg;
458 OB_PUTC2 (')', '(');
459 arg = TYPE_ARG_TYPES (t);
460 if (TREE_CODE (t) == METHOD_TYPE)
461 arg = TREE_CHAIN (arg);
462
463 if (arg)
464 dump_type (arg, v);
465 else
466 OB_PUTS ("...");
467 OB_PUTC (')');
468 if (TREE_CODE (t) == METHOD_TYPE)
469 dump_readonly_or_volatile
470 (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
471 dump_type_suffix (TREE_TYPE (t), v);
472 break;
473 }
474
475 case ARRAY_TYPE:
476 OB_PUTC ('[');
477 if (TYPE_DOMAIN (t))
478 OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
479 OB_PUTC (']');
480 dump_type_suffix (TREE_TYPE (t), v);
481 break;
482
483 case ENUMERAL_TYPE:
484 case ERROR_MARK:
485 case IDENTIFIER_NODE:
486 case INTEGER_TYPE:
2986ae00 487 case BOOLEAN_TYPE:
8d08fdba
MS
488 case REAL_TYPE:
489 case RECORD_TYPE:
490 case TEMPLATE_TYPE_PARM:
491 case TREE_LIST:
492 case TYPE_DECL:
493 case TREE_VEC:
494 case UNINSTANTIATED_P_TYPE:
495 case UNION_TYPE:
496 case UNKNOWN_TYPE:
497 case VOID_TYPE:
498 break;
499
500 default:
51c184be
MS
501 sorry ("`%s' not supported by dump_type_suffix",
502 tree_code_name[(int) TREE_CODE (t)]);
8d08fdba
MS
503 }
504}
505
506/* Return a function declaration which corresponds to the IDENTIFIER_NODE
507 argument. */
508tree
509ident_fndecl (t)
510 tree t;
511{
700f8a87 512 tree n = lookup_name (t, 0);
8d08fdba
MS
513
514 if (TREE_CODE (n) == FUNCTION_DECL)
515 return n;
516 else if (TREE_CODE (n) == TREE_LIST
517 && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL)
518 return TREE_VALUE (n);
8926095f
MS
519
520 my_friendly_abort (66);
521 return NULL_TREE;
8d08fdba
MS
522}
523
524#ifndef NO_DOLLAR_IN_LABEL
525# define GLOBAL_THING "_GLOBAL_$"
526#else
527# ifndef NO_DOT_IN_LABEL
528# define GLOBAL_THING "_GLOBAL_."
529# else
530# define GLOBAL_THING "_GLOBAL__"
531# endif
532#endif
533
534#define GLOBAL_IORD_P(NODE) \
535 !strncmp(IDENTIFIER_POINTER(NODE),GLOBAL_THING,sizeof(GLOBAL_THING)-1)
536
537void
538dump_global_iord (t)
539 tree t;
540{
541 char *name = IDENTIFIER_POINTER (t);
542
543 OB_PUTS ("(static ");
544 if (name [sizeof (GLOBAL_THING) - 1] == 'I')
545 OB_PUTS ("initializers");
546 else if (name [sizeof (GLOBAL_THING) - 1] == 'D')
547 OB_PUTS ("destructors");
548 else
549 my_friendly_abort (352);
550
551 OB_PUTS (" for ");
552 OB_PUTCP (input_filename);
553 OB_PUTC (')');
554}
555
556static void
557dump_decl (t, v)
558 tree t;
559 int v; /* verbosity */
560{
561 if (t == NULL_TREE)
562 return;
563
564 switch (TREE_CODE (t))
565 {
566 case ERROR_MARK:
567 OB_PUTS (" /* decl error */ ");
568 break;
569
7177d104 570 case TYPE_DECL:
8d2733ca
MS
571 {
572 /* Don't say 'typedef class A' */
573 tree type = TREE_TYPE (t);
f376e137
MS
574 if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type))
575 || TREE_CODE (type) == ENUMERAL_TYPE)
8d2733ca
MS
576 && type == TYPE_MAIN_VARIANT (type))
577 {
578 dump_type (type, v);
579 break;
580 }
581 }
582 if (v > 0)
583 OB_PUTS ("typedef ");
584 goto general;
7177d104
MS
585 break;
586
8d08fdba 587 case VAR_DECL:
b7484fbe 588 if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
8d08fdba
MS
589 {
590 OB_PUTS ("vtable for ");
591 dump_type (DECL_CONTEXT (t), v);
592 break;
593 }
594 /* else fall through */
595 case FIELD_DECL:
596 case PARM_DECL:
7177d104 597 general:
8d08fdba
MS
598 if (v > 0)
599 {
600 dump_type_prefix (TREE_TYPE (t), v);
7177d104 601 OB_PUTC (' ');
8ccc31eb 602 dump_readonly_or_volatile (t, after);
8d08fdba
MS
603 }
604 /* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */
8d2733ca
MS
605 if (DECL_CONTEXT (t)
606 && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')
8d08fdba
MS
607 {
608 dump_type (DECL_CONTEXT (t), 0);
7177d104 609 OB_PUTC2 (':', ':');
8d08fdba
MS
610 }
611 if (DECL_NAME (t))
612 dump_decl (DECL_NAME (t), v);
613 else
51c184be 614 OB_PUTS ("{anon}");
7177d104
MS
615 if (v > 0)
616 dump_type_suffix (TREE_TYPE (t), v);
8d08fdba
MS
617 break;
618
619 case ARRAY_REF:
620 dump_decl (TREE_OPERAND (t, 0), v);
621 OB_PUTC ('[');
622 dump_decl (TREE_OPERAND (t, 1), v);
623 OB_PUTC (']');
624 break;
625
626 /* So that we can do dump_decl in dump_aggr_type and have it work for
627 both class and function scope. */
628 case RECORD_TYPE:
629 case UNION_TYPE:
630 case ENUMERAL_TYPE:
631 dump_type (t, v);
632 break;
633
8d08fdba
MS
634 case TYPE_EXPR:
635 my_friendly_abort (69);
636 break;
637
638 /* These special cases are duplicated here so that other functions
639 can feed identifiers to cp_error and get them demangled properly. */
640 case IDENTIFIER_NODE:
641 if (DESTRUCTOR_NAME_P (t))
642 {
643 OB_PUTC ('~');
644 dump_decl (DECL_NAME (ident_fndecl (t)), 0);
645 }
646 else if (IDENTIFIER_TYPENAME_P (t))
647 {
648 OB_PUTS ("operator ");
649 /* Not exactly IDENTIFIER_TYPE_VALUE. */
650 dump_type (TREE_TYPE (t), 0);
651 break;
652 }
653 else if (IDENTIFIER_OPNAME_P (t))
654 {
655 char *name_string = operator_name_string (t);
656 OB_PUTS ("operator ");
657 OB_PUTCP (name_string);
658 }
659 else
660 OB_PUTID (t);
661 break;
662
663 case FUNCTION_DECL:
664 if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
665 dump_global_iord (DECL_ASSEMBLER_NAME (t));
666 else
667 dump_function_decl (t, v);
668 break;
669
670 case TEMPLATE_DECL:
51c184be
MS
671 {
672 tree args = DECL_TEMPLATE_PARMS (t);
f376e137 673 int i, len = args ? TREE_VEC_LENGTH (args) : 0;
51c184be
MS
674 OB_PUTS ("template <");
675 for (i = 0; i < len; i++)
676 {
677 tree arg = TREE_VEC_ELT (args, i);
a292b002
MS
678 tree defval = TREE_PURPOSE (arg);
679 arg = TREE_VALUE (arg);
680 if (TREE_CODE (arg) == TYPE_DECL)
51c184be
MS
681 {
682 OB_PUTS ("class ");
a292b002 683 OB_PUTID (DECL_NAME (arg));
51c184be
MS
684 }
685 else
686 dump_decl (arg, 1);
a292b002
MS
687
688 if (defval)
689 {
690 OB_PUTS (" = ");
691 dump_decl (defval, 1);
692 }
693
51c184be
MS
694 OB_PUTC2 (',', ' ');
695 }
f376e137
MS
696 if (len != 0)
697 OB_UNPUT (2);
51c184be 698 OB_PUTC2 ('>', ' ');
8d08fdba 699
51c184be
MS
700 if (DECL_TEMPLATE_IS_CLASS (t))
701 {
702 OB_PUTS ("class ");
703 OB_PUTID (DECL_NAME (t));
704 }
705 else switch (NEXT_CODE (t))
706 {
707 case METHOD_TYPE:
708 case FUNCTION_TYPE:
709 dump_function_decl (t, v);
710 break;
711
712 default:
713 my_friendly_abort (353);
714 }
715 }
8d08fdba
MS
716 break;
717
718 case LABEL_DECL:
719 OB_PUTID (DECL_NAME (t));
720 break;
721
722 case CONST_DECL:
723 if (NEXT_CODE (t) == ENUMERAL_TYPE)
8d2733ca 724 goto general;
8d08fdba
MS
725 else
726 dump_expr (DECL_INITIAL (t), 0);
727 break;
728
729 default:
51c184be
MS
730 sorry ("`%s' not supported by dump_decl",
731 tree_code_name[(int) TREE_CODE (t)]);
8d08fdba
MS
732 }
733}
734
735/* Pretty printing for announce_function. T is the declaration of the
736 function we are interested in seeing. V is non-zero if we should print
737 the type that this function returns. */
738
739static void
740dump_function_decl (t, v)
741 tree t;
742 int v;
743{
744 tree name = DECL_ASSEMBLER_NAME (t);
745 tree fntype = TREE_TYPE (t);
746 tree parmtypes = TYPE_ARG_TYPES (fntype);
747 tree cname = NULL_TREE;
8d08fdba
MS
748
749 /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */
750 if (DECL_CONTEXT (t))
751 cname = DECL_CLASS_CONTEXT (t);
752 /* this is for partially instantiated template methods */
753 else if (TREE_CODE (fntype) == METHOD_TYPE)
754 cname = TREE_TYPE (TREE_VALUE (parmtypes));
755
756 v = (v > 0);
757
758 if (v)
759 {
760 if (DECL_STATIC_FUNCTION_P (t))
761 OB_PUTS ("static ");
762
763 if (! IDENTIFIER_TYPENAME_P (name)
764 && ! DECL_CONSTRUCTOR_P (t)
765 && ! DESTRUCTOR_NAME_P (name))
766 {
767 dump_type_prefix (TREE_TYPE (fntype), 1);
768 OB_PUTC (' ');
769 }
770 }
771
772 if (cname)
773 {
774 dump_type (cname, 0);
775 OB_PUTC2 (':', ':');
776 if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
777 parmtypes = TREE_CHAIN (parmtypes);
778 if (DECL_CONSTRUCTOR_FOR_VBASE_P (t))
779 /* Skip past "in_charge" identifier. */
780 parmtypes = TREE_CHAIN (parmtypes);
781 }
782
783 if (DESTRUCTOR_NAME_P (name))
784 parmtypes = TREE_CHAIN (parmtypes);
785
786 dump_function_name (t);
787
788 OB_PUTC ('(');
789
790 if (parmtypes)
791 dump_type (parmtypes, v);
792 else
793 OB_PUTS ("...");
794
795 OB_PUTC (')');
796
797 if (v && ! IDENTIFIER_TYPENAME_P (name))
798 dump_type_suffix (TREE_TYPE (fntype), 1);
799
800 if (TREE_CODE (fntype) == METHOD_TYPE)
801 {
802 if (IS_SIGNATURE (cname))
803 /* We look at the type pointed to by the `optr' field of `this.' */
804 dump_readonly_or_volatile
805 (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
806 else
807 dump_readonly_or_volatile
808 (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
809 }
810}
811
812/* Handle the function name for a FUNCTION_DECL node, grokking operators
813 and destructors properly. */
814static void
815dump_function_name (t)
816 tree t;
817{
818 tree name = DECL_NAME (t);
819
820 /* There ought to be a better way to find out whether or not something is
821 a destructor. */
822 if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t)))
823 {
824 OB_PUTC ('~');
825 dump_decl (name, 0);
826 }
827 else if (IDENTIFIER_TYPENAME_P (name))
828 {
829 /* This cannot use the hack that the operator's return
830 type is stashed off of its name because it may be
831 used for error reporting. In the case of conflicting
832 declarations, both will have the same name, yet
833 the types will be different, hence the TREE_TYPE field
834 of the first name will be clobbered by the second. */
835 OB_PUTS ("operator ");
836 dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
837 }
838 else if (IDENTIFIER_OPNAME_P (name))
839 {
840 char *name_string = operator_name_string (name);
841 OB_PUTS ("operator ");
842 OB_PUTCP (name_string);
843 }
844 else
845 dump_decl (name, 0);
846}
847
848static void
849dump_char (c)
850 char c;
851{
852 switch (c)
853 {
a0a33927 854 case TARGET_NEWLINE:
8d08fdba
MS
855 OB_PUTS ("\\n");
856 break;
a0a33927 857 case TARGET_TAB:
8d08fdba
MS
858 OB_PUTS ("\\t");
859 break;
a0a33927 860 case TARGET_VT:
8d08fdba
MS
861 OB_PUTS ("\\v");
862 break;
a0a33927 863 case TARGET_BS:
8d08fdba
MS
864 OB_PUTS ("\\b");
865 break;
a0a33927 866 case TARGET_CR:
8d08fdba
MS
867 OB_PUTS ("\\r");
868 break;
a0a33927 869 case TARGET_FF:
8d08fdba
MS
870 OB_PUTS ("\\f");
871 break;
a0a33927 872 case TARGET_BELL:
8d08fdba
MS
873 OB_PUTS ("\\a");
874 break;
875 case '\\':
876 OB_PUTS ("\\\\");
877 break;
878 case '\'':
879 OB_PUTS ("\\'");
880 break;
881 case '\"':
882 OB_PUTS ("\\\"");
883 break;
884 default:
885 if (isprint (c))
886 OB_PUTC (c);
887 else
888 {
889 sprintf (digit_buffer, "\\%03o", (int) c);
890 OB_PUTCP (digit_buffer);
891 }
892 }
893}
894
895/* Print out a list of initializers (subr of dump_expr) */
896static void
897dump_expr_list (l)
898 tree l;
899{
900 while (l)
901 {
902 dump_expr (TREE_VALUE (l), 0);
903 if (TREE_CHAIN (l))
904 OB_PUTC2 (',', ' ');
905 l = TREE_CHAIN (l);
906 }
907}
908
909/* Print out an expression */
910static void
911dump_expr (t, nop)
912 tree t;
913 int nop; /* suppress parens */
914{
915 switch (TREE_CODE (t))
916 {
917 case VAR_DECL:
918 case PARM_DECL:
919 case FIELD_DECL:
920 case CONST_DECL:
921 case FUNCTION_DECL:
922 dump_decl (t, -1);
923 break;
924
925 case INTEGER_CST:
926 {
927 tree type = TREE_TYPE (t);
928 my_friendly_assert (type != 0, 81);
929
930 /* If it's an enum, output its tag, rather than its value. */
931 if (TREE_CODE (type) == ENUMERAL_TYPE)
932 {
933 char *p = enum_name_string (t, type);
934 OB_PUTCP (p);
935 }
b7484fbe
MS
936 else if (type == boolean_type_node)
937 {
938 if (t == boolean_false_node)
939 OB_PUTS ("false");
940 else if (t == boolean_true_node)
941 OB_PUTS ("true");
942 else
943 my_friendly_abort (366);
944 }
945 else if (type == char_type_node)
8d08fdba
MS
946 {
947 OB_PUTC ('\'');
948 dump_char (TREE_INT_CST_LOW (t));
949 OB_PUTC ('\'');
950 }
951 else if (TREE_INT_CST_HIGH (t)
952 != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1)))
953 {
954 tree val = t;
955 if (TREE_INT_CST_HIGH (val) < 0)
956 {
957 OB_PUTC ('-');
958 val = build_int_2 (~TREE_INT_CST_LOW (val),
959 -TREE_INT_CST_HIGH (val));
960 }
961 /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
962 systems? */
963 {
964 static char format[10]; /* "%x%09999x\0" */
965 if (!format[0])
966 sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
967 sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
968 TREE_INT_CST_LOW (val));
969 OB_PUTCP (digit_buffer);
970 }
971 }
972 else
973 OB_PUTI (TREE_INT_CST_LOW (t));
974 }
975 break;
976
977 case REAL_CST:
978#ifndef REAL_IS_NOT_DOUBLE
979 sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
980#else
981 {
982 unsigned char *p = (unsigned char *) &TREE_REAL_CST (t);
983 int i;
984 strcpy (digit_buffer, "0x");
985 for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
986 sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
987 }
988#endif
989 OB_PUTCP (digit_buffer);
990 break;
991
992 case STRING_CST:
993 {
994 char *p = TREE_STRING_POINTER (t);
995 int len = TREE_STRING_LENGTH (t) - 1;
996 int i;
997
998 OB_PUTC ('\"');
999 for (i = 0; i < len; i++)
1000 dump_char (p[i]);
1001 OB_PUTC ('\"');
1002 }
1003 break;
1004
1005 case COMPOUND_EXPR:
1006 dump_binary_op (",", t);
1007 break;
1008
1009 case COND_EXPR:
1010 OB_PUTC ('(');
1011 dump_expr (TREE_OPERAND (t, 0), 0);
1012 OB_PUTS (" ? ");
1013 dump_expr (TREE_OPERAND (t, 1), 0);
1014 OB_PUTS (" : ");
1015 dump_expr (TREE_OPERAND (t, 2), 0);
1016 OB_PUTC (')');
1017 break;
1018
1019 case SAVE_EXPR:
1020 if (TREE_HAS_CONSTRUCTOR (t))
1021 {
1022 OB_PUTS ("new ");
1023 dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
1024 PARM_DECL_EXPR (t) = 1;
1025 }
1026 else
1027 {
6060a796 1028 dump_expr (TREE_OPERAND (t, 0), 0);
8d08fdba
MS
1029 }
1030 break;
1031
1032 case NEW_EXPR:
1033 OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
1034 OB_PUTC ('(');
1035 dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
1036 OB_PUTC (')');
1037 break;
1038
1039 case CALL_EXPR:
1040 {
1041 tree fn = TREE_OPERAND (t, 0);
1042 tree args = TREE_OPERAND (t, 1);
1043
1044 if (TREE_CODE (fn) == ADDR_EXPR)
1045 fn = TREE_OPERAND (fn, 0);
1046
1047 if (NEXT_CODE (fn) == METHOD_TYPE)
1048 {
1049 tree ob = TREE_VALUE (args);
1050 if (TREE_CODE (ob) == ADDR_EXPR)
1051 {
1052 dump_expr (TREE_OPERAND (ob, 0), 0);
1053 OB_PUTC ('.');
1054 }
1055 else if (TREE_CODE (ob) != PARM_DECL
1056 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1057 {
1058 dump_expr (ob, 0);
1059 OB_PUTC2 ('-', '>');
1060 }
1061 args = TREE_CHAIN (args);
1062 }
1063 dump_expr (fn, 0);
1064 OB_PUTC('(');
1065 dump_expr_list (args);
1066 OB_PUTC (')');
1067 }
1068 break;
1069
1070 case WITH_CLEANUP_EXPR:
1071 /* Note that this only works for G++ cleanups. If somebody
1072 builds a general cleanup, there's no way to represent it. */
1073 dump_expr (TREE_OPERAND (t, 0), 0);
1074 break;
1075
1076 case TARGET_EXPR:
1077 /* Note that this only works for G++ target exprs. If somebody
1078 builds a general TARGET_EXPR, there's no way to represent that
1079 it initializes anything other that the parameter slot for the
1080 default argument. Note we may have cleared out the first
1081 operand in expand_expr, so don't go killing ourselves. */
1082 if (TREE_OPERAND (t, 1))
1083 dump_expr (TREE_OPERAND (t, 1), 0);
1084 break;
1085
1086 case MODIFY_EXPR:
1087 case PLUS_EXPR:
1088 case MINUS_EXPR:
1089 case MULT_EXPR:
1090 case TRUNC_DIV_EXPR:
1091 case TRUNC_MOD_EXPR:
1092 case MIN_EXPR:
1093 case MAX_EXPR:
1094 case LSHIFT_EXPR:
1095 case RSHIFT_EXPR:
1096 case BIT_IOR_EXPR:
1097 case BIT_XOR_EXPR:
1098 case BIT_AND_EXPR:
1099 case BIT_ANDTC_EXPR:
1100 case TRUTH_ANDIF_EXPR:
1101 case TRUTH_ORIF_EXPR:
1102 case LT_EXPR:
1103 case LE_EXPR:
1104 case GT_EXPR:
1105 case GE_EXPR:
1106 case EQ_EXPR:
1107 case NE_EXPR:
1108 dump_binary_op (opname_tab[(int) TREE_CODE (t)], t);
1109 break;
1110
1111 case CEIL_DIV_EXPR:
1112 case FLOOR_DIV_EXPR:
1113 case ROUND_DIV_EXPR:
1114 dump_binary_op ("/", t);
1115 break;
1116
1117 case CEIL_MOD_EXPR:
1118 case FLOOR_MOD_EXPR:
1119 case ROUND_MOD_EXPR:
1120 dump_binary_op ("%", t);
1121 break;
1122
1123 case COMPONENT_REF:
1124 {
1125 tree ob = TREE_OPERAND (t, 0);
1126 if (TREE_CODE (ob) == INDIRECT_REF)
1127 {
1128 ob = TREE_OPERAND (ob, 0);
1129 if (TREE_CODE (ob) != PARM_DECL
1130 || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1131 {
1132 dump_expr (ob, 0);
1133 OB_PUTC2 ('-', '>');
1134 }
1135 }
1136 else
1137 {
1138 dump_expr (ob, 0);
1139 OB_PUTC ('.');
1140 }
1141 dump_expr (TREE_OPERAND (t, 1), 1);
1142 }
1143 break;
1144
28cbf42c
MS
1145 case ARRAY_REF:
1146 dump_expr (TREE_OPERAND (t, 0), 0);
1147 OB_PUTC ('[');
1148 dump_expr (TREE_OPERAND (t, 1), 0);
1149 OB_PUTC (']');
1150 break;
1151
8d08fdba
MS
1152 case CONVERT_EXPR:
1153 dump_unary_op ("+", t, nop);
1154 break;
1155
1156 case ADDR_EXPR:
1157 if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
1158 || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
1159 dump_expr (TREE_OPERAND (t, 0), 0);
1160 else
1161 dump_unary_op ("&", t, nop);
1162 break;
1163
1164 case INDIRECT_REF:
1165 if (TREE_HAS_CONSTRUCTOR (t))
1166 {
1167 t = TREE_OPERAND (t, 0);
1168 my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1169 dump_expr (TREE_OPERAND (t, 0), 0);
1170 OB_PUTC ('(');
1171 dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
1172 OB_PUTC (')');
1173 }
1174 else
1175 {
1176 if (NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
1177 dump_expr (TREE_OPERAND (t, 0), nop);
1178 else
1179 dump_unary_op ("*", t, nop);
1180 }
1181 break;
1182
1183 case NEGATE_EXPR:
1184 case BIT_NOT_EXPR:
1185 case TRUTH_NOT_EXPR:
1186 case PREDECREMENT_EXPR:
1187 case PREINCREMENT_EXPR:
1188 dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, nop);
1189 break;
1190
1191 case POSTDECREMENT_EXPR:
1192 case POSTINCREMENT_EXPR:
1193 OB_PUTC ('(');
1194 dump_expr (TREE_OPERAND (t, 0), 0);
1195 OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
1196 OB_PUTC (')');
1197 break;
1198
1199 case NON_LVALUE_EXPR:
1200 /* FIXME: This is a KLUDGE workaround for a parsing problem. There
1201 should be another level of INDIRECT_REF so that I don't have to do
1202 this. */
1203 if (NEXT_CODE (t) == POINTER_TYPE)
1204 {
1205 tree next = TREE_TYPE (TREE_TYPE (t));
1206
1207 while (TREE_CODE (next) == POINTER_TYPE)
1208 next = TREE_TYPE (next);
1209
1210 if (TREE_CODE (next) == FUNCTION_TYPE)
1211 {
1212 if (!nop) OB_PUTC ('(');
1213 OB_PUTC ('*');
1214 dump_expr (TREE_OPERAND (t, 0), 1);
1215 if (!nop) OB_PUTC (')');
1216 break;
1217 }
1218 /* else FALLTHRU */
1219 }
1220 dump_expr (TREE_OPERAND (t, 0), 0);
1221 break;
1222
1223 case NOP_EXPR:
1224 dump_expr (TREE_OPERAND (t, 0), nop);
1225 break;
1226
1227 case CONSTRUCTOR:
1228 OB_PUTC ('{');
1229 dump_expr_list (CONSTRUCTOR_ELTS (t), 0);
1230 OB_PUTC ('}');
1231 break;
1232
51c184be
MS
1233 case OFFSET_REF:
1234 {
1235 tree ob = TREE_OPERAND (t, 0);
1236 if (TREE_CODE (ob) == NOP_EXPR
1237 && TREE_OPERAND (ob, 0) == error_mark_node
1238 && TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
1239 /* A::f */
1240 dump_expr (TREE_OPERAND (t, 1), 0);
1241 else
1242 {
1243 sorry ("operand of OFFSET_REF not understood");
1244 goto error;
1245 }
1246 break;
1247 }
1248
00595019
MS
1249 case TREE_LIST:
1250 if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
1251 {
1252 OB_PUTID (DECL_NAME (TREE_VALUE (t)));
1253 break;
1254 }
1255 /* else fall through */
1256
8d08fdba
MS
1257 /* This list is incomplete, but should suffice for now.
1258 It is very important that `sorry' does not call
1259 `report_error_function'. That could cause an infinite loop. */
1260 default:
1261 sorry ("`%s' not supported by dump_expr",
1262 tree_code_name[(int) TREE_CODE (t)]);
1263
1264 /* fall through to ERROR_MARK... */
1265 case ERROR_MARK:
1266 error:
51c184be 1267 OB_PUTCP ("{error}");
8d08fdba
MS
1268 break;
1269 }
1270}
1271
1272static void
1273dump_binary_op (opstring, t)
1274 char *opstring;
1275 tree t;
1276{
1277 OB_PUTC ('(');
1278 dump_expr (TREE_OPERAND (t, 0), 1);
1279 OB_PUTC (' ');
1280 OB_PUTCP (opstring);
1281 OB_PUTC (' ');
1282 dump_expr (TREE_OPERAND (t, 1), 1);
1283 OB_PUTC (')');
1284}
1285
1286static void
1287dump_unary_op (opstring, t, nop)
1288 char *opstring;
1289 tree t;
1290 int nop;
1291{
1292 if (!nop) OB_PUTC ('(');
1293 OB_PUTCP (opstring);
1294 dump_expr (TREE_OPERAND (t, 0), 1);
1295 if (!nop) OB_PUTC (')');
1296}
1297
1298char *
1299fndecl_as_string (cname, fndecl, print_ret_type_p)
1300 tree cname, fndecl;
1301 int print_ret_type_p;
1302{
1303 return decl_as_string (fndecl, print_ret_type_p);
1304}
1305
1306/* Same, but handtype a _TYPE.
1307 Called from convert_to_reference, mangle_class_name_for_template,
1308 build_unary_op, and GNU_xref_decl. */
1309char *
1310type_as_string (typ, v)
1311 tree typ;
1312 int v;
1313{
1314 OB_INIT ();
1315
1316 dump_type (typ, v);
1317
1318 OB_FINISH ();
1319
1320 return (char *)obstack_base (&scratch_obstack);
1321}
1322
1323char *
1324expr_as_string (decl, v)
1325 tree decl;
1326 int v;
1327{
1328 OB_INIT ();
1329
1330 dump_expr (decl, 1);
1331
1332 OB_FINISH ();
1333
1334 return (char *)obstack_base (&scratch_obstack);
1335}
1336
1337/* A cross between type_as_string and fndecl_as_string.
1338 Only called from substitute_nice_name. */
1339char *
1340decl_as_string (decl, v)
1341 tree decl;
1342 int v;
1343{
1344 OB_INIT ();
1345
1346 dump_decl (decl, v);
1347
1348 OB_FINISH ();
1349
1350 return (char *)obstack_base (&scratch_obstack);
1351}
1352
1353char *
1354cp_file_of (t)
1355 tree t;
1356{
1357 if (TREE_CODE (t) == PARM_DECL)
1358 return DECL_SOURCE_FILE (DECL_CONTEXT (t));
1359 else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
1360 return DECL_SOURCE_FILE (TYPE_NAME (t));
1361 else
1362 return DECL_SOURCE_FILE (t);
1363}
1364
1365int
1366cp_line_of (t)
1367 tree t;
1368{
f376e137 1369 int line = 0;
8d08fdba 1370 if (TREE_CODE (t) == PARM_DECL)
f376e137
MS
1371 line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
1372 if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
1373 t = TREE_TYPE (t);
1374
1375 if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
1376 {
1377 if (IS_AGGR_TYPE (t))
1378 line = CLASSTYPE_SOURCE_LINE (t);
1379 else
1380 line = DECL_SOURCE_LINE (TYPE_NAME (t));
1381 }
8d08fdba 1382 else
f376e137
MS
1383 line = DECL_SOURCE_LINE (t);
1384
1385 if (line == 0)
1386 return lineno;
1387
1388 return line;
8d08fdba
MS
1389}
1390
1391char *
1392code_as_string (c, v)
1393 enum tree_code c;
1394 int v;
1395{
1396 return tree_code_name [c];
1397}
1398
1399char *
1400language_as_string (c, v)
1401 enum languages c;
8926095f 1402 int v;
8d08fdba
MS
1403{
1404 switch (c)
1405 {
1406 case lang_c:
1407 return "C";
1408
1409 case lang_cplusplus:
1410 return "C++";
1411
1412 default:
1413 my_friendly_abort (355);
8926095f 1414 return 0;
8d08fdba
MS
1415 }
1416}
1417
1418/* Return the proper printed version of a parameter to a C++ function. */
1419char *
1420parm_as_string (p, v)
8926095f 1421 int p, v;
8d08fdba
MS
1422{
1423 if (p < 0)
1424 return "`this'";
1425
1426 sprintf (digit_buffer, "%d", p+1);
1427 return digit_buffer;
1428}
1429
1430char *
1431op_as_string (p, v)
1432 enum tree_code p;
8926095f 1433 int v;
8d08fdba
MS
1434{
1435 static char buf[] = "operator ";
1436
1437 if (p == 0)
51c184be 1438 return "{unknown}";
8d08fdba
MS
1439
1440 strcpy (buf + 9, opname_tab [p]);
1441 return buf;
1442}
1443
1444char *
1445args_as_string (p, v)
1446 tree p;
1447 int v;
1448{
1449 if (p == NULL_TREE)
1450 return "...";
1451
1452 return type_as_string (p, v);
1453}
This page took 0.289886 seconds and 5 git commands to generate.