xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-dump.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Tree-dumping functionality for intermediate representation.
2    Copyright (C) 1999-2015 Free Software Foundation, Inc.
3    Written by Mark Mitchell <mark@codesourcery.com>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "hash-set.h"
26 #include "machmode.h"
27 #include "vec.h"
28 #include "double-int.h"
29 #include "input.h"
30 #include "alias.h"
31 #include "symtab.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "real.h"
35 #include "tree.h"
36 #include "fixed-value.h"
37 #include "splay-tree.h"
38 #include "filenames.h"
39 #include "tree-dump.h"
40 #include "langhooks.h"
41 #include "tree-iterator.h"
42 #include "tree-pretty-print.h"
43 #include "tree-cfg.h"
44 #include "wide-int-print.h"
45 
46 static unsigned int queue (dump_info_p, const_tree, int);
47 static void dump_index (dump_info_p, unsigned int);
48 static void dequeue_and_dump (dump_info_p);
49 static void dump_new_line (dump_info_p);
50 static void dump_maybe_newline (dump_info_p);
51 
52 /* Add T to the end of the queue of nodes to dump.  Returns the index
53    assigned to T.  */
54 
55 static unsigned int
56 queue (dump_info_p di, const_tree t, int flags)
57 {
58   dump_queue_p dq;
59   dump_node_info_p dni;
60   unsigned int index;
61 
62   /* Assign the next available index to T.  */
63   index = ++di->index;
64 
65   /* Obtain a new queue node.  */
66   if (di->free_list)
67     {
68       dq = di->free_list;
69       di->free_list = dq->next;
70     }
71   else
72     dq = XNEW (struct dump_queue);
73 
74   /* Create a new entry in the splay-tree.  */
75   dni = XNEW (struct dump_node_info);
76   dni->index = index;
77   dni->binfo_p = ((flags & DUMP_BINFO) != 0);
78   dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
79 				(splay_tree_value) dni);
80 
81   /* Add it to the end of the queue.  */
82   dq->next = 0;
83   if (!di->queue_end)
84     di->queue = dq;
85   else
86     di->queue_end->next = dq;
87   di->queue_end = dq;
88 
89   /* Return the index.  */
90   return index;
91 }
92 
93 static void
94 dump_index (dump_info_p di, unsigned int index)
95 {
96   fprintf (di->stream, "@%-6u ", index);
97   di->column += 8;
98 }
99 
100 /* If T has not already been output, queue it for subsequent output.
101    FIELD is a string to print before printing the index.  Then, the
102    index of T is printed.  */
103 
104 void
105 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
106 {
107   unsigned int index;
108   splay_tree_node n;
109 
110   /* If there's no node, just return.  This makes for fewer checks in
111      our callers.  */
112   if (!t)
113     return;
114 
115   /* See if we've already queued or dumped this node.  */
116   n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
117   if (n)
118     index = ((dump_node_info_p) n->value)->index;
119   else
120     /* If we haven't, add it to the queue.  */
121     index = queue (di, t, flags);
122 
123   /* Print the index of the node.  */
124   dump_maybe_newline (di);
125   fprintf (di->stream, "%-4s: ", field);
126   di->column += 6;
127   dump_index (di, index);
128 }
129 
130 /* Dump the type of T.  */
131 
132 void
133 queue_and_dump_type (dump_info_p di, const_tree t)
134 {
135   queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
136 }
137 
138 /* Dump column control */
139 #define SOL_COLUMN 25		/* Start of line column.  */
140 #define EOL_COLUMN 55		/* End of line column.  */
141 #define COLUMN_ALIGNMENT 15	/* Alignment.  */
142 
143 /* Insert a new line in the dump output, and indent to an appropriate
144    place to start printing more fields.  */
145 
146 static void
147 dump_new_line (dump_info_p di)
148 {
149   fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
150   di->column = SOL_COLUMN;
151 }
152 
153 /* If necessary, insert a new line.  */
154 
155 static void
156 dump_maybe_newline (dump_info_p di)
157 {
158   int extra;
159 
160   /* See if we need a new line.  */
161   if (di->column > EOL_COLUMN)
162     dump_new_line (di);
163   /* See if we need any padding.  */
164   else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
165     {
166       fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
167       di->column += COLUMN_ALIGNMENT - extra;
168     }
169 }
170 
171 /* Dump FUNCTION_DECL FN as tree dump PHASE.  */
172 
173 void
174 dump_function (int phase, tree fn)
175 {
176   FILE *stream;
177   int flags;
178 
179   stream = dump_begin (phase, &flags);
180   if (stream)
181     {
182       dump_function_to_file (fn, stream, flags);
183       dump_end (phase, stream);
184     }
185 }
186 
187 /* Dump pointer PTR using FIELD to identify it.  */
188 
189 void
190 dump_pointer (dump_info_p di, const char *field, void *ptr)
191 {
192   dump_maybe_newline (di);
193   fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
194 	   (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
195   di->column += 15;
196 }
197 
198 /* Dump integer I using FIELD to identify it.  */
199 
200 void
201 dump_int (dump_info_p di, const char *field, int i)
202 {
203   dump_maybe_newline (di);
204   fprintf (di->stream, "%-4s: %-7d ", field, i);
205   di->column += 14;
206 }
207 
208 /* Dump the floating point value R, using FIELD to identify it.  */
209 
210 static void
211 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
212 {
213   char buf[32];
214   real_to_decimal (buf, r, sizeof (buf), 0, true);
215   dump_maybe_newline (di);
216   fprintf (di->stream, "%-4s: %s ", field, buf);
217   di->column += strlen (buf) + 7;
218 }
219 
220 /* Dump the fixed-point value F, using FIELD to identify it.  */
221 
222 static void
223 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
224 {
225   char buf[32];
226   fixed_to_decimal (buf, f, sizeof (buf));
227   dump_maybe_newline (di);
228   fprintf (di->stream, "%-4s: %s ", field, buf);
229   di->column += strlen (buf) + 7;
230 }
231 
232 
233 /* Dump the string S.  */
234 
235 void
236 dump_string (dump_info_p di, const char *string)
237 {
238   dump_maybe_newline (di);
239   fprintf (di->stream, "%-13s ", string);
240   if (strlen (string) > 13)
241     di->column += strlen (string) + 1;
242   else
243     di->column += 14;
244 }
245 
246 /* Dump the string field S.  */
247 
248 void
249 dump_string_field (dump_info_p di, const char *field, const char *string)
250 {
251   dump_maybe_newline (di);
252   fprintf (di->stream, "%-4s: %-7s ", field, string);
253   if (strlen (string) > 7)
254     di->column += 6 + strlen (string) + 1;
255   else
256     di->column += 14;
257 }
258 
259 /* Dump the next node in the queue.  */
260 
261 static void
262 dequeue_and_dump (dump_info_p di)
263 {
264   dump_queue_p dq;
265   splay_tree_node stn;
266   dump_node_info_p dni;
267   tree t;
268   unsigned int index;
269   enum tree_code code;
270   enum tree_code_class code_class;
271   const char* code_name;
272 
273   /* Get the next node from the queue.  */
274   dq = di->queue;
275   stn = dq->node;
276   t = (tree) stn->key;
277   dni = (dump_node_info_p) stn->value;
278   index = dni->index;
279 
280   /* Remove the node from the queue, and put it on the free list.  */
281   di->queue = dq->next;
282   if (!di->queue)
283     di->queue_end = 0;
284   dq->next = di->free_list;
285   di->free_list = dq;
286 
287   /* Print the node index.  */
288   dump_index (di, index);
289   /* And the type of node this is.  */
290   if (dni->binfo_p)
291     code_name = "binfo";
292   else
293     code_name = get_tree_code_name (TREE_CODE (t));
294   fprintf (di->stream, "%-16s ", code_name);
295   di->column = 25;
296 
297   /* Figure out what kind of node this is.  */
298   code = TREE_CODE (t);
299   code_class = TREE_CODE_CLASS (code);
300 
301   /* Although BINFOs are TREE_VECs, we dump them specially so as to be
302      more informative.  */
303   if (dni->binfo_p)
304     {
305       unsigned ix;
306       tree base;
307       vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
308 
309       dump_child ("type", BINFO_TYPE (t));
310 
311       if (BINFO_VIRTUAL_P (t))
312 	dump_string_field (di, "spec", "virt");
313 
314       dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
315       for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
316 	{
317 	  tree access = (accesses ? (*accesses)[ix] : access_public_node);
318 	  const char *string = NULL;
319 
320 	  if (access == access_public_node)
321 	    string = "pub";
322 	  else if (access == access_protected_node)
323 	    string = "prot";
324 	  else if (access == access_private_node)
325 	    string = "priv";
326 	  else
327 	    gcc_unreachable ();
328 
329 	  dump_string_field (di, "accs", string);
330 	  queue_and_dump_index (di, "binf", base, DUMP_BINFO);
331 	}
332 
333       goto done;
334     }
335 
336   /* We can knock off a bunch of expression nodes in exactly the same
337      way.  */
338   if (IS_EXPR_CODE_CLASS (code_class))
339     {
340       /* If we're dumping children, dump them now.  */
341       queue_and_dump_type (di, t);
342 
343       switch (code_class)
344 	{
345 	case tcc_unary:
346 	  dump_child ("op 0", TREE_OPERAND (t, 0));
347 	  break;
348 
349 	case tcc_binary:
350 	case tcc_comparison:
351 	  dump_child ("op 0", TREE_OPERAND (t, 0));
352 	  dump_child ("op 1", TREE_OPERAND (t, 1));
353 	  break;
354 
355 	case tcc_expression:
356 	case tcc_reference:
357 	case tcc_statement:
358 	case tcc_vl_exp:
359 	  /* These nodes are handled explicitly below.  */
360 	  break;
361 
362 	default:
363 	  gcc_unreachable ();
364 	}
365     }
366   else if (DECL_P (t))
367     {
368       expanded_location xloc;
369       /* All declarations have names.  */
370       if (DECL_NAME (t))
371 	dump_child ("name", DECL_NAME (t));
372       if (DECL_ASSEMBLER_NAME_SET_P (t)
373 	  && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
374 	dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
375       if (DECL_ABSTRACT_ORIGIN (t))
376         dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
377       /* And types.  */
378       queue_and_dump_type (di, t);
379       dump_child ("scpe", DECL_CONTEXT (t));
380       /* And a source position.  */
381       xloc = expand_location (DECL_SOURCE_LOCATION (t));
382       if (xloc.file)
383 	{
384 	  const char *filename = lbasename (xloc.file);
385 
386 	  dump_maybe_newline (di);
387 	  fprintf (di->stream, "srcp: %s:%-6d ", filename,
388 		   xloc.line);
389 	  di->column += 6 + strlen (filename) + 8;
390 	}
391       /* And any declaration can be compiler-generated.  */
392       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
393 	  && DECL_ARTIFICIAL (t))
394 	dump_string_field (di, "note", "artificial");
395       if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
396 	dump_child ("chain", DECL_CHAIN (t));
397     }
398   else if (code_class == tcc_type)
399     {
400       /* All types have qualifiers.  */
401       int quals = lang_hooks.tree_dump.type_quals (t);
402 
403       if (quals != TYPE_UNQUALIFIED)
404 	{
405 	  fprintf (di->stream, "qual: %c%c%c     ",
406 		   (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
407 		   (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
408 		   (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
409 	  di->column += 14;
410 	}
411 
412       /* All types have associated declarations.  */
413       dump_child ("name", TYPE_NAME (t));
414 
415       /* All types have a main variant.  */
416       if (TYPE_MAIN_VARIANT (t) != t)
417 	dump_child ("unql", TYPE_MAIN_VARIANT (t));
418 
419       /* And sizes.  */
420       dump_child ("size", TYPE_SIZE (t));
421 
422       /* All types have alignments.  */
423       dump_int (di, "algn", TYPE_ALIGN (t));
424     }
425   else if (code_class == tcc_constant)
426     /* All constants can have types.  */
427     queue_and_dump_type (di, t);
428 
429   /* Give the language-specific code a chance to print something.  If
430      it's completely taken care of things, don't bother printing
431      anything more ourselves.  */
432   if (lang_hooks.tree_dump.dump_tree (di, t))
433     goto done;
434 
435   /* Now handle the various kinds of nodes.  */
436   switch (code)
437     {
438       int i;
439 
440     case IDENTIFIER_NODE:
441       dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
442       dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
443       break;
444 
445     case TREE_LIST:
446       dump_child ("purp", TREE_PURPOSE (t));
447       dump_child ("valu", TREE_VALUE (t));
448       dump_child ("chan", TREE_CHAIN (t));
449       break;
450 
451     case STATEMENT_LIST:
452       {
453 	tree_stmt_iterator it;
454 	for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
455 	  {
456 	    char buffer[32];
457 	    sprintf (buffer, "%u", i);
458 	    dump_child (buffer, tsi_stmt (it));
459 	  }
460       }
461       break;
462 
463     case TREE_VEC:
464       dump_int (di, "lngt", TREE_VEC_LENGTH (t));
465       for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
466 	{
467 	  char buffer[32];
468 	  sprintf (buffer, "%u", i);
469 	  dump_child (buffer, TREE_VEC_ELT (t, i));
470 	}
471       break;
472 
473     case INTEGER_TYPE:
474     case ENUMERAL_TYPE:
475       dump_int (di, "prec", TYPE_PRECISION (t));
476       dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
477       dump_child ("min", TYPE_MIN_VALUE (t));
478       dump_child ("max", TYPE_MAX_VALUE (t));
479 
480       if (code == ENUMERAL_TYPE)
481 	dump_child ("csts", TYPE_VALUES (t));
482       break;
483 
484     case REAL_TYPE:
485       dump_int (di, "prec", TYPE_PRECISION (t));
486       break;
487 
488     case FIXED_POINT_TYPE:
489       dump_int (di, "prec", TYPE_PRECISION (t));
490       dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
491       dump_string_field (di, "saturating",
492 			 TYPE_SATURATING (t) ? "saturating": "non-saturating");
493       break;
494 
495     case POINTER_TYPE:
496       dump_child ("ptd", TREE_TYPE (t));
497       break;
498 
499     case REFERENCE_TYPE:
500       dump_child ("refd", TREE_TYPE (t));
501       break;
502 
503     case METHOD_TYPE:
504       dump_child ("clas", TYPE_METHOD_BASETYPE (t));
505       /* Fall through.  */
506 
507     case FUNCTION_TYPE:
508       dump_child ("retn", TREE_TYPE (t));
509       dump_child ("prms", TYPE_ARG_TYPES (t));
510       break;
511 
512     case ARRAY_TYPE:
513       dump_child ("elts", TREE_TYPE (t));
514       dump_child ("domn", TYPE_DOMAIN (t));
515       break;
516 
517     case RECORD_TYPE:
518     case UNION_TYPE:
519       if (TREE_CODE (t) == RECORD_TYPE)
520 	dump_string_field (di, "tag", "struct");
521       else
522 	dump_string_field (di, "tag", "union");
523 
524       dump_child ("flds", TYPE_FIELDS (t));
525       dump_child ("fncs", TYPE_METHODS (t));
526       queue_and_dump_index (di, "binf", TYPE_BINFO (t),
527 			    DUMP_BINFO);
528       break;
529 
530     case CONST_DECL:
531       dump_child ("cnst", DECL_INITIAL (t));
532       break;
533 
534     case DEBUG_EXPR_DECL:
535       dump_int (di, "-uid", DEBUG_TEMP_UID (t));
536       /* Fall through.  */
537 
538     case VAR_DECL:
539     case PARM_DECL:
540     case FIELD_DECL:
541     case RESULT_DECL:
542       if (TREE_CODE (t) == PARM_DECL)
543 	dump_child ("argt", DECL_ARG_TYPE (t));
544       else
545 	dump_child ("init", DECL_INITIAL (t));
546       dump_child ("size", DECL_SIZE (t));
547       dump_int (di, "algn", DECL_ALIGN (t));
548 
549       if (TREE_CODE (t) == FIELD_DECL)
550 	{
551 	  if (DECL_FIELD_OFFSET (t))
552 	    dump_child ("bpos", bit_position (t));
553 	}
554       else if (TREE_CODE (t) == VAR_DECL
555 	       || TREE_CODE (t) == PARM_DECL)
556 	{
557 	  dump_int (di, "used", TREE_USED (t));
558 	  if (DECL_REGISTER (t))
559 	    dump_string_field (di, "spec", "register");
560 	}
561       break;
562 
563     case FUNCTION_DECL:
564       dump_child ("args", DECL_ARGUMENTS (t));
565       if (DECL_EXTERNAL (t))
566 	dump_string_field (di, "body", "undefined");
567       if (TREE_PUBLIC (t))
568 	dump_string_field (di, "link", "extern");
569       else
570 	dump_string_field (di, "link", "static");
571       if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
572 	dump_child ("body", DECL_SAVED_TREE (t));
573       break;
574 
575     case INTEGER_CST:
576       fprintf (di->stream, "int: ");
577       print_decs (t, di->stream);
578       break;
579 
580     case STRING_CST:
581       fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
582       dump_int (di, "lngt", TREE_STRING_LENGTH (t));
583       break;
584 
585     case REAL_CST:
586       dump_real (di, "valu", TREE_REAL_CST_PTR (t));
587       break;
588 
589     case FIXED_CST:
590       dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
591       break;
592 
593     case TRUTH_NOT_EXPR:
594     case ADDR_EXPR:
595     case INDIRECT_REF:
596     case CLEANUP_POINT_EXPR:
597     case SAVE_EXPR:
598     case REALPART_EXPR:
599     case IMAGPART_EXPR:
600       /* These nodes are unary, but do not have code class `1'.  */
601       dump_child ("op 0", TREE_OPERAND (t, 0));
602       break;
603 
604     case TRUTH_ANDIF_EXPR:
605     case TRUTH_ORIF_EXPR:
606     case INIT_EXPR:
607     case MODIFY_EXPR:
608     case COMPOUND_EXPR:
609     case PREDECREMENT_EXPR:
610     case PREINCREMENT_EXPR:
611     case POSTDECREMENT_EXPR:
612     case POSTINCREMENT_EXPR:
613       /* These nodes are binary, but do not have code class `2'.  */
614       dump_child ("op 0", TREE_OPERAND (t, 0));
615       dump_child ("op 1", TREE_OPERAND (t, 1));
616       break;
617 
618     case COMPONENT_REF:
619     case BIT_FIELD_REF:
620       dump_child ("op 0", TREE_OPERAND (t, 0));
621       dump_child ("op 1", TREE_OPERAND (t, 1));
622       dump_child ("op 2", TREE_OPERAND (t, 2));
623       break;
624 
625     case ARRAY_REF:
626     case ARRAY_RANGE_REF:
627       dump_child ("op 0", TREE_OPERAND (t, 0));
628       dump_child ("op 1", TREE_OPERAND (t, 1));
629       dump_child ("op 2", TREE_OPERAND (t, 2));
630       dump_child ("op 3", TREE_OPERAND (t, 3));
631       break;
632 
633     case COND_EXPR:
634       dump_child ("op 0", TREE_OPERAND (t, 0));
635       dump_child ("op 1", TREE_OPERAND (t, 1));
636       dump_child ("op 2", TREE_OPERAND (t, 2));
637       break;
638 
639     case TRY_FINALLY_EXPR:
640       dump_child ("op 0", TREE_OPERAND (t, 0));
641       dump_child ("op 1", TREE_OPERAND (t, 1));
642       break;
643 
644     case CALL_EXPR:
645       {
646 	int i = 0;
647 	tree arg;
648 	call_expr_arg_iterator iter;
649 	dump_child ("fn", CALL_EXPR_FN (t));
650 	FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
651 	  {
652 	    char buffer[32];
653 	    sprintf (buffer, "%u", i);
654 	    dump_child (buffer, arg);
655 	    i++;
656 	  }
657       }
658       break;
659 
660     case CONSTRUCTOR:
661       {
662 	unsigned HOST_WIDE_INT cnt;
663 	tree index, value;
664 	dump_int (di, "lngt", vec_safe_length (CONSTRUCTOR_ELTS (t)));
665 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
666 	  {
667 	    dump_child ("idx", index);
668 	    dump_child ("val", value);
669 	  }
670       }
671       break;
672 
673     case BIND_EXPR:
674       dump_child ("vars", TREE_OPERAND (t, 0));
675       dump_child ("body", TREE_OPERAND (t, 1));
676       break;
677 
678     case LOOP_EXPR:
679       dump_child ("body", TREE_OPERAND (t, 0));
680       break;
681 
682     case EXIT_EXPR:
683       dump_child ("cond", TREE_OPERAND (t, 0));
684       break;
685 
686     case RETURN_EXPR:
687       dump_child ("expr", TREE_OPERAND (t, 0));
688       break;
689 
690     case TARGET_EXPR:
691       dump_child ("decl", TREE_OPERAND (t, 0));
692       dump_child ("init", TREE_OPERAND (t, 1));
693       dump_child ("clnp", TREE_OPERAND (t, 2));
694       /* There really are two possible places the initializer can be.
695 	 After RTL expansion, the second operand is moved to the
696 	 position of the fourth operand, and the second operand
697 	 becomes NULL.  */
698       dump_child ("init", TREE_OPERAND (t, 3));
699       break;
700 
701     case CASE_LABEL_EXPR:
702       dump_child ("name", CASE_LABEL (t));
703       if (CASE_LOW (t))
704 	{
705 	  dump_child ("low ", CASE_LOW (t));
706 	  if (CASE_HIGH (t))
707 	    dump_child ("high", CASE_HIGH (t));
708 	}
709       break;
710     case LABEL_EXPR:
711       dump_child ("name", TREE_OPERAND (t,0));
712       break;
713     case GOTO_EXPR:
714       dump_child ("labl", TREE_OPERAND (t, 0));
715       break;
716     case SWITCH_EXPR:
717       dump_child ("cond", TREE_OPERAND (t, 0));
718       dump_child ("body", TREE_OPERAND (t, 1));
719       if (TREE_OPERAND (t, 2))
720         {
721       	  dump_child ("labl", TREE_OPERAND (t,2));
722         }
723       break;
724     case OMP_CLAUSE:
725       {
726 	int i;
727 	fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
728 	for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
729 	  dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
730       }
731       break;
732     default:
733       /* There are no additional fields to print.  */
734       break;
735     }
736 
737  done:
738   if (dump_flag (di, TDF_ADDRESS, NULL))
739     dump_pointer (di, "addr", (void *)t);
740 
741   /* Terminate the line.  */
742   fprintf (di->stream, "\n");
743 }
744 
745 /* Return nonzero if FLAG has been specified for the dump, and NODE
746    is not the root node of the dump.  */
747 
748 int dump_flag (dump_info_p di, int flag, const_tree node)
749 {
750   return (di->flags & flag) && (node != di->node);
751 }
752 
753 /* Dump T, and all its children, on STREAM.  */
754 
755 void
756 dump_node (const_tree t, int flags, FILE *stream)
757 {
758   struct dump_info di;
759   dump_queue_p dq;
760   dump_queue_p next_dq;
761 
762   /* Initialize the dump-information structure.  */
763   di.stream = stream;
764   di.index = 0;
765   di.column = 0;
766   di.queue = 0;
767   di.queue_end = 0;
768   di.free_list = 0;
769   di.flags = flags;
770   di.node = t;
771   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
772 			     (splay_tree_delete_value_fn) &free);
773 
774   /* Queue up the first node.  */
775   queue (&di, t, DUMP_NONE);
776 
777   /* Until the queue is empty, keep dumping nodes.  */
778   while (di.queue)
779     dequeue_and_dump (&di);
780 
781   /* Now, clean up.  */
782   for (dq = di.free_list; dq; dq = next_dq)
783     {
784       next_dq = dq->next;
785       free (dq);
786     }
787   splay_tree_delete (di.nodes);
788 }
789