11debfc3dSmrg /* Tree-dumping functionality for intermediate representation.
2*8feb0f0bSmrg Copyright (C) 1999-2020 Free Software Foundation, Inc.
31debfc3dSmrg Written by Mark Mitchell <mark@codesourcery.com>
41debfc3dSmrg
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3. If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>. */
201debfc3dSmrg
211debfc3dSmrg #include "config.h"
221debfc3dSmrg #include "system.h"
231debfc3dSmrg #include "coretypes.h"
241debfc3dSmrg #include "tree.h"
251debfc3dSmrg #include "tree-pretty-print.h"
261debfc3dSmrg #include "tree-dump.h"
271debfc3dSmrg #include "langhooks.h"
281debfc3dSmrg #include "tree-iterator.h"
291debfc3dSmrg
301debfc3dSmrg static unsigned int queue (dump_info_p, const_tree, int);
311debfc3dSmrg static void dump_index (dump_info_p, unsigned int);
321debfc3dSmrg static void dequeue_and_dump (dump_info_p);
331debfc3dSmrg static void dump_new_line (dump_info_p);
341debfc3dSmrg static void dump_maybe_newline (dump_info_p);
351debfc3dSmrg
361debfc3dSmrg /* Add T to the end of the queue of nodes to dump. Returns the index
371debfc3dSmrg assigned to T. */
381debfc3dSmrg
391debfc3dSmrg static unsigned int
queue(dump_info_p di,const_tree t,int flags)401debfc3dSmrg queue (dump_info_p di, const_tree t, int flags)
411debfc3dSmrg {
421debfc3dSmrg dump_queue_p dq;
431debfc3dSmrg dump_node_info_p dni;
441debfc3dSmrg unsigned int index;
451debfc3dSmrg
461debfc3dSmrg /* Assign the next available index to T. */
471debfc3dSmrg index = ++di->index;
481debfc3dSmrg
491debfc3dSmrg /* Obtain a new queue node. */
501debfc3dSmrg if (di->free_list)
511debfc3dSmrg {
521debfc3dSmrg dq = di->free_list;
531debfc3dSmrg di->free_list = dq->next;
541debfc3dSmrg }
551debfc3dSmrg else
561debfc3dSmrg dq = XNEW (struct dump_queue);
571debfc3dSmrg
581debfc3dSmrg /* Create a new entry in the splay-tree. */
591debfc3dSmrg dni = XNEW (struct dump_node_info);
601debfc3dSmrg dni->index = index;
611debfc3dSmrg dni->binfo_p = ((flags & DUMP_BINFO) != 0);
621debfc3dSmrg dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
631debfc3dSmrg (splay_tree_value) dni);
641debfc3dSmrg
651debfc3dSmrg /* Add it to the end of the queue. */
661debfc3dSmrg dq->next = 0;
671debfc3dSmrg if (!di->queue_end)
681debfc3dSmrg di->queue = dq;
691debfc3dSmrg else
701debfc3dSmrg di->queue_end->next = dq;
711debfc3dSmrg di->queue_end = dq;
721debfc3dSmrg
731debfc3dSmrg /* Return the index. */
741debfc3dSmrg return index;
751debfc3dSmrg }
761debfc3dSmrg
771debfc3dSmrg static void
dump_index(dump_info_p di,unsigned int index)781debfc3dSmrg dump_index (dump_info_p di, unsigned int index)
791debfc3dSmrg {
801debfc3dSmrg fprintf (di->stream, "@%-6u ", index);
811debfc3dSmrg di->column += 8;
821debfc3dSmrg }
831debfc3dSmrg
841debfc3dSmrg /* If T has not already been output, queue it for subsequent output.
851debfc3dSmrg FIELD is a string to print before printing the index. Then, the
861debfc3dSmrg index of T is printed. */
871debfc3dSmrg
881debfc3dSmrg void
queue_and_dump_index(dump_info_p di,const char * field,const_tree t,int flags)891debfc3dSmrg queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
901debfc3dSmrg {
911debfc3dSmrg unsigned int index;
921debfc3dSmrg splay_tree_node n;
931debfc3dSmrg
941debfc3dSmrg /* If there's no node, just return. This makes for fewer checks in
951debfc3dSmrg our callers. */
961debfc3dSmrg if (!t)
971debfc3dSmrg return;
981debfc3dSmrg
991debfc3dSmrg /* See if we've already queued or dumped this node. */
1001debfc3dSmrg n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
1011debfc3dSmrg if (n)
1021debfc3dSmrg index = ((dump_node_info_p) n->value)->index;
1031debfc3dSmrg else
1041debfc3dSmrg /* If we haven't, add it to the queue. */
1051debfc3dSmrg index = queue (di, t, flags);
1061debfc3dSmrg
1071debfc3dSmrg /* Print the index of the node. */
1081debfc3dSmrg dump_maybe_newline (di);
1091debfc3dSmrg fprintf (di->stream, "%-4s: ", field);
1101debfc3dSmrg di->column += 6;
1111debfc3dSmrg dump_index (di, index);
1121debfc3dSmrg }
1131debfc3dSmrg
1141debfc3dSmrg /* Dump the type of T. */
1151debfc3dSmrg
1161debfc3dSmrg void
queue_and_dump_type(dump_info_p di,const_tree t)1171debfc3dSmrg queue_and_dump_type (dump_info_p di, const_tree t)
1181debfc3dSmrg {
1191debfc3dSmrg queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
1201debfc3dSmrg }
1211debfc3dSmrg
1221debfc3dSmrg /* Dump column control */
1231debfc3dSmrg #define SOL_COLUMN 25 /* Start of line column. */
1241debfc3dSmrg #define EOL_COLUMN 55 /* End of line column. */
1251debfc3dSmrg #define COLUMN_ALIGNMENT 15 /* Alignment. */
1261debfc3dSmrg
1271debfc3dSmrg /* Insert a new line in the dump output, and indent to an appropriate
1281debfc3dSmrg place to start printing more fields. */
1291debfc3dSmrg
1301debfc3dSmrg static void
dump_new_line(dump_info_p di)1311debfc3dSmrg dump_new_line (dump_info_p di)
1321debfc3dSmrg {
1331debfc3dSmrg fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
1341debfc3dSmrg di->column = SOL_COLUMN;
1351debfc3dSmrg }
1361debfc3dSmrg
1371debfc3dSmrg /* If necessary, insert a new line. */
1381debfc3dSmrg
1391debfc3dSmrg static void
dump_maybe_newline(dump_info_p di)1401debfc3dSmrg dump_maybe_newline (dump_info_p di)
1411debfc3dSmrg {
1421debfc3dSmrg int extra;
1431debfc3dSmrg
1441debfc3dSmrg /* See if we need a new line. */
1451debfc3dSmrg if (di->column > EOL_COLUMN)
1461debfc3dSmrg dump_new_line (di);
1471debfc3dSmrg /* See if we need any padding. */
1481debfc3dSmrg else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
1491debfc3dSmrg {
1501debfc3dSmrg fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
1511debfc3dSmrg di->column += COLUMN_ALIGNMENT - extra;
1521debfc3dSmrg }
1531debfc3dSmrg }
1541debfc3dSmrg
1551debfc3dSmrg /* Dump pointer PTR using FIELD to identify it. */
1561debfc3dSmrg
1571debfc3dSmrg void
dump_pointer(dump_info_p di,const char * field,void * ptr)1581debfc3dSmrg dump_pointer (dump_info_p di, const char *field, void *ptr)
1591debfc3dSmrg {
1601debfc3dSmrg dump_maybe_newline (di);
1611debfc3dSmrg fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
1621debfc3dSmrg (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
1631debfc3dSmrg di->column += 15;
1641debfc3dSmrg }
1651debfc3dSmrg
1661debfc3dSmrg /* Dump integer I using FIELD to identify it. */
1671debfc3dSmrg
1681debfc3dSmrg void
dump_int(dump_info_p di,const char * field,int i)1691debfc3dSmrg dump_int (dump_info_p di, const char *field, int i)
1701debfc3dSmrg {
1711debfc3dSmrg dump_maybe_newline (di);
1721debfc3dSmrg fprintf (di->stream, "%-4s: %-7d ", field, i);
1731debfc3dSmrg di->column += 14;
1741debfc3dSmrg }
1751debfc3dSmrg
1761debfc3dSmrg /* Dump the floating point value R, using FIELD to identify it. */
1771debfc3dSmrg
1781debfc3dSmrg static void
dump_real(dump_info_p di,const char * field,const REAL_VALUE_TYPE * r)1791debfc3dSmrg dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
1801debfc3dSmrg {
1811debfc3dSmrg char buf[32];
1821debfc3dSmrg real_to_decimal (buf, r, sizeof (buf), 0, true);
1831debfc3dSmrg dump_maybe_newline (di);
1841debfc3dSmrg fprintf (di->stream, "%-4s: %s ", field, buf);
1851debfc3dSmrg di->column += strlen (buf) + 7;
1861debfc3dSmrg }
1871debfc3dSmrg
1881debfc3dSmrg /* Dump the fixed-point value F, using FIELD to identify it. */
1891debfc3dSmrg
1901debfc3dSmrg static void
dump_fixed(dump_info_p di,const char * field,const FIXED_VALUE_TYPE * f)1911debfc3dSmrg dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
1921debfc3dSmrg {
1931debfc3dSmrg char buf[32];
1941debfc3dSmrg fixed_to_decimal (buf, f, sizeof (buf));
1951debfc3dSmrg dump_maybe_newline (di);
1961debfc3dSmrg fprintf (di->stream, "%-4s: %s ", field, buf);
1971debfc3dSmrg di->column += strlen (buf) + 7;
1981debfc3dSmrg }
1991debfc3dSmrg
2001debfc3dSmrg
2011debfc3dSmrg /* Dump the string S. */
2021debfc3dSmrg
2031debfc3dSmrg void
dump_string(dump_info_p di,const char * string)2041debfc3dSmrg dump_string (dump_info_p di, const char *string)
2051debfc3dSmrg {
2061debfc3dSmrg dump_maybe_newline (di);
2071debfc3dSmrg fprintf (di->stream, "%-13s ", string);
2081debfc3dSmrg if (strlen (string) > 13)
2091debfc3dSmrg di->column += strlen (string) + 1;
2101debfc3dSmrg else
2111debfc3dSmrg di->column += 14;
2121debfc3dSmrg }
2131debfc3dSmrg
2141debfc3dSmrg /* Dump the string field S. */
2151debfc3dSmrg
2161debfc3dSmrg void
dump_string_field(dump_info_p di,const char * field,const char * string)2171debfc3dSmrg dump_string_field (dump_info_p di, const char *field, const char *string)
2181debfc3dSmrg {
2191debfc3dSmrg dump_maybe_newline (di);
2201debfc3dSmrg fprintf (di->stream, "%-4s: %-7s ", field, string);
2211debfc3dSmrg if (strlen (string) > 7)
2221debfc3dSmrg di->column += 6 + strlen (string) + 1;
2231debfc3dSmrg else
2241debfc3dSmrg di->column += 14;
2251debfc3dSmrg }
2261debfc3dSmrg
2271debfc3dSmrg /* Dump the next node in the queue. */
2281debfc3dSmrg
2291debfc3dSmrg static void
dequeue_and_dump(dump_info_p di)2301debfc3dSmrg dequeue_and_dump (dump_info_p di)
2311debfc3dSmrg {
2321debfc3dSmrg dump_queue_p dq;
2331debfc3dSmrg splay_tree_node stn;
2341debfc3dSmrg dump_node_info_p dni;
2351debfc3dSmrg tree t;
2361debfc3dSmrg unsigned int index;
2371debfc3dSmrg enum tree_code code;
2381debfc3dSmrg enum tree_code_class code_class;
2391debfc3dSmrg const char* code_name;
2401debfc3dSmrg
2411debfc3dSmrg /* Get the next node from the queue. */
2421debfc3dSmrg dq = di->queue;
2431debfc3dSmrg stn = dq->node;
2441debfc3dSmrg t = (tree) stn->key;
2451debfc3dSmrg dni = (dump_node_info_p) stn->value;
2461debfc3dSmrg index = dni->index;
2471debfc3dSmrg
2481debfc3dSmrg /* Remove the node from the queue, and put it on the free list. */
2491debfc3dSmrg di->queue = dq->next;
2501debfc3dSmrg if (!di->queue)
2511debfc3dSmrg di->queue_end = 0;
2521debfc3dSmrg dq->next = di->free_list;
2531debfc3dSmrg di->free_list = dq;
2541debfc3dSmrg
2551debfc3dSmrg /* Print the node index. */
2561debfc3dSmrg dump_index (di, index);
2571debfc3dSmrg /* And the type of node this is. */
2581debfc3dSmrg if (dni->binfo_p)
2591debfc3dSmrg code_name = "binfo";
2601debfc3dSmrg else
2611debfc3dSmrg code_name = get_tree_code_name (TREE_CODE (t));
2621debfc3dSmrg fprintf (di->stream, "%-16s ", code_name);
2631debfc3dSmrg di->column = 25;
2641debfc3dSmrg
2651debfc3dSmrg /* Figure out what kind of node this is. */
2661debfc3dSmrg code = TREE_CODE (t);
2671debfc3dSmrg code_class = TREE_CODE_CLASS (code);
2681debfc3dSmrg
2691debfc3dSmrg /* Although BINFOs are TREE_VECs, we dump them specially so as to be
2701debfc3dSmrg more informative. */
2711debfc3dSmrg if (dni->binfo_p)
2721debfc3dSmrg {
2731debfc3dSmrg unsigned ix;
2741debfc3dSmrg tree base;
2751debfc3dSmrg vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
2761debfc3dSmrg
2771debfc3dSmrg dump_child ("type", BINFO_TYPE (t));
2781debfc3dSmrg
2791debfc3dSmrg if (BINFO_VIRTUAL_P (t))
2801debfc3dSmrg dump_string_field (di, "spec", "virt");
2811debfc3dSmrg
2821debfc3dSmrg dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
2831debfc3dSmrg for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
2841debfc3dSmrg {
2851debfc3dSmrg tree access = (accesses ? (*accesses)[ix] : access_public_node);
2861debfc3dSmrg const char *string = NULL;
2871debfc3dSmrg
2881debfc3dSmrg if (access == access_public_node)
2891debfc3dSmrg string = "pub";
2901debfc3dSmrg else if (access == access_protected_node)
2911debfc3dSmrg string = "prot";
2921debfc3dSmrg else if (access == access_private_node)
2931debfc3dSmrg string = "priv";
2941debfc3dSmrg else
2951debfc3dSmrg gcc_unreachable ();
2961debfc3dSmrg
2971debfc3dSmrg dump_string_field (di, "accs", string);
2981debfc3dSmrg queue_and_dump_index (di, "binf", base, DUMP_BINFO);
2991debfc3dSmrg }
3001debfc3dSmrg
3011debfc3dSmrg goto done;
3021debfc3dSmrg }
3031debfc3dSmrg
3041debfc3dSmrg /* We can knock off a bunch of expression nodes in exactly the same
3051debfc3dSmrg way. */
3061debfc3dSmrg if (IS_EXPR_CODE_CLASS (code_class))
3071debfc3dSmrg {
3081debfc3dSmrg /* If we're dumping children, dump them now. */
3091debfc3dSmrg queue_and_dump_type (di, t);
3101debfc3dSmrg
3111debfc3dSmrg switch (code_class)
3121debfc3dSmrg {
3131debfc3dSmrg case tcc_unary:
3141debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
3151debfc3dSmrg break;
3161debfc3dSmrg
3171debfc3dSmrg case tcc_binary:
3181debfc3dSmrg case tcc_comparison:
3191debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
3201debfc3dSmrg dump_child ("op 1", TREE_OPERAND (t, 1));
3211debfc3dSmrg break;
3221debfc3dSmrg
3231debfc3dSmrg case tcc_expression:
3241debfc3dSmrg case tcc_reference:
3251debfc3dSmrg case tcc_statement:
3261debfc3dSmrg case tcc_vl_exp:
3271debfc3dSmrg /* These nodes are handled explicitly below. */
3281debfc3dSmrg break;
3291debfc3dSmrg
3301debfc3dSmrg default:
3311debfc3dSmrg gcc_unreachable ();
3321debfc3dSmrg }
3331debfc3dSmrg }
3341debfc3dSmrg else if (DECL_P (t))
3351debfc3dSmrg {
3361debfc3dSmrg expanded_location xloc;
3371debfc3dSmrg /* All declarations have names. */
3381debfc3dSmrg if (DECL_NAME (t))
3391debfc3dSmrg dump_child ("name", DECL_NAME (t));
340a2dc1f3fSmrg if (HAS_DECL_ASSEMBLER_NAME_P (t)
341a2dc1f3fSmrg && DECL_ASSEMBLER_NAME_SET_P (t)
3421debfc3dSmrg && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
3431debfc3dSmrg dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
3441debfc3dSmrg if (DECL_ABSTRACT_ORIGIN (t))
3451debfc3dSmrg dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
3461debfc3dSmrg /* And types. */
3471debfc3dSmrg queue_and_dump_type (di, t);
3481debfc3dSmrg dump_child ("scpe", DECL_CONTEXT (t));
3491debfc3dSmrg /* And a source position. */
3501debfc3dSmrg xloc = expand_location (DECL_SOURCE_LOCATION (t));
3511debfc3dSmrg if (xloc.file)
3521debfc3dSmrg {
3531debfc3dSmrg const char *filename = lbasename (xloc.file);
3541debfc3dSmrg
3551debfc3dSmrg dump_maybe_newline (di);
3561debfc3dSmrg fprintf (di->stream, "srcp: %s:%-6d ", filename,
3571debfc3dSmrg xloc.line);
3581debfc3dSmrg di->column += 6 + strlen (filename) + 8;
3591debfc3dSmrg }
3601debfc3dSmrg /* And any declaration can be compiler-generated. */
3611debfc3dSmrg if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
3621debfc3dSmrg && DECL_ARTIFICIAL (t))
3631debfc3dSmrg dump_string_field (di, "note", "artificial");
3641debfc3dSmrg if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
3651debfc3dSmrg dump_child ("chain", DECL_CHAIN (t));
3661debfc3dSmrg }
3671debfc3dSmrg else if (code_class == tcc_type)
3681debfc3dSmrg {
3691debfc3dSmrg /* All types have qualifiers. */
3701debfc3dSmrg int quals = lang_hooks.tree_dump.type_quals (t);
3711debfc3dSmrg
3721debfc3dSmrg if (quals != TYPE_UNQUALIFIED)
3731debfc3dSmrg {
3741debfc3dSmrg fprintf (di->stream, "qual: %c%c%c ",
3751debfc3dSmrg (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
3761debfc3dSmrg (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
3771debfc3dSmrg (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
3781debfc3dSmrg di->column += 14;
3791debfc3dSmrg }
3801debfc3dSmrg
3811debfc3dSmrg /* All types have associated declarations. */
3821debfc3dSmrg dump_child ("name", TYPE_NAME (t));
3831debfc3dSmrg
3841debfc3dSmrg /* All types have a main variant. */
3851debfc3dSmrg if (TYPE_MAIN_VARIANT (t) != t)
3861debfc3dSmrg dump_child ("unql", TYPE_MAIN_VARIANT (t));
3871debfc3dSmrg
3881debfc3dSmrg /* And sizes. */
3891debfc3dSmrg dump_child ("size", TYPE_SIZE (t));
3901debfc3dSmrg
3911debfc3dSmrg /* All types have alignments. */
3921debfc3dSmrg dump_int (di, "algn", TYPE_ALIGN (t));
3931debfc3dSmrg }
3941debfc3dSmrg else if (code_class == tcc_constant)
3951debfc3dSmrg /* All constants can have types. */
3961debfc3dSmrg queue_and_dump_type (di, t);
3971debfc3dSmrg
3981debfc3dSmrg /* Give the language-specific code a chance to print something. If
3991debfc3dSmrg it's completely taken care of things, don't bother printing
4001debfc3dSmrg anything more ourselves. */
4011debfc3dSmrg if (lang_hooks.tree_dump.dump_tree (di, t))
4021debfc3dSmrg goto done;
4031debfc3dSmrg
4041debfc3dSmrg /* Now handle the various kinds of nodes. */
4051debfc3dSmrg switch (code)
4061debfc3dSmrg {
4071debfc3dSmrg int i;
4081debfc3dSmrg
4091debfc3dSmrg case IDENTIFIER_NODE:
4101debfc3dSmrg dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
4111debfc3dSmrg dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
4121debfc3dSmrg break;
4131debfc3dSmrg
4141debfc3dSmrg case TREE_LIST:
4151debfc3dSmrg dump_child ("purp", TREE_PURPOSE (t));
4161debfc3dSmrg dump_child ("valu", TREE_VALUE (t));
4171debfc3dSmrg dump_child ("chan", TREE_CHAIN (t));
4181debfc3dSmrg break;
4191debfc3dSmrg
4201debfc3dSmrg case STATEMENT_LIST:
4211debfc3dSmrg {
4221debfc3dSmrg tree_stmt_iterator it;
4231debfc3dSmrg for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
4241debfc3dSmrg {
4251debfc3dSmrg char buffer[32];
4261debfc3dSmrg sprintf (buffer, "%u", i);
4271debfc3dSmrg dump_child (buffer, tsi_stmt (it));
4281debfc3dSmrg }
4291debfc3dSmrg }
4301debfc3dSmrg break;
4311debfc3dSmrg
4321debfc3dSmrg case TREE_VEC:
4331debfc3dSmrg dump_int (di, "lngt", TREE_VEC_LENGTH (t));
4341debfc3dSmrg for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
4351debfc3dSmrg {
4361debfc3dSmrg char buffer[32];
4371debfc3dSmrg sprintf (buffer, "%u", i);
4381debfc3dSmrg dump_child (buffer, TREE_VEC_ELT (t, i));
4391debfc3dSmrg }
4401debfc3dSmrg break;
4411debfc3dSmrg
4421debfc3dSmrg case INTEGER_TYPE:
4431debfc3dSmrg case ENUMERAL_TYPE:
4441debfc3dSmrg dump_int (di, "prec", TYPE_PRECISION (t));
4451debfc3dSmrg dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
4461debfc3dSmrg dump_child ("min", TYPE_MIN_VALUE (t));
4471debfc3dSmrg dump_child ("max", TYPE_MAX_VALUE (t));
4481debfc3dSmrg
4491debfc3dSmrg if (code == ENUMERAL_TYPE)
4501debfc3dSmrg dump_child ("csts", TYPE_VALUES (t));
4511debfc3dSmrg break;
4521debfc3dSmrg
4531debfc3dSmrg case REAL_TYPE:
4541debfc3dSmrg dump_int (di, "prec", TYPE_PRECISION (t));
4551debfc3dSmrg break;
4561debfc3dSmrg
4571debfc3dSmrg case FIXED_POINT_TYPE:
4581debfc3dSmrg dump_int (di, "prec", TYPE_PRECISION (t));
4591debfc3dSmrg dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
4601debfc3dSmrg dump_string_field (di, "saturating",
4611debfc3dSmrg TYPE_SATURATING (t) ? "saturating": "non-saturating");
4621debfc3dSmrg break;
4631debfc3dSmrg
4641debfc3dSmrg case POINTER_TYPE:
4651debfc3dSmrg dump_child ("ptd", TREE_TYPE (t));
4661debfc3dSmrg break;
4671debfc3dSmrg
4681debfc3dSmrg case REFERENCE_TYPE:
4691debfc3dSmrg dump_child ("refd", TREE_TYPE (t));
4701debfc3dSmrg break;
4711debfc3dSmrg
4721debfc3dSmrg case METHOD_TYPE:
4731debfc3dSmrg dump_child ("clas", TYPE_METHOD_BASETYPE (t));
4741debfc3dSmrg /* Fall through. */
4751debfc3dSmrg
4761debfc3dSmrg case FUNCTION_TYPE:
4771debfc3dSmrg dump_child ("retn", TREE_TYPE (t));
4781debfc3dSmrg dump_child ("prms", TYPE_ARG_TYPES (t));
4791debfc3dSmrg break;
4801debfc3dSmrg
4811debfc3dSmrg case ARRAY_TYPE:
4821debfc3dSmrg dump_child ("elts", TREE_TYPE (t));
4831debfc3dSmrg dump_child ("domn", TYPE_DOMAIN (t));
4841debfc3dSmrg break;
4851debfc3dSmrg
4861debfc3dSmrg case RECORD_TYPE:
4871debfc3dSmrg case UNION_TYPE:
4881debfc3dSmrg if (TREE_CODE (t) == RECORD_TYPE)
4891debfc3dSmrg dump_string_field (di, "tag", "struct");
4901debfc3dSmrg else
4911debfc3dSmrg dump_string_field (di, "tag", "union");
4921debfc3dSmrg
4931debfc3dSmrg dump_child ("flds", TYPE_FIELDS (t));
4941debfc3dSmrg queue_and_dump_index (di, "binf", TYPE_BINFO (t),
4951debfc3dSmrg DUMP_BINFO);
4961debfc3dSmrg break;
4971debfc3dSmrg
4981debfc3dSmrg case CONST_DECL:
4991debfc3dSmrg dump_child ("cnst", DECL_INITIAL (t));
5001debfc3dSmrg break;
5011debfc3dSmrg
5021debfc3dSmrg case DEBUG_EXPR_DECL:
5031debfc3dSmrg dump_int (di, "-uid", DEBUG_TEMP_UID (t));
5041debfc3dSmrg /* Fall through. */
5051debfc3dSmrg
5061debfc3dSmrg case VAR_DECL:
5071debfc3dSmrg case PARM_DECL:
5081debfc3dSmrg case FIELD_DECL:
5091debfc3dSmrg case RESULT_DECL:
5101debfc3dSmrg if (TREE_CODE (t) == PARM_DECL)
5111debfc3dSmrg dump_child ("argt", DECL_ARG_TYPE (t));
5121debfc3dSmrg else
5131debfc3dSmrg dump_child ("init", DECL_INITIAL (t));
5141debfc3dSmrg dump_child ("size", DECL_SIZE (t));
5151debfc3dSmrg dump_int (di, "algn", DECL_ALIGN (t));
5161debfc3dSmrg
5171debfc3dSmrg if (TREE_CODE (t) == FIELD_DECL)
5181debfc3dSmrg {
5191debfc3dSmrg if (DECL_FIELD_OFFSET (t))
5201debfc3dSmrg dump_child ("bpos", bit_position (t));
5211debfc3dSmrg }
5221debfc3dSmrg else if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
5231debfc3dSmrg {
5241debfc3dSmrg dump_int (di, "used", TREE_USED (t));
5251debfc3dSmrg if (DECL_REGISTER (t))
5261debfc3dSmrg dump_string_field (di, "spec", "register");
5271debfc3dSmrg }
5281debfc3dSmrg break;
5291debfc3dSmrg
5301debfc3dSmrg case FUNCTION_DECL:
5311debfc3dSmrg dump_child ("args", DECL_ARGUMENTS (t));
5321debfc3dSmrg if (DECL_EXTERNAL (t))
5331debfc3dSmrg dump_string_field (di, "body", "undefined");
5341debfc3dSmrg if (TREE_PUBLIC (t))
5351debfc3dSmrg dump_string_field (di, "link", "extern");
5361debfc3dSmrg else
5371debfc3dSmrg dump_string_field (di, "link", "static");
5381debfc3dSmrg if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
5391debfc3dSmrg dump_child ("body", DECL_SAVED_TREE (t));
5401debfc3dSmrg break;
5411debfc3dSmrg
5421debfc3dSmrg case INTEGER_CST:
5431debfc3dSmrg fprintf (di->stream, "int: ");
544a2dc1f3fSmrg print_decs (wi::to_wide (t), di->stream);
5451debfc3dSmrg break;
5461debfc3dSmrg
5471debfc3dSmrg case STRING_CST:
5481debfc3dSmrg fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
5491debfc3dSmrg dump_int (di, "lngt", TREE_STRING_LENGTH (t));
5501debfc3dSmrg break;
5511debfc3dSmrg
5521debfc3dSmrg case REAL_CST:
5531debfc3dSmrg dump_real (di, "valu", TREE_REAL_CST_PTR (t));
5541debfc3dSmrg break;
5551debfc3dSmrg
5561debfc3dSmrg case FIXED_CST:
5571debfc3dSmrg dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
5581debfc3dSmrg break;
5591debfc3dSmrg
5601debfc3dSmrg case TRUTH_NOT_EXPR:
5611debfc3dSmrg case ADDR_EXPR:
5621debfc3dSmrg case INDIRECT_REF:
5631debfc3dSmrg case CLEANUP_POINT_EXPR:
564*8feb0f0bSmrg case VIEW_CONVERT_EXPR:
5651debfc3dSmrg case SAVE_EXPR:
5661debfc3dSmrg case REALPART_EXPR:
5671debfc3dSmrg case IMAGPART_EXPR:
5681debfc3dSmrg /* These nodes are unary, but do not have code class `1'. */
5691debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
5701debfc3dSmrg break;
5711debfc3dSmrg
5721debfc3dSmrg case TRUTH_ANDIF_EXPR:
5731debfc3dSmrg case TRUTH_ORIF_EXPR:
5741debfc3dSmrg case INIT_EXPR:
5751debfc3dSmrg case MODIFY_EXPR:
5761debfc3dSmrg case COMPOUND_EXPR:
5771debfc3dSmrg case PREDECREMENT_EXPR:
5781debfc3dSmrg case PREINCREMENT_EXPR:
5791debfc3dSmrg case POSTDECREMENT_EXPR:
5801debfc3dSmrg case POSTINCREMENT_EXPR:
5811debfc3dSmrg /* These nodes are binary, but do not have code class `2'. */
5821debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
5831debfc3dSmrg dump_child ("op 1", TREE_OPERAND (t, 1));
5841debfc3dSmrg break;
5851debfc3dSmrg
5861debfc3dSmrg case COMPONENT_REF:
5871debfc3dSmrg case BIT_FIELD_REF:
5881debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
5891debfc3dSmrg dump_child ("op 1", TREE_OPERAND (t, 1));
5901debfc3dSmrg dump_child ("op 2", TREE_OPERAND (t, 2));
5911debfc3dSmrg break;
5921debfc3dSmrg
5931debfc3dSmrg case ARRAY_REF:
5941debfc3dSmrg case ARRAY_RANGE_REF:
5951debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
5961debfc3dSmrg dump_child ("op 1", TREE_OPERAND (t, 1));
5971debfc3dSmrg dump_child ("op 2", TREE_OPERAND (t, 2));
5981debfc3dSmrg dump_child ("op 3", TREE_OPERAND (t, 3));
5991debfc3dSmrg break;
6001debfc3dSmrg
6011debfc3dSmrg case COND_EXPR:
6021debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
6031debfc3dSmrg dump_child ("op 1", TREE_OPERAND (t, 1));
6041debfc3dSmrg dump_child ("op 2", TREE_OPERAND (t, 2));
6051debfc3dSmrg break;
6061debfc3dSmrg
6071debfc3dSmrg case TRY_FINALLY_EXPR:
608*8feb0f0bSmrg case EH_ELSE_EXPR:
6091debfc3dSmrg dump_child ("op 0", TREE_OPERAND (t, 0));
6101debfc3dSmrg dump_child ("op 1", TREE_OPERAND (t, 1));
6111debfc3dSmrg break;
6121debfc3dSmrg
6131debfc3dSmrg case CALL_EXPR:
6141debfc3dSmrg {
6151debfc3dSmrg int i = 0;
6161debfc3dSmrg tree arg;
6171debfc3dSmrg call_expr_arg_iterator iter;
6181debfc3dSmrg dump_child ("fn", CALL_EXPR_FN (t));
6191debfc3dSmrg FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
6201debfc3dSmrg {
6211debfc3dSmrg char buffer[32];
6221debfc3dSmrg sprintf (buffer, "%u", i);
6231debfc3dSmrg dump_child (buffer, arg);
6241debfc3dSmrg i++;
6251debfc3dSmrg }
6261debfc3dSmrg }
6271debfc3dSmrg break;
6281debfc3dSmrg
6291debfc3dSmrg case CONSTRUCTOR:
6301debfc3dSmrg {
6311debfc3dSmrg unsigned HOST_WIDE_INT cnt;
6321debfc3dSmrg tree index, value;
6331debfc3dSmrg dump_int (di, "lngt", CONSTRUCTOR_NELTS (t));
6341debfc3dSmrg FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
6351debfc3dSmrg {
6361debfc3dSmrg dump_child ("idx", index);
6371debfc3dSmrg dump_child ("val", value);
6381debfc3dSmrg }
6391debfc3dSmrg }
6401debfc3dSmrg break;
6411debfc3dSmrg
6421debfc3dSmrg case BIND_EXPR:
6431debfc3dSmrg dump_child ("vars", TREE_OPERAND (t, 0));
6441debfc3dSmrg dump_child ("body", TREE_OPERAND (t, 1));
6451debfc3dSmrg break;
6461debfc3dSmrg
6471debfc3dSmrg case LOOP_EXPR:
6481debfc3dSmrg dump_child ("body", TREE_OPERAND (t, 0));
6491debfc3dSmrg break;
6501debfc3dSmrg
6511debfc3dSmrg case EXIT_EXPR:
6521debfc3dSmrg dump_child ("cond", TREE_OPERAND (t, 0));
6531debfc3dSmrg break;
6541debfc3dSmrg
6551debfc3dSmrg case RETURN_EXPR:
6561debfc3dSmrg dump_child ("expr", TREE_OPERAND (t, 0));
6571debfc3dSmrg break;
6581debfc3dSmrg
6591debfc3dSmrg case TARGET_EXPR:
6601debfc3dSmrg dump_child ("decl", TREE_OPERAND (t, 0));
6611debfc3dSmrg dump_child ("init", TREE_OPERAND (t, 1));
6621debfc3dSmrg dump_child ("clnp", TREE_OPERAND (t, 2));
6631debfc3dSmrg /* There really are two possible places the initializer can be.
6641debfc3dSmrg After RTL expansion, the second operand is moved to the
6651debfc3dSmrg position of the fourth operand, and the second operand
6661debfc3dSmrg becomes NULL. */
6671debfc3dSmrg dump_child ("init", TREE_OPERAND (t, 3));
6681debfc3dSmrg break;
6691debfc3dSmrg
6701debfc3dSmrg case CASE_LABEL_EXPR:
6711debfc3dSmrg dump_child ("name", CASE_LABEL (t));
6721debfc3dSmrg if (CASE_LOW (t))
6731debfc3dSmrg {
6741debfc3dSmrg dump_child ("low ", CASE_LOW (t));
6751debfc3dSmrg if (CASE_HIGH (t))
6761debfc3dSmrg dump_child ("high", CASE_HIGH (t));
6771debfc3dSmrg }
6781debfc3dSmrg break;
6791debfc3dSmrg case LABEL_EXPR:
6801debfc3dSmrg dump_child ("name", TREE_OPERAND (t,0));
6811debfc3dSmrg break;
6821debfc3dSmrg case GOTO_EXPR:
6831debfc3dSmrg dump_child ("labl", TREE_OPERAND (t, 0));
6841debfc3dSmrg break;
6851debfc3dSmrg case SWITCH_EXPR:
6861debfc3dSmrg dump_child ("cond", TREE_OPERAND (t, 0));
6871debfc3dSmrg dump_child ("body", TREE_OPERAND (t, 1));
6881debfc3dSmrg break;
6891debfc3dSmrg case OMP_CLAUSE:
6901debfc3dSmrg {
6911debfc3dSmrg int i;
6921debfc3dSmrg fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
6931debfc3dSmrg for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
6941debfc3dSmrg dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
6951debfc3dSmrg }
6961debfc3dSmrg break;
6971debfc3dSmrg default:
6981debfc3dSmrg /* There are no additional fields to print. */
6991debfc3dSmrg break;
7001debfc3dSmrg }
7011debfc3dSmrg
7021debfc3dSmrg done:
7031debfc3dSmrg if (dump_flag (di, TDF_ADDRESS, NULL))
7041debfc3dSmrg dump_pointer (di, "addr", (void *)t);
7051debfc3dSmrg
7061debfc3dSmrg /* Terminate the line. */
7071debfc3dSmrg fprintf (di->stream, "\n");
7081debfc3dSmrg }
7091debfc3dSmrg
7101debfc3dSmrg /* Return nonzero if FLAG has been specified for the dump, and NODE
7111debfc3dSmrg is not the root node of the dump. */
7121debfc3dSmrg
dump_flag(dump_info_p di,dump_flags_t flag,const_tree node)713a2dc1f3fSmrg int dump_flag (dump_info_p di, dump_flags_t flag, const_tree node)
7141debfc3dSmrg {
7151debfc3dSmrg return (di->flags & flag) && (node != di->node);
7161debfc3dSmrg }
7171debfc3dSmrg
7181debfc3dSmrg /* Dump T, and all its children, on STREAM. */
7191debfc3dSmrg
7201debfc3dSmrg void
dump_node(const_tree t,dump_flags_t flags,FILE * stream)721a2dc1f3fSmrg dump_node (const_tree t, dump_flags_t flags, FILE *stream)
7221debfc3dSmrg {
7231debfc3dSmrg struct dump_info di;
7241debfc3dSmrg dump_queue_p dq;
7251debfc3dSmrg dump_queue_p next_dq;
7261debfc3dSmrg
7271debfc3dSmrg /* Initialize the dump-information structure. */
7281debfc3dSmrg di.stream = stream;
7291debfc3dSmrg di.index = 0;
7301debfc3dSmrg di.column = 0;
7311debfc3dSmrg di.queue = 0;
7321debfc3dSmrg di.queue_end = 0;
7331debfc3dSmrg di.free_list = 0;
7341debfc3dSmrg di.flags = flags;
7351debfc3dSmrg di.node = t;
7361debfc3dSmrg di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
737c0a68be4Smrg splay_tree_delete_pointers);
7381debfc3dSmrg
7391debfc3dSmrg /* Queue up the first node. */
7401debfc3dSmrg queue (&di, t, DUMP_NONE);
7411debfc3dSmrg
7421debfc3dSmrg /* Until the queue is empty, keep dumping nodes. */
7431debfc3dSmrg while (di.queue)
7441debfc3dSmrg dequeue_and_dump (&di);
7451debfc3dSmrg
7461debfc3dSmrg /* Now, clean up. */
7471debfc3dSmrg for (dq = di.free_list; dq; dq = next_dq)
7481debfc3dSmrg {
7491debfc3dSmrg next_dq = dq->next;
7501debfc3dSmrg free (dq);
7511debfc3dSmrg }
7521debfc3dSmrg splay_tree_delete (di.nodes);
7531debfc3dSmrg }
754