OSDN Git Service

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