1132727Skan/* Prints out tree in human readable form - GCC
290285Sobrien   Copyright (C) 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3169699Skan   2001, 2002, 2003, 2004, 2005 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
19169699SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169699Skan02110-1301, USA.  */
2118334Speter
2218334Speter
2318334Speter#include "config.h"
2450617Sobrien#include "system.h"
25132727Skan#include "coretypes.h"
26132727Skan#include "tm.h"
2718334Speter#include "tree.h"
28117404Skan#include "real.h"
2990285Sobrien#include "ggc.h"
3090285Sobrien#include "langhooks.h"
31169699Skan#include "tree-iterator.h"
3218334Speter
3318334Speter/* Define the hash table of nodes already seen.
3418334Speter   Such nodes are not repeated; brief cross-references are used.  */
3518334Speter
3618334Speter#define HASH_SIZE 37
3718334Speter
3818334Speterstruct bucket
3918334Speter{
4018334Speter  tree node;
4118334Speter  struct bucket *next;
4218334Speter};
4318334Speter
4418334Speterstatic struct bucket **table;
4518334Speter
4618334Speter/* Print the node NODE on standard error, for debugging.
4718334Speter   Most nodes referred to by this one are printed recursively
4818334Speter   down to a depth of six.  */
4918334Speter
5018334Spetervoid
51132727Skandebug_tree (tree node)
5218334Speter{
53169699Skan  table = XCNEWVEC (struct bucket *, HASH_SIZE);
5418334Speter  print_node (stderr, "", node, 0);
55132727Skan  free (table);
5618334Speter  table = 0;
57132727Skan  putc ('\n', stderr);
5818334Speter}
5918334Speter
60169699Skan/* Print PREFIX and ADDR to FILE.  */
61169699Skanvoid
62169699Skandump_addr (FILE *file, const char *prefix, void *addr)
63169699Skan{
64169699Skan  if (flag_dump_noaddr || flag_dump_unnumbered)
65169699Skan    fprintf (file, "%s#", prefix);
66169699Skan  else
67169699Skan    fprintf (file, "%s%p", prefix, addr);
68169699Skan}
69169699Skan
7018334Speter/* Print a node in brief fashion, with just the code, address and name.  */
7118334Speter
7218334Spetervoid
73132727Skanprint_node_brief (FILE *file, const char *prefix, tree node, int indent)
7418334Speter{
75169699Skan  enum tree_code_class class;
7618334Speter
7718334Speter  if (node == 0)
7818334Speter    return;
7918334Speter
8018334Speter  class = TREE_CODE_CLASS (TREE_CODE (node));
8118334Speter
8218334Speter  /* Always print the slot this node is in, and its code, address and
8318334Speter     name if any.  */
8418334Speter  if (indent > 0)
8518334Speter    fprintf (file, " ");
86169699Skan  fprintf (file, "%s <%s", prefix, tree_code_name[(int) TREE_CODE (node)]);
87169699Skan  dump_addr (file, " ", node);
8818334Speter
89169699Skan  if (class == tcc_declaration)
9018334Speter    {
9118334Speter      if (DECL_NAME (node))
9218334Speter	fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
93169699Skan      else if (TREE_CODE (node) == LABEL_DECL
94169699Skan	       && LABEL_DECL_UID (node) != -1)
95169699Skan	fprintf (file, " L." HOST_WIDE_INT_PRINT_DEC, LABEL_DECL_UID (node));
96169699Skan      else
97169699Skan	fprintf (file, " %c.%u", TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
98169699Skan		 DECL_UID (node));
9918334Speter    }
100169699Skan  else if (class == tcc_type)
10118334Speter    {
10218334Speter      if (TYPE_NAME (node))
10318334Speter	{
10418334Speter	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
10518334Speter	    fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
10618334Speter	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
10718334Speter		   && DECL_NAME (TYPE_NAME (node)))
10818334Speter	    fprintf (file, " %s",
10918334Speter		     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
11018334Speter	}
11118334Speter    }
11218334Speter  if (TREE_CODE (node) == IDENTIFIER_NODE)
11318334Speter    fprintf (file, " %s", IDENTIFIER_POINTER (node));
11490285Sobrien
11590285Sobrien  /* We might as well always print the value of an integer or real.  */
11618334Speter  if (TREE_CODE (node) == INTEGER_CST)
11718334Speter    {
11818334Speter      if (TREE_CONSTANT_OVERFLOW (node))
11918334Speter	fprintf (file, " overflow");
12018334Speter
12150617Sobrien      fprintf (file, " ");
12218334Speter      if (TREE_INT_CST_HIGH (node) == 0)
12350617Sobrien	fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
12418334Speter      else if (TREE_INT_CST_HIGH (node) == -1
12518334Speter	       && TREE_INT_CST_LOW (node) != 0)
126132727Skan	fprintf (file, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
127132727Skan		 -TREE_INT_CST_LOW (node));
12818334Speter      else
12950617Sobrien	fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
13018334Speter		 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
13118334Speter    }
13218334Speter  if (TREE_CODE (node) == REAL_CST)
13318334Speter    {
13418334Speter      REAL_VALUE_TYPE d;
13518334Speter
13618334Speter      if (TREE_OVERFLOW (node))
13718334Speter	fprintf (file, " overflow");
13818334Speter
13918334Speter      d = TREE_REAL_CST (node);
14018334Speter      if (REAL_VALUE_ISINF (d))
141169699Skan	fprintf (file,  REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
14218334Speter      else if (REAL_VALUE_ISNAN (d))
14318334Speter	fprintf (file, " Nan");
14418334Speter      else
14518334Speter	{
146117404Skan	  char string[60];
147117404Skan	  real_to_decimal (string, &d, sizeof (string), 0, 1);
14818334Speter	  fprintf (file, " %s", string);
14918334Speter	}
15018334Speter    }
15118334Speter
15218334Speter  fprintf (file, ">");
15318334Speter}
15418334Speter
15518334Spetervoid
156132727Skanindent_to (FILE *file, int column)
15718334Speter{
15818334Speter  int i;
15918334Speter
16018334Speter  /* Since this is the long way, indent to desired column.  */
16118334Speter  if (column > 0)
16218334Speter    fprintf (file, "\n");
16318334Speter  for (i = 0; i < column; i++)
16418334Speter    fprintf (file, " ");
16518334Speter}
16618334Speter
16718334Speter/* Print the node NODE in full on file FILE, preceded by PREFIX,
16818334Speter   starting in column INDENT.  */
16918334Speter
17018334Spetervoid
171132727Skanprint_node (FILE *file, const char *prefix, tree node, int indent)
17218334Speter{
17318334Speter  int hash;
17418334Speter  struct bucket *b;
17518334Speter  enum machine_mode mode;
176169699Skan  enum tree_code_class class;
17718334Speter  int len;
17818334Speter  int i;
179169699Skan  expanded_location xloc;
180169699Skan  enum tree_code code;
18118334Speter
18218334Speter  if (node == 0)
18318334Speter    return;
184169699Skan
185169699Skan  code = TREE_CODE (node);
186169699Skan  class = TREE_CODE_CLASS (code);
18718334Speter
18818334Speter  /* Don't get too deep in nesting.  If the user wants to see deeper,
18918334Speter     it is easy to use the address of a lowest-level node
19018334Speter     as an argument in another call to debug_tree.  */
19118334Speter
19218334Speter  if (indent > 24)
19318334Speter    {
19418334Speter      print_node_brief (file, prefix, node, indent);
19518334Speter      return;
19618334Speter    }
19718334Speter
198169699Skan  if (indent > 8 && (class == tcc_type || class == tcc_declaration))
19918334Speter    {
20018334Speter      print_node_brief (file, prefix, node, indent);
20118334Speter      return;
20218334Speter    }
20318334Speter
204132727Skan  /* It is unsafe to look at any other fields of an ERROR_MARK node.  */
20518334Speter  if (TREE_CODE (node) == ERROR_MARK)
20618334Speter    {
20718334Speter      print_node_brief (file, prefix, node, indent);
20818334Speter      return;
20918334Speter    }
21018334Speter
21150617Sobrien  hash = ((unsigned long) node) % HASH_SIZE;
21218334Speter
21318334Speter  /* If node is in the table, just mention its address.  */
21418334Speter  for (b = table[hash]; b; b = b->next)
21518334Speter    if (b->node == node)
21618334Speter      {
21718334Speter	print_node_brief (file, prefix, node, indent);
21818334Speter	return;
21918334Speter      }
22018334Speter
22118334Speter  /* Add this node to the table.  */
222169699Skan  b = XNEW (struct bucket);
22318334Speter  b->node = node;
22418334Speter  b->next = table[hash];
22518334Speter  table[hash] = b;
22618334Speter
22718334Speter  /* Indent to the specified column, since this is the long form.  */
22818334Speter  indent_to (file, indent);
22918334Speter
23018334Speter  /* Print the slot this node is in, and its code, and address.  */
231169699Skan  fprintf (file, "%s <%s", prefix, tree_code_name[(int) TREE_CODE (node)]);
232169699Skan  dump_addr (file, " ", node);
23318334Speter
23418334Speter  /* Print the name, if any.  */
235169699Skan  if (class == tcc_declaration)
23618334Speter    {
23718334Speter      if (DECL_NAME (node))
23818334Speter	fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
239169699Skan      else if (TREE_CODE (node) == LABEL_DECL
240169699Skan	       && LABEL_DECL_UID (node) != -1)
241169699Skan	fprintf (file, " L." HOST_WIDE_INT_PRINT_DEC, LABEL_DECL_UID (node));
242169699Skan      else
243169699Skan	fprintf (file, " %c.%u", TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
244169699Skan		 DECL_UID (node));
24518334Speter    }
246169699Skan  else if (class == tcc_type)
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
273169699Skan  if (!TYPE_P (node) && TREE_SIDE_EFFECTS (node))
27418334Speter    fputs (" side-effects", file);
275169699Skan
276169699Skan  if (TYPE_P (node) ? TYPE_READONLY (node) : TREE_READONLY (node))
27718334Speter    fputs (" readonly", file);
278169699Skan  if (!TYPE_P (node) && TREE_CONSTANT (node))
27918334Speter    fputs (" constant", file);
280169699Skan  else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node))
281169699Skan    fputs (" sizes-gimplified", file);
282169699Skan
283169699Skan  if (TREE_INVARIANT (node))
284169699Skan    fputs (" invariant", file);
28518334Speter  if (TREE_ADDRESSABLE (node))
28618334Speter    fputs (" addressable", file);
28718334Speter  if (TREE_THIS_VOLATILE (node))
28818334Speter    fputs (" volatile", file);
28918334Speter  if (TREE_ASM_WRITTEN (node))
29018334Speter    fputs (" asm_written", file);
29118334Speter  if (TREE_USED (node))
29218334Speter    fputs (" used", file);
29390285Sobrien  if (TREE_NOTHROW (node))
294132727Skan    fputs (TYPE_P (node) ? " align-ok" : " nothrow", file);
29518334Speter  if (TREE_PUBLIC (node))
29618334Speter    fputs (" public", file);
29790285Sobrien  if (TREE_PRIVATE (node))
29890285Sobrien    fputs (" private", file);
29990285Sobrien  if (TREE_PROTECTED (node))
30090285Sobrien    fputs (" protected", file);
30118334Speter  if (TREE_STATIC (node))
30218334Speter    fputs (" static", file);
30390285Sobrien  if (TREE_DEPRECATED (node))
30490285Sobrien    fputs (" deprecated", file);
305260014Spfg  /* APPLE LOCAL begin "unavailable" attribute (Radar 2809697) */
306260014Spfg  if (TREE_UNAVAILABLE (node))
307260014Spfg    fputs (" unavailable", file);
308260014Spfg  /* APPLE LOCAL end "unavailable" attribute (Radar 2809697) */
309169699Skan  if (TREE_VISITED (node))
310169699Skan    fputs (" visited", file);
31118334Speter  if (TREE_LANG_FLAG_0 (node))
31218334Speter    fputs (" tree_0", file);
31318334Speter  if (TREE_LANG_FLAG_1 (node))
31418334Speter    fputs (" tree_1", file);
31518334Speter  if (TREE_LANG_FLAG_2 (node))
31618334Speter    fputs (" tree_2", file);
31718334Speter  if (TREE_LANG_FLAG_3 (node))
31818334Speter    fputs (" tree_3", file);
31918334Speter  if (TREE_LANG_FLAG_4 (node))
32018334Speter    fputs (" tree_4", file);
32118334Speter  if (TREE_LANG_FLAG_5 (node))
32218334Speter    fputs (" tree_5", file);
32318334Speter  if (TREE_LANG_FLAG_6 (node))
32418334Speter    fputs (" tree_6", file);
32518334Speter
32618334Speter  /* DECL_ nodes have additional attributes.  */
32718334Speter
32818334Speter  switch (TREE_CODE_CLASS (TREE_CODE (node)))
32918334Speter    {
330169699Skan    case tcc_declaration:
331169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
332169699Skan	{
333169699Skan	  if (DECL_UNSIGNED (node))
334169699Skan	    fputs (" unsigned", file);
335169699Skan	  if (DECL_IGNORED_P (node))
336169699Skan	    fputs (" ignored", file);
337169699Skan	  if (DECL_ABSTRACT (node))
338169699Skan	    fputs (" abstract", file);
339169699Skan	  if (DECL_EXTERNAL (node))
340169699Skan	    fputs (" external", file);
341169699Skan	  if (DECL_NONLOCAL (node))
342169699Skan	    fputs (" nonlocal", file);
343169699Skan	}
344169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
345169699Skan	{
346169699Skan	  if (DECL_WEAK (node))
347169699Skan	    fputs (" weak", file);
348169699Skan	  if (DECL_IN_SYSTEM_HEADER (node))
349169699Skan	    fputs (" in_system_header", file);
350169699Skan	}
351169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)
352169699Skan	  && TREE_CODE (node) != LABEL_DECL
35390285Sobrien	  && TREE_CODE (node) != FUNCTION_DECL
354169699Skan	  && DECL_REGISTER (node))
35518334Speter	fputs (" regdecl", file);
35618334Speter
35718334Speter      if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
35818334Speter	fputs (" suppress-debug", file);
35918334Speter
360132727Skan      if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
361132727Skan	fputs (DECL_DECLARED_INLINE_P (node) ? " inline" : " autoinline", file);
36218334Speter      if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
36318334Speter	fputs (" built-in", file);
36490285Sobrien      if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
36590285Sobrien	fputs (" no-static-chain", file);
36618334Speter
36790285Sobrien      if (TREE_CODE (node) == FIELD_DECL && DECL_PACKED (node))
36890285Sobrien	fputs (" packed", file);
36918334Speter      if (TREE_CODE (node) == FIELD_DECL && DECL_BIT_FIELD (node))
37018334Speter	fputs (" bit-field", file);
37190285Sobrien      if (TREE_CODE (node) == FIELD_DECL && DECL_NONADDRESSABLE_P (node))
37290285Sobrien	fputs (" nonaddressable", file);
37390285Sobrien
37490285Sobrien      if (TREE_CODE (node) == LABEL_DECL && DECL_ERROR_ISSUED (node))
37590285Sobrien	fputs (" error-issued", file);
37690285Sobrien
37718334Speter      if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
37818334Speter	fputs (" in-text-section", file);
379169699Skan      if (TREE_CODE (node) == VAR_DECL && DECL_COMMON (node))
380169699Skan	fputs (" common", file);
381169699Skan      if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL_P (node))
382169699Skan	{
383169699Skan	  enum tls_model kind = DECL_TLS_MODEL (node);
384169699Skan	  switch (kind)
385169699Skan	    {
386169699Skan	      case TLS_MODEL_GLOBAL_DYNAMIC:
387169699Skan		fputs (" tls-global-dynamic", file);
388169699Skan		break;
389169699Skan	      case TLS_MODEL_LOCAL_DYNAMIC:
390169699Skan		fputs (" tls-local-dynamic", file);
391169699Skan		break;
392169699Skan	      case TLS_MODEL_INITIAL_EXEC:
393169699Skan		fputs (" tls-initial-exec", file);
394169699Skan		break;
395169699Skan	      case TLS_MODEL_LOCAL_EXEC:
396169699Skan		fputs (" tls-local-exec", file);
397169699Skan		break;
398169699Skan	      default:
399169699Skan		gcc_unreachable ();
400169699Skan	    }
401169699Skan	}
40218334Speter
403169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
404169699Skan	{
405169699Skan	  if (DECL_VIRTUAL_P (node))
406169699Skan	    fputs (" virtual", file);
407169699Skan	  if (DECL_PRESERVE_P (node))
408259661Spfg	    fputs (" preserve", file);
409169699Skan	  if (DECL_LANG_FLAG_0 (node))
410169699Skan	    fputs (" decl_0", file);
411169699Skan	  if (DECL_LANG_FLAG_1 (node))
412169699Skan	    fputs (" decl_1", file);
413169699Skan	  if (DECL_LANG_FLAG_2 (node))
414169699Skan	    fputs (" decl_2", file);
415169699Skan	  if (DECL_LANG_FLAG_3 (node))
416169699Skan	    fputs (" decl_3", file);
417169699Skan	  if (DECL_LANG_FLAG_4 (node))
418169699Skan	    fputs (" decl_4", file);
419169699Skan	  if (DECL_LANG_FLAG_5 (node))
420169699Skan	    fputs (" decl_5", file);
421169699Skan	  if (DECL_LANG_FLAG_6 (node))
422169699Skan	    fputs (" decl_6", file);
423169699Skan	  if (DECL_LANG_FLAG_7 (node))
424169699Skan	    fputs (" decl_7", file);
425169699Skan
426169699Skan	  mode = DECL_MODE (node);
427169699Skan	  fprintf (file, " %s", GET_MODE_NAME (mode));
428169699Skan	}
42990285Sobrien
430169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)  && DECL_DEFER_OUTPUT (node))
43118334Speter	fputs (" defer-output", file);
43218334Speter
43318334Speter
434169699Skan      xloc = expand_location (DECL_SOURCE_LOCATION (node));
435169699Skan      fprintf (file, " file %s line %d", xloc.file, xloc.line);
43618334Speter
437169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
438169699Skan	{
439169699Skan	  print_node (file, "size", DECL_SIZE (node), indent + 4);
440169699Skan	  print_node (file, "unit size", DECL_SIZE_UNIT (node), indent + 4);
441169699Skan
442169699Skan	  if (TREE_CODE (node) != FUNCTION_DECL
443169699Skan	      || DECL_INLINE (node) || DECL_BUILT_IN (node))
444169699Skan	    indent_to (file, indent + 3);
445169699Skan
446258748Spfg	  if (DECL_USER_ALIGN (node))
447258748Spfg	    fprintf (file, " user");
448258748Spfg
449258748Spfg	  fprintf (file, " align %d", DECL_ALIGN (node));
450258748Spfg	  if (TREE_CODE (node) == FIELD_DECL)
451258748Spfg	    fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
452258748Spfg		     DECL_OFFSET_ALIGN (node));
453258748Spfg
454258748Spfg	  if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
455169699Skan	    {
456169699Skan	      if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
457169699Skan		fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node));
458169699Skan	      else
459169699Skan		fprintf (file, " built-in %s:%s",
460169699Skan			 built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)],
461169699Skan			 built_in_names[(int) DECL_FUNCTION_CODE (node)]);
462169699Skan	    }
463169699Skan
464169699Skan	  if (DECL_POINTER_ALIAS_SET_KNOWN_P (node))
465169699Skan	    fprintf (file, " alias set " HOST_WIDE_INT_PRINT_DEC,
466169699Skan		     DECL_POINTER_ALIAS_SET (node));
46790285Sobrien	}
46818334Speter      if (TREE_CODE (node) == FIELD_DECL)
46990285Sobrien	{
47090285Sobrien	  print_node (file, "offset", DECL_FIELD_OFFSET (node), indent + 4);
47190285Sobrien	  print_node (file, "bit offset", DECL_FIELD_BIT_OFFSET (node),
47290285Sobrien		      indent + 4);
473169699Skan	  if (DECL_BIT_FIELD_TYPE (node))
474169699Skan	    print_node (file, "bit_field_type", DECL_BIT_FIELD_TYPE (node),
475169699Skan			indent + 4);
47690285Sobrien	}
47790285Sobrien
47818334Speter      print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
47918334Speter
480169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
481169699Skan	{
482169699Skan	  print_node_brief (file, "attributes",
483169699Skan			    DECL_ATTRIBUTES (node), indent + 4);
484169699Skan	  print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4);
485169699Skan	}
486169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
487169699Skan	{
488169699Skan	  print_node_brief (file, "abstract_origin",
489169699Skan			    DECL_ABSTRACT_ORIGIN (node), indent + 4);
490169699Skan	}
491169699Skan      if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
492169699Skan	{
493169699Skan	  print_node (file, "arguments", DECL_ARGUMENT_FLD (node), indent + 4);
494169699Skan	  print_node (file, "result", DECL_RESULT_FLD (node), indent + 4);
495169699Skan	}
49618334Speter
497169699Skan      lang_hooks.print_decl (file, node, indent);
49818334Speter
49990285Sobrien      if (DECL_RTL_SET_P (node))
50018334Speter	{
50118334Speter	  indent_to (file, indent + 4);
50218334Speter	  print_rtl (file, DECL_RTL (node));
50318334Speter	}
50418334Speter
50590285Sobrien      if (TREE_CODE (node) == PARM_DECL)
50618334Speter	{
50790285Sobrien	  print_node (file, "arg-type", DECL_ARG_TYPE (node), indent + 4);
50890285Sobrien
50990285Sobrien	  if (DECL_INCOMING_RTL (node) != 0)
51018334Speter	    {
51190285Sobrien	      indent_to (file, indent + 4);
51218334Speter	      fprintf (file, "incoming-rtl ");
51318334Speter	      print_rtl (file, DECL_INCOMING_RTL (node));
51418334Speter	    }
51518334Speter	}
51690285Sobrien      else if (TREE_CODE (node) == FUNCTION_DECL
517169699Skan	       && DECL_STRUCT_FUNCTION (node) != 0)
51890285Sobrien	{
51990285Sobrien	  indent_to (file, indent + 4);
520169699Skan	  dump_addr (file, "saved-insns ", DECL_STRUCT_FUNCTION (node));
52190285Sobrien	}
52218334Speter
523169699Skan      if ((TREE_CODE (node) == VAR_DECL || TREE_CODE (node) == PARM_DECL)
524169699Skan	  && DECL_HAS_VALUE_EXPR_P (node))
525169699Skan	print_node (file, "value-expr", DECL_VALUE_EXPR (node), indent + 4);
526169699Skan
527169699Skan      if (TREE_CODE (node) == STRUCT_FIELD_TAG)
528169699Skan	{
529169699Skan	  fprintf (file, " sft size " HOST_WIDE_INT_PRINT_DEC,
530169699Skan		   SFT_SIZE (node));
531169699Skan	  fprintf (file, " sft offset " HOST_WIDE_INT_PRINT_DEC,
532169699Skan		   SFT_OFFSET (node));
533169699Skan	  print_node_brief (file, "parent var", SFT_PARENT_VAR (node),
534169699Skan			    indent + 4);
535169699Skan	}
53618334Speter      /* Print the decl chain only if decl is at second level.  */
53718334Speter      if (indent == 4)
53818334Speter	print_node (file, "chain", TREE_CHAIN (node), indent + 4);
53918334Speter      else
54018334Speter	print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
54118334Speter      break;
54218334Speter
543169699Skan    case tcc_type:
544169699Skan      if (TYPE_UNSIGNED (node))
545169699Skan	fputs (" unsigned", file);
546169699Skan
54790285Sobrien      /* The no-force-blk flag is used for different things in
54890285Sobrien	 different types.  */
54990285Sobrien      if ((TREE_CODE (node) == RECORD_TYPE
55090285Sobrien	   || TREE_CODE (node) == UNION_TYPE
55190285Sobrien	   || TREE_CODE (node) == QUAL_UNION_TYPE)
55290285Sobrien	  && TYPE_NO_FORCE_BLK (node))
55318334Speter	fputs (" no-force-blk", file);
55490285Sobrien      else if (TREE_CODE (node) == INTEGER_TYPE
55590285Sobrien	       && TYPE_IS_SIZETYPE (node))
55690285Sobrien	fputs (" sizetype", file);
55790285Sobrien      else if (TREE_CODE (node) == FUNCTION_TYPE
55890285Sobrien	       && TYPE_RETURNS_STACK_DEPRESSED (node))
55990285Sobrien	fputs (" returns-stack-depressed", file);
56090285Sobrien
56118334Speter      if (TYPE_STRING_FLAG (node))
56218334Speter	fputs (" string-flag", file);
56318334Speter      if (TYPE_NEEDS_CONSTRUCTING (node))
56418334Speter	fputs (" needs-constructing", file);
56590285Sobrien
56690285Sobrien      /* The transparent-union flag is used for different things in
56790285Sobrien	 different nodes.  */
56890285Sobrien      if (TREE_CODE (node) == UNION_TYPE && TYPE_TRANSPARENT_UNION (node))
56918334Speter	fputs (" transparent-union", file);
57090285Sobrien      else if (TREE_CODE (node) == ARRAY_TYPE
57190285Sobrien	       && TYPE_NONALIASED_COMPONENT (node))
57290285Sobrien	fputs (" nonaliased-component", file);
57390285Sobrien
57418334Speter      if (TYPE_PACKED (node))
57518334Speter	fputs (" packed", file);
57618334Speter
577117404Skan      if (TYPE_RESTRICT (node))
578117404Skan	fputs (" restrict", file);
579117404Skan
58018334Speter      if (TYPE_LANG_FLAG_0 (node))
58118334Speter	fputs (" type_0", file);
58218334Speter      if (TYPE_LANG_FLAG_1 (node))
58318334Speter	fputs (" type_1", file);
58418334Speter      if (TYPE_LANG_FLAG_2 (node))
58518334Speter	fputs (" type_2", file);
58618334Speter      if (TYPE_LANG_FLAG_3 (node))
58718334Speter	fputs (" type_3", file);
58818334Speter      if (TYPE_LANG_FLAG_4 (node))
58918334Speter	fputs (" type_4", file);
59018334Speter      if (TYPE_LANG_FLAG_5 (node))
59118334Speter	fputs (" type_5", file);
59218334Speter      if (TYPE_LANG_FLAG_6 (node))
59318334Speter	fputs (" type_6", file);
59418334Speter
59518334Speter      mode = TYPE_MODE (node);
59690285Sobrien      fprintf (file, " %s", GET_MODE_NAME (mode));
59718334Speter
59818334Speter      print_node (file, "size", TYPE_SIZE (node), indent + 4);
59990285Sobrien      print_node (file, "unit size", TYPE_SIZE_UNIT (node), indent + 4);
60018334Speter      indent_to (file, indent + 3);
60118334Speter
60290285Sobrien      if (TYPE_USER_ALIGN (node))
60390285Sobrien	fprintf (file, " user");
60490285Sobrien
605132727Skan      fprintf (file, " align %d symtab %d alias set " HOST_WIDE_INT_PRINT_DEC,
606132727Skan	       TYPE_ALIGN (node), TYPE_SYMTAB_ADDRESS (node),
607132727Skan	       TYPE_ALIAS_SET (node));
60818334Speter
60918334Speter      print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
61018334Speter
61190285Sobrien      if (INTEGRAL_TYPE_P (node) || TREE_CODE (node) == REAL_TYPE)
61218334Speter	{
61318334Speter	  fprintf (file, " precision %d", TYPE_PRECISION (node));
61490285Sobrien	  print_node_brief (file, "min", TYPE_MIN_VALUE (node), indent + 4);
61590285Sobrien	  print_node_brief (file, "max", TYPE_MAX_VALUE (node), indent + 4);
61618334Speter	}
61790285Sobrien
61890285Sobrien      if (TREE_CODE (node) == ENUMERAL_TYPE)
61990285Sobrien	print_node (file, "values", TYPE_VALUES (node), indent + 4);
620169699Skan      else if (TREE_CODE (node) == ARRAY_TYPE)
62190285Sobrien	print_node (file, "domain", TYPE_DOMAIN (node), indent + 4);
622169699Skan      else if (TREE_CODE (node) == VECTOR_TYPE)
623169699Skan	fprintf (file, " nunits %d", (int) TYPE_VECTOR_SUBPARTS (node));
62418334Speter      else if (TREE_CODE (node) == RECORD_TYPE
62518334Speter	       || TREE_CODE (node) == UNION_TYPE
62618334Speter	       || TREE_CODE (node) == QUAL_UNION_TYPE)
62718334Speter	print_node (file, "fields", TYPE_FIELDS (node), indent + 4);
62890285Sobrien      else if (TREE_CODE (node) == FUNCTION_TYPE
62990285Sobrien	       || TREE_CODE (node) == METHOD_TYPE)
63018334Speter	{
63118334Speter	  if (TYPE_METHOD_BASETYPE (node))
63290285Sobrien	    print_node_brief (file, "method basetype",
63390285Sobrien			      TYPE_METHOD_BASETYPE (node), indent + 4);
63418334Speter	  print_node (file, "arg-types", TYPE_ARG_TYPES (node), indent + 4);
63518334Speter	}
63690285Sobrien      else if (TREE_CODE (node) == OFFSET_TYPE)
63790285Sobrien	print_node_brief (file, "basetype", TYPE_OFFSET_BASETYPE (node),
63890285Sobrien			  indent + 4);
63990285Sobrien
64018334Speter      if (TYPE_CONTEXT (node))
64118334Speter	print_node_brief (file, "context", TYPE_CONTEXT (node), indent + 4);
64218334Speter
643169699Skan      lang_hooks.print_type (file, node, indent);
64418334Speter
64518334Speter      if (TYPE_POINTER_TO (node) || TREE_CHAIN (node))
64618334Speter	indent_to (file, indent + 3);
64790285Sobrien
64890285Sobrien      print_node_brief (file, "pointer_to_this", TYPE_POINTER_TO (node),
64990285Sobrien			indent + 4);
65090285Sobrien      print_node_brief (file, "reference_to_this", TYPE_REFERENCE_TO (node),
65190285Sobrien			indent + 4);
65218334Speter      print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
65318334Speter      break;
65418334Speter
655169699Skan    case tcc_expression:
656169699Skan    case tcc_comparison:
657169699Skan    case tcc_unary:
658169699Skan    case tcc_binary:
659169699Skan    case tcc_reference:
660169699Skan    case tcc_statement:
661169699Skan      if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node))
662169699Skan	fputs (" unsigned", file);
66350617Sobrien      if (TREE_CODE (node) == BIND_EXPR)
66418334Speter	{
66518334Speter	  print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4);
66618334Speter	  print_node (file, "body", TREE_OPERAND (node, 1), indent + 4);
66718334Speter	  print_node (file, "block", TREE_OPERAND (node, 2), indent + 4);
66852521Sobrien	  break;
66918334Speter	}
67018334Speter
67190285Sobrien      len = TREE_CODE_LENGTH (TREE_CODE (node));
67290285Sobrien
67318334Speter      for (i = 0; i < len; i++)
67418334Speter	{
675169699Skan	  char temp[10];
67618334Speter
677169699Skan	  sprintf (temp, "arg %d", i);
678169699Skan	  print_node (file, temp, TREE_OPERAND (node, i), indent + 4);
67918334Speter	}
68050617Sobrien
68190285Sobrien      print_node (file, "chain", TREE_CHAIN (node), indent + 4);
68218334Speter      break;
68318334Speter
684169699Skan    case tcc_constant:
685169699Skan    case tcc_exceptional:
68618334Speter      switch (TREE_CODE (node))
68718334Speter	{
68818334Speter	case INTEGER_CST:
68918334Speter	  if (TREE_CONSTANT_OVERFLOW (node))
69018334Speter	    fprintf (file, " overflow");
69118334Speter
69250617Sobrien	  fprintf (file, " ");
69318334Speter	  if (TREE_INT_CST_HIGH (node) == 0)
69450617Sobrien	    fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
69518334Speter		     TREE_INT_CST_LOW (node));
69618334Speter	  else if (TREE_INT_CST_HIGH (node) == -1
69718334Speter		   && TREE_INT_CST_LOW (node) != 0)
698132727Skan	    fprintf (file, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
699132727Skan		     -TREE_INT_CST_LOW (node));
70018334Speter	  else
70150617Sobrien	    fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
70218334Speter		     TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
70318334Speter	  break;
70418334Speter
70518334Speter	case REAL_CST:
70618334Speter	  {
70718334Speter	    REAL_VALUE_TYPE d;
70818334Speter
70918334Speter	    if (TREE_OVERFLOW (node))
71018334Speter	      fprintf (file, " overflow");
71118334Speter
71218334Speter	    d = TREE_REAL_CST (node);
71318334Speter	    if (REAL_VALUE_ISINF (d))
714169699Skan	      fprintf (file,  REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
71518334Speter	    else if (REAL_VALUE_ISNAN (d))
71618334Speter	      fprintf (file, " Nan");
71718334Speter	    else
71818334Speter	      {
719117404Skan		char string[64];
720117404Skan		real_to_decimal (string, &d, sizeof (string), 0, 1);
72118334Speter		fprintf (file, " %s", string);
72218334Speter	      }
72318334Speter	  }
72418334Speter	  break;
72518334Speter
72696287Sobrien	case VECTOR_CST:
72796287Sobrien	  {
72896287Sobrien	    tree vals = TREE_VECTOR_CST_ELTS (node);
72996287Sobrien	    char buf[10];
73096287Sobrien	    tree link;
73196287Sobrien	    int i;
73296287Sobrien
73396287Sobrien	    i = 0;
73496287Sobrien	    for (link = vals; link; link = TREE_CHAIN (link), ++i)
73596287Sobrien	      {
73696287Sobrien		sprintf (buf, "elt%d: ", i);
73796287Sobrien		print_node (file, buf, TREE_VALUE (link), indent + 4);
73896287Sobrien	      }
73996287Sobrien	  }
74096287Sobrien	  break;
74196287Sobrien
74218334Speter	case COMPLEX_CST:
74318334Speter	  print_node (file, "real", TREE_REALPART (node), indent + 4);
74418334Speter	  print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
74518334Speter	  break;
74618334Speter
74718334Speter	case STRING_CST:
748117404Skan	  {
749117404Skan	    const char *p = TREE_STRING_POINTER (node);
750117404Skan	    int i = TREE_STRING_LENGTH (node);
751117404Skan	    fputs (" \"", file);
752117404Skan	    while (--i >= 0)
753117404Skan	      {
754117404Skan		char ch = *p++;
755117404Skan		if (ch >= ' ' && ch < 127)
756117404Skan		  putc (ch, file);
757117404Skan		else
758117404Skan		  fprintf(file, "\\%03o", ch & 0xFF);
759117404Skan	      }
760117404Skan	    fputc ('\"', file);
761117404Skan	  }
76218334Speter	  /* Print the chain at second level.  */
76318334Speter	  if (indent == 4)
76418334Speter	    print_node (file, "chain", TREE_CHAIN (node), indent + 4);
76518334Speter	  else
76618334Speter	    print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
76718334Speter	  break;
76818334Speter
76918334Speter	case IDENTIFIER_NODE:
770169699Skan	  lang_hooks.print_identifier (file, node, indent);
77118334Speter	  break;
77218334Speter
77318334Speter	case TREE_LIST:
77418334Speter	  print_node (file, "purpose", TREE_PURPOSE (node), indent + 4);
77518334Speter	  print_node (file, "value", TREE_VALUE (node), indent + 4);
77618334Speter	  print_node (file, "chain", TREE_CHAIN (node), indent + 4);
77718334Speter	  break;
77818334Speter
77918334Speter	case TREE_VEC:
78018334Speter	  len = TREE_VEC_LENGTH (node);
78118334Speter	  for (i = 0; i < len; i++)
78218334Speter	    if (TREE_VEC_ELT (node, i))
78318334Speter	      {
78418334Speter		char temp[10];
78518334Speter		sprintf (temp, "elt %d", i);
78618334Speter		indent_to (file, indent + 4);
78718334Speter		print_node_brief (file, temp, TREE_VEC_ELT (node, i), 0);
78818334Speter	      }
78918334Speter	  break;
79018334Speter
791169699Skan    	case STATEMENT_LIST:
792169699Skan	  dump_addr (file, " head ", node->stmt_list.head);
793169699Skan	  dump_addr (file, " tail ", node->stmt_list.tail);
794169699Skan	  fprintf (file, " stmts");
795169699Skan	  {
796169699Skan	    tree_stmt_iterator i;
797169699Skan	    for (i = tsi_start (node); !tsi_end_p (i); tsi_next (&i))
798169699Skan	      {
799169699Skan		/* Not printing the addresses of the (not-a-tree)
800169699Skan		   'struct tree_stmt_list_node's.  */
801169699Skan		dump_addr (file, " ", tsi_stmt (i));
802169699Skan	      }
803169699Skan	    fprintf (file, "\n");
804169699Skan	    for (i = tsi_start (node); !tsi_end_p (i); tsi_next (&i))
805169699Skan	      {
806169699Skan		/* Not printing the addresses of the (not-a-tree)
807169699Skan		   'struct tree_stmt_list_node's.  */
808169699Skan		print_node (file, "stmt", tsi_stmt (i), indent + 4);
809169699Skan	      }
810169699Skan	  }
811169699Skan	  print_node (file, "chain", TREE_CHAIN (node), indent + 4);
812169699Skan	  break;
813169699Skan
814169699Skan	case BLOCK:
815169699Skan	  print_node (file, "vars", BLOCK_VARS (node), indent + 4);
816169699Skan	  print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node),
817169699Skan		      indent + 4);
818169699Skan	  print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4);
819169699Skan	  print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
820169699Skan	  print_node (file, "abstract_origin",
821169699Skan		      BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
822169699Skan	  break;
823169699Skan
824169699Skan	case SSA_NAME:
825169699Skan	  print_node_brief (file, "var", SSA_NAME_VAR (node), indent + 4);
826169699Skan	  print_node_brief (file, "def_stmt",
827169699Skan			    SSA_NAME_DEF_STMT (node), indent + 4);
828169699Skan
829169699Skan	  indent_to (file, indent + 4);
830169699Skan	  fprintf (file, "version %u", SSA_NAME_VERSION (node));
831169699Skan	  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
832169699Skan	    fprintf (file, " in-abnormal-phi");
833169699Skan	  if (SSA_NAME_IN_FREE_LIST (node))
834169699Skan	    fprintf (file, " in-free-list");
835169699Skan
836169699Skan	  if (SSA_NAME_PTR_INFO (node)
837169699Skan	      || SSA_NAME_VALUE (node))
838169699Skan	    {
839169699Skan	      indent_to (file, indent + 3);
840169699Skan	      if (SSA_NAME_PTR_INFO (node))
841169699Skan		dump_addr (file, " ptr-info ", SSA_NAME_PTR_INFO (node));
842169699Skan	      if (SSA_NAME_VALUE (node))
843169699Skan		dump_addr (file, " value ", SSA_NAME_VALUE (node));
844169699Skan	    }
845169699Skan	  break;
846169699Skan
847169699Skan	case OMP_CLAUSE:
848169699Skan	    {
849169699Skan	      int i;
850169699Skan	      fprintf (file, " %s",
851169699Skan		       omp_clause_code_name[OMP_CLAUSE_CODE (node)]);
852169699Skan	      for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (node)]; i++)
853169699Skan		{
854169699Skan		  indent_to (file, indent + 4);
855169699Skan		  fprintf (file, "op %d:", i);
856169699Skan		  print_node_brief (file, "", OMP_CLAUSE_OPERAND (node, i), 0);
857169699Skan		}
858169699Skan	    }
859169699Skan	  break;
860169699Skan
86150617Sobrien	default:
862169699Skan	  if (EXCEPTIONAL_CLASS_P (node))
863169699Skan	    lang_hooks.print_xnode (file, node, indent);
86450617Sobrien	  break;
86518334Speter	}
86618334Speter
86718334Speter      break;
86818334Speter    }
86918334Speter
870169699Skan  if (EXPR_HAS_LOCATION (node))
871169699Skan    {
872169699Skan      expanded_location xloc = expand_location (EXPR_LOCATION (node));
873169699Skan      indent_to (file, indent+4);
874169699Skan      fprintf (file, "%s:%d", xloc.file, xloc.line);
875169699Skan    }
876169699Skan
87718334Speter  fprintf (file, ">");
87818334Speter}
879