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