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