|
|
1.1 root 1: /* Prints out tree in human readable form - GNU C-compiler
2: Copyright (C) 1987 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include "config.h"
23: #include "tree.h"
24: #include <stdio.h>
25:
26:
27: /* Names of tree components.
28: Used for printing out the tree and error messages. */
29: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
30:
31: char *tree_code_name[] = {
32: #include "tree.def"
33: };
34: #undef DEFTREECODE
35:
36: extern char *tree_code_type[];
37: extern int tree_code_length[];
38: extern char *mode_name[];
39:
40: extern char spaces[];
41:
42: #define MIN(x,y) ((x < y) ? x : y)
43:
44: static FILE *outfile;
45:
46: extern int tree_node_counter;
47:
48: /* markvec[i] is 1 if node number i has been seen already. */
49:
50: static char *markvec;
51:
52: static void dump ();
53: void dump_tree ();
54:
55: void
56: debug_dump_tree (root)
57: tree root;
58: {
59: dump_tree (stderr, root);
60: }
61:
62: void
63: dump_tree (outf, root)
64: FILE *outf;
65: tree root;
66: {
67: markvec = (char *) alloca (tree_node_counter + 1);
68: bzero (markvec, tree_node_counter + 1);
69: outfile = outf;
70: dump (root, 0);
71: fflush (outf);
72: }
73:
74: static
75: void
76: wruid (node)
77: tree node;
78: {
79:
80: if (node == NULL)
81: fputs ("<>", outfile);
82: else {
83: fprintf (outfile, "%1d", TREE_UID (node));
84: }
85: }
86:
87: static
88: void
89: part (title, node)
90: char title[];
91: tree node;
92: {
93: fprintf (outfile, " %s = ", title);
94: wruid (node);
95: putc (';', outfile);
96: }
97:
98: /* Similar to `part' but prefix with @ if value is not constant
99: and print the constant value if it is constant. */
100: static
101: void
102: cpart (title, ct, punct)
103: char *title;
104: tree ct;
105: char punct;
106: {
107: fprintf (outfile, " %s = ", title);
108: if (ct == NULL)
109: fputs ("<>", outfile);
110: else
111: {
112: if (!TREE_LITERAL (ct))
113: {
114: putc ('@', outfile);
115: wruid (ct);
116: }
117: else
118: fprintf (outfile, "%ld", TREE_INT_CST_LOW (ct));
119: }
120: putc(punct, outfile);
121: }
122:
123: static
124: void
125: walk (node, leaf, indent)
126: tree node;
127: tree leaf;
128: int indent;
129: {
130: if (node != NULL
131: /* Don't walk any global nodes reached from local nodes!
132: The global nodes will be dumped at the end, all together.
133: Also don't mention a FUNCTION_DECL node that is marked local
134: since it was fully described when it was dumped locally. */
135: && (TREE_CODE (node) != FUNCTION_DECL
136: || TREE_PERMANENT (node))
137: && (TREE_PERMANENT (leaf) == TREE_PERMANENT (node)))
138: dump (node, indent+1);
139: }
140:
141: static
142: void
143: cwalk (s, leaf, indent)
144: tree s;
145: tree leaf;
146: int indent;
147: {
148: if (s != NULL)
149: if (!TREE_LITERAL (s))
150: walk(s, leaf, indent);
151: }
152:
153: static
154: void
155: prtypeinfo (node)
156: register tree node;
157: {
158: int first;
159:
160: part ("type", TREE_TYPE (node));
161: first = 1;
162: fputs (" [", outfile);
163: if (TREE_EXTERNAL (node))
164: {
165: if (!first) putc (' ', outfile);
166: fputs ("external", outfile);
167: first = 0;
168: }
169: if (TREE_PUBLIC (node))
170: {
171: if (!first) putc (' ', outfile);
172: fputs ("public", outfile);
173: first = 0;
174: }
175: if (TREE_STATIC (node))
176: {
177: if (!first) putc (' ', outfile);
178: fputs ("static", outfile);
179: first = 0;
180: }
181: if (TREE_VOLATILE (node))
182: {
183: if (!first) putc (' ', outfile);
184: fputs ("volatile", outfile);
185: first = 0;
186: }
187: if (TREE_PACKED (node))
188: {
189: if (!first) putc (' ', outfile);
190: fputs ("packed", outfile);
191: first = 0;
192: }
193: if (TREE_READONLY (node))
194: {
195: if (!first) putc (' ', outfile);
196: fputs ("readonly", outfile);
197: first = 0;
198: }
199: if (TREE_LITERAL (node))
200: {
201: if (!first) putc (' ', outfile);
202: fputs ("literal", outfile);
203: first = 0;
204: }
205: if (TREE_NONLOCAL (node))
206: {
207: if (!first) putc (' ', outfile);
208: fputs ("nonlocal", outfile);
209: first = 0;
210: }
211: if (TREE_ADDRESSABLE (node))
212: {
213: if (!first) putc (' ', outfile);
214: fputs ("addressable", outfile);
215: first = 0;
216: }
217: if (TREE_REGDECL (node))
218: {
219: if (!first) putc (' ', outfile);
220: fputs ("regdecl", outfile);
221: first = 0;
222: }
223: if (TREE_THIS_VOLATILE (node))
224: {
225: if (!first) putc (' ', outfile);
226: fputs ("this_vol", outfile);
227: first = 0;
228: }
229: if (TREE_UNSIGNED (node))
230: {
231: if (!first) putc (' ', outfile);
232: fputs ("unsigned", outfile);
233: first = 0;
234: }
235: if (TREE_ASM_WRITTEN (node))
236: {
237: if (!first) putc (' ', outfile);
238: fputs ("asm_written", outfile);
239: first = 0;
240: }
241: if (TREE_INLINE (node))
242: {
243: if (!first) putc (' ', outfile);
244: fputs ("inline", outfile);
245: first = 0;
246: }
247: fputs ("] ", outfile);
248: }
249:
250: static
251: void
252: prdeclmodeinfo(node)
253: tree node;
254: {
255: register enum machine_mode mode = DECL_MODE (node);
256: fprintf (outfile, " %s;", mode_name[(int) mode]);
257:
258: cpart ("size", DECL_SIZE (node), '*');
259: fprintf (outfile, "%d;", DECL_SIZE_UNIT (node));
260:
261: fprintf (outfile, " alignment = %1d;", DECL_ALIGN (node));
262: }
263:
264: static
265: void
266: prtypemodeinfo(node)
267: tree node;
268: {
269: register enum machine_mode mode = TYPE_MODE (node);
270: fprintf (outfile, " %s;", mode_name[(int) mode]);
271:
272: cpart ("size", TYPE_SIZE (node), '*');
273: fprintf (outfile, "%d;", TYPE_SIZE_UNIT (node));
274:
275: fprintf (outfile, " alignment = %1d;", TYPE_ALIGN (node));
276: }
277:
278: static
279: void
280: skip (indent)
281: int indent;
282: {
283: putc ('\n',outfile);
284: fputs (spaces + (strlen (spaces) - (12 + MIN (40,(indent+1)*2))), outfile);
285: }
286:
287: /* Output a description of the tree node NODE
288: if its description has not been output already. */
289:
290: static
291: void
292: dump (node, indent)
293: tree node;
294: int indent;
295: {
296: register enum tree_code code = TREE_CODE (node);
297: register int i;
298: register int len;
299: int nochain = 0;
300:
301: if (markvec[TREE_UID (node)])
302: return;
303: markvec[TREE_UID (node)] = 1;
304:
305: fputs (" ", outfile);
306: fprintf (outfile, "%5d", TREE_UID (node));
307: fputs (spaces + (strlen (spaces) - MIN (40, (indent+1)*2)), outfile);
308: fputs (tree_code_name[(int) code], outfile);
309:
310: switch (*tree_code_type[(int) code])
311: {
312: case 'd':
313: fputs (" name = ", outfile);
314: if (DECL_NAME (node) == NULL)
315: fputs("<>;", outfile);
316: else
317: fprintf (outfile, "%s;",
318: IDENTIFIER_POINTER (DECL_NAME (node)));
319: fprintf (outfile, " at %s line %d;",
320: DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
321: skip (indent);
322: prdeclmodeinfo (node);
323: prtypeinfo (node);
324: skip (indent);
325: fprintf (outfile, " offset = %1d;", DECL_OFFSET (node));
326: if (DECL_VOFFSET (node) != NULL)
327: {
328: fputs ("voffset = ", outfile);
329: wruid (DECL_VOFFSET (node));
330: fprintf (outfile, "*%1d;", DECL_VOFFSET_UNIT (node));
331: }
332: part ("context", DECL_CONTEXT (node));
333: if (DECL_ARGUMENTS (node) || DECL_RESULT (node)
334: || DECL_INITIAL (node))
335: {
336: skip(indent);
337: part ("arguments", DECL_ARGUMENTS (node));
338: part ("result", DECL_RESULT (node));
339: if ((int) (DECL_INITIAL (node)) == 1)
340: fprintf (outfile, " initial = const 1;");
341: else
342: part ("initial", DECL_INITIAL (node));
343: }
344: part ("chain", TREE_CHAIN (node));
345: fputc ('\n', outfile);
346: cwalk (DECL_SIZE (node), node, indent);
347: walk (TREE_TYPE (node), node, indent);
348: walk (DECL_VOFFSET (node), node, indent);
349: walk (DECL_CONTEXT (node), node, indent);
350: walk (DECL_ARGUMENTS (node), node, indent);
351: walk (DECL_RESULT (node), node, indent);
352: if ((int) (DECL_INITIAL (node)) != 1)
353: walk (DECL_INITIAL (node), node, indent);
354: break;
355:
356: case 't':
357: prtypemodeinfo (node);
358: prtypeinfo (node);
359: skip (indent);
360: part ("pointers_to_this", TYPE_POINTER_TO (node));
361: if (code == ARRAY_TYPE || code == SET_TYPE)
362: {
363: part ("domain", TYPE_DOMAIN (node));
364: cpart ("separation", TYPE_SEP (node), '*');
365: fprintf (outfile, "%d;", TYPE_SEP_UNIT (node));
366: }
367: else if (code == INTEGER_TYPE)
368: {
369: cpart ("min", TYPE_MIN_VALUE (node), ';');
370: cpart ("max", TYPE_MAX_VALUE (node), ';');
371: fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
372: }
373: else if (code == ENUMERAL_TYPE)
374: {
375: cpart ("min", TYPE_MIN_VALUE (node), ';');
376: cpart ("max", TYPE_MAX_VALUE (node), ';');
377: part ("values", TYPE_VALUES (node));
378: fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
379: }
380: else if (code == REAL_TYPE)
381: {
382: fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
383: }
384: else if (code == RECORD_TYPE
385: || code == UNION_TYPE)
386: {
387: part ("fields", TYPE_FIELDS (node));
388: }
389: else if (code == FUNCTION_TYPE)
390: {
391: part ("arg_types", TYPE_ARG_TYPES (node));
392: }
393: /* A type's chain is not printed because the chain of types
394: is not part of the meaning of any particular type. */
395: /* part ("chain", TREE_CHAIN (node)); */
396: nochain = 1;
397: fputc ('\n', outfile);
398: cwalk (TYPE_SIZE (node), node, indent);
399: walk (TREE_TYPE (node), node, indent);
400: walk (TYPE_VALUES (node), node, indent);
401: walk (TYPE_SEP (node), node, indent);
402: walk (TYPE_POINTER_TO (node), node, indent);
403: break;
404:
405: case 'e':
406: case 'r':
407: prtypeinfo (node);
408: fputs (" ops =", outfile);
409: len = tree_code_length[(int) code];
410: for (i = 0; i < len; i++)
411: {
412: fputs (" ", outfile);
413: wruid (TREE_OPERAND (node, i));
414: fputs (";", outfile);
415: }
416: part ("chain", TREE_CHAIN (node));
417: fputc ('\n', outfile);
418: walk (TREE_TYPE (node), node, indent);
419: for (i = 0; i < len; i++)
420: walk (TREE_OPERAND (node, i), node, indent);
421: break;
422:
423: case 's':
424: prtypeinfo (node);
425: fprintf (outfile, " at %s line %d;",
426: STMT_SOURCE_FILE (node), STMT_SOURCE_LINE (node));
427: fputs (" ops =", outfile);
428: len = tree_code_length[(int) code];
429: for (i = 0; i < len; i++)
430: {
431: fputs (" ", outfile);
432: wruid (TREE_OPERAND (node, i+2));
433: fputs (";", outfile);
434: }
435: part ("chain", TREE_CHAIN (node));
436: fputc ('\n', outfile);
437: walk (TREE_TYPE (node), node, indent);
438: for (i = 0; i < len; i++)
439: walk (TREE_OPERAND (node, i+2), node, indent);
440: break;
441:
442: case 'c':
443: switch (code)
444: {
445: case INTEGER_CST:
446: if (TREE_INT_CST_HIGH (node) == 0)
447: fprintf (outfile, " = %1u;", TREE_INT_CST_LOW (node));
448: else if (TREE_INT_CST_HIGH (node) == -1
449: && TREE_INT_CST_LOW (node) != 0)
450: fprintf (outfile, " = -%1u;", -TREE_INT_CST_LOW (node));
451: else
452: fprintf (outfile, " = 0x%x%08x;",
453: TREE_INT_CST_HIGH (node),
454: TREE_INT_CST_LOW (node));
455: break;
456:
457: case REAL_CST:
458: fprintf (outfile, " = %e;", TREE_REAL_CST (node));
459: break;
460:
461: case COMPLEX_CST:
462: part ("realpart", TREE_REALPART (node));
463: part ("imagpart", TREE_IMAGPART (node));
464: walk (TREE_REALPART (node), node, indent);
465: walk (TREE_IMAGPART (node), node, indent);
466: break;
467:
468: case STRING_CST:
469: fprintf (outfile, " = \"%s\";", TREE_STRING_POINTER (node));
470: }
471: prtypeinfo(node);
472: part ("chain", TREE_CHAIN (node));
473: fputc ('\n', outfile);
474: walk (TREE_TYPE (node), node, indent);
475: break;
476:
477: case 'x':
478: if (code == IDENTIFIER_NODE)
479: fprintf (outfile, " = %s;\n", IDENTIFIER_POINTER (node));
480: else if (code == TREE_LIST)
481: {
482: prtypeinfo (node);
483: part ("purpose", TREE_PURPOSE (node));
484: part ("value", TREE_VALUE (node));
485: part ("chain", TREE_CHAIN (node));
486: fputc ('\n', outfile);
487: walk (TREE_TYPE (node), node, indent);
488: walk (TREE_PURPOSE (node), node, indent);
489: walk (TREE_VALUE (node), node, indent);
490: }
491: else if (code == ERROR_MARK)
492: fputc ('\n', outfile);
493: else abort ();
494:
495: break;
496:
497: default:
498: abort ();
499: } /* switch */
500:
501: if (TREE_CHAIN (node) != NULL && ! nochain)
502: dump(TREE_CHAIN (node), indent);
503: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.