OSDN Git Service

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