Update gcc-50 to SVN version 221572
[dragonfly.git] / contrib / gcc-5.0 / gcc / tree-dump.c
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 }