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