]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-dump.c
re PR debug/4252 (cc1: Invalid option `-fdump-translation-unit')
[thirdparty/gcc.git] / gcc / tree-dump.c
1 /* Tree-dumping functionality for intermediate representation.
2 Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3 Written by Mark Mitchell <mark@codesourcery.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
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 "langhooks.h"
32
33 static unsigned int queue (dump_info_p, tree, int);
34 static void dump_index (dump_info_p, unsigned int);
35 static void dequeue_and_dump (dump_info_p);
36 static void dump_new_line (dump_info_p);
37 static void dump_maybe_newline (dump_info_p);
38 static void dump_string_field (dump_info_p, const char *, const char *);
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, 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 = (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);
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, 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, 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, (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 string S. */
180
181 void
182 dump_string (dump_info_p di, const char *string)
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
194 static void
195 dump_string_field (dump_info_p di, const char *field, const char *string)
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
205 /* Dump the next node in the queue. */
206
207 static void
208 dequeue_and_dump (dump_info_p di)
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 {
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);
255
256 dump_child ("type", BINFO_TYPE (t));
257
258 if (TREE_VIA_VIRTUAL (t))
259 dump_string (di, "virt");
260
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 ();
277
278 dump_string (di, string);
279 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
280 }
281
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;
297
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;
303
304 case 'e':
305 /* These nodes are handled explicitly below. */
306 break;
307
308 default:
309 abort ();
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));
317 if (DECL_ASSEMBLER_NAME_SET_P (t)
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);
334 fprintf (di->stream, "srcp: %s:%-6d ", filename,
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);
348
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));
364
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");
451
452 dump_child ("flds", TYPE_FIELDS (t));
453 dump_child ("fncs", TYPE_METHODS (t));
454 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
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 {
475 if (DECL_FIELD_OFFSET (t))
476 dump_child ("bpos", bit_position (t));
477 }
478 else if (TREE_CODE (t) == VAR_DECL
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
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:
547 dump_child ("elts", CONSTRUCTOR_ELTS (t));
548 break;
549
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;
573
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);
586
587 /* Terminate the line. */
588 fprintf (di->stream, "\n");
589 }
590
591 /* Return nonzero if FLAG has been specified for the dump, and NODE
592 is not the root node of the dump. */
593
594 int dump_flag (dump_info_p di, int flag, tree node)
595 {
596 return (di->flags & flag) && (node != di->node);
597 }
598
599 /* Dump T, and all its children, on STREAM. */
600
601 void
602 dump_node (tree t, int flags, FILE *stream)
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;
617 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
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. */
637 struct dump_file_info
638 {
639 const char *const suffix; /* suffix to give output file. */
640 const char *const swtch; /* command line switch */
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 */
647 static struct dump_file_info dump_files[TDI_end] =
648 {
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},
654 };
655
656 /* Define a name->number mapping for a dump flag value. */
657 struct 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 */
665 static 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
678 FILE *
679 dump_begin (enum tree_dump_index phase, int *flag_ptr)
680 {
681 FILE *stream;
682 char *name;
683
684 if (!dump_files[phase].state)
685 return NULL;
686
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;
696
697 return stream;
698 }
699
700 /* Returns nonzero if tree dump PHASE is enabled. */
701
702 int
703 dump_enabled_p (enum tree_dump_index phase)
704 {
705 return dump_files[phase].state;
706 }
707
708 /* Returns the switch name of PHASE. */
709
710 const char *
711 dump_flag_name (enum tree_dump_index phase)
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
719 void
720 dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream)
721 {
722 fclose (stream);
723 }
724
725 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
726 relevant details in the dump_files array. */
727
728 int
729 dump_switch_p (const char *arg)
730 {
731 unsigned ix;
732 const char *option_value;
733
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;
739
740 while (*ptr)
741 {
742 const struct dump_option_value_info *option_ptr;
743 const char *end_ptr;
744 unsigned length;
745
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;
752
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 }
761 warning ("ignoring unknown option `%.*s' in `-fdump-%s'",
762 length, ptr, dump_files[ix].swtch);
763 found:;
764 ptr = end_ptr;
765 }
766
767 dump_files[ix].state = -1;
768 dump_files[ix].flags = flags;
769
770 return 1;
771 }
772 return 0;
773 }