xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-dump.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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