1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999, 2000 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. */
27 /* Flags used with queue functions. */
31 /* Information about a node to be dumped. */
33 typedef struct dump_node_info
35 /* The index for the node. */
37 /* Nonzero if the node is a binfo. */
38 unsigned int binfo_p : 1;
41 /* A dump_queue is a link in the queue of things to be dumped. */
43 typedef struct dump_queue
45 /* The queued tree node. */
47 /* The next node in the queue. */
48 struct dump_queue *next;
51 /* A dump_info gives information about how we should perform the dump
52 and about the current state of the dump. */
54 typedef struct dump_info
56 /* The stream on which to dump the information. */
58 /* The next unused node index. */
60 /* The next column. */
62 /* The first node in the queue of nodes to be written out. */
64 /* The last node in the queue. */
65 dump_queue_p queue_end;
66 /* Free queue nodes. */
67 dump_queue_p free_list;
68 /* The tree nodes which we have already written out. The
69 keys are the addresses of the nodes; the values are the integer
70 indices we assigned them. */
74 static unsigned int queue PARAMS ((dump_info_p, tree, int));
75 static void dump_index PARAMS ((dump_info_p, unsigned int));
76 static void queue_and_dump_index PARAMS ((dump_info_p, const char *, tree, int));
77 static void queue_and_dump_type PARAMS ((dump_info_p, tree));
78 static void dequeue_and_dump PARAMS ((dump_info_p));
79 static void dump_new_line PARAMS ((dump_info_p));
80 static void dump_maybe_newline PARAMS ((dump_info_p));
81 static void dump_int PARAMS ((dump_info_p, const char *, int));
82 static void dump_string PARAMS ((dump_info_p, const char *));
83 static void dump_string_field PARAMS ((dump_info_p, const char *, const char *));
84 static void dump_node PARAMS ((tree, FILE *));
85 static void dump_stmt PARAMS ((dump_info_p, tree));
86 static void dump_next_stmt PARAMS ((dump_info_p, tree));
88 /* Add T to the end of the queue of nodes to dump. Returns the index
101 /* Assign the next available index to T. */
104 /* Obtain a new queue node. */
108 di->free_list = dq->next;
111 dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
113 /* Create a new entry in the splay-tree. */
114 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
116 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
117 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
118 (splay_tree_value) dni);
120 /* Add it to the end of the queue. */
125 di->queue_end->next = dq;
128 /* Return the index. */
133 dump_index (di, index)
137 fprintf (di->stream, "@%-6u ", index);
141 /* If T has not already been output, queue it for subsequent output.
142 FIELD is a string to print before printing the index. Then, the
143 index of T is printed. */
146 queue_and_dump_index (di, field, t, flags)
155 /* If there's no node, just return. This makes for fewer checks in
160 /* See if we've already queued or dumped this node. */
161 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
163 index = ((dump_node_info_p) n->value)->index;
165 /* If we haven't, add it to the queue. */
166 index = queue (di, t, flags);
168 /* Print the index of the node. */
169 dump_maybe_newline (di);
170 fprintf (di->stream, "%-4s: ", field);
172 dump_index (di, index);
175 /* Dump the type of T. */
178 queue_and_dump_type (di, t)
182 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
185 /* Insert a new line in the dump output, and indent to an appropriate
186 place to start printing more fields. */
192 fprintf (di->stream, "\n%25s", "");
196 /* If necessary, insert a new line. */
199 dump_maybe_newline (di)
202 /* See if we need a new line. */
205 /* See if we need any padding. */
206 else if ((di->column - 25) % 14 != 0)
208 fprintf (di->stream, "%*s", 14 - ((di->column - 25) % 14), "");
209 di->column += 14 - (di->column - 25) % 14;
213 /* Dump I using FIELD to identity it. */
216 dump_int (di, field, i)
221 dump_maybe_newline (di);
222 fprintf (di->stream, "%-4s: %-7d ", field, i);
226 /* Dump the string S. */
229 dump_string (di, string)
233 dump_maybe_newline (di);
234 fprintf (di->stream, "%-13s ", string);
235 if (strlen (string) > 13)
236 di->column += strlen (string) + 1;
241 /* Dump the string field S. */
244 dump_string_field (di, field, string)
249 dump_maybe_newline (di);
250 fprintf (di->stream, "%-4s: %-7s ", field, string);
251 if (strlen (string) > 7)
252 di->column += 6 + strlen (string) + 1;
257 /* Dump information common to statements from STMT. */
264 dump_int (di, "line", STMT_LINENO (t));
267 /* Dump the CHILD and its children. */
268 #define dump_child(field, child) \
269 queue_and_dump_index (di, field, child, DUMP_NONE)
271 /* Dump the next statement after STMT. */
274 dump_next_stmt (di, t)
278 dump_child ("next", TREE_CHAIN (t));
281 /* Dump the next node in the queue. */
284 dequeue_and_dump (di)
289 dump_node_info_p dni;
294 const char* code_name;
296 /* Get the next node from the queue. */
300 dni = (dump_node_info_p) stn->value;
303 /* Remove the node from the queue, and put it on the free list. */
304 di->queue = dq->next;
307 dq->next = di->free_list;
310 /* Print the node index. */
311 dump_index (di, index);
312 /* And the type of node this is. */
316 code_name = tree_code_name[(int) TREE_CODE (t)];
317 fprintf (di->stream, "%-16s ", code_name);
320 /* Figure out what kind of node this is. */
321 code = TREE_CODE (t);
322 code_class = TREE_CODE_CLASS (code);
324 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
328 if (TREE_VIA_PUBLIC (t))
329 dump_string (di, "pub");
330 else if (TREE_VIA_PROTECTED (t))
331 dump_string (di, "prot");
332 else if (TREE_VIA_PRIVATE (t))
333 dump_string (di, "priv");
334 if (TREE_VIA_VIRTUAL (t))
335 dump_string (di, "virt");
337 dump_child ("type", BINFO_TYPE (t));
338 dump_child ("base", BINFO_BASETYPES (t));
343 /* We can knock off a bunch of expression nodes in exactly the same
345 if (IS_EXPR_CODE_CLASS (code_class))
347 /* If we're dumping children, dump them now. */
348 queue_and_dump_type (di, t);
353 dump_child ("op 0", TREE_OPERAND (t, 0));
358 dump_child ("op 0", TREE_OPERAND (t, 0));
359 dump_child ("op 1", TREE_OPERAND (t, 1));
363 /* These nodes are handled explicitly below. */
367 my_friendly_abort (19990726);
370 else if (code_class == 'd')
372 /* All declarations have names. */
374 dump_child ("name", DECL_NAME (t));
376 queue_and_dump_type (di, t);
377 dump_child ("scpe", DECL_CONTEXT (t));
378 /* And a source position. */
379 if (DECL_SOURCE_FILE (t))
381 const char *filename = rindex (DECL_SOURCE_FILE (t), '/');
383 filename = DECL_SOURCE_FILE (t);
385 /* Skip the slash. */
388 dump_maybe_newline (di);
389 fprintf (di->stream, "srcp: %s:%-6d ", filename,
390 DECL_SOURCE_LINE (t));
391 di->column += 6 + strlen (filename) + 8;
393 /* And any declaration can be compiler-generated. */
394 if (DECL_ARTIFICIAL (t))
395 dump_string (di, "artificial");
397 dump_child ("chan", TREE_CHAIN (t));
398 if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
399 dump_string (di, language_to_string (DECL_LANGUAGE (t), 0));
401 else if (code_class == 't')
403 /* All types have qualifiers. */
404 int quals = CP_TYPE_QUALS (t);
405 if (quals != TYPE_UNQUALIFIED)
407 fprintf (di->stream, "qual: %c%c%c ",
408 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
409 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
410 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
414 /* All types have associated declarations. */
415 dump_child ("name", TYPE_NAME (t));
417 /* All types have a main variant. */
418 if (TYPE_MAIN_VARIANT (t) != t)
419 dump_child ("unql", TYPE_MAIN_VARIANT (t));
422 dump_child ("size", TYPE_SIZE (t));
424 /* All types have alignments. */
425 dump_int (di, "algn", TYPE_ALIGN (t));
427 else if (code_class == 'c')
428 /* All constants can have types. */
429 queue_and_dump_type (di, t);
431 /* Now handle the various kinds of nodes. */
436 case IDENTIFIER_NODE:
437 if (IDENTIFIER_OPNAME_P (t))
438 dump_string (di, "operator");
439 else if (IDENTIFIER_TYPENAME_P (t))
440 dump_child ("tynm", TREE_TYPE (t));
441 else if (t == anonymous_namespace_name)
442 dump_string (di, "unnamed");
445 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
446 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
451 dump_child ("purp", TREE_PURPOSE (t));
452 dump_child ("valu", TREE_VALUE (t));
453 dump_child ("chan", TREE_CHAIN (t));
457 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
458 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
461 sprintf (buffer, "%u", i);
462 dump_child (buffer, TREE_VEC_ELT (t, i));
468 dump_int (di, "prec", TYPE_PRECISION (t));
469 if (TREE_UNSIGNED (t))
470 dump_string (di, "unsigned");
471 dump_child ("min", TYPE_MIN_VALUE (t));
472 dump_child ("max", TYPE_MAX_VALUE (t));
474 if (code == ENUMERAL_TYPE)
475 dump_child ("csts", TYPE_VALUES (t));
479 dump_int (di, "prec", TYPE_PRECISION (t));
483 if (TYPE_PTRMEM_P (t))
485 dump_string (di, "ptrmem");
486 dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
487 dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
490 dump_child ("ptd", TREE_TYPE (t));
494 dump_child ("refd", TREE_TYPE (t));
498 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
502 dump_child ("retn", TREE_TYPE (t));
503 dump_child ("prms", TYPE_ARG_TYPES (t));
507 dump_child ("elts", TREE_TYPE (t));
508 dump_child ("domn", TYPE_DOMAIN (t));
513 if (TYPE_PTRMEMFUNC_P (t))
515 dump_string (di, "ptrmem");
516 dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
517 dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
521 if (CLASSTYPE_DECLARED_CLASS (t))
522 dump_string (di, "class");
523 else if (TREE_CODE (t) == RECORD_TYPE)
524 dump_string (di, "struct");
526 dump_string (di, "union");
528 dump_child ("flds", TYPE_FIELDS (t));
529 dump_child ("fncs", TYPE_METHODS (t));
530 dump_child ("vfld", TYPE_VFIELD (t));
531 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
537 dump_child ("cnst", DECL_INITIAL (t));
544 if (TREE_CODE (t) == PARM_DECL)
545 dump_child ("argt", DECL_ARG_TYPE (t));
547 dump_child ("init", DECL_INITIAL (t));
548 dump_child ("size", DECL_SIZE (t));
549 dump_int (di, "algn", DECL_ALIGN (t));
551 if (TREE_CODE (t) == FIELD_DECL)
553 if (DECL_C_BIT_FIELD (t))
554 dump_string (di, "bitfield");
555 if (DECL_FIELD_OFFSET (t))
556 dump_child ("bpos", bit_position (t));
561 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
562 dump_child ("args", DECL_ARGUMENTS (t));
563 if (DECL_EXTERNAL (t))
564 dump_string (di, "undefined");
566 dump_string(di, "extern");
568 dump_string (di, "static");
569 if (TREE_CODE (t) == FUNCTION_DECL)
571 if (DECL_FUNCTION_MEMBER_P (t))
572 dump_string (di, "member");
573 if (DECL_CONSTRUCTOR_P (t))
574 dump_string (di, "constructor");
575 if (DECL_DESTRUCTOR_P (t))
576 dump_string (di, "destructor");
577 if (DECL_OVERLOADED_OPERATOR_P (t))
578 dump_string (di, "operator");
579 if (DECL_CONV_FN_P (t))
580 dump_string (di, "conversion");
581 if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
583 if (DECL_GLOBAL_CTOR_P (t))
584 dump_string (di, "global init");
585 if (DECL_GLOBAL_DTOR_P (t))
586 dump_string (di, "global fini");
587 dump_int (di, "prio", GLOBAL_INIT_PRIORITY (t));
589 if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
590 dump_string (di, "pseudo tmpl");
592 dump_child ("body", DECL_SAVED_TREE (t));
596 dump_int (di, "dlta", THUNK_DELTA (t));
597 dump_child ("init", DECL_INITIAL (t));
602 /* The fake `::std' namespace does not have DECL_LANG_SPECIFIC,
603 and therefore many other macros do not work on it. */
606 if (DECL_NAMESPACE_ALIAS (t))
607 dump_child ("alis", DECL_NAMESPACE_ALIAS (t));
609 dump_child ("dcls", cp_namespace_decls (t));
613 dump_child ("rslt", DECL_TEMPLATE_RESULT (t));
614 dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
615 dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
619 dump_child ("crnt", OVL_CURRENT (t));
620 dump_child ("chan", OVL_CHAIN (t));
625 if (ASM_VOLATILE_P (t))
626 dump_string (di, "volatile");
627 dump_child ("strg", ASM_STRING (t));
628 dump_child ("outs", ASM_OUTPUTS (t));
629 dump_child ("ins", ASM_INPUTS (t));
630 dump_child ("clbr", ASM_CLOBBERS (t));
631 dump_next_stmt (di, t);
637 dump_next_stmt (di, t);
641 /* Note that a case label is not like other statments; there is
642 no way to get the line-number of a case label. */
643 dump_child ("low", CASE_LOW (t));
644 dump_child ("high", CASE_HIGH (t));
645 dump_next_stmt (di, t);
650 dump_child ("body", COMPOUND_BODY (t));
651 dump_next_stmt (di, t);
656 if (CTOR_BEGIN_P (t))
657 dump_string (di, "begn");
659 dump_string (di, "end");
660 dump_next_stmt (di, t);
665 dump_child ("decl", DECL_STMT_DECL (t));
666 dump_next_stmt (di, t);
671 dump_child ("body", DO_BODY (t));
672 dump_child ("cond", DO_COND (t));
673 dump_next_stmt (di, t);
678 dump_child ("expr", EXPR_STMT_EXPR (t));
679 dump_next_stmt (di, t);
684 dump_child ("init", FOR_INIT_STMT (t));
685 dump_child ("cond", FOR_COND (t));
686 dump_child ("expr", FOR_EXPR (t));
687 dump_child ("body", FOR_BODY (t));
688 dump_next_stmt (di, t);
693 dump_child ("dest", GOTO_DESTINATION (t));
694 dump_next_stmt (di, t);
699 dump_child ("body", HANDLER_BODY (t));
700 dump_next_stmt (di, t);
705 dump_child ("cond", IF_COND (t));
706 dump_child ("then", THEN_CLAUSE (t));
707 dump_child ("else", ELSE_CLAUSE (t));
708 dump_next_stmt (di, t);
713 dump_child ("labl", LABEL_STMT_LABEL (t));
714 dump_next_stmt (di, t);
719 dump_child ("expr", RETURN_EXPR (t));
720 dump_next_stmt (di, t);
725 dump_child ("cond", SWITCH_COND (t));
726 dump_child ("body", SWITCH_BODY (t));
727 dump_next_stmt (di, t);
733 dump_string (di, "cleanup");
734 dump_child ("body", TRY_STMTS (t));
735 dump_child ("hdlr", TRY_HANDLERS (t));
736 dump_next_stmt (di, t);
741 dump_child ("cond", WHILE_COND (t));
742 dump_child ("body", WHILE_BODY (t));
743 dump_next_stmt (di, t);
748 dump_child ("clnp", TREE_OPERAND (t, 0));
749 dump_next_stmt (di, t);
752 case START_CATCH_STMT:
754 queue_and_dump_type (di, t);
755 dump_next_stmt (di, t);
760 dump_child ("decl", CLEANUP_DECL (t));
761 dump_child ("expr", CLEANUP_EXPR (t));
762 dump_next_stmt (di, t);
767 if (SCOPE_BEGIN_P (t))
768 dump_string (di, "begn");
770 dump_string (di, "end");
771 if (SCOPE_NULLIFIED_P (t))
772 dump_string (di, "null");
773 if (!SCOPE_NO_CLEANUPS_P (t))
774 dump_string (di, "clnp");
775 dump_next_stmt (di, t);
779 if (TREE_INT_CST_HIGH (t))
780 dump_int (di, "high", TREE_INT_CST_HIGH (t));
781 dump_int (di, "low", TREE_INT_CST_LOW (t));
785 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
786 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
790 dump_child ("clas", PTRMEM_CST_CLASS (t));
791 dump_child ("mbr", PTRMEM_CST_MEMBER (t));
798 case CLEANUP_POINT_EXPR:
800 /* These nodes are unary, but do not have code class `1'. */
801 dump_child ("op 0", TREE_OPERAND (t, 0));
804 case TRUTH_ANDIF_EXPR:
805 case TRUTH_ORIF_EXPR:
811 case PREDECREMENT_EXPR:
812 case PREINCREMENT_EXPR:
813 case POSTDECREMENT_EXPR:
814 case POSTINCREMENT_EXPR:
815 /* These nodes are binary, but do not have code class `2'. */
816 dump_child ("op 0", TREE_OPERAND (t, 0));
817 dump_child ("op 1", TREE_OPERAND (t, 1));
821 dump_child ("op 0", TREE_OPERAND (t, 0));
822 dump_child ("op 1", TREE_OPERAND (t, 1));
823 dump_child ("op 2", TREE_OPERAND (t, 2));
827 dump_child ("fn", TREE_OPERAND (t, 0));
828 dump_child ("args", TREE_OPERAND (t, 1));
832 dump_child ("elts", TREE_OPERAND (t, 1));
836 dump_child ("stmt", STMT_EXPR_STMT (t));
840 dump_child ("vars", TREE_OPERAND (t, 0));
841 dump_child ("body", TREE_OPERAND (t, 1));
845 dump_child ("body", TREE_OPERAND (t, 0));
849 dump_child ("cond", TREE_OPERAND (t, 0));
853 dump_child ("decl", TREE_OPERAND (t, 0));
854 dump_child ("init", TREE_OPERAND (t, 1));
855 dump_child ("clnp", TREE_OPERAND (t, 2));
856 /* There really are two possible places the initializer can be.
857 After RTL expansion, the second operand is moved to the
858 position of the fourth operand, and the second operand
860 dump_child ("init", TREE_OPERAND (t, 3));
864 dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
865 dump_child ("fn", TREE_OPERAND (t, 0));
866 dump_child ("args", TREE_OPERAND (t, 1));
867 dump_child ("decl", TREE_OPERAND (t, 2));
870 case EXPR_WITH_FILE_LOCATION:
871 dump_child ("expr", EXPR_WFL_NODE (t));
875 /* There are no additional fields to print. */
880 /* Terminate the line. */
881 fprintf (di->stream, "\n");
884 /* Dump T, and all its children, on STREAM. */
887 dump_node (t, stream)
893 dump_queue_p next_dq;
895 /* Initialize the dump-information structure. */
902 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
903 (splay_tree_delete_value_fn) &free);
905 /* Queue up the first node. */
906 queue (&di, t, DUMP_NONE);
908 /* Until the queue is empty, keep dumping nodes. */
910 dequeue_and_dump (&di);
913 for (dq = di.free_list; dq; dq = next_dq)
918 splay_tree_delete (di.nodes);
921 /* Dump T, and all its children, to FILE. */
924 dump_node_to_file (t, file)
930 f = fopen (file, "w");
932 cp_error ("could not open `%s'", file);