Upgrade GCC from 4.7.2 to 4.7.3 on the vendor branch
[dragonfly.git] / contrib / gcc-4.7 / gcc / tree-dump.c
1 /* Tree-dumping functionality for intermediate representation.
2    Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3    2010, 2011 Free Software Foundation, Inc.
4    Written by Mark Mitchell <mark@codesourcery.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "splay-tree.h"
28 #include "filenames.h"
29 #include "diagnostic-core.h"
30 #include "toplev.h"
31 #include "tree-dump.h"
32 #include "tree-pass.h"
33 #include "langhooks.h"
34 #include "tree-iterator.h"
35
36 /* If non-NULL, return one past-the-end of the matching SUBPART of
37    the WHOLE string.  */
38 #define skip_leading_substring(whole,  part) \
39    (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
40
41 static unsigned int queue (dump_info_p, const_tree, int);
42 static void dump_index (dump_info_p, unsigned int);
43 static void dequeue_and_dump (dump_info_p);
44 static void dump_new_line (dump_info_p);
45 static void dump_maybe_newline (dump_info_p);
46
47 /* Add T to the end of the queue of nodes to dump.  Returns the index
48    assigned to T.  */
49
50 static unsigned int
51 queue (dump_info_p di, const_tree t, int flags)
52 {
53   dump_queue_p dq;
54   dump_node_info_p dni;
55   unsigned int index;
56
57   /* Assign the next available index to T.  */
58   index = ++di->index;
59
60   /* Obtain a new queue node.  */
61   if (di->free_list)
62     {
63       dq = di->free_list;
64       di->free_list = dq->next;
65     }
66   else
67     dq = XNEW (struct dump_queue);
68
69   /* Create a new entry in the splay-tree.  */
70   dni = XNEW (struct dump_node_info);
71   dni->index = index;
72   dni->binfo_p = ((flags & DUMP_BINFO) != 0);
73   dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
74                                 (splay_tree_value) dni);
75
76   /* Add it to the end of the queue.  */
77   dq->next = 0;
78   if (!di->queue_end)
79     di->queue = dq;
80   else
81     di->queue_end->next = dq;
82   di->queue_end = dq;
83
84   /* Return the index.  */
85   return index;
86 }
87
88 static void
89 dump_index (dump_info_p di, unsigned int index)
90 {
91   fprintf (di->stream, "@%-6u ", index);
92   di->column += 8;
93 }
94
95 /* If T has not already been output, queue it for subsequent output.
96    FIELD is a string to print before printing the index.  Then, the
97    index of T is printed.  */
98
99 void
100 queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
101 {
102   unsigned int index;
103   splay_tree_node n;
104
105   /* If there's no node, just return.  This makes for fewer checks in
106      our callers.  */
107   if (!t)
108     return;
109
110   /* See if we've already queued or dumped this node.  */
111   n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
112   if (n)
113     index = ((dump_node_info_p) n->value)->index;
114   else
115     /* If we haven't, add it to the queue.  */
116     index = queue (di, t, flags);
117
118   /* Print the index of the node.  */
119   dump_maybe_newline (di);
120   fprintf (di->stream, "%-4s: ", field);
121   di->column += 6;
122   dump_index (di, index);
123 }
124
125 /* Dump the type of T.  */
126
127 void
128 queue_and_dump_type (dump_info_p di, const_tree t)
129 {
130   queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
131 }
132
133 /* Dump column control */
134 #define SOL_COLUMN 25           /* Start of line column.  */
135 #define EOL_COLUMN 55           /* End of line column.  */
136 #define COLUMN_ALIGNMENT 15     /* Alignment.  */
137
138 /* Insert a new line in the dump output, and indent to an appropriate
139    place to start printing more fields.  */
140
141 static void
142 dump_new_line (dump_info_p di)
143 {
144   fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
145   di->column = SOL_COLUMN;
146 }
147
148 /* If necessary, insert a new line.  */
149
150 static void
151 dump_maybe_newline (dump_info_p di)
152 {
153   int extra;
154
155   /* See if we need a new line.  */
156   if (di->column > EOL_COLUMN)
157     dump_new_line (di);
158   /* See if we need any padding.  */
159   else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
160     {
161       fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
162       di->column += COLUMN_ALIGNMENT - extra;
163     }
164 }
165
166 /* Dump pointer PTR using FIELD to identify it.  */
167
168 void
169 dump_pointer (dump_info_p di, const char *field, void *ptr)
170 {
171   dump_maybe_newline (di);
172   fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
173            (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
174   di->column += 15;
175 }
176
177 /* Dump integer I using FIELD to identify it.  */
178
179 void
180 dump_int (dump_info_p di, const char *field, int i)
181 {
182   dump_maybe_newline (di);
183   fprintf (di->stream, "%-4s: %-7d ", field, i);
184   di->column += 14;
185 }
186
187 /* Dump the floating point value R, using FIELD to identify it.  */
188
189 static void
190 dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
191 {
192   char buf[32];
193   real_to_decimal (buf, r, sizeof (buf), 0, true);
194   dump_maybe_newline (di);
195   fprintf (di->stream, "%-4s: %s ", field, buf);
196   di->column += strlen (buf) + 7;
197 }
198
199 /* Dump the fixed-point value F, using FIELD to identify it.  */
200
201 static void
202 dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
203 {
204   char buf[32];
205   fixed_to_decimal (buf, f, sizeof (buf));
206   dump_maybe_newline (di);
207   fprintf (di->stream, "%-4s: %s ", field, buf);
208   di->column += strlen (buf) + 7;
209 }
210
211
212 /* Dump the string S.  */
213
214 void
215 dump_string (dump_info_p di, const char *string)
216 {
217   dump_maybe_newline (di);
218   fprintf (di->stream, "%-13s ", string);
219   if (strlen (string) > 13)
220     di->column += strlen (string) + 1;
221   else
222     di->column += 14;
223 }
224
225 /* Dump the string field S.  */
226
227 void
228 dump_string_field (dump_info_p di, const char *field, const char *string)
229 {
230   dump_maybe_newline (di);
231   fprintf (di->stream, "%-4s: %-7s ", field, string);
232   if (strlen (string) > 7)
233     di->column += 6 + strlen (string) + 1;
234   else
235     di->column += 14;
236 }
237
238 /* Dump the next node in the queue.  */
239
240 static void
241 dequeue_and_dump (dump_info_p di)
242 {
243   dump_queue_p dq;
244   splay_tree_node stn;
245   dump_node_info_p dni;
246   tree t;
247   unsigned int index;
248   enum tree_code code;
249   enum tree_code_class code_class;
250   const char* code_name;
251
252   /* Get the next node from the queue.  */
253   dq = di->queue;
254   stn = dq->node;
255   t = (tree) stn->key;
256   dni = (dump_node_info_p) stn->value;
257   index = dni->index;
258
259   /* Remove the node from the queue, and put it on the free list.  */
260   di->queue = dq->next;
261   if (!di->queue)
262     di->queue_end = 0;
263   dq->next = di->free_list;
264   di->free_list = dq;
265
266   /* Print the node index.  */
267   dump_index (di, index);
268   /* And the type of node this is.  */
269   if (dni->binfo_p)
270     code_name = "binfo";
271   else
272     code_name = tree_code_name[(int) TREE_CODE (t)];
273   fprintf (di->stream, "%-16s ", code_name);
274   di->column = 25;
275
276   /* Figure out what kind of node this is.  */
277   code = TREE_CODE (t);
278   code_class = TREE_CODE_CLASS (code);
279
280   /* Although BINFOs are TREE_VECs, we dump them specially so as to be
281      more informative.  */
282   if (dni->binfo_p)
283     {
284       unsigned ix;
285       tree base;
286       VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (t);
287
288       dump_child ("type", BINFO_TYPE (t));
289
290       if (BINFO_VIRTUAL_P (t))
291         dump_string_field (di, "spec", "virt");
292
293       dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
294       for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
295         {
296           tree access = (accesses ? VEC_index (tree, accesses, ix)
297                          : access_public_node);
298           const char *string = NULL;
299
300           if (access == access_public_node)
301             string = "pub";
302           else if (access == access_protected_node)
303             string = "prot";
304           else if (access == access_private_node)
305             string = "priv";
306           else
307             gcc_unreachable ();
308
309           dump_string_field (di, "accs", string);
310           queue_and_dump_index (di, "binf", base, DUMP_BINFO);
311         }
312
313       goto done;
314     }
315
316   /* We can knock off a bunch of expression nodes in exactly the same
317      way.  */
318   if (IS_EXPR_CODE_CLASS (code_class))
319     {
320       /* If we're dumping children, dump them now.  */
321       queue_and_dump_type (di, t);
322
323       switch (code_class)
324         {
325         case tcc_unary:
326           dump_child ("op 0", TREE_OPERAND (t, 0));
327           break;
328
329         case tcc_binary:
330         case tcc_comparison:
331           dump_child ("op 0", TREE_OPERAND (t, 0));
332           dump_child ("op 1", TREE_OPERAND (t, 1));
333           break;
334
335         case tcc_expression:
336         case tcc_reference:
337         case tcc_statement:
338         case tcc_vl_exp:
339           /* These nodes are handled explicitly below.  */
340           break;
341
342         default:
343           gcc_unreachable ();
344         }
345     }
346   else if (DECL_P (t))
347     {
348       expanded_location xloc;
349       /* All declarations have names.  */
350       if (DECL_NAME (t))
351         dump_child ("name", DECL_NAME (t));
352       if (DECL_ASSEMBLER_NAME_SET_P (t)
353           && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
354         dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
355       if (DECL_ABSTRACT_ORIGIN (t))
356         dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
357       /* And types.  */
358       queue_and_dump_type (di, t);
359       dump_child ("scpe", DECL_CONTEXT (t));
360       /* And a source position.  */
361       xloc = expand_location (DECL_SOURCE_LOCATION (t));
362       if (xloc.file)
363         {
364           const char *filename = lbasename (xloc.file);
365
366           dump_maybe_newline (di);
367           fprintf (di->stream, "srcp: %s:%-6d ", filename,
368                    xloc.line);
369           di->column += 6 + strlen (filename) + 8;
370         }
371       /* And any declaration can be compiler-generated.  */
372       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
373           && DECL_ARTIFICIAL (t))
374         dump_string_field (di, "note", "artificial");
375       if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
376         dump_child ("chain", DECL_CHAIN (t));
377     }
378   else if (code_class == tcc_type)
379     {
380       /* All types have qualifiers.  */
381       int quals = lang_hooks.tree_dump.type_quals (t);
382
383       if (quals != TYPE_UNQUALIFIED)
384         {
385           fprintf (di->stream, "qual: %c%c%c     ",
386                    (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
387                    (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
388                    (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
389           di->column += 14;
390         }
391
392       /* All types have associated declarations.  */
393       dump_child ("name", TYPE_NAME (t));
394
395       /* All types have a main variant.  */
396       if (TYPE_MAIN_VARIANT (t) != t)
397         dump_child ("unql", TYPE_MAIN_VARIANT (t));
398
399       /* And sizes.  */
400       dump_child ("size", TYPE_SIZE (t));
401
402       /* All types have alignments.  */
403       dump_int (di, "algn", TYPE_ALIGN (t));
404     }
405   else if (code_class == tcc_constant)
406     /* All constants can have types.  */
407     queue_and_dump_type (di, t);
408
409   /* Give the language-specific code a chance to print something.  If
410      it's completely taken care of things, don't bother printing
411      anything more ourselves.  */
412   if (lang_hooks.tree_dump.dump_tree (di, t))
413     goto done;
414
415   /* Now handle the various kinds of nodes.  */
416   switch (code)
417     {
418       int i;
419
420     case IDENTIFIER_NODE:
421       dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
422       dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
423       break;
424
425     case TREE_LIST:
426       dump_child ("purp", TREE_PURPOSE (t));
427       dump_child ("valu", TREE_VALUE (t));
428       dump_child ("chan", TREE_CHAIN (t));
429       break;
430
431     case STATEMENT_LIST:
432       {
433         tree_stmt_iterator it;
434         for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
435           {
436             char buffer[32];
437             sprintf (buffer, "%u", i);
438             dump_child (buffer, tsi_stmt (it));
439           }
440       }
441       break;
442
443     case TREE_VEC:
444       dump_int (di, "lngt", TREE_VEC_LENGTH (t));
445       for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
446         {
447           char buffer[32];
448           sprintf (buffer, "%u", i);
449           dump_child (buffer, TREE_VEC_ELT (t, i));
450         }
451       break;
452
453     case INTEGER_TYPE:
454     case ENUMERAL_TYPE:
455       dump_int (di, "prec", TYPE_PRECISION (t));
456       dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
457       dump_child ("min", TYPE_MIN_VALUE (t));
458       dump_child ("max", TYPE_MAX_VALUE (t));
459
460       if (code == ENUMERAL_TYPE)
461         dump_child ("csts", TYPE_VALUES (t));
462       break;
463
464     case REAL_TYPE:
465       dump_int (di, "prec", TYPE_PRECISION (t));
466       break;
467
468     case FIXED_POINT_TYPE:
469       dump_int (di, "prec", TYPE_PRECISION (t));
470       dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
471       dump_string_field (di, "saturating",
472                          TYPE_SATURATING (t) ? "saturating": "non-saturating");
473       break;
474
475     case POINTER_TYPE:
476       dump_child ("ptd", TREE_TYPE (t));
477       break;
478
479     case REFERENCE_TYPE:
480       dump_child ("refd", TREE_TYPE (t));
481       break;
482
483     case METHOD_TYPE:
484       dump_child ("clas", TYPE_METHOD_BASETYPE (t));
485       /* Fall through.  */
486
487     case FUNCTION_TYPE:
488       dump_child ("retn", TREE_TYPE (t));
489       dump_child ("prms", TYPE_ARG_TYPES (t));
490       break;
491
492     case ARRAY_TYPE:
493       dump_child ("elts", TREE_TYPE (t));
494       dump_child ("domn", TYPE_DOMAIN (t));
495       break;
496
497     case RECORD_TYPE:
498     case UNION_TYPE:
499       if (TREE_CODE (t) == RECORD_TYPE)
500         dump_string_field (di, "tag", "struct");
501       else
502         dump_string_field (di, "tag", "union");
503
504       dump_child ("flds", TYPE_FIELDS (t));
505       dump_child ("fncs", TYPE_METHODS (t));
506       queue_and_dump_index (di, "binf", TYPE_BINFO (t),
507                             DUMP_BINFO);
508       break;
509
510     case CONST_DECL:
511       dump_child ("cnst", DECL_INITIAL (t));
512       break;
513
514     case DEBUG_EXPR_DECL:
515       dump_int (di, "-uid", DEBUG_TEMP_UID (t));
516       /* Fall through.  */
517
518     case VAR_DECL:
519     case PARM_DECL:
520     case FIELD_DECL:
521     case RESULT_DECL:
522       if (TREE_CODE (t) == PARM_DECL)
523         dump_child ("argt", DECL_ARG_TYPE (t));
524       else
525         dump_child ("init", DECL_INITIAL (t));
526       dump_child ("size", DECL_SIZE (t));
527       dump_int (di, "algn", DECL_ALIGN (t));
528
529       if (TREE_CODE (t) == FIELD_DECL)
530         {
531           if (DECL_FIELD_OFFSET (t))
532             dump_child ("bpos", bit_position (t));
533         }
534       else if (TREE_CODE (t) == VAR_DECL
535                || TREE_CODE (t) == PARM_DECL)
536         {
537           dump_int (di, "used", TREE_USED (t));
538           if (DECL_REGISTER (t))
539             dump_string_field (di, "spec", "register");
540         }
541       break;
542
543     case FUNCTION_DECL:
544       dump_child ("args", DECL_ARGUMENTS (t));
545       if (DECL_EXTERNAL (t))
546         dump_string_field (di, "body", "undefined");
547       if (TREE_PUBLIC (t))
548         dump_string_field (di, "link", "extern");
549       else
550         dump_string_field (di, "link", "static");
551       if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
552         dump_child ("body", DECL_SAVED_TREE (t));
553       break;
554
555     case INTEGER_CST:
556       if (TREE_INT_CST_HIGH (t))
557         dump_int (di, "high", TREE_INT_CST_HIGH (t));
558       dump_int (di, "low", TREE_INT_CST_LOW (t));
559       break;
560
561     case STRING_CST:
562       fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
563       dump_int (di, "lngt", TREE_STRING_LENGTH (t));
564       break;
565
566     case REAL_CST:
567       dump_real (di, "valu", TREE_REAL_CST_PTR (t));
568       break;
569
570     case FIXED_CST:
571       dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
572       break;
573
574     case TRUTH_NOT_EXPR:
575     case ADDR_EXPR:
576     case INDIRECT_REF:
577     case CLEANUP_POINT_EXPR:
578     case SAVE_EXPR:
579     case REALPART_EXPR:
580     case IMAGPART_EXPR:
581       /* These nodes are unary, but do not have code class `1'.  */
582       dump_child ("op 0", TREE_OPERAND (t, 0));
583       break;
584
585     case TRUTH_ANDIF_EXPR:
586     case TRUTH_ORIF_EXPR:
587     case INIT_EXPR:
588     case MODIFY_EXPR:
589     case COMPOUND_EXPR:
590     case PREDECREMENT_EXPR:
591     case PREINCREMENT_EXPR:
592     case POSTDECREMENT_EXPR:
593     case POSTINCREMENT_EXPR:
594       /* These nodes are binary, but do not have code class `2'.  */
595       dump_child ("op 0", TREE_OPERAND (t, 0));
596       dump_child ("op 1", TREE_OPERAND (t, 1));
597       break;
598
599     case COMPONENT_REF:
600       dump_child ("op 0", TREE_OPERAND (t, 0));
601       dump_child ("op 1", TREE_OPERAND (t, 1));
602       dump_child ("op 2", TREE_OPERAND (t, 2));
603       break;
604
605     case ARRAY_REF:
606     case ARRAY_RANGE_REF:
607       dump_child ("op 0", TREE_OPERAND (t, 0));
608       dump_child ("op 1", TREE_OPERAND (t, 1));
609       dump_child ("op 2", TREE_OPERAND (t, 2));
610       dump_child ("op 3", TREE_OPERAND (t, 3));
611       break;
612
613     case COND_EXPR:
614       dump_child ("op 0", TREE_OPERAND (t, 0));
615       dump_child ("op 1", TREE_OPERAND (t, 1));
616       dump_child ("op 2", TREE_OPERAND (t, 2));
617       break;
618
619     case TRY_FINALLY_EXPR:
620       dump_child ("op 0", TREE_OPERAND (t, 0));
621       dump_child ("op 1", TREE_OPERAND (t, 1));
622       break;
623
624     case CALL_EXPR:
625       {
626         int i = 0;
627         tree arg;
628         call_expr_arg_iterator iter;
629         dump_child ("fn", CALL_EXPR_FN (t));
630         FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
631           {
632             char buffer[32];
633             sprintf (buffer, "%u", i);
634             dump_child (buffer, arg);
635             i++;
636           }
637       }
638       break;
639
640     case CONSTRUCTOR:
641       {
642         unsigned HOST_WIDE_INT cnt;
643         tree index, value;
644         dump_int (di, "lngt", VEC_length (constructor_elt,
645                                           CONSTRUCTOR_ELTS (t)));
646         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
647           {
648             dump_child ("idx", index);
649             dump_child ("val", value);
650           }
651       }
652       break;
653
654     case BIND_EXPR:
655       dump_child ("vars", TREE_OPERAND (t, 0));
656       dump_child ("body", TREE_OPERAND (t, 1));
657       break;
658
659     case LOOP_EXPR:
660       dump_child ("body", TREE_OPERAND (t, 0));
661       break;
662
663     case EXIT_EXPR:
664       dump_child ("cond", TREE_OPERAND (t, 0));
665       break;
666
667     case RETURN_EXPR:
668       dump_child ("expr", TREE_OPERAND (t, 0));
669       break;
670
671     case TARGET_EXPR:
672       dump_child ("decl", TREE_OPERAND (t, 0));
673       dump_child ("init", TREE_OPERAND (t, 1));
674       dump_child ("clnp", TREE_OPERAND (t, 2));
675       /* There really are two possible places the initializer can be.
676          After RTL expansion, the second operand is moved to the
677          position of the fourth operand, and the second operand
678          becomes NULL.  */
679       dump_child ("init", TREE_OPERAND (t, 3));
680       break;
681
682     case CASE_LABEL_EXPR:
683       dump_child ("name", CASE_LABEL (t));
684       if (CASE_LOW (t))
685         {
686           dump_child ("low ", CASE_LOW (t));
687           if (CASE_HIGH (t))
688             dump_child ("high", CASE_HIGH (t));
689         }
690       break;
691     case LABEL_EXPR:
692       dump_child ("name", TREE_OPERAND (t,0));
693       break;
694     case GOTO_EXPR:
695       dump_child ("labl", TREE_OPERAND (t, 0));
696       break;
697     case SWITCH_EXPR:
698       dump_child ("cond", TREE_OPERAND (t, 0));
699       dump_child ("body", TREE_OPERAND (t, 1));
700       if (TREE_OPERAND (t, 2))
701         {
702           dump_child ("labl", TREE_OPERAND (t,2));
703         }
704       break;
705     case OMP_CLAUSE:
706       {
707         int i;
708         fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
709         for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
710           dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
711       }
712       break;
713     default:
714       /* There are no additional fields to print.  */
715       break;
716     }
717
718  done:
719   if (dump_flag (di, TDF_ADDRESS, NULL))
720     dump_pointer (di, "addr", (void *)t);
721
722   /* Terminate the line.  */
723   fprintf (di->stream, "\n");
724 }
725
726 /* Return nonzero if FLAG has been specified for the dump, and NODE
727    is not the root node of the dump.  */
728
729 int dump_flag (dump_info_p di, int flag, const_tree node)
730 {
731   return (di->flags & flag) && (node != di->node);
732 }
733
734 /* Dump T, and all its children, on STREAM.  */
735
736 void
737 dump_node (const_tree t, int flags, FILE *stream)
738 {
739   struct dump_info di;
740   dump_queue_p dq;
741   dump_queue_p next_dq;
742
743   /* Initialize the dump-information structure.  */
744   di.stream = stream;
745   di.index = 0;
746   di.column = 0;
747   di.queue = 0;
748   di.queue_end = 0;
749   di.free_list = 0;
750   di.flags = flags;
751   di.node = t;
752   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
753                              (splay_tree_delete_value_fn) &free);
754
755   /* Queue up the first node.  */
756   queue (&di, t, DUMP_NONE);
757
758   /* Until the queue is empty, keep dumping nodes.  */
759   while (di.queue)
760     dequeue_and_dump (&di);
761
762   /* Now, clean up.  */
763   for (dq = di.free_list; dq; dq = next_dq)
764     {
765       next_dq = dq->next;
766       free (dq);
767     }
768   splay_tree_delete (di.nodes);
769 }
770 \f
771
772 /* Table of tree dump switches. This must be consistent with the
773    tree_dump_index enumeration in tree-pass.h.  */
774 static struct dump_file_info dump_files[TDI_end] =
775 {
776   {NULL, NULL, NULL, 0, 0, 0},
777   {".cgraph", "ipa-cgraph", NULL, TDF_IPA, 0,  0},
778   {".tu", "translation-unit", NULL, TDF_TREE, 0, 1},
779   {".class", "class-hierarchy", NULL, TDF_TREE, 0, 2},
780   {".original", "tree-original", NULL, TDF_TREE, 0, 3},
781   {".gimple", "tree-gimple", NULL, TDF_TREE, 0, 4},
782   {".nested", "tree-nested", NULL, TDF_TREE, 0, 5},
783   {".vcg", "tree-vcg", NULL, TDF_TREE, 0, 6},
784   {".ads", "ada-spec", NULL, 0, 0, 7},
785 #define FIRST_AUTO_NUMBERED_DUMP 8
786
787   {NULL, "tree-all", NULL, TDF_TREE, 0, 0},
788   {NULL, "rtl-all", NULL, TDF_RTL, 0, 0},
789   {NULL, "ipa-all", NULL, TDF_IPA, 0, 0},
790 };
791
792 /* Dynamically registered tree dump files and switches.  */
793 static struct dump_file_info *extra_dump_files;
794 static size_t extra_dump_files_in_use;
795 static size_t extra_dump_files_alloced;
796
797 /* Define a name->number mapping for a dump flag value.  */
798 struct dump_option_value_info
799 {
800   const char *const name;       /* the name of the value */
801   const int value;              /* the value of the name */
802 };
803
804 /* Table of dump options. This must be consistent with the TDF_* flags
805    in tree.h */
806 static const struct dump_option_value_info dump_options[] =
807 {
808   {"address", TDF_ADDRESS},
809   {"asmname", TDF_ASMNAME},
810   {"slim", TDF_SLIM},
811   {"raw", TDF_RAW},
812   {"graph", TDF_GRAPH},
813   {"details", TDF_DETAILS},
814   {"cselib", TDF_CSELIB},
815   {"stats", TDF_STATS},
816   {"blocks", TDF_BLOCKS},
817   {"vops", TDF_VOPS},
818   {"lineno", TDF_LINENO},
819   {"uid", TDF_UID},
820   {"stmtaddr", TDF_STMTADDR},
821   {"memsyms", TDF_MEMSYMS},
822   {"verbose", TDF_VERBOSE},
823   {"eh", TDF_EH},
824   {"alias", TDF_ALIAS},
825   {"nouid", TDF_NOUID},
826   {"enumerate_locals", TDF_ENUMERATE_LOCALS},
827   {"scev", TDF_SCEV},
828   {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
829             | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
830             | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
831   {NULL, 0}
832 };
833
834 unsigned int
835 dump_register (const char *suffix, const char *swtch, const char *glob,
836                int flags)
837 {
838   static int next_dump = FIRST_AUTO_NUMBERED_DUMP;
839   int num = next_dump++;
840
841   size_t count = extra_dump_files_in_use++;
842
843   if (count >= extra_dump_files_alloced)
844     {
845       if (extra_dump_files_alloced == 0)
846         extra_dump_files_alloced = 32;
847       else
848         extra_dump_files_alloced *= 2;
849       extra_dump_files = XRESIZEVEC (struct dump_file_info,
850                                      extra_dump_files,
851                                      extra_dump_files_alloced);
852     }
853
854   memset (&extra_dump_files[count], 0, sizeof (struct dump_file_info));
855   extra_dump_files[count].suffix = suffix;
856   extra_dump_files[count].swtch = swtch;
857   extra_dump_files[count].glob = glob;
858   extra_dump_files[count].flags = flags;
859   extra_dump_files[count].num = num;
860
861   return count + TDI_end;
862 }
863
864
865 /* Return the dump_file_info for the given phase.  */
866
867 struct dump_file_info *
868 get_dump_file_info (int phase)
869 {
870   if (phase < TDI_end)
871     return &dump_files[phase];
872   else if ((size_t) (phase - TDI_end) >= extra_dump_files_in_use)
873     return NULL;
874   else
875     return extra_dump_files + (phase - TDI_end);
876 }
877
878
879 /* Return the name of the dump file for the given phase.
880    If the dump is not enabled, returns NULL.  */
881
882 char *
883 get_dump_file_name (int phase)
884 {
885   char dump_id[10];
886   struct dump_file_info *dfi;
887
888   if (phase == TDI_none)
889     return NULL;
890
891   dfi = get_dump_file_info (phase);
892   if (dfi->state == 0)
893     return NULL;
894
895   if (dfi->num < 0)
896     dump_id[0] = '\0';
897   else
898     {
899       char suffix;
900       if (dfi->flags & TDF_TREE)
901         suffix = 't';
902       else if (dfi->flags & TDF_IPA)
903         suffix = 'i';
904       else
905         suffix = 'r';
906
907       if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
908         dump_id[0] = '\0';
909     }
910
911   return concat (dump_base_name, dump_id, dfi->suffix, NULL);
912 }
913
914 /* Begin a tree dump for PHASE. Stores any user supplied flag in
915    *FLAG_PTR and returns a stream to write to. If the dump is not
916    enabled, returns NULL.
917    Multiple calls will reopen and append to the dump file.  */
918
919 FILE *
920 dump_begin (int phase, int *flag_ptr)
921 {
922   char *name;
923   struct dump_file_info *dfi;
924   FILE *stream;
925
926   if (phase == TDI_none || !dump_enabled_p (phase))
927     return NULL;
928
929   name = get_dump_file_name (phase);
930   dfi = get_dump_file_info (phase);
931   stream = fopen (name, dfi->state < 0 ? "w" : "a");
932   if (!stream)
933     error ("could not open dump file %qs: %m", name);
934   else
935     dfi->state = 1;
936   free (name);
937
938   if (flag_ptr)
939     *flag_ptr = dfi->flags;
940
941   return stream;
942 }
943
944 /* Returns nonzero if tree dump PHASE is enabled.  If PHASE is
945    TDI_tree_all, return nonzero if any dump is enabled.  */
946
947 int
948 dump_enabled_p (int phase)
949 {
950   if (phase == TDI_tree_all)
951     {
952       size_t i;
953       for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
954         if (dump_files[i].state)
955           return 1;
956       for (i = 0; i < extra_dump_files_in_use; i++)
957         if (extra_dump_files[i].state)
958           return 1;
959       return 0;
960     }
961   else
962     {
963       struct dump_file_info *dfi = get_dump_file_info (phase);
964       return dfi->state;
965     }
966 }
967
968 /* Returns nonzero if tree dump PHASE has been initialized.  */
969
970 int
971 dump_initialized_p (int phase)
972 {
973   struct dump_file_info *dfi = get_dump_file_info (phase);
974   return dfi->state > 0;
975 }
976
977 /* Returns the switch name of PHASE.  */
978
979 const char *
980 dump_flag_name (int phase)
981 {
982   struct dump_file_info *dfi = get_dump_file_info (phase);
983   return dfi->swtch;
984 }
985
986 /* Finish a tree dump for PHASE. STREAM is the stream created by
987    dump_begin.  */
988
989 void
990 dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
991 {
992   fclose (stream);
993 }
994
995 /* Enable all tree dumps.  Return number of enabled tree dumps.  */
996
997 static int
998 dump_enable_all (int flags)
999 {
1000   int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
1001   int n = 0;
1002   size_t i;
1003
1004   for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
1005     if ((dump_files[i].flags & ir_dump_type))
1006       {
1007         dump_files[i].state = -1;
1008         dump_files[i].flags |= flags;
1009         n++;
1010       }
1011
1012   for (i = 0; i < extra_dump_files_in_use; i++)
1013     if ((extra_dump_files[i].flags & ir_dump_type))
1014       {
1015         extra_dump_files[i].state = -1;
1016         extra_dump_files[i].flags |= flags;
1017         n++;
1018       }
1019
1020   return n;
1021 }
1022
1023 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
1024    relevant details in the dump_files array.  */
1025
1026 static int
1027 dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
1028 {
1029   const char *option_value;
1030   const char *ptr;
1031   int flags;
1032
1033   if (doglob && !dfi->glob)
1034     return 0;
1035
1036   option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
1037   if (!option_value)
1038     return 0;
1039
1040   if (*option_value && *option_value != '-')
1041     return 0;
1042
1043   ptr = option_value;
1044   flags = 0;
1045
1046   while (*ptr)
1047     {
1048       const struct dump_option_value_info *option_ptr;
1049       const char *end_ptr;
1050       unsigned length;
1051
1052       while (*ptr == '-')
1053         ptr++;
1054       end_ptr = strchr (ptr, '-');
1055       if (!end_ptr)
1056         end_ptr = ptr + strlen (ptr);
1057       length = end_ptr - ptr;
1058
1059       for (option_ptr = dump_options; option_ptr->name; option_ptr++)
1060         if (strlen (option_ptr->name) == length
1061             && !memcmp (option_ptr->name, ptr, length))
1062           {
1063             flags |= option_ptr->value;
1064             goto found;
1065           }
1066       warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
1067                length, ptr, dfi->swtch);
1068     found:;
1069       ptr = end_ptr;
1070     }
1071
1072   dfi->state = -1;
1073   dfi->flags |= flags;
1074
1075   /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
1076      known dumps.  */
1077   if (dfi->suffix == NULL)
1078     dump_enable_all (dfi->flags);
1079
1080   return 1;
1081 }
1082
1083 int
1084 dump_switch_p (const char *arg)
1085 {
1086   size_t i;
1087   int any = 0;
1088
1089   for (i = TDI_none + 1; i != TDI_end; i++)
1090     any |= dump_switch_p_1 (arg, &dump_files[i], false);
1091
1092   /* Don't glob if we got a hit already */
1093   if (!any)
1094     for (i = TDI_none + 1; i != TDI_end; i++)
1095       any |= dump_switch_p_1 (arg, &dump_files[i], true);
1096
1097   for (i = 0; i < extra_dump_files_in_use; i++)
1098     any |= dump_switch_p_1 (arg, &extra_dump_files[i], false);
1099
1100   if (!any)
1101     for (i = 0; i < extra_dump_files_in_use; i++)
1102       any |= dump_switch_p_1 (arg, &extra_dump_files[i], true);
1103
1104
1105   return any;
1106 }
1107
1108 /* Dump FUNCTION_DECL FN as tree dump PHASE.  */
1109
1110 void
1111 dump_function (int phase, tree fn)
1112 {
1113   FILE *stream;
1114   int flags;
1115
1116   stream = dump_begin (phase, &flags);
1117   if (stream)
1118     {
1119       dump_function_to_file (fn, stream, flags);
1120       dump_end (phase, stream);
1121     }
1122 }
1123
1124 bool
1125 enable_rtl_dump_file (void)
1126 {
1127   return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0;
1128 }