print-tree.c revision 96287
118334Speter/* Prints out tree in human readable form - GNU C-compiler
290285Sobrien   Copyright (C) 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
390285Sobrien   2001, 2002 Free Software Foundation, Inc.
418334Speter
590285SobrienThis file is part of GCC.
618334Speter
790285SobrienGCC is free software; you can redistribute it and/or modify it under
890285Sobrienthe terms of the GNU General Public License as published by the Free
990285SobrienSoftware Foundation; either version 2, or (at your option) any later
1090285Sobrienversion.
1118334Speter
1290285SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390285SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490285SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590285Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890285Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990285SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090285Sobrien02111-1307, USA.  */
2118334Speter
2252521Sobrien/* $FreeBSD: head/contrib/gcc/print-tree.c 96287 2002-05-09 22:05:33Z obrien $ */
2318334Speter
2452521Sobrien
2518334Speter#include "config.h"
2650617Sobrien#include "system.h"
2718334Speter#include "tree.h"
2890285Sobrien#include "ggc.h"
2990285Sobrien#include "langhooks.h"
3018334Speter
3118334Speter/* Define the hash table of nodes already seen.
3218334Speter   Such nodes are not repeated; brief cross-references are used.  */
3318334Speter
3418334Speter#define HASH_SIZE 37
3518334Speter
3618334Speterstruct bucket
3718334Speter{
3818334Speter  tree node;
3918334Speter  struct bucket *next;
4018334Speter};
4118334Speter
4218334Speterstatic struct bucket **table;
4318334Speter
4418334Speter/* Print the node NODE on standard error, for debugging.
4518334Speter   Most nodes referred to by this one are printed recursively
4618334Speter   down to a depth of six.  */
4718334Speter
4818334Spetervoid
4918334Speterdebug_tree (node)
5018334Speter     tree node;
5118334Speter{
5290285Sobrien  table = (struct bucket **) permalloc (HASH_SIZE * sizeof (struct bucket *));
5390285Sobrien  memset ((char *) table, 0, HASH_SIZE * sizeof (struct bucket *));
5418334Speter  print_node (stderr, "", node, 0);
5518334Speter  table = 0;
5618334Speter  fprintf (stderr, "\n");
5718334Speter}
5818334Speter
5918334Speter/* Print a node in brief fashion, with just the code, address and name.  */
6018334Speter
6118334Spetervoid
6218334Speterprint_node_brief (file, prefix, node, indent)
6318334Speter     FILE *file;
6452521Sobrien     const char *prefix;
6518334Speter     tree node;
6618334Speter     int indent;
6718334Speter{
6818334Speter  char class;
6918334Speter
7018334Speter  if (node == 0)
7118334Speter    return;
7218334Speter
7318334Speter  class = TREE_CODE_CLASS (TREE_CODE (node));
7418334Speter
7518334Speter  /* Always print the slot this node is in, and its code, address and
7618334Speter     name if any.  */
7718334Speter  if (indent > 0)
7818334Speter    fprintf (file, " ");
7918334Speter  fprintf (file, "%s <%s ", prefix, tree_code_name[(int) TREE_CODE (node)]);
8050617Sobrien  fprintf (file, HOST_PTR_PRINTF, (char *) node);
8118334Speter
8218334Speter  if (class == 'd')
8318334Speter    {
8418334Speter      if (DECL_NAME (node))
8518334Speter	fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
8618334Speter    }
8718334Speter  else if (class == 't')
8818334Speter    {
8918334Speter      if (TYPE_NAME (node))
9018334Speter	{
9118334Speter	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
9218334Speter	    fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
9318334Speter	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
9418334Speter		   && DECL_NAME (TYPE_NAME (node)))
9518334Speter	    fprintf (file, " %s",
9618334Speter		     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
9718334Speter	}
9818334Speter    }
9918334Speter  if (TREE_CODE (node) == IDENTIFIER_NODE)
10018334Speter    fprintf (file, " %s", IDENTIFIER_POINTER (node));
10190285Sobrien
10290285Sobrien  /* We might as well always print the value of an integer or real.  */
10318334Speter  if (TREE_CODE (node) == INTEGER_CST)
10418334Speter    {
10518334Speter      if (TREE_CONSTANT_OVERFLOW (node))
10618334Speter	fprintf (file, " overflow");
10718334Speter
10850617Sobrien      fprintf (file, " ");
10918334Speter      if (TREE_INT_CST_HIGH (node) == 0)
11050617Sobrien	fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
11118334Speter      else if (TREE_INT_CST_HIGH (node) == -1
11218334Speter	       && TREE_INT_CST_LOW (node) != 0)
11350617Sobrien	{
11450617Sobrien	  fprintf (file, "-");
11550617Sobrien	  fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
11690285Sobrien		   -TREE_INT_CST_LOW (node));
11750617Sobrien	}
11818334Speter      else
11950617Sobrien	fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
12018334Speter		 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
12118334Speter    }
12218334Speter  if (TREE_CODE (node) == REAL_CST)
12318334Speter    {
12418334Speter      REAL_VALUE_TYPE d;
12518334Speter
12618334Speter      if (TREE_OVERFLOW (node))
12718334Speter	fprintf (file, " overflow");
12818334Speter
12918334Speter#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
13018334Speter      d = TREE_REAL_CST (node);
13118334Speter      if (REAL_VALUE_ISINF (d))
13218334Speter	fprintf (file, " Inf");
13318334Speter      else if (REAL_VALUE_ISNAN (d))
13418334Speter	fprintf (file, " Nan");
13518334Speter      else
13618334Speter	{
13718334Speter	  char string[100];
13818334Speter
13918334Speter	  REAL_VALUE_TO_DECIMAL (d, "%e", string);
14018334Speter	  fprintf (file, " %s", string);
14118334Speter	}
14218334Speter#else
14318334Speter      {
14418334Speter	int i;
14518334Speter	unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
14618334Speter	fprintf (file, " 0x");
14718334Speter	for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
14818334Speter	  fprintf (file, "%02x", *p++);
14918334Speter	fprintf (file, "");
15018334Speter      }
15118334Speter#endif
15218334Speter    }
15318334Speter
15418334Speter  fprintf (file, ">");
15518334Speter}
15618334Speter
15718334Spetervoid
15818334Speterindent_to (file, column)
15918334Speter     FILE *file;
16018334Speter     int column;
16118334Speter{
16218334Speter  int i;
16318334Speter
16418334Speter  /* Since this is the long way, indent to desired column.  */
16518334Speter  if (column > 0)
16618334Speter    fprintf (file, "\n");
16718334Speter  for (i = 0; i < column; i++)
16818334Speter    fprintf (file, " ");
16918334Speter}
17018334Speter
17118334Speter/* Print the node NODE in full on file FILE, preceded by PREFIX,
17218334Speter   starting in column INDENT.  */
17318334Speter
17418334Spetervoid
17518334Speterprint_node (file, prefix, node, indent)
17618334Speter     FILE *file;
17752521Sobrien     const char *prefix;
17818334Speter     tree node;
17918334Speter     int indent;
18018334Speter{
18118334Speter  int hash;
18218334Speter  struct bucket *b;
18318334Speter  enum machine_mode mode;
18418334Speter  char class;
18518334Speter  int len;
18618334Speter  int first_rtl;
18718334Speter  int i;
18818334Speter
18918334Speter  if (node == 0)
19018334Speter    return;
19118334Speter
19218334Speter  class = TREE_CODE_CLASS (TREE_CODE (node));
19318334Speter
19418334Speter  /* Don't get too deep in nesting.  If the user wants to see deeper,
19518334Speter     it is easy to use the address of a lowest-level node
19618334Speter     as an argument in another call to debug_tree.  */
19718334Speter
19818334Speter  if (indent > 24)
19918334Speter    {
20018334Speter      print_node_brief (file, prefix, node, indent);
20118334Speter      return;
20218334Speter    }
20318334Speter
20418334Speter  if (indent > 8 && (class == 't' || class == 'd'))
20518334Speter    {
20618334Speter      print_node_brief (file, prefix, node, indent);
20718334Speter      return;
20818334Speter    }
20918334Speter
21050617Sobrien  /* It is unsafe to look at any other filds of an ERROR_MARK node.  */
21118334Speter  if (TREE_CODE (node) == ERROR_MARK)
21218334Speter    {
21318334Speter      print_node_brief (file, prefix, node, indent);
21418334Speter      return;
21518334Speter    }
21618334Speter
21750617Sobrien  hash = ((unsigned long) node) % HASH_SIZE;
21818334Speter
21918334Speter  /* If node is in the table, just mention its address.  */
22018334Speter  for (b = table[hash]; b; b = b->next)
22118334Speter    if (b->node == node)
22218334Speter      {
22318334Speter	print_node_brief (file, prefix, node, indent);
22418334Speter	return;
22518334Speter      }
22618334Speter
22718334Speter  /* Add this node to the table.  */
22890285Sobrien  b = (struct bucket *) permalloc (sizeof (struct bucket));
22918334Speter  b->node = node;
23018334Speter  b->next = table[hash];
23118334Speter  table[hash] = b;
23218334Speter
23318334Speter  /* Indent to the specified column, since this is the long form.  */
23418334Speter  indent_to (file, indent);
23518334Speter
23618334Speter  /* Print the slot this node is in, and its code, and address.  */
23718334Speter  fprintf (file, "%s <%s ", prefix, tree_code_name[(int) TREE_CODE (node)]);
23850617Sobrien  fprintf (file, HOST_PTR_PRINTF, (char *) node);
23918334Speter
24018334Speter  /* Print the name, if any.  */
24118334Speter  if (class == 'd')
24218334Speter    {
24318334Speter      if (DECL_NAME (node))
24418334Speter	fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
24518334Speter    }
24618334Speter  else if (class == 't')
24718334Speter    {
24818334Speter      if (TYPE_NAME (node))
24918334Speter	{
25018334Speter	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
25118334Speter	    fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
25218334Speter	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
25318334Speter		   && DECL_NAME (TYPE_NAME (node)))
25418334Speter	    fprintf (file, " %s",
25518334Speter		     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
25618334Speter	}
25718334Speter    }
25818334Speter  if (TREE_CODE (node) == IDENTIFIER_NODE)
25918334Speter    fprintf (file, " %s", IDENTIFIER_POINTER (node));
26018334Speter
26118334Speter  if (TREE_CODE (node) == INTEGER_CST)
26218334Speter    {
26318334Speter      if (indent <= 4)
26418334Speter	print_node_brief (file, "type", TREE_TYPE (node), indent + 4);
26518334Speter    }
26618334Speter  else
26718334Speter    {
26818334Speter      print_node (file, "type", TREE_TYPE (node), indent + 4);
26918334Speter      if (TREE_TYPE (node))
27018334Speter	indent_to (file, indent + 3);
27118334Speter    }
27218334Speter
27318334Speter  if (TREE_SIDE_EFFECTS (node))
27418334Speter    fputs (" side-effects", file);
27518334Speter  if (TREE_READONLY (node))
27618334Speter    fputs (" readonly", file);
27718334Speter  if (TREE_CONSTANT (node))
27818334Speter    fputs (" constant", file);
27918334Speter  if (TREE_ADDRESSABLE (node))
28018334Speter    fputs (" addressable", file);
28118334Speter  if (TREE_THIS_VOLATILE (node))
28218334Speter    fputs (" volatile", file);
28318334Speter  if (TREE_UNSIGNED (node))
28418334Speter    fputs (" unsigned", file);
28518334Speter  if (TREE_ASM_WRITTEN (node))
28618334Speter    fputs (" asm_written", file);
28718334Speter  if (TREE_USED (node))
28818334Speter    fputs (" used", file);
28990285Sobrien  if (TREE_NOTHROW (node))
29090285Sobrien    fputs (" nothrow", file);
29118334Speter  if (TREE_PUBLIC (node))
29218334Speter    fputs (" public", file);
29390285Sobrien  if (TREE_PRIVATE (node))
29490285Sobrien    fputs (" private", file);
29590285Sobrien  if (TREE_PROTECTED (node))
29690285Sobrien    fputs (" protected", file);
29718334Speter  if (TREE_STATIC (node))
29818334Speter    fputs (" static", file);
29990285Sobrien  if (TREE_DEPRECATED (node))
30090285Sobrien    fputs (" deprecated", file);
30118334Speter  if (TREE_LANG_FLAG_0 (node))
30218334Speter    fputs (" tree_0", file);
30318334Speter  if (TREE_LANG_FLAG_1 (node))
30418334Speter    fputs (" tree_1", file);
30518334Speter  if (TREE_LANG_FLAG_2 (node))
30618334Speter    fputs (" tree_2", file);
30718334Speter  if (TREE_LANG_FLAG_3 (node))
30818334Speter    fputs (" tree_3", file);
30918334Speter  if (TREE_LANG_FLAG_4 (node))
31018334Speter    fputs (" tree_4", file);
31118334Speter  if (TREE_LANG_FLAG_5 (node))
31218334Speter    fputs (" tree_5", file);
31318334Speter  if (TREE_LANG_FLAG_6 (node))
31418334Speter    fputs (" tree_6", file);
31518334Speter
31618334Speter  /* DECL_ nodes have additional attributes.  */
31718334Speter
31818334Speter  switch (TREE_CODE_CLASS (TREE_CODE (node)))
31918334Speter    {
32018334Speter    case 'd':
32118334Speter      mode = DECL_MODE (node);
32218334Speter
32318334Speter      if (DECL_IGNORED_P (node))
32418334Speter	fputs (" ignored", file);
32518334Speter      if (DECL_ABSTRACT (node))
32618334Speter	fputs (" abstract", file);
32718334Speter      if (DECL_IN_SYSTEM_HEADER (node))
32818334Speter	fputs (" in_system_header", file);
32918334Speter      if (DECL_COMMON (node))
33018334Speter	fputs (" common", file);
33118334Speter      if (DECL_EXTERNAL (node))
33218334Speter	fputs (" external", file);
33396287Sobrien      if (DECL_WEAK (node))
33496287Sobrien	fputs (" weak", file);
33590285Sobrien      if (DECL_REGISTER (node) && TREE_CODE (node) != FIELD_DECL
33690285Sobrien	  && TREE_CODE (node) != FUNCTION_DECL
33790285Sobrien	  && TREE_CODE (node) != LABEL_DECL)
33818334Speter	fputs (" regdecl", file);
33918334Speter      if (DECL_NONLOCAL (node))
34018334Speter	fputs (" nonlocal", file);
34118334Speter
34218334Speter      if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
34318334Speter	fputs (" suppress-debug", file);
34418334Speter
34590285Sobrien      if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
34690285Sobrien	fputs (" inline", file);
34718334Speter      if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
34818334Speter	fputs (" built-in", file);
34918334Speter      if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN_NONANSI (node))
35018334Speter	fputs (" built-in-nonansi", file);
35190285Sobrien      if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
35290285Sobrien	fputs (" no-static-chain", file);
35318334Speter
35490285Sobrien      if (TREE_CODE (node) == FIELD_DECL && DECL_PACKED (node))
35590285Sobrien	fputs (" packed", file);
35618334Speter      if (TREE_CODE (node) == FIELD_DECL && DECL_BIT_FIELD (node))
35718334Speter	fputs (" bit-field", file);
35890285Sobrien      if (TREE_CODE (node) == FIELD_DECL && DECL_NONADDRESSABLE_P (node))
35990285Sobrien	fputs (" nonaddressable", file);
36090285Sobrien
36118334Speter      if (TREE_CODE (node) == LABEL_DECL && DECL_TOO_LATE (node))
36218334Speter	fputs (" too-late", file);
36390285Sobrien      if (TREE_CODE (node) == LABEL_DECL && DECL_ERROR_ISSUED (node))
36490285Sobrien	fputs (" error-issued", file);
36590285Sobrien
36618334Speter      if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
36718334Speter	fputs (" in-text-section", file);
36818334Speter
36990285Sobrien      if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
37090285Sobrien	fputs (" transparent-union", file);
37190285Sobrien
37218334Speter      if (DECL_VIRTUAL_P (node))
37318334Speter	fputs (" virtual", file);
37418334Speter      if (DECL_DEFER_OUTPUT (node))
37518334Speter	fputs (" defer-output", file);
37618334Speter
37718334Speter      if (DECL_LANG_FLAG_0 (node))
37818334Speter	fputs (" decl_0", file);
37918334Speter      if (DECL_LANG_FLAG_1 (node))
38018334Speter	fputs (" decl_1", file);
38118334Speter      if (DECL_LANG_FLAG_2 (node))
38218334Speter	fputs (" decl_2", file);
38318334Speter      if (DECL_LANG_FLAG_3 (node))
38418334Speter	fputs (" decl_3", file);
38518334Speter      if (DECL_LANG_FLAG_4 (node))
38618334Speter	fputs (" decl_4", file);
38718334Speter      if (DECL_LANG_FLAG_5 (node))
38818334Speter	fputs (" decl_5", file);
38918334Speter      if (DECL_LANG_FLAG_6 (node))
39018334Speter	fputs (" decl_6", file);
39118334Speter      if (DECL_LANG_FLAG_7 (node))
39218334Speter	fputs (" decl_7", file);
39318334Speter
39490285Sobrien      fprintf (file, " %s", GET_MODE_NAME (mode));
39518334Speter      fprintf (file, " file %s line %d",
39618334Speter	       DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
39718334Speter
39818334Speter      print_node (file, "size", DECL_SIZE (node), indent + 4);
39990285Sobrien      print_node (file, "unit size", DECL_SIZE_UNIT (node), indent + 4);
40090285Sobrien
40190285Sobrien      if (TREE_CODE (node) != FUNCTION_DECL
40290285Sobrien	  || DECL_INLINE (node) || DECL_BUILT_IN (node))
40390285Sobrien	indent_to (file, indent + 3);
40490285Sobrien
40518334Speter      if (TREE_CODE (node) != FUNCTION_DECL)
40690285Sobrien	{
40790285Sobrien	  if (DECL_USER_ALIGN (node))
40890285Sobrien	    fprintf (file, " user");
40990285Sobrien
41090285Sobrien	  fprintf (file, " align %d", DECL_ALIGN (node));
41190285Sobrien	  if (TREE_CODE (node) == FIELD_DECL)
41290285Sobrien	    {
41390285Sobrien	      fprintf (file, " offset_align ");
41490285Sobrien	      fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
41590285Sobrien		       DECL_OFFSET_ALIGN (node));
41690285Sobrien	    }
41790285Sobrien	}
41818334Speter      else if (DECL_BUILT_IN (node))
41990285Sobrien	{
42090285Sobrien	  if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
42190285Sobrien	    fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node));
42290285Sobrien	  else
42390285Sobrien	    fprintf (file, " built-in %s:%s",
42490285Sobrien		     built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)],
42590285Sobrien		     built_in_names[(int) DECL_FUNCTION_CODE (node)]);
42690285Sobrien	}
42790285Sobrien
42890285Sobrien      if (DECL_POINTER_ALIAS_SET_KNOWN_P (node))
42990285Sobrien	{
43090285Sobrien	  fprintf (file, " alias set ");
43190285Sobrien	  fprintf (file, HOST_WIDE_INT_PRINT_DEC,
43290285Sobrien		   DECL_POINTER_ALIAS_SET (node));
43390285Sobrien	}
43490285Sobrien
43518334Speter      if (TREE_CODE (node) == FIELD_DECL)
43690285Sobrien	{
43790285Sobrien	  print_node (file, "offset", DECL_FIELD_OFFSET (node), indent + 4);
43890285Sobrien	  print_node (file, "bit offset", DECL_FIELD_BIT_OFFSET (node),
43990285Sobrien		      indent + 4);
44090285Sobrien	}
44190285Sobrien
44218334Speter      print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
44390285Sobrien      print_node_brief (file, "attributes",
44490285Sobrien			DECL_ATTRIBUTES (node), indent + 4);
44518334Speter      print_node_brief (file, "abstract_origin",
44618334Speter			DECL_ABSTRACT_ORIGIN (node), indent + 4);
44718334Speter
44818334Speter      print_node (file, "arguments", DECL_ARGUMENTS (node), indent + 4);
44990285Sobrien      print_node (file, "result", DECL_RESULT_FLD (node), indent + 4);
45018334Speter      print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4);
45118334Speter
45290285Sobrien      (*lang_hooks.print_decl) (file, node, indent);
45318334Speter
45490285Sobrien      if (DECL_RTL_SET_P (node))
45518334Speter	{
45618334Speter	  indent_to (file, indent + 4);
45718334Speter	  print_rtl (file, DECL_RTL (node));
45818334Speter	}
45918334Speter
46090285Sobrien      if (TREE_CODE (node) == PARM_DECL)
46118334Speter	{
46290285Sobrien	  print_node (file, "arg-type", DECL_ARG_TYPE (node), indent + 4);
46390285Sobrien	  print_node (file, "arg-type-as-written",
46490285Sobrien		      DECL_ARG_TYPE_AS_WRITTEN (node), indent + 4);
46590285Sobrien
46690285Sobrien	  if (DECL_INCOMING_RTL (node) != 0)
46718334Speter	    {
46890285Sobrien	      indent_to (file, indent + 4);
46918334Speter	      fprintf (file, "incoming-rtl ");
47018334Speter	      print_rtl (file, DECL_INCOMING_RTL (node));
47118334Speter	    }
47218334Speter	}
47390285Sobrien      else if (TREE_CODE (node) == FUNCTION_DECL
47490285Sobrien	       && DECL_SAVED_INSNS (node) != 0)
47590285Sobrien	{
47690285Sobrien	  indent_to (file, indent + 4);
47790285Sobrien	  fprintf (file, "saved-insns ");
47890285Sobrien	  fprintf (file, HOST_PTR_PRINTF, (char *) DECL_SAVED_INSNS (node));
47990285Sobrien	}
48018334Speter
48118334Speter      /* Print the decl chain only if decl is at second level.  */
48218334Speter      if (indent == 4)
48318334Speter	print_node (file, "chain", TREE_CHAIN (node), indent + 4);
48418334Speter      else
48518334Speter	print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
48618334Speter      break;
48718334Speter
48818334Speter    case 't':
48990285Sobrien      /* The no-force-blk flag is used for different things in
49090285Sobrien	 different types.  */
49190285Sobrien      if ((TREE_CODE (node) == RECORD_TYPE
49290285Sobrien	   || TREE_CODE (node) == UNION_TYPE
49390285Sobrien	   || TREE_CODE (node) == QUAL_UNION_TYPE)
49490285Sobrien	  && TYPE_NO_FORCE_BLK (node))
49518334Speter	fputs (" no-force-blk", file);
49690285Sobrien      else if (TREE_CODE (node) == INTEGER_TYPE
49790285Sobrien	       && TYPE_IS_SIZETYPE (node))
49890285Sobrien	fputs (" sizetype", file);
49990285Sobrien      else if (TREE_CODE (node) == FUNCTION_TYPE
50090285Sobrien	       && TYPE_RETURNS_STACK_DEPRESSED (node))
50190285Sobrien	fputs (" returns-stack-depressed", file);
50290285Sobrien
50318334Speter      if (TYPE_STRING_FLAG (node))
50418334Speter	fputs (" string-flag", file);
50518334Speter      if (TYPE_NEEDS_CONSTRUCTING (node))
50618334Speter	fputs (" needs-constructing", file);
50790285Sobrien
50890285Sobrien      /* The transparent-union flag is used for different things in
50990285Sobrien	 different nodes.  */
51090285Sobrien      if (TREE_CODE (node) == UNION_TYPE && TYPE_TRANSPARENT_UNION (node))
51118334Speter	fputs (" transparent-union", file);
51290285Sobrien      else if (TREE_CODE (node) == ARRAY_TYPE
51390285Sobrien	       && TYPE_NONALIASED_COMPONENT (node))
51490285Sobrien	fputs (" nonaliased-component", file);
51590285Sobrien      else if (TREE_CODE (node) == FUNCTION_TYPE
51690285Sobrien	       && TYPE_AMBIENT_BOUNDEDNESS (node))
51790285Sobrien	fputs (" ambient-boundedness", file);
51890285Sobrien
51918334Speter      if (TYPE_PACKED (node))
52018334Speter	fputs (" packed", file);
52118334Speter
52218334Speter      if (TYPE_LANG_FLAG_0 (node))
52318334Speter	fputs (" type_0", file);
52418334Speter      if (TYPE_LANG_FLAG_1 (node))
52518334Speter	fputs (" type_1", file);
52618334Speter      if (TYPE_LANG_FLAG_2 (node))
52718334Speter	fputs (" type_2", file);
52818334Speter      if (TYPE_LANG_FLAG_3 (node))
52918334Speter	fputs (" type_3", file);
53018334Speter      if (TYPE_LANG_FLAG_4 (node))
53118334Speter	fputs (" type_4", file);
53218334Speter      if (TYPE_LANG_FLAG_5 (node))
53318334Speter	fputs (" type_5", file);
53418334Speter      if (TYPE_LANG_FLAG_6 (node))
53518334Speter	fputs (" type_6", file);
53618334Speter
53718334Speter      mode = TYPE_MODE (node);
53890285Sobrien      fprintf (file, " %s", GET_MODE_NAME (mode));
53918334Speter
54018334Speter      print_node (file, "size", TYPE_SIZE (node), indent + 4);
54190285Sobrien      print_node (file, "unit size", TYPE_SIZE_UNIT (node), indent + 4);
54218334Speter      indent_to (file, indent + 3);
54318334Speter
54490285Sobrien      if (TYPE_USER_ALIGN (node))
54590285Sobrien	fprintf (file, " user");
54690285Sobrien
54718334Speter      fprintf (file, " align %d", TYPE_ALIGN (node));
54818334Speter      fprintf (file, " symtab %d", TYPE_SYMTAB_ADDRESS (node));
54990285Sobrien      fprintf (file, " alias set ");
55090285Sobrien      fprintf (file, HOST_WIDE_INT_PRINT_DEC, TYPE_ALIAS_SET (node));
55118334Speter
55218334Speter      print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
55318334Speter
55490285Sobrien      if (INTEGRAL_TYPE_P (node) || TREE_CODE (node) == REAL_TYPE)
55518334Speter	{
55618334Speter	  fprintf (file, " precision %d", TYPE_PRECISION (node));
55790285Sobrien	  print_node_brief (file, "min", TYPE_MIN_VALUE (node), indent + 4);
55890285Sobrien	  print_node_brief (file, "max", TYPE_MAX_VALUE (node), indent + 4);
55918334Speter	}
56090285Sobrien
56190285Sobrien      if (TREE_CODE (node) == ENUMERAL_TYPE)
56290285Sobrien	print_node (file, "values", TYPE_VALUES (node), indent + 4);
56390285Sobrien      else if (TREE_CODE (node) == ARRAY_TYPE || TREE_CODE (node) == SET_TYPE)
56490285Sobrien	print_node (file, "domain", TYPE_DOMAIN (node), indent + 4);
56518334Speter      else if (TREE_CODE (node) == RECORD_TYPE
56618334Speter	       || TREE_CODE (node) == UNION_TYPE
56718334Speter	       || TREE_CODE (node) == QUAL_UNION_TYPE)
56818334Speter	print_node (file, "fields", TYPE_FIELDS (node), indent + 4);
56990285Sobrien      else if (TREE_CODE (node) == FUNCTION_TYPE
57090285Sobrien	       || TREE_CODE (node) == METHOD_TYPE)
57118334Speter	{
57218334Speter	  if (TYPE_METHOD_BASETYPE (node))
57390285Sobrien	    print_node_brief (file, "method basetype",
57490285Sobrien			      TYPE_METHOD_BASETYPE (node), indent + 4);
57518334Speter	  print_node (file, "arg-types", TYPE_ARG_TYPES (node), indent + 4);
57618334Speter	}
57790285Sobrien      else if (TREE_CODE (node) == OFFSET_TYPE)
57890285Sobrien	print_node_brief (file, "basetype", TYPE_OFFSET_BASETYPE (node),
57990285Sobrien			  indent + 4);
58090285Sobrien
58118334Speter      if (TYPE_CONTEXT (node))
58218334Speter	print_node_brief (file, "context", TYPE_CONTEXT (node), indent + 4);
58318334Speter
58490285Sobrien      (*lang_hooks.print_type) (file, node, indent);
58518334Speter
58618334Speter      if (TYPE_POINTER_TO (node) || TREE_CHAIN (node))
58718334Speter	indent_to (file, indent + 3);
58890285Sobrien
58990285Sobrien      print_node_brief (file, "pointer_to_this", TYPE_POINTER_TO (node),
59090285Sobrien			indent + 4);
59190285Sobrien      print_node_brief (file, "reference_to_this", TYPE_REFERENCE_TO (node),
59290285Sobrien			indent + 4);
59318334Speter      print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
59418334Speter      break;
59518334Speter
59618334Speter    case 'b':
59718334Speter      print_node (file, "vars", BLOCK_VARS (node), indent + 4);
59818334Speter      print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node), indent + 4);
59918334Speter      print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4);
60018334Speter      print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
60118334Speter      print_node (file, "abstract_origin",
60218334Speter		  BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
60352521Sobrien      break;
60418334Speter
60518334Speter    case 'e':
60618334Speter    case '<':
60718334Speter    case '1':
60818334Speter    case '2':
60918334Speter    case 'r':
61018334Speter    case 's':
61150617Sobrien      if (TREE_CODE (node) == BIND_EXPR)
61218334Speter	{
61318334Speter	  print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4);
61418334Speter	  print_node (file, "body", TREE_OPERAND (node, 1), indent + 4);
61518334Speter	  print_node (file, "block", TREE_OPERAND (node, 2), indent + 4);
61652521Sobrien	  break;
61718334Speter	}
61818334Speter
61990285Sobrien      len = TREE_CODE_LENGTH (TREE_CODE (node));
62090285Sobrien
62150617Sobrien      /* Some nodes contain rtx's, not trees,
62218334Speter	 after a certain point.  Print the rtx's as rtx's.  */
62350617Sobrien      first_rtl = first_rtl_op (TREE_CODE (node));
62490285Sobrien
62518334Speter      for (i = 0; i < len; i++)
62618334Speter	{
62718334Speter	  if (i >= first_rtl)
62818334Speter	    {
62918334Speter	      indent_to (file, indent + 4);
63018334Speter	      fprintf (file, "rtl %d ", i);
63118334Speter	      if (TREE_OPERAND (node, i))
63218334Speter		print_rtl (file, (struct rtx_def *) TREE_OPERAND (node, i));
63318334Speter	      else
63418334Speter		fprintf (file, "(nil)");
63518334Speter	      fprintf (file, "\n");
63618334Speter	    }
63718334Speter	  else
63818334Speter	    {
63918334Speter	      char temp[10];
64018334Speter
64118334Speter	      sprintf (temp, "arg %d", i);
64218334Speter	      print_node (file, temp, TREE_OPERAND (node, i), indent + 4);
64318334Speter	    }
64418334Speter	}
64550617Sobrien
64650617Sobrien      if (TREE_CODE (node) == EXPR_WITH_FILE_LOCATION)
64750617Sobrien	{
64850617Sobrien	  indent_to (file, indent+4);
64950617Sobrien          fprintf (file, "%s:%d:%d",
65050617Sobrien		   (EXPR_WFL_FILENAME_NODE (node ) ?
65150617Sobrien		    EXPR_WFL_FILENAME (node) : "(no file info)"),
65250617Sobrien		   EXPR_WFL_LINENO (node), EXPR_WFL_COLNO (node));
65350617Sobrien	}
65490285Sobrien      print_node (file, "chain", TREE_CHAIN (node), indent + 4);
65518334Speter      break;
65618334Speter
65718334Speter    case 'c':
65818334Speter    case 'x':
65918334Speter      switch (TREE_CODE (node))
66018334Speter	{
66118334Speter	case INTEGER_CST:
66218334Speter	  if (TREE_CONSTANT_OVERFLOW (node))
66318334Speter	    fprintf (file, " overflow");
66418334Speter
66550617Sobrien	  fprintf (file, " ");
66618334Speter	  if (TREE_INT_CST_HIGH (node) == 0)
66750617Sobrien	    fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
66818334Speter		     TREE_INT_CST_LOW (node));
66918334Speter	  else if (TREE_INT_CST_HIGH (node) == -1
67018334Speter		   && TREE_INT_CST_LOW (node) != 0)
67150617Sobrien	    {
67250617Sobrien	      fprintf (file, "-");
67350617Sobrien	      fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
67450617Sobrien		       -TREE_INT_CST_LOW (node));
67550617Sobrien	    }
67618334Speter	  else
67750617Sobrien	    fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
67818334Speter		     TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
67918334Speter	  break;
68018334Speter
68118334Speter	case REAL_CST:
68218334Speter	  {
68318334Speter	    REAL_VALUE_TYPE d;
68418334Speter
68518334Speter	    if (TREE_OVERFLOW (node))
68618334Speter	      fprintf (file, " overflow");
68718334Speter
68818334Speter#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
68918334Speter	    d = TREE_REAL_CST (node);
69018334Speter	    if (REAL_VALUE_ISINF (d))
69118334Speter	      fprintf (file, " Inf");
69218334Speter	    else if (REAL_VALUE_ISNAN (d))
69318334Speter	      fprintf (file, " Nan");
69418334Speter	    else
69518334Speter	      {
69618334Speter		char string[100];
69718334Speter
69818334Speter		REAL_VALUE_TO_DECIMAL (d, "%e", string);
69918334Speter		fprintf (file, " %s", string);
70018334Speter	      }
70118334Speter#else
70218334Speter	    {
70318334Speter	      int i;
70418334Speter	      unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
70518334Speter	      fprintf (file, " 0x");
70618334Speter	      for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
70718334Speter		fprintf (file, "%02x", *p++);
70818334Speter	      fprintf (file, "");
70918334Speter	    }
71018334Speter#endif
71118334Speter	  }
71218334Speter	  break;
71318334Speter
71496287Sobrien	case VECTOR_CST:
71596287Sobrien	  {
71696287Sobrien	    tree vals = TREE_VECTOR_CST_ELTS (node);
71796287Sobrien	    char buf[10];
71896287Sobrien	    tree link;
71996287Sobrien	    int i;
72096287Sobrien
72196287Sobrien	    i = 0;
72296287Sobrien	    for (link = vals; link; link = TREE_CHAIN (link), ++i)
72396287Sobrien	      {
72496287Sobrien		sprintf (buf, "elt%d: ", i);
72596287Sobrien		print_node (file, buf, TREE_VALUE (link), indent + 4);
72696287Sobrien	      }
72796287Sobrien	  }
72896287Sobrien	  break;
72996287Sobrien
73018334Speter	case COMPLEX_CST:
73118334Speter	  print_node (file, "real", TREE_REALPART (node), indent + 4);
73218334Speter	  print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
73318334Speter	  break;
73418334Speter
73518334Speter	case STRING_CST:
73618334Speter	  fprintf (file, " \"%s\"", TREE_STRING_POINTER (node));
73718334Speter	  /* Print the chain at second level.  */
73818334Speter	  if (indent == 4)
73918334Speter	    print_node (file, "chain", TREE_CHAIN (node), indent + 4);
74018334Speter	  else
74118334Speter	    print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
74218334Speter	  break;
74318334Speter
74418334Speter	case IDENTIFIER_NODE:
74590285Sobrien	  (*lang_hooks.print_identifier) (file, node, indent);
74618334Speter	  break;
74718334Speter
74818334Speter	case TREE_LIST:
74918334Speter	  print_node (file, "purpose", TREE_PURPOSE (node), indent + 4);
75018334Speter	  print_node (file, "value", TREE_VALUE (node), indent + 4);
75118334Speter	  print_node (file, "chain", TREE_CHAIN (node), indent + 4);
75218334Speter	  break;
75318334Speter
75418334Speter	case TREE_VEC:
75518334Speter	  len = TREE_VEC_LENGTH (node);
75618334Speter	  for (i = 0; i < len; i++)
75718334Speter	    if (TREE_VEC_ELT (node, i))
75818334Speter	      {
75918334Speter		char temp[10];
76018334Speter		sprintf (temp, "elt %d", i);
76118334Speter		indent_to (file, indent + 4);
76218334Speter		print_node_brief (file, temp, TREE_VEC_ELT (node, i), 0);
76318334Speter	      }
76418334Speter	  break;
76518334Speter
76650617Sobrien	default:
76750617Sobrien	  if (TREE_CODE_CLASS (TREE_CODE (node)) == 'x')
76890285Sobrien	    (*lang_hooks.print_xnode) (file, node, indent);
76950617Sobrien	  break;
77018334Speter	}
77118334Speter
77218334Speter      break;
77318334Speter    }
77418334Speter
77518334Speter  fprintf (file, ">");
77618334Speter}
777