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