]> gcc.gnu.org Git - gcc.git/blame - gcc/tree-dump.c
re PR c++/10784 (Warning about choosing custom operator over copy constructor cannot...
[gcc.git] / gcc / tree-dump.c
CommitLineData
9c5a221c 1/* Tree-dumping functionality for intermediate representation.
dbbf88d1 2 Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
9c5a221c
BM
3 Written by Mark Mitchell <mark@codesourcery.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22#include "config.h"
23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
9c5a221c 26#include "tree.h"
9c5a221c
BM
27#include "splay-tree.h"
28#include "diagnostic.h"
29#include "toplev.h"
89d684bb 30#include "tree-dump.h"
9c5a221c
BM
31#include "langhooks.h"
32
79a490a9
AJ
33static unsigned int queue (dump_info_p, tree, int);
34static void dump_index (dump_info_p, unsigned int);
35static void dequeue_and_dump (dump_info_p);
36static void dump_new_line (dump_info_p);
37static void dump_maybe_newline (dump_info_p);
38static void dump_string_field (dump_info_p, const char *, const char *);
9c5a221c
BM
39
40/* Add T to the end of the queue of nodes to dump. Returns the index
41 assigned to T. */
42
43static unsigned int
79a490a9 44queue (dump_info_p di, tree t, int flags)
9c5a221c
BM
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 = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
61
62 /* Create a new entry in the splay-tree. */
63 dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
64 dni->index = index;
65 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
d92b4486 66 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
9c5a221c
BM
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
81static void
79a490a9 82dump_index (dump_info_p di, unsigned int index)
9c5a221c
BM
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
92void
79a490a9 93queue_and_dump_index (dump_info_p di, const char *field, tree t, int flags)
9c5a221c
BM
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
120void
79a490a9 121queue_and_dump_type (dump_info_p di, tree t)
9c5a221c
BM
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
134static void
79a490a9 135dump_new_line (dump_info_p di)
9c5a221c
BM
136{
137 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
138 di->column = SOL_COLUMN;
139}
140
141/* If necessary, insert a new line. */
142
143static void
79a490a9 144dump_maybe_newline (dump_info_p di)
9c5a221c
BM
145{
146 int extra;
d92b4486 147
9c5a221c
BM
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
161void
79a490a9 162dump_pointer (dump_info_p di, const char *field, void *ptr)
9c5a221c
BM
163{
164 dump_maybe_newline (di);
165 fprintf (di->stream, "%-4s: %-8lx ", field, (long) ptr);
166 di->column += 15;
167}
168
169/* Dump integer I using FIELD to identify it. */
170
171void
79a490a9 172dump_int (dump_info_p di, const char *field, int i)
9c5a221c
BM
173{
174 dump_maybe_newline (di);
175 fprintf (di->stream, "%-4s: %-7d ", field, i);
176 di->column += 14;
177}
178
179/* Dump the string S. */
180
181void
79a490a9 182dump_string (dump_info_p di, const char *string)
9c5a221c
BM
183{
184 dump_maybe_newline (di);
185 fprintf (di->stream, "%-13s ", string);
186 if (strlen (string) > 13)
187 di->column += strlen (string) + 1;
188 else
189 di->column += 14;
190}
191
192/* Dump the string field S. */
193
194static void
79a490a9 195dump_string_field (dump_info_p di, const char *field, const char *string)
9c5a221c
BM
196{
197 dump_maybe_newline (di);
198 fprintf (di->stream, "%-4s: %-7s ", field, string);
199 if (strlen (string) > 7)
200 di->column += 6 + strlen (string) + 1;
201 else
202 di->column += 14;
203}
204
9c5a221c
BM
205/* Dump the next node in the queue. */
206
d92b4486 207static void
79a490a9 208dequeue_and_dump (dump_info_p di)
9c5a221c
BM
209{
210 dump_queue_p dq;
211 splay_tree_node stn;
212 dump_node_info_p dni;
213 tree t;
214 unsigned int index;
215 enum tree_code code;
216 char code_class;
217 const char* code_name;
218
219 /* Get the next node from the queue. */
220 dq = di->queue;
221 stn = dq->node;
222 t = (tree) stn->key;
223 dni = (dump_node_info_p) stn->value;
224 index = dni->index;
225
226 /* Remove the node from the queue, and put it on the free list. */
227 di->queue = dq->next;
228 if (!di->queue)
229 di->queue_end = 0;
230 dq->next = di->free_list;
231 di->free_list = dq;
232
233 /* Print the node index. */
234 dump_index (di, index);
235 /* And the type of node this is. */
236 if (dni->binfo_p)
237 code_name = "binfo";
238 else
239 code_name = tree_code_name[(int) TREE_CODE (t)];
240 fprintf (di->stream, "%-16s ", code_name);
241 di->column = 25;
242
243 /* Figure out what kind of node this is. */
244 code = TREE_CODE (t);
245 code_class = TREE_CODE_CLASS (code);
246
247 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
248 more informative. */
249 if (dni->binfo_p)
250 {
dbbf88d1
NS
251 unsigned ix;
252 tree bases = BINFO_BASETYPES (t);
253 unsigned n_bases = bases ? TREE_VEC_LENGTH (bases): 0;
254 tree accesses = BINFO_BASEACCESSES (t);
79a490a9 255
dbbf88d1
NS
256 dump_child ("type", BINFO_TYPE (t));
257
9c5a221c
BM
258 if (TREE_VIA_VIRTUAL (t))
259 dump_string (di, "virt");
d92b4486 260
dbbf88d1
NS
261 dump_int (di, "bases", n_bases);
262 for (ix = 0; ix != n_bases; ix++)
263 {
264 tree base = TREE_VEC_ELT (bases, ix);
265 tree access = (accesses ? TREE_VEC_ELT (accesses, ix)
266 : access_public_node);
267 const char *string = NULL;
268
269 if (access == access_public_node)
270 string = "pub";
271 else if (access == access_protected_node)
272 string = "prot";
273 else if (access == access_private_node)
274 string = "priv";
275 else
276 abort ();
79a490a9 277
dbbf88d1
NS
278 dump_string (di, string);
279 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
280 }
79a490a9 281
9c5a221c
BM
282 goto done;
283 }
284
285 /* We can knock off a bunch of expression nodes in exactly the same
286 way. */
287 if (IS_EXPR_CODE_CLASS (code_class))
288 {
289 /* If we're dumping children, dump them now. */
290 queue_and_dump_type (di, t);
291
292 switch (code_class)
293 {
294 case '1':
295 dump_child ("op 0", TREE_OPERAND (t, 0));
296 break;
d92b4486 297
9c5a221c
BM
298 case '2':
299 case '<':
300 dump_child ("op 0", TREE_OPERAND (t, 0));
301 dump_child ("op 1", TREE_OPERAND (t, 1));
302 break;
d92b4486 303
9c5a221c
BM
304 case 'e':
305 /* These nodes are handled explicitly below. */
306 break;
d92b4486 307
9c5a221c 308 default:
a01da83b 309 abort ();
9c5a221c
BM
310 }
311 }
312 else if (DECL_P (t))
313 {
314 /* All declarations have names. */
315 if (DECL_NAME (t))
316 dump_child ("name", DECL_NAME (t));
d92b4486 317 if (DECL_ASSEMBLER_NAME_SET_P (t)
9c5a221c
BM
318 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
319 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
320 /* And types. */
321 queue_and_dump_type (di, t);
322 dump_child ("scpe", DECL_CONTEXT (t));
323 /* And a source position. */
324 if (DECL_SOURCE_FILE (t))
325 {
326 const char *filename = strrchr (DECL_SOURCE_FILE (t), '/');
327 if (!filename)
328 filename = DECL_SOURCE_FILE (t);
329 else
330 /* Skip the slash. */
331 ++filename;
332
333 dump_maybe_newline (di);
d92b4486 334 fprintf (di->stream, "srcp: %s:%-6d ", filename,
9c5a221c
BM
335 DECL_SOURCE_LINE (t));
336 di->column += 6 + strlen (filename) + 8;
337 }
338 /* And any declaration can be compiler-generated. */
339 if (DECL_ARTIFICIAL (t))
340 dump_string (di, "artificial");
341 if (TREE_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
342 dump_child ("chan", TREE_CHAIN (t));
343 }
344 else if (code_class == 't')
345 {
346 /* All types have qualifiers. */
347 int quals = (*lang_hooks.tree_dump.type_quals) (t);
d92b4486 348
9c5a221c
BM
349 if (quals != TYPE_UNQUALIFIED)
350 {
351 fprintf (di->stream, "qual: %c%c%c ",
352 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
353 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
354 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
355 di->column += 14;
356 }
357
358 /* All types have associated declarations. */
359 dump_child ("name", TYPE_NAME (t));
360
361 /* All types have a main variant. */
362 if (TYPE_MAIN_VARIANT (t) != t)
363 dump_child ("unql", TYPE_MAIN_VARIANT (t));
d92b4486 364
9c5a221c
BM
365 /* And sizes. */
366 dump_child ("size", TYPE_SIZE (t));
367
368 /* All types have alignments. */
369 dump_int (di, "algn", TYPE_ALIGN (t));
370 }
371 else if (code_class == 'c')
372 /* All constants can have types. */
373 queue_and_dump_type (di, t);
374
375 /* Give the language-specific code a chance to print something. If
376 it's completely taken care of things, don't bother printing
377 anything more ourselves. */
378 if ((*lang_hooks.tree_dump.dump_tree) (di, t))
379 goto done;
380
381 /* Now handle the various kinds of nodes. */
382 switch (code)
383 {
384 int i;
385
386 case IDENTIFIER_NODE:
387 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
388 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
389 break;
390
391 case TREE_LIST:
392 dump_child ("purp", TREE_PURPOSE (t));
393 dump_child ("valu", TREE_VALUE (t));
394 dump_child ("chan", TREE_CHAIN (t));
395 break;
396
397 case TREE_VEC:
398 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
399 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
400 {
401 char buffer[32];
402 sprintf (buffer, "%u", i);
403 dump_child (buffer, TREE_VEC_ELT (t, i));
404 }
405 break;
406
407 case INTEGER_TYPE:
408 case ENUMERAL_TYPE:
409 dump_int (di, "prec", TYPE_PRECISION (t));
410 if (TREE_UNSIGNED (t))
411 dump_string (di, "unsigned");
412 dump_child ("min", TYPE_MIN_VALUE (t));
413 dump_child ("max", TYPE_MAX_VALUE (t));
414
415 if (code == ENUMERAL_TYPE)
416 dump_child ("csts", TYPE_VALUES (t));
417 break;
418
419 case REAL_TYPE:
420 dump_int (di, "prec", TYPE_PRECISION (t));
421 break;
422
423 case POINTER_TYPE:
424 dump_child ("ptd", TREE_TYPE (t));
425 break;
426
427 case REFERENCE_TYPE:
428 dump_child ("refd", TREE_TYPE (t));
429 break;
430
431 case METHOD_TYPE:
432 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
433 /* Fall through. */
434
435 case FUNCTION_TYPE:
436 dump_child ("retn", TREE_TYPE (t));
437 dump_child ("prms", TYPE_ARG_TYPES (t));
438 break;
439
440 case ARRAY_TYPE:
441 dump_child ("elts", TREE_TYPE (t));
442 dump_child ("domn", TYPE_DOMAIN (t));
443 break;
444
445 case RECORD_TYPE:
446 case UNION_TYPE:
447 if (TREE_CODE (t) == RECORD_TYPE)
448 dump_string (di, "struct");
449 else
450 dump_string (di, "union");
d92b4486 451
9c5a221c
BM
452 dump_child ("flds", TYPE_FIELDS (t));
453 dump_child ("fncs", TYPE_METHODS (t));
d92b4486 454 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
9c5a221c
BM
455 DUMP_BINFO);
456 break;
457
458 case CONST_DECL:
459 dump_child ("cnst", DECL_INITIAL (t));
460 break;
461
462 case VAR_DECL:
463 case PARM_DECL:
464 case FIELD_DECL:
465 case RESULT_DECL:
466 if (TREE_CODE (t) == PARM_DECL)
467 dump_child ("argt", DECL_ARG_TYPE (t));
468 else
469 dump_child ("init", DECL_INITIAL (t));
470 dump_child ("size", DECL_SIZE (t));
471 dump_int (di, "algn", DECL_ALIGN (t));
472
473 if (TREE_CODE (t) == FIELD_DECL)
474 {
9c5a221c
BM
475 if (DECL_FIELD_OFFSET (t))
476 dump_child ("bpos", bit_position (t));
477 }
d92b4486 478 else if (TREE_CODE (t) == VAR_DECL
9c5a221c
BM
479 || TREE_CODE (t) == PARM_DECL)
480 {
481 dump_int (di, "used", TREE_USED (t));
482 if (DECL_REGISTER (t))
483 dump_string (di, "register");
484 }
485 break;
486
487 case FUNCTION_DECL:
488 dump_child ("args", DECL_ARGUMENTS (t));
489 if (DECL_EXTERNAL (t))
490 dump_string (di, "undefined");
491 if (TREE_PUBLIC (t))
492 dump_string (di, "extern");
493 else
494 dump_string (di, "static");
495 if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
496 dump_child ("body", DECL_SAVED_TREE (t));
497 break;
498
9c5a221c
BM
499 case INTEGER_CST:
500 if (TREE_INT_CST_HIGH (t))
501 dump_int (di, "high", TREE_INT_CST_HIGH (t));
502 dump_int (di, "low", TREE_INT_CST_LOW (t));
503 break;
504
505 case STRING_CST:
506 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
507 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
508 break;
509
510 case TRUTH_NOT_EXPR:
511 case ADDR_EXPR:
512 case INDIRECT_REF:
513 case CLEANUP_POINT_EXPR:
514 case SAVE_EXPR:
515 /* These nodes are unary, but do not have code class `1'. */
516 dump_child ("op 0", TREE_OPERAND (t, 0));
517 break;
518
519 case TRUTH_ANDIF_EXPR:
520 case TRUTH_ORIF_EXPR:
521 case INIT_EXPR:
522 case MODIFY_EXPR:
523 case COMPONENT_REF:
524 case COMPOUND_EXPR:
525 case ARRAY_REF:
526 case PREDECREMENT_EXPR:
527 case PREINCREMENT_EXPR:
528 case POSTDECREMENT_EXPR:
529 case POSTINCREMENT_EXPR:
530 /* These nodes are binary, but do not have code class `2'. */
531 dump_child ("op 0", TREE_OPERAND (t, 0));
532 dump_child ("op 1", TREE_OPERAND (t, 1));
533 break;
534
535 case COND_EXPR:
536 dump_child ("op 0", TREE_OPERAND (t, 0));
537 dump_child ("op 1", TREE_OPERAND (t, 1));
538 dump_child ("op 2", TREE_OPERAND (t, 2));
539 break;
540
541 case CALL_EXPR:
542 dump_child ("fn", TREE_OPERAND (t, 0));
543 dump_child ("args", TREE_OPERAND (t, 1));
544 break;
545
546 case CONSTRUCTOR:
5675294b 547 dump_child ("elts", CONSTRUCTOR_ELTS (t));
9c5a221c
BM
548 break;
549
9c5a221c
BM
550 case BIND_EXPR:
551 dump_child ("vars", TREE_OPERAND (t, 0));
552 dump_child ("body", TREE_OPERAND (t, 1));
553 break;
554
555 case LOOP_EXPR:
556 dump_child ("body", TREE_OPERAND (t, 0));
557 break;
558
559 case EXIT_EXPR:
560 dump_child ("cond", TREE_OPERAND (t, 0));
561 break;
562
563 case TARGET_EXPR:
564 dump_child ("decl", TREE_OPERAND (t, 0));
565 dump_child ("init", TREE_OPERAND (t, 1));
566 dump_child ("clnp", TREE_OPERAND (t, 2));
567 /* There really are two possible places the initializer can be.
568 After RTL expansion, the second operand is moved to the
569 position of the fourth operand, and the second operand
570 becomes NULL. */
571 dump_child ("init", TREE_OPERAND (t, 3));
572 break;
d92b4486 573
9c5a221c
BM
574 case EXPR_WITH_FILE_LOCATION:
575 dump_child ("expr", EXPR_WFL_NODE (t));
576 break;
577
578 default:
579 /* There are no additional fields to print. */
580 break;
581 }
582
583 done:
584 if (dump_flag (di, TDF_ADDRESS, NULL))
585 dump_pointer (di, "addr", (void *)t);
d92b4486 586
9c5a221c
BM
587 /* Terminate the line. */
588 fprintf (di->stream, "\n");
589}
590
0e9e1e0a 591/* Return nonzero if FLAG has been specified for the dump, and NODE
9c5a221c
BM
592 is not the root node of the dump. */
593
79a490a9 594int dump_flag (dump_info_p di, int flag, tree node)
9c5a221c
BM
595{
596 return (di->flags & flag) && (node != di->node);
597}
598
599/* Dump T, and all its children, on STREAM. */
600
601void
79a490a9 602dump_node (tree t, int flags, FILE *stream)
9c5a221c
BM
603{
604 struct dump_info di;
605 dump_queue_p dq;
606 dump_queue_p next_dq;
607
608 /* Initialize the dump-information structure. */
609 di.stream = stream;
610 di.index = 0;
611 di.column = 0;
612 di.queue = 0;
613 di.queue_end = 0;
614 di.free_list = 0;
615 di.flags = flags;
616 di.node = t;
d92b4486 617 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
9c5a221c
BM
618 (splay_tree_delete_value_fn) &free);
619
620 /* Queue up the first node. */
621 queue (&di, t, DUMP_NONE);
622
623 /* Until the queue is empty, keep dumping nodes. */
624 while (di.queue)
625 dequeue_and_dump (&di);
626
627 /* Now, clean up. */
628 for (dq = di.free_list; dq; dq = next_dq)
629 {
630 next_dq = dq->next;
631 free (dq);
632 }
633 splay_tree_delete (di.nodes);
634}
635
636/* Define a tree dump switch. */
637struct dump_file_info
638{
c083a819
KG
639 const char *const suffix; /* suffix to give output file. */
640 const char *const swtch; /* command line switch */
9c5a221c
BM
641 int flags; /* user flags */
642 int state; /* state of play */
643};
644
645/* Table of tree dump switches. This must be consistent with the
646 TREE_DUMP_INDEX enumeration in tree.h */
647static struct dump_file_info dump_files[TDI_end] =
648{
f3f735eb
RA
649 {".tu", "translation-unit", 0, 0},
650 {".class", "class-hierarchy", 0, 0},
651 {".original", "tree-original", 0, 0},
652 {".optimized", "tree-optimized", 0, 0},
653 {".inlined", "tree-inlined", 0, 0},
9c5a221c
BM
654};
655
656/* Define a name->number mapping for a dump flag value. */
657struct dump_option_value_info
658{
659 const char *const name; /* the name of the value */
660 const int value; /* the value of the name */
661};
662
663/* Table of dump options. This must be consistent with the TDF_* flags
664 in tree.h */
665static const struct dump_option_value_info dump_options[] =
666{
667 {"address", TDF_ADDRESS},
668 {"slim", TDF_SLIM},
669 {"all", ~0},
670 {NULL, 0}
671};
672
673/* Begin a tree dump for PHASE. Stores any user supplied flag in
674 *FLAG_PTR and returns a stream to write to. If the dump is not
675 enabled, returns NULL.
676 Multiple calls will reopen and append to the dump file. */
677
678FILE *
79a490a9 679dump_begin (enum tree_dump_index phase, int *flag_ptr)
9c5a221c
BM
680{
681 FILE *stream;
682 char *name;
d92b4486 683
9c5a221c
BM
684 if (!dump_files[phase].state)
685 return NULL;
d92b4486 686
9c5a221c
BM
687 name = concat (dump_base_name, dump_files[phase].suffix, NULL);
688 stream = fopen (name, dump_files[phase].state < 0 ? "w" : "a");
689 if (!stream)
690 error ("could not open dump file `%s'", name);
691 else
692 dump_files[phase].state = 1;
693 free (name);
694 if (flag_ptr)
695 *flag_ptr = dump_files[phase].flags;
d92b4486 696
9c5a221c
BM
697 return stream;
698}
699
0e9e1e0a 700/* Returns nonzero if tree dump PHASE is enabled. */
9c5a221c
BM
701
702int
79a490a9 703dump_enabled_p (enum tree_dump_index phase)
9c5a221c
BM
704{
705 return dump_files[phase].state;
706}
707
708/* Returns the switch name of PHASE. */
709
710const char *
79a490a9 711dump_flag_name (enum tree_dump_index phase)
9c5a221c
BM
712{
713 return dump_files[phase].swtch;
714}
715
716/* Finish a tree dump for PHASE. STREAM is the stream created by
717 dump_begin. */
718
719void
79a490a9 720dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream)
9c5a221c
BM
721{
722 fclose (stream);
723}
724
0e9e1e0a 725/* Parse ARG as a dump switch. Return nonzero if it is, and store the
9c5a221c
BM
726 relevant details in the dump_files array. */
727
728int
79a490a9 729dump_switch_p (const char *arg)
9c5a221c
BM
730{
731 unsigned ix;
732 const char *option_value;
d92b4486 733
9c5a221c
BM
734 for (ix = 0; ix != TDI_end; ix++)
735 if ((option_value = skip_leading_substring (arg, dump_files[ix].swtch)))
736 {
737 const char *ptr = option_value;
738 int flags = 0;
d92b4486 739
9c5a221c
BM
740 while (*ptr)
741 {
742 const struct dump_option_value_info *option_ptr;
743 const char *end_ptr;
744 unsigned length;
d92b4486 745
9c5a221c
BM
746 while (*ptr == '-')
747 ptr++;
748 end_ptr = strchr (ptr, '-');
749 if (!end_ptr)
750 end_ptr = ptr + strlen (ptr);
751 length = end_ptr - ptr;
d92b4486 752
9c5a221c
BM
753 for (option_ptr = dump_options; option_ptr->name;
754 option_ptr++)
755 if (strlen (option_ptr->name) == length
756 && !memcmp (option_ptr->name, ptr, length))
757 {
758 flags |= option_ptr->value;
759 goto found;
760 }
f3f735eb 761 warning ("ignoring unknown option `%.*s' in `-fdump-%s'",
9c5a221c
BM
762 length, ptr, dump_files[ix].swtch);
763 found:;
764 ptr = end_ptr;
765 }
d92b4486 766
9c5a221c
BM
767 dump_files[ix].state = -1;
768 dump_files[ix].flags = flags;
d92b4486 769
9c5a221c
BM
770 return 1;
771 }
772 return 0;
773}
This page took 0.715784 seconds and 5 git commands to generate.