Fix attribution in ChangeLog
[official-gcc.git] / gcc / c-dump.c
blob98a496d81fc6b52cdb5f96f2cd093a08df85d17e
1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 Written by Mark Mitchell <mark@codesourcery.com>
5 This file is part of GNU CC.
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.
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.
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "tree.h"
25 #include "c-common.h"
26 #include "splay-tree.h"
27 #include "diagnostic.h"
28 #include "toplev.h"
29 #include "c-dump.h"
31 /* A callback function used dump language-specific parts of tree
32 nodes. Returns non-zero if it does not want the usual dumping of
33 the second argument. */
35 dump_tree_fn lang_dump_tree;
37 static unsigned int queue PARAMS ((dump_info_p, tree, int));
38 static void dump_index PARAMS ((dump_info_p, unsigned int));
39 static void dequeue_and_dump PARAMS ((dump_info_p));
40 static void dump_new_line PARAMS ((dump_info_p));
41 static void dump_maybe_newline PARAMS ((dump_info_p));
42 static void dump_string_field PARAMS ((dump_info_p, const char *, const char *));
43 static void dump_node PARAMS ((tree, FILE *));
45 /* Add T to the end of the queue of nodes to dump. Returns the index
46 assigned to T. */
48 static unsigned int
49 queue (di, t, flags)
50 dump_info_p di;
51 tree t;
52 int flags;
54 dump_queue_p dq;
55 dump_node_info_p dni;
56 unsigned int index;
58 /* Assign the next available index to T. */
59 index = ++di->index;
61 /* Obtain a new queue node. */
62 if (di->free_list)
64 dq = di->free_list;
65 di->free_list = dq->next;
67 else
68 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
70 /* Create a new entry in the splay-tree. */
71 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
72 dni->index = index;
73 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
74 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
75 (splay_tree_value) dni);
77 /* Add it to the end of the queue. */
78 dq->next = 0;
79 if (!di->queue_end)
80 di->queue = dq;
81 else
82 di->queue_end->next = dq;
83 di->queue_end = dq;
85 /* Return the index. */
86 return index;
89 static void
90 dump_index (di, index)
91 dump_info_p di;
92 unsigned int index;
94 fprintf (di->stream, "@%-6u ", index);
95 di->column += 8;
98 /* If T has not already been output, queue it for subsequent output.
99 FIELD is a string to print before printing the index. Then, the
100 index of T is printed. */
102 void
103 queue_and_dump_index (di, field, t, flags)
104 dump_info_p di;
105 const char *field;
106 tree t;
107 int flags;
109 unsigned int index;
110 splay_tree_node n;
112 /* If there's no node, just return. This makes for fewer checks in
113 our callers. */
114 if (!t)
115 return;
117 /* See if we've already queued or dumped this node. */
118 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
119 if (n)
120 index = ((dump_node_info_p) n->value)->index;
121 else
122 /* If we haven't, add it to the queue. */
123 index = queue (di, t, flags);
125 /* Print the index of the node. */
126 dump_maybe_newline (di);
127 fprintf (di->stream, "%-4s: ", field);
128 di->column += 6;
129 dump_index (di, index);
132 /* Dump the type of T. */
134 void
135 queue_and_dump_type (di, t)
136 dump_info_p di;
137 tree t;
139 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
142 /* Insert a new line in the dump output, and indent to an appropriate
143 place to start printing more fields. */
145 static void
146 dump_new_line (di)
147 dump_info_p di;
149 fprintf (di->stream, "\n%25s", "");
150 di->column = 25;
153 /* If necessary, insert a new line. */
155 static void
156 dump_maybe_newline (di)
157 dump_info_p di;
159 /* See if we need a new line. */
160 if (di->column > 53)
161 dump_new_line (di);
162 /* See if we need any padding. */
163 else if ((di->column - 25) % 14 != 0)
165 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
166 di->column += 14 - (di->column - 25) % 14;
170 /* Dump I using FIELD to identity it. */
172 void
173 dump_int (di, field, i)
174 dump_info_p di;
175 const char *field;
176 int i;
178 dump_maybe_newline (di);
179 fprintf (di->stream, "%-4s: %-7d ", field, i);
180 di->column += 14;
183 /* Dump the string S. */
185 void
186 dump_string (di, string)
187 dump_info_p di;
188 const char *string;
190 dump_maybe_newline (di);
191 fprintf (di->stream, "%-13s ", string);
192 if (strlen (string) > 13)
193 di->column += strlen (string) + 1;
194 else
195 di->column += 14;
198 /* Dump the string field S. */
200 static void
201 dump_string_field (di, field, string)
202 dump_info_p di;
203 const char *field;
204 const char *string;
206 dump_maybe_newline (di);
207 fprintf (di->stream, "%-4s: %-7s ", field, string);
208 if (strlen (string) > 7)
209 di->column += 6 + strlen (string) + 1;
210 else
211 di->column += 14;
214 /* Dump information common to statements from STMT. */
216 void
217 dump_stmt (di, t)
218 dump_info_p di;
219 tree t;
221 dump_int (di, "line", STMT_LINENO (t));
224 /* Dump the next statement after STMT. */
226 void
227 dump_next_stmt (di, t)
228 dump_info_p di;
229 tree t;
231 dump_child ("next", TREE_CHAIN (t));
234 /* Dump the next node in the queue. */
236 static void
237 dequeue_and_dump (di)
238 dump_info_p di;
240 dump_queue_p dq;
241 splay_tree_node stn;
242 dump_node_info_p dni;
243 tree t;
244 unsigned int index;
245 enum tree_code code;
246 char code_class;
247 const char* code_name;
249 /* Get the next node from the queue. */
250 dq = di->queue;
251 stn = dq->node;
252 t = (tree) stn->key;
253 dni = (dump_node_info_p) stn->value;
254 index = dni->index;
256 /* Remove the node from the queue, and put it on the free list. */
257 di->queue = dq->next;
258 if (!di->queue)
259 di->queue_end = 0;
260 dq->next = di->free_list;
261 di->free_list = dq;
263 /* Print the node index. */
264 dump_index (di, index);
265 /* And the type of node this is. */
266 if (dni->binfo_p)
267 code_name = "binfo";
268 else
269 code_name = tree_code_name[(int) TREE_CODE (t)];
270 fprintf (di->stream, "%-16s ", code_name);
271 di->column = 25;
273 /* Figure out what kind of node this is. */
274 code = TREE_CODE (t);
275 code_class = TREE_CODE_CLASS (code);
277 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
278 more informative. */
279 if (dni->binfo_p)
281 if (TREE_VIA_PUBLIC (t))
282 dump_string (di, "pub");
283 else if (TREE_VIA_PROTECTED (t))
284 dump_string (di, "prot");
285 else if (TREE_VIA_PRIVATE (t))
286 dump_string (di, "priv");
287 if (TREE_VIA_VIRTUAL (t))
288 dump_string (di, "virt");
290 dump_child ("type", BINFO_TYPE (t));
291 dump_child ("base", BINFO_BASETYPES (t));
293 goto done;
296 /* We can knock off a bunch of expression nodes in exactly the same
297 way. */
298 if (IS_EXPR_CODE_CLASS (code_class))
300 /* If we're dumping children, dump them now. */
301 queue_and_dump_type (di, t);
303 switch (code_class)
305 case '1':
306 dump_child ("op 0", TREE_OPERAND (t, 0));
307 break;
309 case '2':
310 case '<':
311 dump_child ("op 0", TREE_OPERAND (t, 0));
312 dump_child ("op 1", TREE_OPERAND (t, 1));
313 break;
315 case 'e':
316 /* These nodes are handled explicitly below. */
317 break;
319 default:
320 abort();
323 else if (DECL_P (t))
325 /* All declarations have names. */
326 if (DECL_NAME (t))
327 dump_child ("name", DECL_NAME (t));
328 if (DECL_ASSEMBLER_NAME_SET_P (t)
329 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
330 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
331 /* And types. */
332 queue_and_dump_type (di, t);
333 dump_child ("scpe", DECL_CONTEXT (t));
334 /* And a source position. */
335 if (DECL_SOURCE_FILE (t))
337 const char *filename = strrchr (DECL_SOURCE_FILE (t), '/');
338 if (!filename)
339 filename = DECL_SOURCE_FILE (t);
340 else
341 /* Skip the slash. */
342 ++filename;
344 dump_maybe_newline (di);
345 fprintf (di->stream, "srcp: %s:%-6d ", filename,
346 DECL_SOURCE_LINE (t));
347 di->column += 6 + strlen (filename) + 8;
349 /* And any declaration can be compiler-generated. */
350 if (DECL_ARTIFICIAL (t))
351 dump_string (di, "artificial");
352 if (TREE_CHAIN (t))
353 dump_child ("chan", TREE_CHAIN (t));
355 else if (code_class == 't')
357 /* All types have qualifiers. */
358 int quals = C_TYPE_QUALS (t);
359 if (quals != TYPE_UNQUALIFIED)
361 fprintf (di->stream, "qual: %c%c%c ",
362 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
363 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
364 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
365 di->column += 14;
368 /* All types have associated declarations. */
369 dump_child ("name", TYPE_NAME (t));
371 /* All types have a main variant. */
372 if (TYPE_MAIN_VARIANT (t) != t)
373 dump_child ("unql", TYPE_MAIN_VARIANT (t));
375 /* And sizes. */
376 dump_child ("size", TYPE_SIZE (t));
378 /* All types have alignments. */
379 dump_int (di, "algn", TYPE_ALIGN (t));
381 else if (code_class == 'c')
382 /* All constants can have types. */
383 queue_and_dump_type (di, t);
385 /* Give the language-specific code a chance to print something. If
386 it's completely taken care of things, don't bother printing
387 anything more ourselves. */
388 if (lang_dump_tree && (*lang_dump_tree) (di, t))
389 goto done;
391 /* Now handle the various kinds of nodes. */
392 switch (code)
394 int i;
396 case IDENTIFIER_NODE:
397 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
398 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
399 break;
401 case TREE_LIST:
402 dump_child ("purp", TREE_PURPOSE (t));
403 dump_child ("valu", TREE_VALUE (t));
404 dump_child ("chan", TREE_CHAIN (t));
405 break;
407 case TREE_VEC:
408 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
409 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
411 char buffer[32];
412 sprintf (buffer, "%u", i);
413 dump_child (buffer, TREE_VEC_ELT (t, i));
415 break;
417 case INTEGER_TYPE:
418 case ENUMERAL_TYPE:
419 dump_int (di, "prec", TYPE_PRECISION (t));
420 if (TREE_UNSIGNED (t))
421 dump_string (di, "unsigned");
422 dump_child ("min", TYPE_MIN_VALUE (t));
423 dump_child ("max", TYPE_MAX_VALUE (t));
425 if (code == ENUMERAL_TYPE)
426 dump_child ("csts", TYPE_VALUES (t));
427 break;
429 case REAL_TYPE:
430 dump_int (di, "prec", TYPE_PRECISION (t));
431 break;
433 case POINTER_TYPE:
434 dump_child ("ptd", TREE_TYPE (t));
435 break;
437 case REFERENCE_TYPE:
438 dump_child ("refd", TREE_TYPE (t));
439 break;
441 case METHOD_TYPE:
442 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
443 /* Fall through. */
445 case FUNCTION_TYPE:
446 dump_child ("retn", TREE_TYPE (t));
447 dump_child ("prms", TYPE_ARG_TYPES (t));
448 break;
450 case ARRAY_TYPE:
451 dump_child ("elts", TREE_TYPE (t));
452 dump_child ("domn", TYPE_DOMAIN (t));
453 break;
455 case RECORD_TYPE:
456 case UNION_TYPE:
457 if (TREE_CODE (t) == RECORD_TYPE)
458 dump_string (di, "struct");
459 else
460 dump_string (di, "union");
462 dump_child ("flds", TYPE_FIELDS (t));
463 dump_child ("fncs", TYPE_METHODS (t));
464 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
465 DUMP_BINFO);
466 break;
468 case CONST_DECL:
469 dump_child ("cnst", DECL_INITIAL (t));
470 break;
472 case VAR_DECL:
473 case PARM_DECL:
474 case FIELD_DECL:
475 case RESULT_DECL:
476 if (TREE_CODE (t) == PARM_DECL)
477 dump_child ("argt", DECL_ARG_TYPE (t));
478 else
479 dump_child ("init", DECL_INITIAL (t));
480 dump_child ("size", DECL_SIZE (t));
481 dump_int (di, "algn", DECL_ALIGN (t));
483 if (TREE_CODE (t) == FIELD_DECL)
485 if (DECL_C_BIT_FIELD (t))
486 dump_string (di, "bitfield");
487 if (DECL_FIELD_OFFSET (t))
488 dump_child ("bpos", bit_position (t));
490 else if (TREE_CODE (t) == VAR_DECL
491 || TREE_CODE (t) == PARM_DECL)
493 dump_int (di, "used", TREE_USED (t));
494 if (DECL_REGISTER (t))
495 dump_string (di, "register");
497 break;
499 case FUNCTION_DECL:
500 dump_child ("args", DECL_ARGUMENTS (t));
501 if (DECL_EXTERNAL (t))
502 dump_string (di, "undefined");
503 if (TREE_PUBLIC (t))
504 dump_string (di, "extern");
505 else
506 dump_string (di, "static");
507 if (DECL_LANG_SPECIFIC (t))
508 dump_child ("body", DECL_SAVED_TREE (t));
509 break;
511 case ASM_STMT:
512 dump_stmt (di, t);
513 if (ASM_VOLATILE_P (t))
514 dump_string (di, "volatile");
515 dump_child ("strg", ASM_STRING (t));
516 dump_child ("outs", ASM_OUTPUTS (t));
517 dump_child ("ins", ASM_INPUTS (t));
518 dump_child ("clbr", ASM_CLOBBERS (t));
519 dump_next_stmt (di, t);
520 break;
522 case BREAK_STMT:
523 case CONTINUE_STMT:
524 dump_stmt (di, t);
525 dump_next_stmt (di, t);
526 break;
528 case CASE_LABEL:
529 /* Note that a case label is not like other statments; there is
530 no way to get the line-number of a case label. */
531 dump_child ("low", CASE_LOW (t));
532 dump_child ("high", CASE_HIGH (t));
533 dump_next_stmt (di, t);
534 break;
536 case COMPOUND_STMT:
537 dump_stmt (di, t);
538 dump_child ("body", COMPOUND_BODY (t));
539 dump_next_stmt (di, t);
540 break;
542 case DECL_STMT:
543 dump_stmt (di, t);
544 dump_child ("decl", DECL_STMT_DECL (t));
545 dump_next_stmt (di, t);
546 break;
548 case DO_STMT:
549 dump_stmt (di, t);
550 dump_child ("body", DO_BODY (t));
551 dump_child ("cond", DO_COND (t));
552 dump_next_stmt (di, t);
553 break;
555 case EXPR_STMT:
556 dump_stmt (di, t);
557 dump_child ("expr", EXPR_STMT_EXPR (t));
558 dump_next_stmt (di, t);
559 break;
561 case FOR_STMT:
562 dump_stmt (di, t);
563 dump_child ("init", FOR_INIT_STMT (t));
564 dump_child ("cond", FOR_COND (t));
565 dump_child ("expr", FOR_EXPR (t));
566 dump_child ("body", FOR_BODY (t));
567 dump_next_stmt (di, t);
568 break;
570 case GOTO_STMT:
571 dump_stmt (di, t);
572 dump_child ("dest", GOTO_DESTINATION (t));
573 dump_next_stmt (di, t);
574 break;
576 case IF_STMT:
577 dump_stmt (di, t);
578 dump_child ("cond", IF_COND (t));
579 dump_child ("then", THEN_CLAUSE (t));
580 dump_child ("else", ELSE_CLAUSE (t));
581 dump_next_stmt (di, t);
582 break;
584 case LABEL_STMT:
585 dump_stmt (di, t);
586 dump_child ("labl", LABEL_STMT_LABEL (t));
587 dump_next_stmt (di, t);
588 break;
590 case RETURN_STMT:
591 dump_stmt (di, t);
592 dump_child ("expr", RETURN_EXPR (t));
593 dump_next_stmt (di, t);
594 break;
596 case SWITCH_STMT:
597 dump_stmt (di, t);
598 dump_child ("cond", SWITCH_COND (t));
599 dump_child ("body", SWITCH_BODY (t));
600 dump_next_stmt (di, t);
601 break;
603 case WHILE_STMT:
604 dump_stmt (di, t);
605 dump_child ("cond", WHILE_COND (t));
606 dump_child ("body", WHILE_BODY (t));
607 dump_next_stmt (di, t);
608 break;
610 case SCOPE_STMT:
611 dump_stmt (di, t);
612 if (SCOPE_BEGIN_P (t))
613 dump_string (di, "begn");
614 else
615 dump_string (di, "end");
616 if (SCOPE_NULLIFIED_P (t))
617 dump_string (di, "null");
618 if (!SCOPE_NO_CLEANUPS_P (t))
619 dump_string (di, "clnp");
620 dump_next_stmt (di, t);
621 break;
623 case INTEGER_CST:
624 if (TREE_INT_CST_HIGH (t))
625 dump_int (di, "high", TREE_INT_CST_HIGH (t));
626 dump_int (di, "low", TREE_INT_CST_LOW (t));
627 break;
629 case STRING_CST:
630 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
631 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
632 break;
634 case TRUTH_NOT_EXPR:
635 case ADDR_EXPR:
636 case INDIRECT_REF:
637 case CLEANUP_POINT_EXPR:
638 case SAVE_EXPR:
639 /* These nodes are unary, but do not have code class `1'. */
640 dump_child ("op 0", TREE_OPERAND (t, 0));
641 break;
643 case TRUTH_ANDIF_EXPR:
644 case TRUTH_ORIF_EXPR:
645 case INIT_EXPR:
646 case MODIFY_EXPR:
647 case COMPONENT_REF:
648 case COMPOUND_EXPR:
649 case ARRAY_REF:
650 case PREDECREMENT_EXPR:
651 case PREINCREMENT_EXPR:
652 case POSTDECREMENT_EXPR:
653 case POSTINCREMENT_EXPR:
654 /* These nodes are binary, but do not have code class `2'. */
655 dump_child ("op 0", TREE_OPERAND (t, 0));
656 dump_child ("op 1", TREE_OPERAND (t, 1));
657 break;
659 case COND_EXPR:
660 dump_child ("op 0", TREE_OPERAND (t, 0));
661 dump_child ("op 1", TREE_OPERAND (t, 1));
662 dump_child ("op 2", TREE_OPERAND (t, 2));
663 break;
665 case CALL_EXPR:
666 dump_child ("fn", TREE_OPERAND (t, 0));
667 dump_child ("args", TREE_OPERAND (t, 1));
668 break;
670 case CONSTRUCTOR:
671 dump_child ("elts", TREE_OPERAND (t, 1));
672 break;
674 case STMT_EXPR:
675 dump_child ("stmt", STMT_EXPR_STMT (t));
676 break;
678 case BIND_EXPR:
679 dump_child ("vars", TREE_OPERAND (t, 0));
680 dump_child ("body", TREE_OPERAND (t, 1));
681 break;
683 case LOOP_EXPR:
684 dump_child ("body", TREE_OPERAND (t, 0));
685 break;
687 case EXIT_EXPR:
688 dump_child ("cond", TREE_OPERAND (t, 0));
689 break;
691 case TARGET_EXPR:
692 dump_child ("decl", TREE_OPERAND (t, 0));
693 dump_child ("init", TREE_OPERAND (t, 1));
694 dump_child ("clnp", TREE_OPERAND (t, 2));
695 /* There really are two possible places the initializer can be.
696 After RTL expansion, the second operand is moved to the
697 position of the fourth operand, and the second operand
698 becomes NULL. */
699 dump_child ("init", TREE_OPERAND (t, 3));
700 break;
702 case EXPR_WITH_FILE_LOCATION:
703 dump_child ("expr", EXPR_WFL_NODE (t));
704 break;
706 default:
707 /* There are no additional fields to print. */
708 break;
711 done:
712 /* Terminate the line. */
713 fprintf (di->stream, "\n");
716 /* Dump T, and all its children, on STREAM. */
718 static void
719 dump_node (t, stream)
720 tree t;
721 FILE *stream;
723 struct dump_info di;
724 dump_queue_p dq;
725 dump_queue_p next_dq;
727 /* Initialize the dump-information structure. */
728 di.stream = stream;
729 di.index = 0;
730 di.column = 0;
731 di.queue = 0;
732 di.queue_end = 0;
733 di.free_list = 0;
734 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
735 (splay_tree_delete_value_fn) &free);
737 /* Queue up the first node. */
738 queue (&di, t, DUMP_NONE);
740 /* Until the queue is empty, keep dumping nodes. */
741 while (di.queue)
742 dequeue_and_dump (&di);
744 /* Now, clean up. */
745 for (dq = di.free_list; dq; dq = next_dq)
747 next_dq = dq->next;
748 free (dq);
750 splay_tree_delete (di.nodes);
753 /* Dump T, and all its children, to FILE. */
755 void
756 dump_node_to_file (t, file)
757 tree t;
758 const char *file;
760 FILE *f;
762 f = fopen (file, "w");
763 if (!f)
764 error ("could not open dump file `%s'", file);
765 else
767 dump_node (t, f);
768 fclose (f);