home *** CD-ROM | disk | FTP | other *** search
/ OpenStep (Enterprise) / OpenStepENTCD.toast / OEDEV / GNUSRC.Z / print-tree.c < prev    next >
C/C++ Source or Header  |  1995-06-15  |  21KB  |  739 lines

  1. /* Prints out tree in human readable form - GNU C-compiler
  2.    Copyright (C) 1990, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21.  
  22. #include "config.h"
  23. #include "tree.h"
  24. #include <stdio.h>
  25.  
  26. extern char **tree_code_name;
  27.  
  28. extern char *mode_name[];
  29.  
  30. void print_node ();
  31. void indent_to ();
  32.  
  33. /* Define the hash table of nodes already seen.
  34.    Such nodes are not repeated; brief cross-references are used.  */
  35.  
  36. #define HASH_SIZE 37
  37.  
  38. struct bucket
  39. {
  40.   tree node;
  41.   struct bucket *next;
  42. };
  43.  
  44. static struct bucket **table;
  45.  
  46. /* Print the node NODE on standard error, for debugging.
  47.    Most nodes referred to by this one are printed recursively
  48.    down to a depth of six.  */
  49.  
  50. void
  51. debug_tree (node)
  52.      tree node;
  53. {
  54.   char *object = (char *) oballoc (0);
  55.  
  56.   table = (struct bucket **) oballoc (HASH_SIZE * sizeof (struct bucket *));
  57.   bzero ((char *) table, HASH_SIZE * sizeof (struct bucket *));
  58.   print_node (stderr, "", node, 0);
  59.   table = 0;
  60.   obfree (object);
  61.   fprintf (stderr, "\n");
  62. }
  63.  
  64. /* Print a node in brief fashion, with just the code, address and name.  */
  65.  
  66. void
  67. print_node_brief (file, prefix, node, indent)
  68.      FILE *file;
  69.      char *prefix;
  70.      tree node;
  71.      int indent;
  72. {
  73.   char class;
  74.  
  75.   if (node == 0)
  76.     return;
  77.  
  78.   class = TREE_CODE_CLASS (TREE_CODE (node));
  79.  
  80.   /* Always print the slot this node is in, and its code, address and
  81.      name if any.  */
  82.   if (indent > 0)
  83.     fprintf (file, " ");
  84.   fprintf (file, "%s <%s ", prefix, tree_code_name[(int) TREE_CODE (node)]);
  85.   fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) node);
  86.  
  87.   if (class == 'd')
  88.     {
  89.       if (DECL_NAME (node))
  90.     fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
  91.     }
  92.   else if (class == 't')
  93.     {
  94.       if (TYPE_NAME (node))
  95.     {
  96.       if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
  97.         fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
  98.       else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
  99.            && DECL_NAME (TYPE_NAME (node)))
  100.         fprintf (file, " %s",
  101.              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
  102.     }
  103.     }
  104.   if (TREE_CODE (node) == IDENTIFIER_NODE)
  105.     fprintf (file, " %s", IDENTIFIER_POINTER (node));
  106.   /* We might as well always print the value of an integer.  */
  107.   if (TREE_CODE (node) == INTEGER_CST)
  108.     {
  109.       if (TREE_CONSTANT_OVERFLOW (node))
  110.     fprintf (file, " overflow");
  111.  
  112.       if (TREE_INT_CST_HIGH (node) == 0)
  113.     fprintf (file,
  114. #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  115.          " %1u",
  116. #else
  117.          " %1lu",
  118. #endif
  119.          TREE_INT_CST_LOW (node));
  120.       else if (TREE_INT_CST_HIGH (node) == -1
  121.            && TREE_INT_CST_LOW (node) != 0)
  122.     fprintf (file,
  123. #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  124.          " -%1u",
  125. #else
  126.          " -%1lu",
  127. #endif
  128.          -TREE_INT_CST_LOW (node));
  129.       else
  130.     fprintf (file,
  131. #if HOST_BITS_PER_WIDE_INT == 64
  132. #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
  133.          " 0x%lx%016lx",
  134. #else
  135.          " 0x%x%016x",
  136. #endif
  137. #else
  138. #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
  139.          " 0x%lx%08lx",
  140. #else
  141.          " 0x%x%08x",
  142. #endif
  143. #endif
  144.          TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
  145.     }
  146.   if (TREE_CODE (node) == REAL_CST)
  147.     {
  148.       REAL_VALUE_TYPE d;
  149.  
  150.       if (TREE_OVERFLOW (node))
  151.     fprintf (file, " overflow");
  152.  
  153. #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
  154.       d = TREE_REAL_CST (node);
  155.       if (REAL_VALUE_ISINF (d))
  156.     fprintf (file, " Inf");
  157.       else if (REAL_VALUE_ISNAN (d))
  158.     fprintf (file, " Nan");
  159.       else
  160.     {
  161.       char string[100];
  162.  
  163.       REAL_VALUE_TO_DECIMAL (d, "%e", string);
  164.       fprintf (file, " %s", string);
  165.     }
  166. #else
  167.       {
  168.     int i;
  169.     unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
  170.     fprintf (file, " 0x");
  171.     for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
  172.       fprintf (file, "%02x", *p++);
  173.     fprintf (file, "");
  174.       }
  175. #endif
  176.     }
  177.  
  178.   fprintf (file, ">");
  179. }
  180.  
  181. void
  182. indent_to (file, column)
  183.      FILE *file;
  184.      int column;
  185. {
  186.   int i;
  187.  
  188.   /* Since this is the long way, indent to desired column.  */
  189.   if (column > 0)
  190.     fprintf (file, "\n");
  191.   for (i = 0; i < column; i++)
  192.     fprintf (file, " ");
  193. }
  194.  
  195. /* Print the node NODE in full on file FILE, preceded by PREFIX,
  196.    starting in column INDENT.  */
  197.  
  198. void
  199. print_node (file, prefix, node, indent)
  200.      FILE *file;
  201.      char *prefix;
  202.      tree node;
  203.      int indent;
  204. {
  205.   int hash;
  206.   struct bucket *b;
  207.   enum machine_mode mode;
  208.   char class;
  209.   int len;
  210.   int first_rtl;
  211.   int i;
  212.  
  213.   if (node == 0)
  214.     return;
  215.  
  216.   class = TREE_CODE_CLASS (TREE_CODE (node));
  217.  
  218.   /* Don't get too deep in nesting.  If the user wants to see deeper,
  219.      it is easy to use the address of a lowest-level node
  220.      as an argument in another call to debug_tree.  */
  221.  
  222.   if (indent > 24)
  223.     {
  224.       print_node_brief (file, prefix, node, indent);
  225.       return;
  226.     }
  227.  
  228.   if (indent > 8 && (class == 't' || class == 'd'))
  229.     {
  230.       print_node_brief (file, prefix, node, indent);
  231.       return;
  232.     }
  233.  
  234.   /* It is unsafe to look at any other filds of an ERROR_MARK node. */
  235.   if (TREE_CODE (node) == ERROR_MARK)
  236.     {
  237.       print_node_brief (file, prefix, node, indent);
  238.       return;
  239.     }
  240.  
  241.   hash = ((unsigned HOST_WIDE_INT) node) % HASH_SIZE;
  242.  
  243.   /* If node is in the table, just mention its address.  */
  244.   for (b = table[hash]; b; b = b->next)
  245.     if (b->node == node)
  246.       {
  247.     print_node_brief (file, prefix, node, indent);
  248.     return;
  249.       }
  250.  
  251.   /* Add this node to the table.  */
  252.   b = (struct bucket *) oballoc (sizeof (struct bucket));
  253.   b->node = node;
  254.   b->next = table[hash];
  255.   table[hash] = b;
  256.  
  257.   /* Indent to the specified column, since this is the long form.  */
  258.   indent_to (file, indent);
  259.  
  260.   /* Print the slot this node is in, and its code, and address.  */
  261.   fprintf (file, "%s <%s ", prefix, tree_code_name[(int) TREE_CODE (node)]);
  262.   fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) node);
  263.  
  264.   /* Print the name, if any.  */
  265.   if (class == 'd')
  266.     {
  267.       if (DECL_NAME (node))
  268.     fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
  269.     }
  270.   else if (class == 't')
  271.     {
  272.       if (TYPE_NAME (node))
  273.     {
  274.       if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
  275.         fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
  276.       else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
  277.            && DECL_NAME (TYPE_NAME (node)))
  278.         fprintf (file, " %s",
  279.              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
  280.     }
  281.     }
  282.   if (TREE_CODE (node) == IDENTIFIER_NODE)
  283.     fprintf (file, " %s", IDENTIFIER_POINTER (node));
  284.  
  285.   if (TREE_CODE (node) == INTEGER_CST)
  286.     {
  287.       if (indent <= 4)
  288.     print_node_brief (file, "type", TREE_TYPE (node), indent + 4);
  289.     }
  290.   else
  291.     {
  292.       print_node (file, "type", TREE_TYPE (node), indent + 4);
  293.       if (TREE_TYPE (node))
  294.     indent_to (file, indent + 3);
  295.  
  296.       print_obstack_name ((char *) node, file, "");
  297.       indent_to (file, indent + 3);
  298.     }
  299.  
  300.   /* If a permanent object is in the wrong obstack, or the reverse, warn.  */
  301.   if (object_permanent_p (node) != TREE_PERMANENT (node))
  302.     {
  303.       if (TREE_PERMANENT (node))
  304.     fputs (" !!permanent object in non-permanent obstack!!", file);
  305.       else
  306.     fputs (" !!non-permanent object in permanent obstack!!", file);
  307.       indent_to (file, indent + 3);
  308.     }
  309.  
  310.   if (TREE_SIDE_EFFECTS (node))
  311.     fputs (" side-effects", file);
  312.   if (TREE_READONLY (node))
  313.     fputs (" readonly", file);
  314.   if (TREE_CONSTANT (node))
  315.     fputs (" constant", file);
  316.   if (TREE_ADDRESSABLE (node))
  317.     fputs (" addressable", file);
  318.   if (TREE_THIS_VOLATILE (node))
  319.     fputs (" volatile", file);
  320.   if (TREE_UNSIGNED (node))
  321.     fputs (" unsigned", file);
  322.   if (TREE_ASM_WRITTEN (node))
  323.     fputs (" asm_written", file);
  324.   if (TREE_USED (node))
  325.     fputs (" used", file);
  326.   if (TREE_RAISES (node))
  327.     fputs (" raises", file);
  328.   if (TREE_PERMANENT (node))
  329.     fputs (" permanent", file);
  330.   if (TREE_PUBLIC (node))
  331.     fputs (" public", file);
  332.   if (TREE_STATIC (node))
  333.     fputs (" static", file);
  334.   if (TREE_LANG_FLAG_0 (node))
  335.     fputs (" tree_0", file);
  336.   if (TREE_LANG_FLAG_1 (node))
  337.     fputs (" tree_1", file);
  338.   if (TREE_LANG_FLAG_2 (node))
  339.     fputs (" tree_2", file);
  340.   if (TREE_LANG_FLAG_3 (node))
  341.     fputs (" tree_3", file);
  342.   if (TREE_LANG_FLAG_4 (node))
  343.     fputs (" tree_4", file);
  344.   if (TREE_LANG_FLAG_5 (node))
  345.     fputs (" tree_5", file);
  346.   if (TREE_LANG_FLAG_6 (node))
  347.     fputs (" tree_6", file);
  348.  
  349.   /* DECL_ nodes have additional attributes.  */
  350.  
  351.   switch (TREE_CODE_CLASS (TREE_CODE (node)))
  352.     {
  353.     case 'd':
  354.       mode = DECL_MODE (node);
  355.  
  356.       if (DECL_IGNORED_P (node))
  357.     fputs (" ignored", file);
  358.       if (DECL_ABSTRACT (node))
  359.     fputs (" abstract", file);
  360.       if (DECL_IN_SYSTEM_HEADER (node))
  361.     fputs (" in_system_header", file);
  362.       if (DECL_COMMON (node))
  363.     fputs (" common", file);
  364.       if (DECL_EXTERNAL (node))
  365.     fputs (" external", file);
  366.       if (DECL_REGISTER (node))
  367.     fputs (" regdecl", file);
  368.       if (DECL_PACKED (node))
  369.     fputs (" packed", file);
  370.       if (DECL_NONLOCAL (node))
  371.     fputs (" nonlocal", file);
  372.       if (DECL_INLINE (node))
  373.     fputs (" inline", file);
  374.  
  375.       if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
  376.     fputs (" suppress-debug", file);
  377.  
  378.       if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
  379.     fputs (" built-in", file);
  380.       if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN_NONANSI (node))
  381.     fputs (" built-in-nonansi", file);
  382.  
  383.       if (TREE_CODE (node) == FIELD_DECL && DECL_BIT_FIELD (node))
  384.     fputs (" bit-field", file);
  385.       if (TREE_CODE (node) == LABEL_DECL && DECL_TOO_LATE (node))
  386.     fputs (" too-late", file);
  387.       if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
  388.     fputs (" in-text-section", file);
  389.  
  390.       if (DECL_VIRTUAL_P (node))
  391.     fputs (" virtual", file);
  392.       if (DECL_DEFER_OUTPUT (node))
  393.     fputs (" defer-output", file);
  394.       if (DECL_TRANSPARENT_UNION (node))
  395.     fputs (" transparent-union", file);
  396.  
  397.       if (DECL_LANG_FLAG_0 (node))
  398.     fputs (" decl_0", file);
  399.       if (DECL_LANG_FLAG_1 (node))
  400.     fputs (" decl_1", file);
  401.       if (DECL_LANG_FLAG_2 (node))
  402.     fputs (" decl_2", file);
  403.       if (DECL_LANG_FLAG_3 (node))
  404.     fputs (" decl_3", file);
  405.       if (DECL_LANG_FLAG_4 (node))
  406.     fputs (" decl_4", file);
  407.       if (DECL_LANG_FLAG_5 (node))
  408.     fputs (" decl_5", file);
  409.       if (DECL_LANG_FLAG_6 (node))
  410.     fputs (" decl_6", file);
  411.       if (DECL_LANG_FLAG_7 (node))
  412.     fputs (" decl_7", file);
  413.  
  414.       fprintf (file, " %s", mode_name[(int) mode]);
  415.  
  416.       fprintf (file, " file %s line %d",
  417.            DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
  418.  
  419.       print_node (file, "size", DECL_SIZE (node), indent + 4);
  420.       print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
  421.       indent_to (file, indent + 3);
  422.       if (TREE_CODE (node) != FUNCTION_DECL)
  423.     fprintf (file, " align %d", DECL_ALIGN (node));
  424.       else if (DECL_INLINE (node))
  425.     fprintf (file, " frame_size %d", DECL_FRAME_SIZE (node));
  426.       else if (DECL_BUILT_IN (node))
  427.     fprintf (file, " built-in code %d", DECL_FUNCTION_CODE (node));
  428.       if (TREE_CODE (node) == FIELD_DECL)
  429.     print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4);
  430.       print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
  431.       print_node_brief (file, "machine_attributes", DECL_MACHINE_ATTRIBUTES (node), indent + 4);
  432.       print_node_brief (file, "abstract_origin",
  433.             DECL_ABSTRACT_ORIGIN (node), indent + 4);
  434.  
  435.       print_node (file, "arguments", DECL_ARGUMENTS (node), indent + 4);
  436.       print_node (file, "result", DECL_RESULT (node), indent + 4);
  437.       print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4);
  438.  
  439.       print_lang_decl (file, node, indent);
  440.  
  441.       if (DECL_RTL (node) != 0)
  442.     {
  443.       indent_to (file, indent + 4);
  444.       print_rtl (file, DECL_RTL (node));
  445.     }
  446.  
  447.       if (DECL_SAVED_INSNS (node) != 0)
  448.     {
  449.       indent_to (file, indent + 4);
  450.       if (TREE_CODE (node) == PARM_DECL)
  451.         {
  452.           fprintf (file, "incoming-rtl ");
  453.           print_rtl (file, DECL_INCOMING_RTL (node));
  454.         }
  455.       else if (TREE_CODE (node) == FUNCTION_DECL)
  456.         {
  457.           fprintf (file, "saved-insns ");
  458.           fprintf (file, HOST_PTR_PRINTF,
  459.                 (HOST_WIDE_INT) DECL_SAVED_INSNS (node));
  460.         }
  461.     }
  462.  
  463.       /* Print the decl chain only if decl is at second level.  */
  464.       if (indent == 4)
  465.     print_node (file, "chain", TREE_CHAIN (node), indent + 4);
  466.       else
  467.     print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
  468.       break;
  469.  
  470.     case 't':
  471.       if (TYPE_NO_FORCE_BLK (node))
  472.     fputs (" no-force-blk", file);
  473.       if (TYPE_STRING_FLAG (node))
  474.     fputs (" string-flag", file);
  475.       if (TYPE_NEEDS_CONSTRUCTING (node))
  476.     fputs (" needs-constructing", file);
  477.       if (TYPE_TRANSPARENT_UNION (node))
  478.     fputs (" transparent-union", file);
  479.       if (TYPE_PACKED (node))
  480.     fputs (" packed", file);
  481.  
  482.       if (TYPE_LANG_FLAG_0 (node))
  483.     fputs (" type_0", file);
  484.       if (TYPE_LANG_FLAG_1 (node))
  485.     fputs (" type_1", file);
  486.       if (TYPE_LANG_FLAG_2 (node))
  487.     fputs (" type_2", file);
  488.       if (TYPE_LANG_FLAG_3 (node))
  489.     fputs (" type_3", file);
  490.       if (TYPE_LANG_FLAG_4 (node))
  491.     fputs (" type_4", file);
  492.       if (TYPE_LANG_FLAG_5 (node))
  493.     fputs (" type_5", file);
  494.       if (TYPE_LANG_FLAG_6 (node))
  495.     fputs (" type_6", file);
  496.  
  497.       mode = TYPE_MODE (node);
  498.       fprintf (file, " %s", mode_name[(int) mode]);
  499.  
  500.       print_node (file, "size", TYPE_SIZE (node), indent + 4);
  501.       indent_to (file, indent + 3);
  502.  
  503.       fprintf (file, " align %d", TYPE_ALIGN (node));
  504.       fprintf (file, " symtab %d", TYPE_SYMTAB_ADDRESS (node));
  505.  
  506.       print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
  507.  
  508.       if (TREE_CODE (node) == ARRAY_TYPE || TREE_CODE (node) == SET_TYPE)
  509.     print_node (file, "domain", TYPE_DOMAIN (node), indent + 4);
  510.       else if (TREE_CODE (node) == INTEGER_TYPE
  511.            || TREE_CODE (node) == BOOLEAN_TYPE
  512.            || TREE_CODE (node) == CHAR_TYPE)
  513.     {
  514.       fprintf (file, " precision %d", TYPE_PRECISION (node));
  515.       print_node (file, "min", TYPE_MIN_VALUE (node), indent + 4);
  516.       print_node (file, "max", TYPE_MAX_VALUE (node), indent + 4);
  517.     }
  518.       else if (TREE_CODE (node) == ENUMERAL_TYPE)
  519.     {
  520.       fprintf (file, " precision %d", TYPE_PRECISION (node));
  521.       print_node (file, "min", TYPE_MIN_VALUE (node), indent + 4);
  522.       print_node (file, "max", TYPE_MAX_VALUE (node), indent + 4);
  523.       print_node (file, "values", TYPE_VALUES (node), indent + 4);
  524.     }
  525.       else if (TREE_CODE (node) == REAL_TYPE)
  526.     fprintf (file, " precision %d", TYPE_PRECISION (node));
  527.       else if (TREE_CODE (node) == RECORD_TYPE
  528.            || TREE_CODE (node) == UNION_TYPE
  529.            || TREE_CODE (node) == QUAL_UNION_TYPE)
  530.     print_node (file, "fields", TYPE_FIELDS (node), indent + 4);
  531.       else if (TREE_CODE (node) == FUNCTION_TYPE || TREE_CODE (node) == METHOD_TYPE)
  532.     {
  533.       if (TYPE_METHOD_BASETYPE (node))
  534.         print_node_brief (file, "method basetype", TYPE_METHOD_BASETYPE (node), indent + 4);
  535.       print_node (file, "arg-types", TYPE_ARG_TYPES (node), indent + 4);
  536.     }
  537.       if (TYPE_CONTEXT (node))
  538.     print_node_brief (file, "context", TYPE_CONTEXT (node), indent + 4);
  539.  
  540.       print_lang_type (file, node, indent);
  541.  
  542.       if (TYPE_POINTER_TO (node) || TREE_CHAIN (node))
  543.     indent_to (file, indent + 3);
  544.       print_node_brief (file, "pointer_to_this", TYPE_POINTER_TO (node), indent + 4);
  545.       print_node_brief (file, "reference_to_this", TYPE_REFERENCE_TO (node), indent + 4);
  546.       print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
  547.       break;
  548.  
  549.     case 'b':
  550.       print_node (file, "vars", BLOCK_VARS (node), indent + 4);
  551.       print_node (file, "tags", BLOCK_TYPE_TAGS (node), indent + 4);
  552.       print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node), indent + 4);
  553.       print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4);
  554.       print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
  555.       print_node (file, "abstract_origin",
  556.           BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
  557.       return;
  558.  
  559.     case 'e':
  560.     case '<':
  561.     case '1':
  562.     case '2':
  563.     case 'r':
  564.     case 's':
  565.       switch (TREE_CODE (node))
  566.     {
  567.     case BIND_EXPR:
  568.       print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4);
  569.       print_node (file, "body", TREE_OPERAND (node, 1), indent + 4);
  570.       print_node (file, "block", TREE_OPERAND (node, 2), indent + 4);
  571.       return;
  572.     }
  573.  
  574.       first_rtl = len = tree_code_length[(int) TREE_CODE (node)];
  575.       /* These kinds of nodes contain rtx's, not trees,
  576.      after a certain point.  Print the rtx's as rtx's.  */
  577.       switch (TREE_CODE (node))
  578.     {
  579.     case SAVE_EXPR:
  580.       first_rtl = 2;
  581.       break;
  582.     case CALL_EXPR:
  583.       first_rtl = 2;
  584.       break;
  585.     case METHOD_CALL_EXPR:
  586.       first_rtl = 3;
  587.       break;
  588.     case WITH_CLEANUP_EXPR:
  589.       /* Should be defined to be 2.  */
  590.       first_rtl = 1;
  591.       break;
  592.     case RTL_EXPR:
  593.       first_rtl = 0;
  594.     }
  595.       for (i = 0; i < len; i++)
  596.     {
  597.       if (i >= first_rtl)
  598.         {
  599.           indent_to (file, indent + 4);
  600.           fprintf (file, "rtl %d ", i);
  601.           if (TREE_OPERAND (node, i))
  602.         print_rtl (file, (struct rtx_def *) TREE_OPERAND (node, i));
  603.           else
  604.         fprintf (file, "(nil)");
  605.           fprintf (file, "\n");
  606.         }
  607.       else
  608.         {
  609.           char temp[10];
  610.  
  611.           sprintf (temp, "arg %d", i);
  612.           print_node (file, temp, TREE_OPERAND (node, i), indent + 4);
  613.         }
  614.     }
  615.       break;
  616.  
  617.     case 'c':
  618.     case 'x':
  619.       switch (TREE_CODE (node))
  620.     {
  621.     case INTEGER_CST:
  622.       if (TREE_CONSTANT_OVERFLOW (node))
  623.         fprintf (file, " overflow");
  624.  
  625.       if (TREE_INT_CST_HIGH (node) == 0)
  626.         fprintf (file,
  627. #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  628.              " %1u",
  629. #else
  630.              " %1lu",
  631. #endif
  632.              TREE_INT_CST_LOW (node));
  633.       else if (TREE_INT_CST_HIGH (node) == -1
  634.            && TREE_INT_CST_LOW (node) != 0)
  635.         fprintf (file,
  636. #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  637.              " -%1u",
  638. #else
  639.              " -%1lu",
  640. #endif
  641.              -TREE_INT_CST_LOW (node));
  642.       else
  643.         fprintf (file,
  644. #if HOST_BITS_PER_WIDE_INT == 64
  645. #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
  646.              " 0x%lx%016lx",
  647. #else
  648.              " 0x%x%016x",
  649. #endif
  650. #else
  651. #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
  652.              " 0x%lx%08lx",
  653. #else
  654.              " 0x%x%08x",
  655. #endif
  656. #endif
  657.              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
  658.       break;
  659.  
  660.     case REAL_CST:
  661.       {
  662.         REAL_VALUE_TYPE d;
  663.  
  664.         if (TREE_OVERFLOW (node))
  665.           fprintf (file, " overflow");
  666.  
  667. #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
  668.         d = TREE_REAL_CST (node);
  669.         if (REAL_VALUE_ISINF (d))
  670.           fprintf (file, " Inf");
  671.         else if (REAL_VALUE_ISNAN (d))
  672.           fprintf (file, " Nan");
  673.         else
  674.           {
  675.         char string[100];
  676.  
  677.         REAL_VALUE_TO_DECIMAL (d, "%e", string);
  678.         fprintf (file, " %s", string);
  679.           }
  680. #else
  681.         {
  682.           int i;
  683.           unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
  684.           fprintf (file, " 0x");
  685.           for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
  686.         fprintf (file, "%02x", *p++);
  687.           fprintf (file, "");
  688.         }
  689. #endif
  690.       }
  691.       break;
  692.  
  693.     case COMPLEX_CST:
  694.       print_node (file, "real", TREE_REALPART (node), indent + 4);
  695.       print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
  696.       break;
  697.  
  698.     case STRING_CST:
  699.       fprintf (file, " \"%s\"", TREE_STRING_POINTER (node));
  700.       /* Print the chain at second level.  */
  701.       if (indent == 4)
  702.         print_node (file, "chain", TREE_CHAIN (node), indent + 4);
  703.       else
  704.         print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
  705.       break;
  706.  
  707.     case IDENTIFIER_NODE:
  708.       print_lang_identifier (file, node, indent);
  709.       break;
  710.  
  711.     case TREE_LIST:
  712.       print_node (file, "purpose", TREE_PURPOSE (node), indent + 4);
  713.       print_node (file, "value", TREE_VALUE (node), indent + 4);
  714.       print_node (file, "chain", TREE_CHAIN (node), indent + 4);
  715.       break;
  716.  
  717.     case TREE_VEC:
  718.       len = TREE_VEC_LENGTH (node);
  719.       for (i = 0; i < len; i++)
  720.         if (TREE_VEC_ELT (node, i))
  721.           {
  722.         char temp[10];
  723.         sprintf (temp, "elt %d", i);
  724.         indent_to (file, indent + 4);
  725.         print_node_brief (file, temp, TREE_VEC_ELT (node, i), 0);
  726.           }
  727.       break;
  728.  
  729.     case OP_IDENTIFIER:
  730.       print_node (file, "op1", TREE_PURPOSE (node), indent + 4);
  731.       print_node (file, "op2", TREE_VALUE (node), indent + 4);
  732.     }
  733.  
  734.       break;
  735.     }
  736.  
  737.   fprintf (file, ">");
  738. }
  739.