tree-dump.c revision 132718
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 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" 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 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 *); 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 44queue (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 = xmalloc (sizeof (struct dump_queue)); 61 62 /* Create a new entry in the splay-tree. */ 63 dni = 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 81static void 82dump_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 92void 93queue_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 120void 121queue_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 134static void 135dump_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 143static void 144dump_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 161void 162dump_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 171void 172dump_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 181void 182dump_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 194static void 195dump_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 207static void 208dequeue_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 case 'r': 306 case 's': 307 /* These nodes are handled explicitly below. */ 308 break; 309 310 default: 311 abort (); 312 } 313 } 314 else if (DECL_P (t)) 315 { 316 /* All declarations have names. */ 317 if (DECL_NAME (t)) 318 dump_child ("name", DECL_NAME (t)); 319 if (DECL_ASSEMBLER_NAME_SET_P (t) 320 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t)) 321 dump_child ("mngl", DECL_ASSEMBLER_NAME (t)); 322 /* And types. */ 323 queue_and_dump_type (di, t); 324 dump_child ("scpe", DECL_CONTEXT (t)); 325 /* And a source position. */ 326 if (DECL_SOURCE_FILE (t)) 327 { 328 const char *filename = strrchr (DECL_SOURCE_FILE (t), '/'); 329 if (!filename) 330 filename = DECL_SOURCE_FILE (t); 331 else 332 /* Skip the slash. */ 333 ++filename; 334 335 dump_maybe_newline (di); 336 fprintf (di->stream, "srcp: %s:%-6d ", filename, 337 DECL_SOURCE_LINE (t)); 338 di->column += 6 + strlen (filename) + 8; 339 } 340 /* And any declaration can be compiler-generated. */ 341 if (DECL_ARTIFICIAL (t)) 342 dump_string (di, "artificial"); 343 if (TREE_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL)) 344 dump_child ("chan", TREE_CHAIN (t)); 345 } 346 else if (code_class == 't') 347 { 348 /* All types have qualifiers. */ 349 int quals = (*lang_hooks.tree_dump.type_quals) (t); 350 351 if (quals != TYPE_UNQUALIFIED) 352 { 353 fprintf (di->stream, "qual: %c%c%c ", 354 (quals & TYPE_QUAL_CONST) ? 'c' : ' ', 355 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ', 356 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' '); 357 di->column += 14; 358 } 359 360 /* All types have associated declarations. */ 361 dump_child ("name", TYPE_NAME (t)); 362 363 /* All types have a main variant. */ 364 if (TYPE_MAIN_VARIANT (t) != t) 365 dump_child ("unql", TYPE_MAIN_VARIANT (t)); 366 367 /* And sizes. */ 368 dump_child ("size", TYPE_SIZE (t)); 369 370 /* All types have alignments. */ 371 dump_int (di, "algn", TYPE_ALIGN (t)); 372 } 373 else if (code_class == 'c') 374 /* All constants can have types. */ 375 queue_and_dump_type (di, t); 376 377 /* Give the language-specific code a chance to print something. If 378 it's completely taken care of things, don't bother printing 379 anything more ourselves. */ 380 if ((*lang_hooks.tree_dump.dump_tree) (di, t)) 381 goto done; 382 383 /* Now handle the various kinds of nodes. */ 384 switch (code) 385 { 386 int i; 387 388 case IDENTIFIER_NODE: 389 dump_string_field (di, "strg", IDENTIFIER_POINTER (t)); 390 dump_int (di, "lngt", IDENTIFIER_LENGTH (t)); 391 break; 392 393 case TREE_LIST: 394 dump_child ("purp", TREE_PURPOSE (t)); 395 dump_child ("valu", TREE_VALUE (t)); 396 dump_child ("chan", TREE_CHAIN (t)); 397 break; 398 399 case TREE_VEC: 400 dump_int (di, "lngt", TREE_VEC_LENGTH (t)); 401 for (i = 0; i < TREE_VEC_LENGTH (t); ++i) 402 { 403 char buffer[32]; 404 sprintf (buffer, "%u", i); 405 dump_child (buffer, TREE_VEC_ELT (t, i)); 406 } 407 break; 408 409 case INTEGER_TYPE: 410 case ENUMERAL_TYPE: 411 dump_int (di, "prec", TYPE_PRECISION (t)); 412 if (TREE_UNSIGNED (t)) 413 dump_string (di, "unsigned"); 414 dump_child ("min", TYPE_MIN_VALUE (t)); 415 dump_child ("max", TYPE_MAX_VALUE (t)); 416 417 if (code == ENUMERAL_TYPE) 418 dump_child ("csts", TYPE_VALUES (t)); 419 break; 420 421 case REAL_TYPE: 422 dump_int (di, "prec", TYPE_PRECISION (t)); 423 break; 424 425 case POINTER_TYPE: 426 dump_child ("ptd", TREE_TYPE (t)); 427 break; 428 429 case REFERENCE_TYPE: 430 dump_child ("refd", TREE_TYPE (t)); 431 break; 432 433 case METHOD_TYPE: 434 dump_child ("clas", TYPE_METHOD_BASETYPE (t)); 435 /* Fall through. */ 436 437 case FUNCTION_TYPE: 438 dump_child ("retn", TREE_TYPE (t)); 439 dump_child ("prms", TYPE_ARG_TYPES (t)); 440 break; 441 442 case ARRAY_TYPE: 443 dump_child ("elts", TREE_TYPE (t)); 444 dump_child ("domn", TYPE_DOMAIN (t)); 445 break; 446 447 case RECORD_TYPE: 448 case UNION_TYPE: 449 if (TREE_CODE (t) == RECORD_TYPE) 450 dump_string (di, "struct"); 451 else 452 dump_string (di, "union"); 453 454 dump_child ("flds", TYPE_FIELDS (t)); 455 dump_child ("fncs", TYPE_METHODS (t)); 456 queue_and_dump_index (di, "binf", TYPE_BINFO (t), 457 DUMP_BINFO); 458 break; 459 460 case CONST_DECL: 461 dump_child ("cnst", DECL_INITIAL (t)); 462 break; 463 464 case VAR_DECL: 465 case PARM_DECL: 466 case FIELD_DECL: 467 case RESULT_DECL: 468 if (TREE_CODE (t) == PARM_DECL) 469 dump_child ("argt", DECL_ARG_TYPE (t)); 470 else 471 dump_child ("init", DECL_INITIAL (t)); 472 dump_child ("size", DECL_SIZE (t)); 473 dump_int (di, "algn", DECL_ALIGN (t)); 474 475 if (TREE_CODE (t) == FIELD_DECL) 476 { 477 if (DECL_FIELD_OFFSET (t)) 478 dump_child ("bpos", bit_position (t)); 479 } 480 else if (TREE_CODE (t) == VAR_DECL 481 || TREE_CODE (t) == PARM_DECL) 482 { 483 dump_int (di, "used", TREE_USED (t)); 484 if (DECL_REGISTER (t)) 485 dump_string (di, "register"); 486 } 487 break; 488 489 case FUNCTION_DECL: 490 dump_child ("args", DECL_ARGUMENTS (t)); 491 if (DECL_EXTERNAL (t)) 492 dump_string (di, "undefined"); 493 if (TREE_PUBLIC (t)) 494 dump_string (di, "extern"); 495 else 496 dump_string (di, "static"); 497 if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t)) 498 dump_child ("body", DECL_SAVED_TREE (t)); 499 break; 500 501 case INTEGER_CST: 502 if (TREE_INT_CST_HIGH (t)) 503 dump_int (di, "high", TREE_INT_CST_HIGH (t)); 504 dump_int (di, "low", TREE_INT_CST_LOW (t)); 505 break; 506 507 case STRING_CST: 508 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t)); 509 dump_int (di, "lngt", TREE_STRING_LENGTH (t)); 510 break; 511 512 case TRUTH_NOT_EXPR: 513 case ADDR_EXPR: 514 case INDIRECT_REF: 515 case CLEANUP_POINT_EXPR: 516 case SAVE_EXPR: 517 /* These nodes are unary, but do not have code class `1'. */ 518 dump_child ("op 0", TREE_OPERAND (t, 0)); 519 break; 520 521 case TRUTH_ANDIF_EXPR: 522 case TRUTH_ORIF_EXPR: 523 case INIT_EXPR: 524 case MODIFY_EXPR: 525 case COMPONENT_REF: 526 case COMPOUND_EXPR: 527 case ARRAY_REF: 528 case PREDECREMENT_EXPR: 529 case PREINCREMENT_EXPR: 530 case POSTDECREMENT_EXPR: 531 case POSTINCREMENT_EXPR: 532 /* These nodes are binary, but do not have code class `2'. */ 533 dump_child ("op 0", TREE_OPERAND (t, 0)); 534 dump_child ("op 1", TREE_OPERAND (t, 1)); 535 break; 536 537 case COND_EXPR: 538 dump_child ("op 0", TREE_OPERAND (t, 0)); 539 dump_child ("op 1", TREE_OPERAND (t, 1)); 540 dump_child ("op 2", TREE_OPERAND (t, 2)); 541 break; 542 543 case CALL_EXPR: 544 dump_child ("fn", TREE_OPERAND (t, 0)); 545 dump_child ("args", TREE_OPERAND (t, 1)); 546 break; 547 548 case CONSTRUCTOR: 549 dump_child ("elts", CONSTRUCTOR_ELTS (t)); 550 break; 551 552 case BIND_EXPR: 553 dump_child ("vars", TREE_OPERAND (t, 0)); 554 dump_child ("body", TREE_OPERAND (t, 1)); 555 break; 556 557 case LOOP_EXPR: 558 dump_child ("body", TREE_OPERAND (t, 0)); 559 break; 560 561 case EXIT_EXPR: 562 dump_child ("cond", TREE_OPERAND (t, 0)); 563 break; 564 565 case TARGET_EXPR: 566 dump_child ("decl", TREE_OPERAND (t, 0)); 567 dump_child ("init", TREE_OPERAND (t, 1)); 568 dump_child ("clnp", TREE_OPERAND (t, 2)); 569 /* There really are two possible places the initializer can be. 570 After RTL expansion, the second operand is moved to the 571 position of the fourth operand, and the second operand 572 becomes NULL. */ 573 dump_child ("init", TREE_OPERAND (t, 3)); 574 break; 575 576 case EXPR_WITH_FILE_LOCATION: 577 dump_child ("expr", EXPR_WFL_NODE (t)); 578 break; 579 580 default: 581 /* There are no additional fields to print. */ 582 break; 583 } 584 585 done: 586 if (dump_flag (di, TDF_ADDRESS, NULL)) 587 dump_pointer (di, "addr", (void *)t); 588 589 /* Terminate the line. */ 590 fprintf (di->stream, "\n"); 591} 592 593/* Return nonzero if FLAG has been specified for the dump, and NODE 594 is not the root node of the dump. */ 595 596int dump_flag (dump_info_p di, int flag, tree node) 597{ 598 return (di->flags & flag) && (node != di->node); 599} 600 601/* Dump T, and all its children, on STREAM. */ 602 603void 604dump_node (tree t, int flags, FILE *stream) 605{ 606 struct dump_info di; 607 dump_queue_p dq; 608 dump_queue_p next_dq; 609 610 /* Initialize the dump-information structure. */ 611 di.stream = stream; 612 di.index = 0; 613 di.column = 0; 614 di.queue = 0; 615 di.queue_end = 0; 616 di.free_list = 0; 617 di.flags = flags; 618 di.node = t; 619 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0, 620 (splay_tree_delete_value_fn) &free); 621 622 /* Queue up the first node. */ 623 queue (&di, t, DUMP_NONE); 624 625 /* Until the queue is empty, keep dumping nodes. */ 626 while (di.queue) 627 dequeue_and_dump (&di); 628 629 /* Now, clean up. */ 630 for (dq = di.free_list; dq; dq = next_dq) 631 { 632 next_dq = dq->next; 633 free (dq); 634 } 635 splay_tree_delete (di.nodes); 636} 637 638/* Define a tree dump switch. */ 639struct dump_file_info 640{ 641 const char *const suffix; /* suffix to give output file. */ 642 const char *const swtch; /* command line switch */ 643 int flags; /* user flags */ 644 int state; /* state of play */ 645}; 646 647/* Table of tree dump switches. This must be consistent with the 648 TREE_DUMP_INDEX enumeration in tree.h */ 649static struct dump_file_info dump_files[TDI_end] = 650{ 651 {".tu", "translation-unit", 0, 0}, 652 {".class", "class-hierarchy", 0, 0}, 653 {".original", "tree-original", 0, 0}, 654 {".optimized", "tree-optimized", 0, 0}, 655 {".inlined", "tree-inlined", 0, 0}, 656}; 657 658/* Define a name->number mapping for a dump flag value. */ 659struct dump_option_value_info 660{ 661 const char *const name; /* the name of the value */ 662 const int value; /* the value of the name */ 663}; 664 665/* Table of dump options. This must be consistent with the TDF_* flags 666 in tree.h */ 667static const struct dump_option_value_info dump_options[] = 668{ 669 {"address", TDF_ADDRESS}, 670 {"slim", TDF_SLIM}, 671 {"all", ~0}, 672 {NULL, 0} 673}; 674 675/* Begin a tree dump for PHASE. Stores any user supplied flag in 676 *FLAG_PTR and returns a stream to write to. If the dump is not 677 enabled, returns NULL. 678 Multiple calls will reopen and append to the dump file. */ 679 680FILE * 681dump_begin (enum tree_dump_index phase, int *flag_ptr) 682{ 683 FILE *stream; 684 char *name; 685 686 if (!dump_files[phase].state) 687 return NULL; 688 689 name = concat (dump_base_name, dump_files[phase].suffix, NULL); 690 stream = fopen (name, dump_files[phase].state < 0 ? "w" : "a"); 691 if (!stream) 692 error ("could not open dump file `%s'", name); 693 else 694 dump_files[phase].state = 1; 695 free (name); 696 if (flag_ptr) 697 *flag_ptr = dump_files[phase].flags; 698 699 return stream; 700} 701 702/* Returns nonzero if tree dump PHASE is enabled. */ 703 704int 705dump_enabled_p (enum tree_dump_index phase) 706{ 707 return dump_files[phase].state; 708} 709 710/* Returns the switch name of PHASE. */ 711 712const char * 713dump_flag_name (enum tree_dump_index phase) 714{ 715 return dump_files[phase].swtch; 716} 717 718/* Finish a tree dump for PHASE. STREAM is the stream created by 719 dump_begin. */ 720 721void 722dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream) 723{ 724 fclose (stream); 725} 726 727/* Parse ARG as a dump switch. Return nonzero if it is, and store the 728 relevant details in the dump_files array. */ 729 730int 731dump_switch_p (const char *arg) 732{ 733 unsigned ix; 734 const char *option_value; 735 736 for (ix = 0; ix != TDI_end; ix++) 737 if ((option_value = skip_leading_substring (arg, dump_files[ix].swtch))) 738 { 739 const char *ptr = option_value; 740 int flags = 0; 741 742 while (*ptr) 743 { 744 const struct dump_option_value_info *option_ptr; 745 const char *end_ptr; 746 unsigned length; 747 748 while (*ptr == '-') 749 ptr++; 750 end_ptr = strchr (ptr, '-'); 751 if (!end_ptr) 752 end_ptr = ptr + strlen (ptr); 753 length = end_ptr - ptr; 754 755 for (option_ptr = dump_options; option_ptr->name; 756 option_ptr++) 757 if (strlen (option_ptr->name) == length 758 && !memcmp (option_ptr->name, ptr, length)) 759 { 760 flags |= option_ptr->value; 761 goto found; 762 } 763 warning ("ignoring unknown option `%.*s' in `-fdump-%s'", 764 length, ptr, dump_files[ix].swtch); 765 found:; 766 ptr = end_ptr; 767 } 768 769 dump_files[ix].state = -1; 770 dump_files[ix].flags = flags; 771 772 return 1; 773 } 774 return 0; 775} 776