1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999 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)
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. */
26 #include "splay-tree.h"
28 /* Flags used with queue functions. */
32 /* Information about a node to be dumped. */
34 typedef struct dump_node_info
36 /* The index for the node. */
38 /* Nonzero if the node is a binfo. */
39 unsigned int binfo_p : 1;
42 /* A dump_queue is a link in the queue of things to be dumped. */
44 typedef struct dump_queue
46 /* The queued tree node. */
48 /* The next node in the queue. */
49 struct dump_queue *next;
52 /* A dump_info gives information about how we should perform the dump
53 and about the current state of the dump. */
55 typedef struct dump_info
57 /* The stream on which to dump the information. */
59 /* The next unused node index. */
61 /* The next column. */
63 /* The first node in the queue of nodes to be written out. */
65 /* The last node in the queue. */
66 dump_queue_p queue_end;
67 /* Free queue nodes. */
68 dump_queue_p free_list;
69 /* The tree nodes which we have already written out. The
70 keys are the addresses of the nodes; the values are the integer
71 indices we assigned them. */
75 static unsigned int queue PROTO ((dump_info_p, tree, int));
76 static void dump_index PROTO ((dump_info_p, unsigned int));
77 static void queue_and_dump_index PROTO ((dump_info_p, const char *, tree, int));
78 static void queue_and_dump_type PROTO ((dump_info_p, tree));
79 static void dequeue_and_dump PROTO ((dump_info_p));
80 static void dump_new_line PROTO ((dump_info_p));
81 static void dump_maybe_newline PROTO ((dump_info_p));
82 static void dump_int PROTO ((dump_info_p, const char *, int));
83 static void dump_string PROTO ((dump_info_p, const char *));
84 static void dump_string_field PROTO ((dump_info_p, const char *, const char *));
85 static void dump_node PROTO ((tree, FILE *));
86 static void dump_stmt PROTO ((dump_info_p, tree));
87 static void dump_next_stmt PROTO ((dump_info_p, tree));
89 /* Add T to the end of the queue of nodes to dump. Returns the index
102 /* Assign the next available index to T. */
105 /* Obtain a new queue node. */
109 di->free_list = dq->next;
112 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
114 /* Create a new entry in the splay-tree. */
115 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
117 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
118 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
119 (splay_tree_value) dni);
121 /* Add it to the end of the queue. */
126 di->queue_end->next = dq;
129 /* Return the index. */
134 dump_index (di, index)
138 fprintf (di->stream, "@%-6u ", index);
142 /* If T has not already been output, queue it for subsequent output.
143 FIELD is a string to print before printing the index. Then, the
144 index of T is printed. */
147 queue_and_dump_index (di, field, t, flags)
156 /* If there's no node, just return. This makes for fewer checks in
161 /* See if we've already queued or dumped this node. */
162 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
164 index = ((dump_node_info_p) n->value)->index;
166 /* If we haven't, add it to the queue. */
167 index = queue (di, t, flags);
169 /* Print the index of the node. */
170 dump_maybe_newline (di);
171 fprintf (di->stream, "%-4s: ", field);
173 dump_index (di, index);
176 /* Dump the type of T. */
179 queue_and_dump_type (di, t)
183 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
186 /* Insert a new line in the dump output, and indent to an appropriate
187 place to start printing more fields. */
193 fprintf (di->stream, "\n%25s", "");
197 /* If necessary, insert a new line. */
200 dump_maybe_newline (di)
203 /* See if we need a new line. */
206 /* See if we need any padding. */
207 else if ((di->column - 25) % 14 != 0)
209 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
210 di->column += 14 - (di->column - 25) % 14;
214 /* Dump I using FIELD to identity it. */
217 dump_int (di, field, i)
222 dump_maybe_newline (di);
223 fprintf (di->stream, "%-4s: %-7d ", field, i);
227 /* Dump the string S. */
230 dump_string (di, string)
234 dump_maybe_newline (di);
235 fprintf (di->stream, "%-13s ", string);
236 if (strlen (string) > 13)
237 di->column += strlen (string) + 1;
242 /* Dump the string field S. */
245 dump_string_field (di, field, string)
250 dump_maybe_newline (di);
251 fprintf (di->stream, "%-4s: %-7s ", field, string);
252 if (strlen (string) > 7)
253 di->column += 6 + strlen (string) + 1;
258 /* Dump information common to statements from STMT. */
265 dump_int (di, "line", STMT_LINENO (t));
268 /* Dump the CHILD and its children. */
269 #define dump_child(field, child) \
270 queue_and_dump_index (di, field, child, DUMP_NONE)
272 /* Dump the next statement after STMT. */
275 dump_next_stmt (di, t)
279 dump_child ("next", TREE_CHAIN (t));
282 /* Dump the next node in the queue. */
285 dequeue_and_dump (di)
290 dump_node_info_p dni;
295 const char* code_name;
297 /* Get the next node from the queue. */
301 dni = (dump_node_info_p) stn->value;
304 /* Remove the node from the queue, and put it on the free list. */
305 di->queue = dq->next;
308 dq->next = di->free_list;
311 /* Print the node index. */
312 dump_index (di, index);
313 /* And the type of node this is. */
317 code_name = tree_code_name[(int) TREE_CODE (t)];
318 fprintf (di->stream, "%-16s ", code_name);
321 /* Figure out what kind of node this is. */
322 code = TREE_CODE (t);
323 code_class = TREE_CODE_CLASS (code);
325 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
329 if (TREE_VIA_PUBLIC (t))
330 dump_string (di, "pub");
331 else if (TREE_VIA_PROTECTED (t))
332 dump_string (di, "prot");
333 else if (TREE_VIA_PRIVATE (t))
334 dump_string (di, "priv");
335 if (TREE_VIA_VIRTUAL (t))
336 dump_string (di, "virt");
338 dump_child ("type", BINFO_TYPE (t));
339 dump_child ("base", BINFO_BASETYPES (t));
344 /* We can knock off a bunch of expression nodes in exactly the same
346 if (IS_EXPR_CODE_CLASS (code_class))
348 /* If we're dumping children, dump them now. */
349 queue_and_dump_type (di, t);
354 dump_child ("op 0", TREE_OPERAND (t, 0));
359 dump_child ("op 0", TREE_OPERAND (t, 0));
360 dump_child ("op 1", TREE_OPERAND (t, 1));
364 /* These nodes are handled explicitly below. */
368 my_friendly_abort (19990726);
371 else if (code_class == 'd')
373 /* All declarations have names. */
375 dump_child ("name", DECL_NAME (t));
377 queue_and_dump_type (di, t);
378 queue_and_dump_index (di, "scpe", DECL_CONTEXT (t), 0);
379 /* And a source position. */
380 if (DECL_SOURCE_FILE (t))
382 const char *filename = rindex (DECL_SOURCE_FILE (t), '/');
384 filename = DECL_SOURCE_FILE (t);
386 /* Skip the slash. */
389 dump_maybe_newline (di);
390 fprintf (di->stream, "srcp: %s:%-6d ", filename,
391 DECL_SOURCE_LINE (t));
392 di->column += 6 + strlen (filename) + 8;
394 /* And any declaration can be compiler-generated. */
395 if (DECL_ARTIFICIAL (t))
396 dump_string (di, "artificial");
398 dump_child ("chan", TREE_CHAIN (t));
400 else if (code_class == 't')
402 /* All types have qualifiers. */
403 int quals = CP_TYPE_QUALS (t);
404 if (quals != TYPE_UNQUALIFIED)
406 fprintf (di->stream, "qual: %c%c%c ",
407 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
408 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
409 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
413 /* All types have associated declarations. */
414 dump_child ("name", TYPE_NAME (t));
416 /* All types have a main variant. */
417 if (TYPE_MAIN_VARIANT (t) != t)
418 dump_child ("unql", TYPE_MAIN_VARIANT (t));
421 dump_child ("size", TYPE_SIZE (t));
423 /* All types have alignments. */
424 dump_int (di, "algn", TYPE_ALIGN (t));
426 else if (code_class == 'c')
427 /* All constants can have types. */
428 queue_and_dump_type (di, t);
430 /* Now handle the various kinds of nodes. */
435 case IDENTIFIER_NODE:
436 if (IDENTIFIER_OPNAME_P (t))
437 dump_string (di, "operator");
438 else if (IDENTIFIER_TYPENAME_P (t))
439 queue_and_dump_index (di, "tynm", TREE_TYPE (t), 0);
440 else if (t == anonymous_namespace_name)
441 dump_string (di, "unnamed");
444 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
445 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
450 dump_child ("purp", TREE_PURPOSE (t));
451 dump_child ("valu", TREE_VALUE (t));
452 dump_child ("chan", TREE_CHAIN (t));
456 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
457 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
460 sprintf (buffer, "%u", i);
461 queue_and_dump_index (di, buffer, TREE_VEC_ELT (t, i), 1);
467 dump_int (di, "prec", TYPE_PRECISION (t));
468 if (TREE_UNSIGNED (t))
469 dump_string (di, "unsigned");
470 dump_child ("min", TYPE_MIN_VALUE (t));
471 dump_child ("max", TYPE_MAX_VALUE (t));
473 if (code == ENUMERAL_TYPE)
474 dump_child ("csts", TYPE_VALUES (t));
478 dump_int (di, "prec", TYPE_PRECISION (t));
482 if (TYPE_PTRMEM_P (t))
484 dump_string (di, "ptrmem");
485 queue_and_dump_index (di, "ptd",
486 TYPE_PTRMEM_POINTED_TO_TYPE (t), 1);
487 queue_and_dump_index (di, "cls",
488 TYPE_PTRMEM_CLASS_TYPE (t), 1);
491 dump_child ("ptd", TREE_TYPE (t));
495 dump_child ("refd", TREE_TYPE (t));
499 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
503 dump_child ("retn", TREE_TYPE (t));
504 dump_child ("prms", TYPE_ARG_TYPES (t));
508 dump_child ("elts", TREE_TYPE (t));
509 dump_child ("domn", TYPE_DOMAIN (t));
514 if (TYPE_PTRMEMFUNC_P (t))
516 dump_string (di, "ptrmem");
517 queue_and_dump_index (di, "ptd",
518 TYPE_PTRMEM_POINTED_TO_TYPE (t), 1);
519 queue_and_dump_index (di, "cls",
520 TYPE_PTRMEM_CLASS_TYPE (t), 1);
524 if (CLASSTYPE_DECLARED_CLASS (t))
525 dump_string (di, "class");
526 else if (TREE_CODE (t) == RECORD_TYPE)
527 dump_string (di, "struct");
529 dump_string (di, "union");
531 dump_child ("flds", TYPE_FIELDS (t));
532 dump_child ("fncs", TYPE_METHODS (t));
533 dump_child ("vfld", TYPE_VFIELD (t));
534 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
540 dump_child ("cnst", DECL_INITIAL (t));
547 if (TREE_CODE (t) == PARM_DECL)
548 dump_child ("argt", DECL_ARG_TYPE (t));
550 dump_child ("init", DECL_INITIAL (t));
551 dump_child ("size", DECL_SIZE (t));
552 dump_int (di, "algn", DECL_ALIGN (t));
554 if (TREE_CODE (t) == FIELD_DECL)
556 if (DECL_C_BIT_FIELD (t))
557 dump_string (di, "bitfield");
558 dump_child ("bpos", DECL_FIELD_BITPOS (t));
564 queue_and_dump_index (di, "scpe", DECL_REAL_CONTEXT (t), 0);
565 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
566 dump_child ("args", DECL_ARGUMENTS (t));
567 if (DECL_EXTERNAL (t))
568 dump_string (di, "undefined");
570 dump_string(di, "extern");
572 dump_string (di, "static");
573 if (TREE_CODE (t) == FUNCTION_DECL)
575 if (DECL_FUNCTION_MEMBER_P (t))
576 dump_string (di, "member");
577 if (DECL_CONSTRUCTOR_P (t))
578 dump_string (di, "constructor");
579 if (DECL_DESTRUCTOR_P (t))
580 dump_string (di, "destructor");
581 if (DECL_OVERLOADED_OPERATOR_P (t))
582 dump_string (di, "operator");
583 if (DECL_CONV_FN_P (t))
584 dump_string (di, "conversion");
585 if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
587 if (DECL_GLOBAL_CTOR_P (t))
588 dump_string (di, "global init");
589 if (DECL_GLOBAL_DTOR_P (t))
590 dump_string (di, "global fini");
591 dump_int (di, "prio", GLOBAL_INIT_PRIORITY (t));
594 dump_child ("body", DECL_SAVED_TREE (t));
598 dump_int (di, "dlta", THUNK_DELTA (t));
599 dump_child ("init", DECL_INITIAL (t));
604 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
605 and therefore many other macros do not work on it. */
608 dump_child ("dcls", cp_namespace_decls (t));
612 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
616 dump_child ("crnt", OVL_CURRENT (t));
617 dump_child ("chan", OVL_CHAIN (t));
622 if (ASM_VOLATILE_P (t))
623 dump_string (di, "volatile");
624 dump_child ("strg", ASM_STRING (t));
625 dump_child ("outs", ASM_OUTPUTS (t));
626 dump_child ("ins", ASM_INPUTS (t));
627 dump_child ("clbr", ASM_CLOBBERS (t));
628 dump_next_stmt (di, t);
634 dump_next_stmt (di, t);
638 /* Note that a case label is not like other statments; there is
639 no way to get the line-number of a case label. */
640 dump_child ("low", CASE_LOW (t));
641 dump_child ("high", CASE_HIGH (t));
642 dump_next_stmt (di, t);
647 dump_child ("body", COMPOUND_BODY (t));
648 dump_next_stmt (di, t);
653 dump_child ("decl", DECL_STMT_DECL (t));
654 dump_next_stmt (di, t);
659 dump_child ("body", DO_BODY (t));
660 dump_child ("cond", DO_COND (t));
661 dump_next_stmt (di, t);
666 dump_child ("expr", EXPR_STMT_EXPR (t));
667 dump_next_stmt (di, t);
672 dump_child ("init", FOR_INIT_STMT (t));
673 dump_child ("cond", FOR_COND (t));
674 dump_child ("expr", FOR_EXPR (t));
675 dump_child ("body", FOR_BODY (t));
676 dump_next_stmt (di, t);
681 dump_child ("dest", GOTO_DESTINATION (t));
682 dump_next_stmt (di, t);
687 dump_child ("cond", IF_COND (t));
688 dump_child ("then", THEN_CLAUSE (t));
689 dump_child ("else", ELSE_CLAUSE (t));
690 dump_next_stmt (di, t);
695 dump_child ("labl", LABEL_STMT_LABEL (t));
696 dump_next_stmt (di, t);
701 dump_child ("expr", RETURN_EXPR (t));
702 dump_next_stmt (di, t);
707 dump_child ("cond", SWITCH_COND (t));
708 dump_child ("body", SWITCH_BODY (t));
709 dump_next_stmt (di, t);
714 dump_child ("body", TRY_STMTS (t));
715 dump_child ("hdlr", TRY_HANDLERS (t));
716 dump_next_stmt (di, t);
721 dump_child ("cond", WHILE_COND (t));
722 dump_child ("body", WHILE_BODY (t));
723 dump_next_stmt (di, t);
728 dump_child ("clnp", TREE_OPERAND (t, 0));
729 dump_next_stmt (di, t);
732 case START_CATCH_STMT:
734 queue_and_dump_type (di, TREE_TYPE (t));
735 dump_next_stmt (di, t);
740 dump_child ("decl", CLEANUP_DECL (t));
741 dump_child ("expr", CLEANUP_EXPR (t));
742 dump_next_stmt (di, t);
747 if (SCOPE_BEGIN_P (t))
748 dump_string (di, "begn");
750 dump_string (di, "end");
751 if (SCOPE_NULLIFIED_P (t))
752 dump_string (di, "null");
753 dump_next_stmt (di, t);
757 if (TREE_INT_CST_HIGH (t))
758 dump_int (di, "high", TREE_INT_CST_HIGH (t));
759 dump_int (di, "low", TREE_INT_CST_LOW (t));
763 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
764 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
768 dump_child ("clas", PTRMEM_CST_CLASS (t));
769 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
776 /* These nodes are unary, but do not have code class `1'. */
777 dump_child ("op 0", TREE_OPERAND (t, 0));
780 case TRUTH_ANDIF_EXPR:
781 case TRUTH_ORIF_EXPR:
787 /* These nodes are binary, but do not have code class `2'. */
788 dump_child ("op 0", TREE_OPERAND (t, 0));
789 dump_child ("op 1", TREE_OPERAND (t, 1));
793 dump_child ("op 0", TREE_OPERAND (t, 0));
794 dump_child ("op 1", TREE_OPERAND (t, 1));
795 dump_child ("op 2", TREE_OPERAND (t, 2));
799 dump_child ("fn", TREE_OPERAND (t, 0));
800 dump_child ("args", TREE_OPERAND (t, 1));
804 dump_child ("elts", TREE_OPERAND (t, 1));
808 dump_child ("stmt", STMT_EXPR_STMT (t));
812 dump_child ("vars", TREE_OPERAND (t, 0));
813 dump_child ("body", TREE_OPERAND (t, 1));
817 dump_child ("body", TREE_OPERAND (t, 0));
821 dump_child ("cond", TREE_OPERAND (t, 0));
825 dump_child ("decl", TREE_OPERAND (t, 0));
826 dump_child ("init", TREE_OPERAND (t, 1));
827 dump_child ("clnp", TREE_OPERAND (t, 2));
828 /* There really are two possible places the initializer can be.
829 After RTL expansion, the second operand is moved to the
830 position of the fourth operand, and the second operand
832 dump_child ("init", TREE_OPERAND (t, 3));
836 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
837 dump_child ("fn", TREE_OPERAND (t, 0));
838 dump_child ("args", TREE_OPERAND (t, 1));
839 dump_child ("decl", TREE_OPERAND (t, 2));
843 /* There are no additional fields to print. */
848 /* Terminate the line. */
849 fprintf (di->stream, "\n");
852 /* Dump T, and all its children, on STREAM. */
855 dump_node (t, stream)
861 dump_queue_p next_dq;
863 /* Initialize the dump-information structure. */
870 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
871 (splay_tree_delete_value_fn) &free);
873 /* Queue up the first node. */
874 queue (&di, t, DUMP_NONE);
876 /* Until the queue is empty, keep dumping nodes. */
878 dequeue_and_dump (&di);
881 for (dq = di.free_list; dq; dq = next_dq)
886 splay_tree_delete (di.nodes);
889 /* Dump T, and all its children, to FILE. */
892 dump_node_to_file (t, file)
898 f = fopen (file, "w");
900 cp_error ("could not open `%s'", file);