OSDN Git Service

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