[multiple changes]
[gcc.git] / 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 }