OSDN Git Service

* config/sh/elf.h (LIB_SPEC): Define.
[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 "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   {"stats", TDF_STATS},
818   {"blocks", TDF_BLOCKS},
819   {"vops", TDF_VOPS},
820   {"lineno", TDF_LINENO},
821   {"uid", TDF_UID},
822   {"stmtaddr", TDF_STMTADDR},
823   {"memsyms", TDF_MEMSYMS},
824   {"verbose", TDF_VERBOSE},
825   {"eh", TDF_EH},
826   {"alias", TDF_ALIAS},
827   {"nouid", TDF_NOUID},
828   {"enumerate_locals", TDF_ENUMERATE_LOCALS},
829   {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
830             | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
831             | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS)},
832   {NULL, 0}
833 };
834
835 unsigned int
836 dump_register (const char *suffix, const char *swtch, const char *glob,
837                int flags)
838 {
839   static int next_dump = FIRST_AUTO_NUMBERED_DUMP;
840   int num = next_dump++;
841
842   size_t count = extra_dump_files_in_use++;
843
844   if (count >= extra_dump_files_alloced)
845     {
846       if (extra_dump_files_alloced == 0)
847         extra_dump_files_alloced = 32;
848       else
849         extra_dump_files_alloced *= 2;
850       extra_dump_files = XRESIZEVEC (struct dump_file_info,
851                                      extra_dump_files,
852                                      extra_dump_files_alloced);
853     }
854
855   memset (&extra_dump_files[count], 0, sizeof (struct dump_file_info));
856   extra_dump_files[count].suffix = suffix;
857   extra_dump_files[count].swtch = swtch;
858   extra_dump_files[count].glob = glob;
859   extra_dump_files[count].flags = flags;
860   extra_dump_files[count].num = num;
861
862   return count + TDI_end;
863 }
864
865
866 /* Return the dump_file_info for the given phase.  */
867
868 struct dump_file_info *
869 get_dump_file_info (int phase)
870 {
871   if (phase < TDI_end)
872     return &dump_files[phase];
873   else if ((size_t) (phase - TDI_end) >= extra_dump_files_in_use)
874     return NULL;
875   else
876     return extra_dump_files + (phase - TDI_end);
877 }
878
879
880 /* Return the name of the dump file for the given phase.
881    If the dump is not enabled, returns NULL.  */
882
883 char *
884 get_dump_file_name (int phase)
885 {
886   char dump_id[10];
887   struct dump_file_info *dfi;
888
889   if (phase == TDI_none)
890     return NULL;
891
892   dfi = get_dump_file_info (phase);
893   if (dfi->state == 0)
894     return NULL;
895
896   if (dfi->num < 0)
897     dump_id[0] = '\0';
898   else
899     {
900       char suffix;
901       if (dfi->flags & TDF_TREE)
902         suffix = 't';
903       else if (dfi->flags & TDF_IPA)
904         suffix = 'i';
905       else
906         suffix = 'r';
907
908       if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
909         dump_id[0] = '\0';
910     }
911
912   return concat (dump_base_name, dump_id, dfi->suffix, NULL);
913 }
914
915 /* Begin a tree dump for PHASE. Stores any user supplied flag in
916    *FLAG_PTR and returns a stream to write to. If the dump is not
917    enabled, returns NULL.
918    Multiple calls will reopen and append to the dump file.  */
919
920 FILE *
921 dump_begin (int phase, int *flag_ptr)
922 {
923   char *name;
924   struct dump_file_info *dfi;
925   FILE *stream;
926
927   if (phase == TDI_none || !dump_enabled_p (phase))
928     return NULL;
929
930   name = get_dump_file_name (phase);
931   dfi = get_dump_file_info (phase);
932   stream = fopen (name, dfi->state < 0 ? "w" : "a");
933   if (!stream)
934     error ("could not open dump file %qs: %m", name);
935   else
936     dfi->state = 1;
937   free (name);
938
939   if (flag_ptr)
940     *flag_ptr = dfi->flags;
941
942   return stream;
943 }
944
945 /* Returns nonzero if tree dump PHASE is enabled.  If PHASE is
946    TDI_tree_all, return nonzero if any dump is enabled.  */
947
948 int
949 dump_enabled_p (int phase)
950 {
951   if (phase == TDI_tree_all)
952     {
953       size_t i;
954       for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
955         if (dump_files[i].state)
956           return 1;
957       for (i = 0; i < extra_dump_files_in_use; i++)
958         if (extra_dump_files[i].state)
959           return 1;
960       return 0;
961     }
962   else
963     {
964       struct dump_file_info *dfi = get_dump_file_info (phase);
965       return dfi->state;
966     }
967 }
968
969 /* Returns nonzero if tree dump PHASE has been initialized.  */
970
971 int
972 dump_initialized_p (int phase)
973 {
974   struct dump_file_info *dfi = get_dump_file_info (phase);
975   return dfi->state > 0;
976 }
977
978 /* Returns the switch name of PHASE.  */
979
980 const char *
981 dump_flag_name (int phase)
982 {
983   struct dump_file_info *dfi = get_dump_file_info (phase);
984   return dfi->swtch;
985 }
986
987 /* Finish a tree dump for PHASE. STREAM is the stream created by
988    dump_begin.  */
989
990 void
991 dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
992 {
993   fclose (stream);
994 }
995
996 /* Enable all tree dumps.  Return number of enabled tree dumps.  */
997
998 static int
999 dump_enable_all (int flags)
1000 {
1001   int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
1002   int n = 0;
1003   size_t i;
1004
1005   for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
1006     if ((dump_files[i].flags & ir_dump_type))
1007       {
1008         dump_files[i].state = -1;
1009         dump_files[i].flags |= flags;
1010         n++;
1011       }
1012
1013   for (i = 0; i < extra_dump_files_in_use; i++)
1014     if ((extra_dump_files[i].flags & ir_dump_type))
1015       {
1016         extra_dump_files[i].state = -1;
1017         extra_dump_files[i].flags |= flags;
1018         n++;
1019       }
1020
1021   return n;
1022 }
1023
1024 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
1025    relevant details in the dump_files array.  */
1026
1027 static int
1028 dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
1029 {
1030   const char *option_value;
1031   const char *ptr;
1032   int flags;
1033
1034   if (doglob && !dfi->glob)
1035     return 0;
1036
1037   option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
1038   if (!option_value)
1039     return 0;
1040
1041   if (*option_value && *option_value != '-')
1042     return 0;
1043
1044   ptr = option_value;
1045   flags = 0;
1046
1047   while (*ptr)
1048     {
1049       const struct dump_option_value_info *option_ptr;
1050       const char *end_ptr;
1051       unsigned length;
1052
1053       while (*ptr == '-')
1054         ptr++;
1055       end_ptr = strchr (ptr, '-');
1056       if (!end_ptr)
1057         end_ptr = ptr + strlen (ptr);
1058       length = end_ptr - ptr;
1059
1060       for (option_ptr = dump_options; option_ptr->name; option_ptr++)
1061         if (strlen (option_ptr->name) == length
1062             && !memcmp (option_ptr->name, ptr, length))
1063           {
1064             flags |= option_ptr->value;
1065             goto found;
1066           }
1067       warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
1068                length, ptr, dfi->swtch);
1069     found:;
1070       ptr = end_ptr;
1071     }
1072
1073   dfi->state = -1;
1074   dfi->flags |= flags;
1075
1076   /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
1077      known dumps.  */
1078   if (dfi->suffix == NULL)
1079     dump_enable_all (dfi->flags);
1080
1081   return 1;
1082 }
1083
1084 int
1085 dump_switch_p (const char *arg)
1086 {
1087   size_t i;
1088   int any = 0;
1089
1090   for (i = TDI_none + 1; i != TDI_end; i++)
1091     any |= dump_switch_p_1 (arg, &dump_files[i], false);
1092
1093   /* Don't glob if we got a hit already */
1094   if (!any)
1095     for (i = TDI_none + 1; i != TDI_end; i++)
1096       any |= dump_switch_p_1 (arg, &dump_files[i], true);
1097
1098   for (i = 0; i < extra_dump_files_in_use; i++)
1099     any |= dump_switch_p_1 (arg, &extra_dump_files[i], false);
1100
1101   if (!any)
1102     for (i = 0; i < extra_dump_files_in_use; i++)
1103       any |= dump_switch_p_1 (arg, &extra_dump_files[i], true);
1104
1105
1106   return any;
1107 }
1108
1109 /* Dump FUNCTION_DECL FN as tree dump PHASE.  */
1110
1111 void
1112 dump_function (int phase, tree fn)
1113 {
1114   FILE *stream;
1115   int flags;
1116
1117   stream = dump_begin (phase, &flags);
1118   if (stream)
1119     {
1120       dump_function_to_file (fn, stream, flags);
1121       dump_end (phase, stream);
1122     }
1123 }
1124
1125 bool
1126 enable_rtl_dump_file (void)
1127 {
1128   return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0;
1129 }