|
|
1.1 root 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:
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, 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:
27: typedef 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
39: cp_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. */
64: static struct obstack scratch_obstack;
65: static 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)
79: # define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N));
80:
81: # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
82:
83: static void dump_type (), dump_decl (), dump_function_decl ();
84: static void dump_expr (), dump_unary_op (), dump_binary_op ();
85: static void dump_aggr_type (), dump_type_prefix (), dump_type_suffix ();
86: static void dump_function_name ();
87:
88: void
89: init_error ()
90: {
91: gcc_obstack_init (&scratch_obstack);
92: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
93: }
94:
95: enum pad { none, before, after };
96:
97: static void
98: dump_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");
107: if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
108: OB_PUTC (' ');
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. */
117: static char digit_buffer[128];
118:
119: /* Dump into the obstack a human-readable equivalent of TYPE. */
120: static void
121: dump_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:
134: OB_PUTS ("{error}");
135: break;
136:
137: case UNKNOWN_TYPE:
138: OB_PUTS ("{unknown type}");
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:
191: dump_decl (t, v);
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:
203: case BOOLEAN_TYPE:
204: dump_readonly_or_volatile (t, after);
205: OB_PUTID (TYPE_IDENTIFIER (t));
206: break;
207:
208: case TEMPLATE_TYPE_PARM:
209: OB_PUTID (TYPE_IDENTIFIER (t));
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:
231: sorry ("`%s' not supported by dump_type",
232: tree_code_name[(int) TREE_CODE (t)]);
233: }
234: }
235:
236: static char *
237: aggr_variety (t)
238: tree t;
239: {
240: if (TREE_CODE (t) == ENUMERAL_TYPE)
241: return "enum";
242: else if (TREE_CODE (t) == UNION_TYPE)
243: return "union";
244: else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
245: return "class";
246: else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t))
247: return "signature";
248: else
249: return "struct";
250: }
251:
252: /* Print out a class declaration, in the form `class foo'. */
253: static void
254: dump_aggr_type (t, v)
255: tree t;
256: int v; /* verbose? */
257: {
258: tree name;
259: char *variety = aggr_variety (t);
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: {
284: OB_PUTS ("{anonymous");
285: if (!v)
286: {
287: OB_PUTC (' ');
288: OB_PUTCP (variety);
289: }
290: OB_PUTC ('}');
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:
307: static void
308: dump_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:
336: case ARRAY_TYPE:
337: OB_PUTC2 (' ', '(');
338: break;
339:
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: {
362: case ARRAY_TYPE:
363: OB_PUTC2 (' ', '(');
364: break;
365:
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);
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: }
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:
415: case BOOLEAN_TYPE:
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:
430: sorry ("`%s' not supported by dump_type_prefix",
431: tree_code_name[(int) TREE_CODE (t)]);
432: }
433: }
434:
435: static void
436: dump_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:
448: if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
449: OB_PUTC (')');
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:
487: case BOOLEAN_TYPE:
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:
501: sorry ("`%s' not supported by dump_type_suffix",
502: tree_code_name[(int) TREE_CODE (t)]);
503: }
504: }
505:
506: /* Return a function declaration which corresponds to the IDENTIFIER_NODE
507: argument. */
508: tree
509: ident_fndecl (t)
510: tree t;
511: {
512: tree n = lookup_name (t, 0);
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);
519:
520: my_friendly_abort (66);
521: return NULL_TREE;
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:
537: void
538: dump_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:
556: static void
557: dump_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:
570: case TYPE_DECL:
571: {
572: /* Don't say 'typedef class A' */
573: tree type = TREE_TYPE (t);
574: if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type))
575: || TREE_CODE (type) == ENUMERAL_TYPE)
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;
585: break;
586:
587: case VAR_DECL:
588: if (VTABLE_NAME_P (DECL_NAME (t)))
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:
597: general:
598: if (v > 0)
599: {
600: dump_type_prefix (TREE_TYPE (t), v);
601: OB_PUTC (' ');
602: }
603: /* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */
604: if (DECL_CONTEXT (t)
605: && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')
606: {
607: dump_type (DECL_CONTEXT (t), 0);
608: OB_PUTC2 (':', ':');
609: }
610: if (DECL_NAME (t))
611: dump_decl (DECL_NAME (t), v);
612: else
613: OB_PUTS ("{anon}");
614: if (v > 0)
615: dump_type_suffix (TREE_TYPE (t), v);
616: break;
617:
618: case ARRAY_REF:
619: dump_decl (TREE_OPERAND (t, 0), v);
620: OB_PUTC ('[');
621: dump_decl (TREE_OPERAND (t, 1), v);
622: OB_PUTC (']');
623: break;
624:
625: /* So that we can do dump_decl in dump_aggr_type and have it work for
626: both class and function scope. */
627: case RECORD_TYPE:
628: case UNION_TYPE:
629: case ENUMERAL_TYPE:
630: dump_type (t, v);
631: break;
632:
633: case TYPE_EXPR:
634: my_friendly_abort (69);
635: break;
636:
637: /* These special cases are duplicated here so that other functions
638: can feed identifiers to cp_error and get them demangled properly. */
639: case IDENTIFIER_NODE:
640: if (DESTRUCTOR_NAME_P (t))
641: {
642: OB_PUTC ('~');
643: dump_decl (DECL_NAME (ident_fndecl (t)), 0);
644: }
645: else if (IDENTIFIER_TYPENAME_P (t))
646: {
647: OB_PUTS ("operator ");
648: /* Not exactly IDENTIFIER_TYPE_VALUE. */
649: dump_type (TREE_TYPE (t), 0);
650: break;
651: }
652: else if (IDENTIFIER_OPNAME_P (t))
653: {
654: char *name_string = operator_name_string (t);
655: OB_PUTS ("operator ");
656: OB_PUTCP (name_string);
657: }
658: else
659: OB_PUTID (t);
660: break;
661:
662: case FUNCTION_DECL:
663: if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
664: dump_global_iord (DECL_ASSEMBLER_NAME (t));
665: else
666: dump_function_decl (t, v);
667: break;
668:
669: case TEMPLATE_DECL:
670: {
671: tree args = DECL_TEMPLATE_PARMS (t);
672: int i, len = args ? TREE_VEC_LENGTH (args) : 0;
673: OB_PUTS ("template <");
674: for (i = 0; i < len; i++)
675: {
676: tree arg = TREE_VEC_ELT (args, i);
677: tree defval = TREE_PURPOSE (arg);
678: arg = TREE_VALUE (arg);
679: if (TREE_CODE (arg) == TYPE_DECL)
680: {
681: OB_PUTS ("class ");
682: OB_PUTID (DECL_NAME (arg));
683: }
684: else
685: dump_decl (arg, 1);
686:
687: if (defval)
688: {
689: OB_PUTS (" = ");
690: dump_decl (defval, 1);
691: }
692:
693: OB_PUTC2 (',', ' ');
694: }
695: if (len != 0)
696: OB_UNPUT (2);
697: OB_PUTC2 ('>', ' ');
698:
699: if (DECL_TEMPLATE_IS_CLASS (t))
700: {
701: OB_PUTS ("class ");
702: OB_PUTID (DECL_NAME (t));
703: }
704: else switch (NEXT_CODE (t))
705: {
706: case METHOD_TYPE:
707: case FUNCTION_TYPE:
708: dump_function_decl (t, v);
709: break;
710:
711: default:
712: my_friendly_abort (353);
713: }
714: }
715: break;
716:
717: case LABEL_DECL:
718: OB_PUTID (DECL_NAME (t));
719: break;
720:
721: case CONST_DECL:
722: if (NEXT_CODE (t) == ENUMERAL_TYPE)
723: goto general;
724: else
725: dump_expr (DECL_INITIAL (t), 0);
726: break;
727:
728: default:
729: sorry ("`%s' not supported by dump_decl",
730: tree_code_name[(int) TREE_CODE (t)]);
731: }
732: }
733:
734: /* Pretty printing for announce_function. T is the declaration of the
735: function we are interested in seeing. V is non-zero if we should print
736: the type that this function returns. */
737:
738: static void
739: dump_function_decl (t, v)
740: tree t;
741: int v;
742: {
743: tree name = DECL_ASSEMBLER_NAME (t);
744: tree fntype = TREE_TYPE (t);
745: tree parmtypes = TYPE_ARG_TYPES (fntype);
746: tree cname = NULL_TREE;
747:
748: /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */
749: if (DECL_CONTEXT (t))
750: cname = DECL_CLASS_CONTEXT (t);
751: /* this is for partially instantiated template methods */
752: else if (TREE_CODE (fntype) == METHOD_TYPE)
753: cname = TREE_TYPE (TREE_VALUE (parmtypes));
754:
755: v = (v > 0);
756:
757: if (v)
758: {
759: if (DECL_STATIC_FUNCTION_P (t))
760: OB_PUTS ("static ");
761:
762: if (! IDENTIFIER_TYPENAME_P (name)
763: && ! DECL_CONSTRUCTOR_P (t)
764: && ! DESTRUCTOR_NAME_P (name))
765: {
766: dump_type_prefix (TREE_TYPE (fntype), 1);
767: OB_PUTC (' ');
768: }
769: }
770:
771: if (cname)
772: {
773: dump_type (cname, 0);
774: OB_PUTC2 (':', ':');
775: if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
776: parmtypes = TREE_CHAIN (parmtypes);
777: if (DECL_CONSTRUCTOR_FOR_VBASE_P (t))
778: /* Skip past "in_charge" identifier. */
779: parmtypes = TREE_CHAIN (parmtypes);
780: }
781:
782: if (DESTRUCTOR_NAME_P (name))
783: parmtypes = TREE_CHAIN (parmtypes);
784:
785: dump_function_name (t);
786:
787: OB_PUTC ('(');
788:
789: if (parmtypes)
790: dump_type (parmtypes, v);
791: else
792: OB_PUTS ("...");
793:
794: OB_PUTC (')');
795:
796: if (v && ! IDENTIFIER_TYPENAME_P (name))
797: dump_type_suffix (TREE_TYPE (fntype), 1);
798:
799: if (TREE_CODE (fntype) == METHOD_TYPE)
800: {
801: if (IS_SIGNATURE (cname))
802: /* We look at the type pointed to by the `optr' field of `this.' */
803: dump_readonly_or_volatile
804: (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
805: else
806: dump_readonly_or_volatile
807: (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
808: }
809: }
810:
811: /* Handle the function name for a FUNCTION_DECL node, grokking operators
812: and destructors properly. */
813: static void
814: dump_function_name (t)
815: tree t;
816: {
817: tree name = DECL_NAME (t);
818:
819: /* There ought to be a better way to find out whether or not something is
820: a destructor. */
821: if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t)))
822: {
823: OB_PUTC ('~');
824: dump_decl (name, 0);
825: }
826: else if (IDENTIFIER_TYPENAME_P (name))
827: {
828: /* This cannot use the hack that the operator's return
829: type is stashed off of its name because it may be
830: used for error reporting. In the case of conflicting
831: declarations, both will have the same name, yet
832: the types will be different, hence the TREE_TYPE field
833: of the first name will be clobbered by the second. */
834: OB_PUTS ("operator ");
835: dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
836: }
837: else if (IDENTIFIER_OPNAME_P (name))
838: {
839: char *name_string = operator_name_string (name);
840: OB_PUTS ("operator ");
841: OB_PUTCP (name_string);
842: }
843: else
844: dump_decl (name, 0);
845: }
846:
847: static void
848: dump_char (c)
849: char c;
850: {
851: switch (c)
852: {
853: case TARGET_NEWLINE:
854: OB_PUTS ("\\n");
855: break;
856: case TARGET_TAB:
857: OB_PUTS ("\\t");
858: break;
859: case TARGET_VT:
860: OB_PUTS ("\\v");
861: break;
862: case TARGET_BS:
863: OB_PUTS ("\\b");
864: break;
865: case TARGET_CR:
866: OB_PUTS ("\\r");
867: break;
868: case TARGET_FF:
869: OB_PUTS ("\\f");
870: break;
871: case TARGET_BELL:
872: OB_PUTS ("\\a");
873: break;
874: case '\\':
875: OB_PUTS ("\\\\");
876: break;
877: case '\'':
878: OB_PUTS ("\\'");
879: break;
880: case '\"':
881: OB_PUTS ("\\\"");
882: break;
883: default:
884: if (isprint (c))
885: OB_PUTC (c);
886: else
887: {
888: sprintf (digit_buffer, "\\%03o", (int) c);
889: OB_PUTCP (digit_buffer);
890: }
891: }
892: }
893:
894: /* Print out a list of initializers (subr of dump_expr) */
895: static void
896: dump_expr_list (l)
897: tree l;
898: {
899: while (l)
900: {
901: dump_expr (TREE_VALUE (l), 0);
902: if (TREE_CHAIN (l))
903: OB_PUTC2 (',', ' ');
904: l = TREE_CHAIN (l);
905: }
906: }
907:
908: /* Print out an expression */
909: static void
910: dump_expr (t, nop)
911: tree t;
912: int nop; /* suppress parens */
913: {
914: switch (TREE_CODE (t))
915: {
916: case VAR_DECL:
917: case PARM_DECL:
918: case FIELD_DECL:
919: case CONST_DECL:
920: case FUNCTION_DECL:
921: dump_decl (t, -1);
922: break;
923:
924: case INTEGER_CST:
925: {
926: tree type = TREE_TYPE (t);
927: my_friendly_assert (type != 0, 81);
928:
929: /* If it's an enum, output its tag, rather than its value. */
930: if (TREE_CODE (type) == ENUMERAL_TYPE)
931: {
932: char *p = enum_name_string (t, type);
933: OB_PUTCP (p);
934: }
935: else if (type == char_type_node
936: || type == signed_char_type_node
937: || type == unsigned_char_type_node)
938: {
939: OB_PUTC ('\'');
940: dump_char (TREE_INT_CST_LOW (t));
941: OB_PUTC ('\'');
942: }
943: else if (TREE_INT_CST_HIGH (t)
944: != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1)))
945: {
946: tree val = t;
947: if (TREE_INT_CST_HIGH (val) < 0)
948: {
949: OB_PUTC ('-');
950: val = build_int_2 (~TREE_INT_CST_LOW (val),
951: -TREE_INT_CST_HIGH (val));
952: }
953: /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
954: systems? */
955: {
956: static char format[10]; /* "%x%09999x\0" */
957: if (!format[0])
958: sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
959: sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
960: TREE_INT_CST_LOW (val));
961: OB_PUTCP (digit_buffer);
962: }
963: }
964: else
965: OB_PUTI (TREE_INT_CST_LOW (t));
966: }
967: break;
968:
969: case REAL_CST:
970: #ifndef REAL_IS_NOT_DOUBLE
971: sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
972: #else
973: {
974: unsigned char *p = (unsigned char *) &TREE_REAL_CST (t);
975: int i;
976: strcpy (digit_buffer, "0x");
977: for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
978: sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
979: }
980: #endif
981: OB_PUTCP (digit_buffer);
982: break;
983:
984: case STRING_CST:
985: {
986: char *p = TREE_STRING_POINTER (t);
987: int len = TREE_STRING_LENGTH (t) - 1;
988: int i;
989:
990: OB_PUTC ('\"');
991: for (i = 0; i < len; i++)
992: dump_char (p[i]);
993: OB_PUTC ('\"');
994: }
995: break;
996:
997: case COMPOUND_EXPR:
998: dump_binary_op (",", t);
999: break;
1000:
1001: case COND_EXPR:
1002: OB_PUTC ('(');
1003: dump_expr (TREE_OPERAND (t, 0), 0);
1004: OB_PUTS (" ? ");
1005: dump_expr (TREE_OPERAND (t, 1), 0);
1006: OB_PUTS (" : ");
1007: dump_expr (TREE_OPERAND (t, 2), 0);
1008: OB_PUTC (')');
1009: break;
1010:
1011: case SAVE_EXPR:
1012: if (TREE_HAS_CONSTRUCTOR (t))
1013: {
1014: OB_PUTS ("new ");
1015: dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
1016: PARM_DECL_EXPR (t) = 1;
1017: }
1018: else
1019: {
1020: sorry ("operand of SAVE_EXPR not understood");
1021: goto error;
1022: }
1023: break;
1024:
1025: case NEW_EXPR:
1026: OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
1027: OB_PUTC ('(');
1028: dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
1029: OB_PUTC (')');
1030: break;
1031:
1032: case CALL_EXPR:
1033: {
1034: tree fn = TREE_OPERAND (t, 0);
1035: tree args = TREE_OPERAND (t, 1);
1036:
1037: if (TREE_CODE (fn) == ADDR_EXPR)
1038: fn = TREE_OPERAND (fn, 0);
1039:
1040: if (NEXT_CODE (fn) == METHOD_TYPE)
1041: {
1042: tree ob = TREE_VALUE (args);
1043: if (TREE_CODE (ob) == ADDR_EXPR)
1044: {
1045: dump_expr (TREE_OPERAND (ob, 0), 0);
1046: OB_PUTC ('.');
1047: }
1048: else if (TREE_CODE (ob) != PARM_DECL
1049: || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1050: {
1051: dump_expr (ob, 0);
1052: OB_PUTC2 ('-', '>');
1053: }
1054: args = TREE_CHAIN (args);
1055: }
1056: dump_expr (fn, 0);
1057: OB_PUTC('(');
1058: dump_expr_list (args);
1059: OB_PUTC (')');
1060: }
1061: break;
1062:
1063: case WITH_CLEANUP_EXPR:
1064: /* Note that this only works for G++ cleanups. If somebody
1065: builds a general cleanup, there's no way to represent it. */
1066: dump_expr (TREE_OPERAND (t, 0), 0);
1067: break;
1068:
1069: case TARGET_EXPR:
1070: /* Note that this only works for G++ target exprs. If somebody
1071: builds a general TARGET_EXPR, there's no way to represent that
1072: it initializes anything other that the parameter slot for the
1073: default argument. Note we may have cleared out the first
1074: operand in expand_expr, so don't go killing ourselves. */
1075: if (TREE_OPERAND (t, 1))
1076: dump_expr (TREE_OPERAND (t, 1), 0);
1077: break;
1078:
1079: case MODIFY_EXPR:
1080: case PLUS_EXPR:
1081: case MINUS_EXPR:
1082: case MULT_EXPR:
1083: case TRUNC_DIV_EXPR:
1084: case TRUNC_MOD_EXPR:
1085: case MIN_EXPR:
1086: case MAX_EXPR:
1087: case LSHIFT_EXPR:
1088: case RSHIFT_EXPR:
1089: case BIT_IOR_EXPR:
1090: case BIT_XOR_EXPR:
1091: case BIT_AND_EXPR:
1092: case BIT_ANDTC_EXPR:
1093: case TRUTH_ANDIF_EXPR:
1094: case TRUTH_ORIF_EXPR:
1095: case LT_EXPR:
1096: case LE_EXPR:
1097: case GT_EXPR:
1098: case GE_EXPR:
1099: case EQ_EXPR:
1100: case NE_EXPR:
1101: dump_binary_op (opname_tab[(int) TREE_CODE (t)], t);
1102: break;
1103:
1104: case CEIL_DIV_EXPR:
1105: case FLOOR_DIV_EXPR:
1106: case ROUND_DIV_EXPR:
1107: dump_binary_op ("/", t);
1108: break;
1109:
1110: case CEIL_MOD_EXPR:
1111: case FLOOR_MOD_EXPR:
1112: case ROUND_MOD_EXPR:
1113: dump_binary_op ("%", t);
1114: break;
1115:
1116: case COMPONENT_REF:
1117: {
1118: tree ob = TREE_OPERAND (t, 0);
1119: if (TREE_CODE (ob) == INDIRECT_REF)
1120: {
1121: ob = TREE_OPERAND (ob, 0);
1122: if (TREE_CODE (ob) != PARM_DECL
1123: || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
1124: {
1125: dump_expr (ob, 0);
1126: OB_PUTC2 ('-', '>');
1127: }
1128: }
1129: else
1130: {
1131: dump_expr (ob, 0);
1132: OB_PUTC ('.');
1133: }
1134: dump_expr (TREE_OPERAND (t, 1), 1);
1135: }
1136: break;
1137:
1138: case CONVERT_EXPR:
1139: dump_unary_op ("+", t, nop);
1140: break;
1141:
1142: case ADDR_EXPR:
1143: if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
1144: || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
1145: dump_expr (TREE_OPERAND (t, 0), 0);
1146: else
1147: dump_unary_op ("&", t, nop);
1148: break;
1149:
1150: case INDIRECT_REF:
1151: if (TREE_HAS_CONSTRUCTOR (t))
1152: {
1153: t = TREE_OPERAND (t, 0);
1154: my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1155: dump_expr (TREE_OPERAND (t, 0), 0);
1156: OB_PUTC ('(');
1157: dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
1158: OB_PUTC (')');
1159: }
1160: else
1161: {
1162: if (NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
1163: dump_expr (TREE_OPERAND (t, 0), nop);
1164: else
1165: dump_unary_op ("*", t, nop);
1166: }
1167: break;
1168:
1169: case NEGATE_EXPR:
1170: case BIT_NOT_EXPR:
1171: case TRUTH_NOT_EXPR:
1172: case PREDECREMENT_EXPR:
1173: case PREINCREMENT_EXPR:
1174: dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, nop);
1175: break;
1176:
1177: case POSTDECREMENT_EXPR:
1178: case POSTINCREMENT_EXPR:
1179: OB_PUTC ('(');
1180: dump_expr (TREE_OPERAND (t, 0), 0);
1181: OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
1182: OB_PUTC (')');
1183: break;
1184:
1185: case NON_LVALUE_EXPR:
1186: /* FIXME: This is a KLUDGE workaround for a parsing problem. There
1187: should be another level of INDIRECT_REF so that I don't have to do
1188: this. */
1189: if (NEXT_CODE (t) == POINTER_TYPE)
1190: {
1191: tree next = TREE_TYPE (TREE_TYPE (t));
1192:
1193: while (TREE_CODE (next) == POINTER_TYPE)
1194: next = TREE_TYPE (next);
1195:
1196: if (TREE_CODE (next) == FUNCTION_TYPE)
1197: {
1198: if (!nop) OB_PUTC ('(');
1199: OB_PUTC ('*');
1200: dump_expr (TREE_OPERAND (t, 0), 1);
1201: if (!nop) OB_PUTC (')');
1202: break;
1203: }
1204: /* else FALLTHRU */
1205: }
1206: dump_expr (TREE_OPERAND (t, 0), 0);
1207: break;
1208:
1209: case NOP_EXPR:
1210: dump_expr (TREE_OPERAND (t, 0), nop);
1211: break;
1212:
1213: case CONSTRUCTOR:
1214: OB_PUTC ('{');
1215: dump_expr_list (CONSTRUCTOR_ELTS (t), 0);
1216: OB_PUTC ('}');
1217: break;
1218:
1219: case OFFSET_REF:
1220: {
1221: tree ob = TREE_OPERAND (t, 0);
1222: if (TREE_CODE (ob) == NOP_EXPR
1223: && TREE_OPERAND (ob, 0) == error_mark_node
1224: && TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
1225: /* A::f */
1226: dump_expr (TREE_OPERAND (t, 1), 0);
1227: else
1228: {
1229: sorry ("operand of OFFSET_REF not understood");
1230: goto error;
1231: }
1232: break;
1233: }
1234:
1235: case TREE_LIST:
1236: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
1237: {
1238: OB_PUTID (DECL_NAME (TREE_VALUE (t)));
1239: break;
1240: }
1241: /* else fall through */
1242:
1243: /* This list is incomplete, but should suffice for now.
1244: It is very important that `sorry' does not call
1245: `report_error_function'. That could cause an infinite loop. */
1246: default:
1247: sorry ("`%s' not supported by dump_expr",
1248: tree_code_name[(int) TREE_CODE (t)]);
1249:
1250: /* fall through to ERROR_MARK... */
1251: case ERROR_MARK:
1252: error:
1253: OB_PUTCP ("{error}");
1254: break;
1255: }
1256: }
1257:
1258: static void
1259: dump_binary_op (opstring, t)
1260: char *opstring;
1261: tree t;
1262: {
1263: OB_PUTC ('(');
1264: dump_expr (TREE_OPERAND (t, 0), 1);
1265: OB_PUTC (' ');
1266: OB_PUTCP (opstring);
1267: OB_PUTC (' ');
1268: dump_expr (TREE_OPERAND (t, 1), 1);
1269: OB_PUTC (')');
1270: }
1271:
1272: static void
1273: dump_unary_op (opstring, t, nop)
1274: char *opstring;
1275: tree t;
1276: int nop;
1277: {
1278: if (!nop) OB_PUTC ('(');
1279: OB_PUTCP (opstring);
1280: dump_expr (TREE_OPERAND (t, 0), 1);
1281: if (!nop) OB_PUTC (')');
1282: }
1283:
1284: char *
1285: fndecl_as_string (cname, fndecl, print_ret_type_p)
1286: tree cname, fndecl;
1287: int print_ret_type_p;
1288: {
1289: return decl_as_string (fndecl, print_ret_type_p);
1290: }
1291:
1292: /* Same, but handtype a _TYPE.
1293: Called from convert_to_reference, mangle_class_name_for_template,
1294: build_unary_op, and GNU_xref_decl. */
1295: char *
1296: type_as_string (typ, v)
1297: tree typ;
1298: int v;
1299: {
1300: OB_INIT ();
1301:
1302: dump_type (typ, v);
1303:
1304: OB_FINISH ();
1305:
1306: return (char *)obstack_base (&scratch_obstack);
1307: }
1308:
1309: char *
1310: expr_as_string (decl, v)
1311: tree decl;
1312: int v;
1313: {
1314: OB_INIT ();
1315:
1316: dump_expr (decl, 1);
1317:
1318: OB_FINISH ();
1319:
1320: return (char *)obstack_base (&scratch_obstack);
1321: }
1322:
1323: /* A cross between type_as_string and fndecl_as_string.
1324: Only called from substitute_nice_name. */
1325: char *
1326: decl_as_string (decl, v)
1327: tree decl;
1328: int v;
1329: {
1330: OB_INIT ();
1331:
1332: dump_decl (decl, v);
1333:
1334: OB_FINISH ();
1335:
1336: return (char *)obstack_base (&scratch_obstack);
1337: }
1338:
1339: char *
1340: cp_file_of (t)
1341: tree t;
1342: {
1343: if (TREE_CODE (t) == PARM_DECL)
1344: return DECL_SOURCE_FILE (DECL_CONTEXT (t));
1345: else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
1346: return DECL_SOURCE_FILE (TYPE_NAME (t));
1347: else
1348: return DECL_SOURCE_FILE (t);
1349: }
1350:
1351: int
1352: cp_line_of (t)
1353: tree t;
1354: {
1355: int line = 0;
1356: if (TREE_CODE (t) == PARM_DECL)
1357: line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
1358: if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
1359: t = TREE_TYPE (t);
1360:
1361: if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
1362: {
1363: if (IS_AGGR_TYPE (t))
1364: line = CLASSTYPE_SOURCE_LINE (t);
1365: else
1366: line = DECL_SOURCE_LINE (TYPE_NAME (t));
1367: }
1368: else
1369: line = DECL_SOURCE_LINE (t);
1370:
1371: if (line == 0)
1372: return lineno;
1373:
1374: return line;
1375: }
1376:
1377: char *
1378: code_as_string (c, v)
1379: enum tree_code c;
1380: int v;
1381: {
1382: return tree_code_name [c];
1383: }
1384:
1385: char *
1386: language_as_string (c, v)
1387: enum languages c;
1388: int v;
1389: {
1390: switch (c)
1391: {
1392: case lang_c:
1393: return "C";
1394:
1395: case lang_cplusplus:
1396: return "C++";
1397:
1398: default:
1399: my_friendly_abort (355);
1400: return 0;
1401: }
1402: }
1403:
1404: /* Return the proper printed version of a parameter to a C++ function. */
1405: char *
1406: parm_as_string (p, v)
1407: int p, v;
1408: {
1409: if (p < 0)
1410: return "`this'";
1411:
1412: sprintf (digit_buffer, "%d", p+1);
1413: return digit_buffer;
1414: }
1415:
1416: char *
1417: op_as_string (p, v)
1418: enum tree_code p;
1419: int v;
1420: {
1421: static char buf[] = "operator ";
1422:
1423: if (p == 0)
1424: return "{unknown}";
1425:
1426: strcpy (buf + 9, opname_tab [p]);
1427: return buf;
1428: }
1429:
1430: char *
1431: args_as_string (p, v)
1432: tree p;
1433: int v;
1434: {
1435: if (p == NULL_TREE)
1436: return "...";
1437:
1438: return type_as_string (p, v);
1439: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.