1 /* MD reader for GCC. 2 Copyright (C) 1987-2020 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 /* This file is compiled twice: once for the generator programs 21 once for the compiler. */ 22 #ifdef GENERATOR_FILE 23 #include "bconfig.h" 24 #else 25 #include "config.h" 26 #endif 27 #include "system.h" 28 #include "coretypes.h" 29 #ifdef GENERATOR_FILE 30 #include "errors.h" 31 #endif /* #ifdef GENERATOR_FILE */ 32 #include "statistics.h" 33 #include "vec.h" 34 #include "read-md.h" 35 36 #ifndef GENERATOR_FILE 37 38 /* Minimal reimplementation of errors.c for use by RTL frontend 39 within cc1. */ 40 41 int have_error = 0; 42 43 #endif /* #ifndef GENERATOR_FILE */ 44 45 46 /* This callback will be invoked whenever an md include directive is 47 processed. To be used for creation of the dependency file. */ 48 void (*include_callback) (const char *); 49 50 /* Global singleton. */ 51 52 md_reader *md_reader_ptr; 53 54 /* Given an object that starts with a char * name field, return a hash 55 code for its name. */ 56 57 hashval_t 58 leading_string_hash (const void *def) 59 { 60 return htab_hash_string (*(const char *const *) def); 61 } 62 63 /* Given two objects that start with char * name fields, return true if 64 they have the same name. */ 65 66 int 67 leading_string_eq_p (const void *def1, const void *def2) 68 { 69 return strcmp (*(const char *const *) def1, 70 *(const char *const *) def2) == 0; 71 } 72 73 /* Return a hash value for the pointer pointed to by DEF. */ 74 75 static hashval_t 76 leading_ptr_hash (const void *def) 77 { 78 return htab_hash_pointer (*(const void *const *) def); 79 } 80 81 /* Return true if DEF1 and DEF2 are pointers to the same pointer. */ 82 83 static int 84 leading_ptr_eq_p (const void *def1, const void *def2) 85 { 86 return *(const void *const *) def1 == *(const void *const *) def2; 87 } 88 89 /* Associate PTR with the file position given by FILE_LOC. */ 90 91 void 92 md_reader::set_md_ptr_loc (const void *ptr, file_location file_loc) 93 { 94 struct ptr_loc *loc; 95 96 loc = (struct ptr_loc *) obstack_alloc (&m_ptr_loc_obstack, 97 sizeof (struct ptr_loc)); 98 loc->ptr = ptr; 99 loc->loc = file_loc; 100 *htab_find_slot (m_ptr_locs, loc, INSERT) = loc; 101 } 102 103 /* Return the position associated with pointer PTR. Return null if no 104 position was set. */ 105 106 const md_reader::ptr_loc * 107 md_reader::get_md_ptr_loc (const void *ptr) 108 { 109 return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr); 110 } 111 112 /* Associate NEW_PTR with the same file position as OLD_PTR. */ 113 114 void 115 md_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr) 116 { 117 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr); 118 if (loc != 0) 119 set_md_ptr_loc (new_ptr, loc->loc); 120 } 121 122 /* If PTR is associated with a known file position, print a #line 123 directive for it to OUTF. */ 124 125 void 126 md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr) 127 { 128 const struct ptr_loc *loc = get_md_ptr_loc (ptr); 129 if (loc != 0) 130 fprintf (outf, "#line %d \"%s\"\n", loc->loc.lineno, loc->loc.filename); 131 } 132 133 /* Special fprint_md_ptr_loc for writing to STDOUT. */ 134 void 135 md_reader::print_md_ptr_loc (const void *ptr) 136 { 137 fprint_md_ptr_loc (stdout, ptr); 138 } 139 140 /* Return a condition that satisfies both COND1 and COND2. Either string 141 may be null or empty. */ 142 143 const char * 144 md_reader::join_c_conditions (const char *cond1, const char *cond2) 145 { 146 char *result; 147 const void **entry; 148 149 if (cond1 == 0 || cond1[0] == 0) 150 return cond2; 151 152 if (cond2 == 0 || cond2[0] == 0) 153 return cond1; 154 155 if (strcmp (cond1, cond2) == 0) 156 return cond1; 157 158 result = concat ("(", cond1, ") && (", cond2, ")", NULL); 159 obstack_ptr_grow (&m_joined_conditions_obstack, result); 160 obstack_ptr_grow (&m_joined_conditions_obstack, cond1); 161 obstack_ptr_grow (&m_joined_conditions_obstack, cond2); 162 entry = XOBFINISH (&m_joined_conditions_obstack, const void **); 163 *htab_find_slot (m_joined_conditions, entry, INSERT) = entry; 164 return result; 165 } 166 167 /* Print condition COND to OUTF, wrapped in brackets. If COND was created 168 by join_c_conditions, recursively invoke this function for the original 169 conditions and join the result with "&&". Otherwise print a #line 170 directive for COND if its original file position is known. */ 171 172 void 173 md_reader::fprint_c_condition (FILE *outf, const char *cond) 174 { 175 const char **halves = (const char **) htab_find (m_joined_conditions, &cond); 176 if (halves != 0) 177 { 178 fprintf (outf, "("); 179 fprint_c_condition (outf, halves[1]); 180 fprintf (outf, " && "); 181 fprint_c_condition (outf, halves[2]); 182 fprintf (outf, ")"); 183 } 184 else 185 { 186 fputc ('\n', outf); 187 fprint_md_ptr_loc (outf, cond); 188 fprintf (outf, "(%s)", cond); 189 } 190 } 191 192 /* Special fprint_c_condition for writing to STDOUT. */ 193 194 void 195 md_reader::print_c_condition (const char *cond) 196 { 197 fprint_c_condition (stdout, cond); 198 } 199 200 /* A vfprintf-like function for reporting an error against line LINENO 201 of the current MD file. */ 202 203 static void ATTRIBUTE_PRINTF(2,0) 204 message_at_1 (file_location loc, const char *msg, va_list ap) 205 { 206 fprintf (stderr, "%s:%d:%d: ", loc.filename, loc.lineno, loc.colno); 207 vfprintf (stderr, msg, ap); 208 fputc ('\n', stderr); 209 } 210 211 /* A printf-like function for reporting a message against location LOC. */ 212 213 void 214 message_at (file_location loc, const char *msg, ...) 215 { 216 va_list ap; 217 218 va_start (ap, msg); 219 message_at_1 (loc, msg, ap); 220 va_end (ap); 221 } 222 223 /* Like message_at, but treat the condition as an error. */ 224 225 void 226 error_at (file_location loc, const char *msg, ...) 227 { 228 va_list ap; 229 230 va_start (ap, msg); 231 message_at_1 (loc, msg, ap); 232 va_end (ap); 233 have_error = 1; 234 } 235 236 /* Like message_at, but treat the condition as a fatal error. */ 237 238 void 239 fatal_at (file_location loc, const char *msg, ...) 240 { 241 va_list ap; 242 243 va_start (ap, msg); 244 message_at_1 (loc, msg, ap); 245 va_end (ap); 246 exit (1); 247 } 248 249 /* A printf-like function for reporting an error against the current 250 position in the MD file. */ 251 252 void 253 fatal_with_file_and_line (const char *msg, ...) 254 { 255 char context[64]; 256 size_t i; 257 int c; 258 va_list ap; 259 260 va_start (ap, msg); 261 262 fprintf (stderr, "%s:%d:%d: error: ", md_reader_ptr->get_filename (), 263 md_reader_ptr->get_lineno (), 264 md_reader_ptr->get_colno ()); 265 vfprintf (stderr, msg, ap); 266 putc ('\n', stderr); 267 268 /* Gather some following context. */ 269 for (i = 0; i < sizeof (context)-1; ++i) 270 { 271 c = read_char (); 272 if (c == EOF) 273 break; 274 if (c == '\r' || c == '\n') 275 { 276 unread_char (c); 277 break; 278 } 279 context[i] = c; 280 } 281 context[i] = '\0'; 282 283 fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n", 284 md_reader_ptr->get_filename (), 285 md_reader_ptr->get_lineno (), 286 md_reader_ptr->get_colno (), context); 287 288 va_end (ap); 289 exit (1); 290 } 291 292 /* Report that we found character ACTUAL when we expected to find 293 character EXPECTED. */ 294 295 void 296 fatal_expected_char (int expected, int actual) 297 { 298 if (actual == EOF) 299 fatal_with_file_and_line ("expected character `%c', found EOF", 300 expected); 301 else 302 fatal_with_file_and_line ("expected character `%c', found `%c'", 303 expected, actual); 304 } 305 306 /* Read chars from the MD file until a non-whitespace char and return that. 307 Comments, both Lisp style and C style, are treated as whitespace. */ 308 309 int 310 read_skip_spaces (void) 311 { 312 int c; 313 314 while (1) 315 { 316 c = read_char (); 317 switch (c) 318 { 319 case ' ': case '\t': case '\f': case '\r': case '\n': 320 break; 321 322 case ';': 323 do 324 c = read_char (); 325 while (c != '\n' && c != EOF); 326 break; 327 328 case '/': 329 { 330 int prevc; 331 c = read_char (); 332 if (c != '*') 333 { 334 unread_char (c); 335 fatal_with_file_and_line ("stray '/' in file"); 336 } 337 338 prevc = 0; 339 while ((c = read_char ()) && c != EOF) 340 { 341 if (prevc == '*' && c == '/') 342 break; 343 prevc = c; 344 } 345 } 346 break; 347 348 default: 349 return c; 350 } 351 } 352 } 353 354 /* Consume the next character, issuing a fatal error if it is not 355 EXPECTED. */ 356 357 void 358 md_reader::require_char (char expected) 359 { 360 int ch = read_char (); 361 if (ch != expected) 362 fatal_expected_char (expected, ch); 363 } 364 365 /* Consume any whitespace, then consume the next non-whitespace 366 character, issuing a fatal error if it is not EXPECTED. */ 367 368 void 369 md_reader::require_char_ws (char expected) 370 { 371 int ch = read_skip_spaces (); 372 if (ch != expected) 373 fatal_expected_char (expected, ch); 374 } 375 376 /* Consume any whitespace, then consume the next word (as per read_name), 377 issuing a fatal error if it is not EXPECTED. */ 378 379 void 380 md_reader::require_word_ws (const char *expected) 381 { 382 struct md_name name; 383 read_name (&name); 384 if (strcmp (name.string, expected)) 385 fatal_with_file_and_line ("missing '%s'", expected); 386 } 387 388 /* Read the next character from the file. */ 389 390 int 391 md_reader::read_char (void) 392 { 393 int ch; 394 395 ch = getc (m_read_md_file); 396 if (ch == '\n') 397 { 398 m_read_md_lineno++; 399 m_last_line_colno = m_read_md_colno; 400 m_read_md_colno = 0; 401 } 402 else 403 m_read_md_colno++; 404 405 /* If we're filtering lines, treat everything before the range of 406 interest as a space, and as EOF for everything after. */ 407 if (m_first_line && m_last_line) 408 { 409 if (m_read_md_lineno < m_first_line) 410 return ' '; 411 if (m_read_md_lineno > m_last_line) 412 return EOF; 413 } 414 415 return ch; 416 } 417 418 /* Put back CH, which was the last character read from the file. */ 419 420 void 421 md_reader::unread_char (int ch) 422 { 423 if (ch == '\n') 424 { 425 m_read_md_lineno--; 426 m_read_md_colno = m_last_line_colno; 427 } 428 else 429 m_read_md_colno--; 430 ungetc (ch, m_read_md_file); 431 } 432 433 /* Peek at the next character from the file without consuming it. */ 434 435 int 436 md_reader::peek_char (void) 437 { 438 int ch = read_char (); 439 unread_char (ch); 440 return ch; 441 } 442 443 /* Read an rtx code name into NAME. It is terminated by any of the 444 punctuation chars of rtx printed syntax. */ 445 446 bool 447 md_reader::read_name_1 (struct md_name *name, file_location *out_loc) 448 { 449 int c; 450 size_t i; 451 int angle_bracket_depth; 452 453 c = read_skip_spaces (); 454 455 *out_loc = get_current_location (); 456 457 i = 0; 458 angle_bracket_depth = 0; 459 while (1) 460 { 461 if (c == '<') 462 angle_bracket_depth++; 463 464 if ((c == '>') && (angle_bracket_depth > 0)) 465 angle_bracket_depth--; 466 467 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' 468 || c == EOF) 469 break; 470 if (angle_bracket_depth == 0) 471 { 472 if (c == ':' || c == ')' || c == ']' 473 || c == '"' || c == '/' || c == '(' || c == '[') 474 { 475 unread_char (c); 476 break; 477 } 478 } 479 480 if (i == sizeof (name->buffer) - 1) 481 fatal_with_file_and_line ("name too long"); 482 name->buffer[i++] = c; 483 484 c = read_char (); 485 } 486 487 if (i == 0) 488 return false; 489 490 name->buffer[i] = 0; 491 name->string = name->buffer; 492 493 if (m_md_constants) 494 { 495 /* Do constant expansion. */ 496 struct md_constant *def; 497 498 do 499 { 500 struct md_constant tmp_def; 501 502 tmp_def.name = name->string; 503 def = (struct md_constant *) htab_find (m_md_constants, &tmp_def); 504 if (def) 505 name->string = def->value; 506 } 507 while (def); 508 } 509 510 return true; 511 } 512 513 /* Read an rtx code name into NAME. It is terminated by any of the 514 punctuation chars of rtx printed syntax. */ 515 516 file_location 517 md_reader::read_name (struct md_name *name) 518 { 519 file_location loc; 520 if (!read_name_1 (name, &loc)) 521 fatal_with_file_and_line ("missing name or number"); 522 return loc; 523 } 524 525 file_location 526 md_reader::read_name_or_nil (struct md_name *name) 527 { 528 file_location loc; 529 if (!read_name_1 (name, &loc)) 530 { 531 file_location loc = get_current_location (); 532 read_skip_construct (0, loc); 533 /* Skip the ')'. */ 534 read_char (); 535 name->buffer[0] = 0; 536 name->string = name->buffer; 537 } 538 return loc; 539 } 540 541 /* Subroutine of the string readers. Handles backslash escapes. 542 Caller has read the backslash, but not placed it into the obstack. */ 543 544 void 545 md_reader::read_escape () 546 { 547 int c = read_char (); 548 549 switch (c) 550 { 551 /* Backslash-newline is replaced by nothing, as in C. */ 552 case '\n': 553 return; 554 555 /* \" \' \\ are replaced by the second character. */ 556 case '\\': 557 case '"': 558 case '\'': 559 break; 560 561 /* Standard C string escapes: 562 \a \b \f \n \r \t \v 563 \[0-7] \x 564 all are passed through to the output string unmolested. 565 In normal use these wind up in a string constant processed 566 by the C compiler, which will translate them appropriately. 567 We do not bother checking that \[0-7] are followed by up to 568 two octal digits, or that \x is followed by N hex digits. 569 \? \u \U are left out because they are not in traditional C. */ 570 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v': 571 case '0': case '1': case '2': case '3': case '4': case '5': case '6': 572 case '7': case 'x': 573 obstack_1grow (&m_string_obstack, '\\'); 574 break; 575 576 /* \; makes stuff for a C string constant containing 577 newline and tab. */ 578 case ';': 579 obstack_grow (&m_string_obstack, "\\n\\t", 4); 580 return; 581 582 /* pass anything else through, but issue a warning. */ 583 default: 584 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n", 585 get_filename (), get_lineno (), 586 c); 587 obstack_1grow (&m_string_obstack, '\\'); 588 break; 589 } 590 591 obstack_1grow (&m_string_obstack, c); 592 } 593 594 /* Read a double-quoted string onto the obstack. Caller has scanned 595 the leading quote. */ 596 597 char * 598 md_reader::read_quoted_string () 599 { 600 int c; 601 602 while (1) 603 { 604 c = read_char (); /* Read the string */ 605 if (c == '\\') 606 { 607 read_escape (); 608 continue; 609 } 610 else if (c == '"' || c == EOF) 611 break; 612 613 obstack_1grow (&m_string_obstack, c); 614 } 615 616 obstack_1grow (&m_string_obstack, 0); 617 return XOBFINISH (&m_string_obstack, char *); 618 } 619 620 /* Read a braced string (a la Tcl) onto the string obstack. Caller 621 has scanned the leading brace. Note that unlike quoted strings, 622 the outermost braces _are_ included in the string constant. */ 623 624 char * 625 md_reader::read_braced_string () 626 { 627 int c; 628 int brace_depth = 1; /* caller-processed */ 629 unsigned long starting_read_md_lineno = get_lineno (); 630 631 obstack_1grow (&m_string_obstack, '{'); 632 while (brace_depth) 633 { 634 c = read_char (); /* Read the string */ 635 636 if (c == '{') 637 brace_depth++; 638 else if (c == '}') 639 brace_depth--; 640 else if (c == '\\') 641 { 642 read_escape (); 643 continue; 644 } 645 else if (c == EOF) 646 fatal_with_file_and_line 647 ("missing closing } for opening brace on line %lu", 648 starting_read_md_lineno); 649 650 obstack_1grow (&m_string_obstack, c); 651 } 652 653 obstack_1grow (&m_string_obstack, 0); 654 return XOBFINISH (&m_string_obstack, char *); 655 } 656 657 /* Read some kind of string constant. This is the high-level routine 658 used by read_rtx. It handles surrounding parentheses, leading star, 659 and dispatch to the appropriate string constant reader. */ 660 661 char * 662 md_reader::read_string (int star_if_braced) 663 { 664 char *stringbuf; 665 int saw_paren = 0; 666 int c; 667 668 c = read_skip_spaces (); 669 if (c == '(') 670 { 671 saw_paren = 1; 672 c = read_skip_spaces (); 673 } 674 675 file_location loc = get_current_location (); 676 if (c == '"') 677 stringbuf = read_quoted_string (); 678 else if (c == '{') 679 { 680 if (star_if_braced) 681 obstack_1grow (&m_string_obstack, '*'); 682 stringbuf = read_braced_string (); 683 } 684 else if (saw_paren && c == 'n') 685 { 686 /* Handle (nil) by returning NULL. */ 687 require_char ('i'); 688 require_char ('l'); 689 require_char_ws (')'); 690 return NULL; 691 } 692 else 693 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c); 694 695 if (saw_paren) 696 require_char_ws (')'); 697 698 set_md_ptr_loc (stringbuf, loc); 699 return stringbuf; 700 } 701 702 /* Skip the rest of a construct that started at line LINENO and that 703 is currently nested by DEPTH levels of parentheses. */ 704 705 void 706 md_reader::read_skip_construct (int depth, file_location loc) 707 { 708 struct md_name name; 709 int c; 710 711 do 712 { 713 c = read_skip_spaces (); 714 if (c == EOF) 715 { 716 error_at (loc, "unterminated construct"); 717 exit (1); 718 } 719 switch (c) 720 { 721 case '(': 722 depth++; 723 break; 724 725 case ')': 726 depth--; 727 break; 728 729 case ':': 730 case '[': 731 case ']': 732 case '/': 733 break; 734 735 case '\"': 736 case '{': 737 unread_char (c); 738 read_string (false); 739 break; 740 741 default: 742 unread_char (c); 743 read_name (&name); 744 break; 745 } 746 } 747 while (depth > 0); 748 unread_char (c); 749 } 750 751 /* Given a string, return the number of comma-separated elements in it. 752 Return 0 for the null string. */ 753 754 int 755 n_comma_elts (const char *s) 756 { 757 int n; 758 759 if (*s == '\0') 760 return 0; 761 762 for (n = 1; *s; s++) 763 if (*s == ',') 764 n++; 765 766 return n; 767 } 768 769 /* Given a pointer to a (char *), return a pointer to the beginning of the 770 next comma-separated element in the string. Advance the pointer given 771 to the end of that element. Return NULL if at end of string. Caller 772 is responsible for copying the string if necessary. White space between 773 a comma and an element is ignored. */ 774 775 const char * 776 scan_comma_elt (const char **pstr) 777 { 778 const char *start; 779 const char *p = *pstr; 780 781 if (*p == ',') 782 p++; 783 while (ISSPACE (*p)) 784 p++; 785 786 if (*p == '\0') 787 return NULL; 788 789 start = p; 790 791 while (*p != ',' && *p != '\0') 792 p++; 793 794 *pstr = p; 795 return start; 796 } 797 798 /* Convert STRING to uppercase. */ 799 800 void 801 upcase_string (char *string) 802 { 803 int i; 804 805 for (i = 0; string[i]; i++) 806 string[i] = TOUPPER (string[i]); 807 } 808 809 /* Add a NAME = VALUE definition to md_constants-style hash table DEFS, 810 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the 811 enum to which NAME belongs, or null if NAME is a stand-alone constant. */ 812 813 static struct md_constant * 814 add_constant (htab_t defs, char *name, char *value, 815 struct enum_type *parent_enum) 816 { 817 struct md_constant *def, tmp_def; 818 void **entry_ptr; 819 820 tmp_def.name = name; 821 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT); 822 if (*entry_ptr) 823 { 824 def = (struct md_constant *) *entry_ptr; 825 if (strcmp (def->value, value) != 0) 826 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'", 827 def->name, def->value, value); 828 else if (parent_enum || def->parent_enum) 829 fatal_with_file_and_line ("redefinition of `%s'", def->name); 830 free (name); 831 free (value); 832 } 833 else 834 { 835 def = XNEW (struct md_constant); 836 def->name = name; 837 def->value = value; 838 def->parent_enum = parent_enum; 839 *entry_ptr = def; 840 } 841 return def; 842 } 843 844 /* Process a define_constants directive, starting with the optional space 845 after the "define_constants". */ 846 847 void 848 md_reader::handle_constants () 849 { 850 int c; 851 htab_t defs; 852 853 require_char_ws ('['); 854 855 /* Disable constant expansion during definition processing. */ 856 defs = m_md_constants; 857 m_md_constants = 0; 858 while ( (c = read_skip_spaces ()) != ']') 859 { 860 struct md_name name, value; 861 862 if (c != '(') 863 fatal_expected_char ('(', c); 864 865 read_name (&name); 866 read_name (&value); 867 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0); 868 869 require_char_ws (')'); 870 } 871 m_md_constants = defs; 872 } 873 874 /* For every constant definition, call CALLBACK with two arguments: 875 a pointer a pointer to the constant definition and INFO. 876 Stop when CALLBACK returns zero. */ 877 878 void 879 md_reader::traverse_md_constants (htab_trav callback, void *info) 880 { 881 htab_traverse (get_md_constants (), callback, info); 882 } 883 884 /* Return a malloc()ed decimal string that represents number NUMBER. */ 885 886 static char * 887 md_decimal_string (int number) 888 { 889 /* A safe overestimate. +1 for sign, +1 for null terminator. */ 890 char buffer[sizeof (int) * CHAR_BIT + 1 + 1]; 891 892 sprintf (buffer, "%d", number); 893 return xstrdup (buffer); 894 } 895 896 /* Process a define_enum or define_c_enum directive, starting with 897 the optional space after the "define_enum". LINENO is the line 898 number on which the directive started and MD_P is true if the 899 directive is a define_enum rather than a define_c_enum. */ 900 901 void 902 md_reader::handle_enum (file_location loc, bool md_p) 903 { 904 char *enum_name, *value_name; 905 struct md_name name; 906 struct enum_type *def; 907 struct enum_value *ev; 908 void **slot; 909 int c; 910 911 enum_name = read_string (false); 912 slot = htab_find_slot (m_enum_types, &enum_name, INSERT); 913 if (*slot) 914 { 915 def = (struct enum_type *) *slot; 916 if (def->md_p != md_p) 917 error_at (loc, "redefining `%s' as a different type of enum", 918 enum_name); 919 } 920 else 921 { 922 def = XNEW (struct enum_type); 923 def->name = enum_name; 924 def->md_p = md_p; 925 def->values = 0; 926 def->tail_ptr = &def->values; 927 def->num_values = 0; 928 *slot = def; 929 } 930 931 require_char_ws ('['); 932 933 while ((c = read_skip_spaces ()) != ']') 934 { 935 if (c == EOF) 936 { 937 error_at (loc, "unterminated construct"); 938 exit (1); 939 } 940 unread_char (c); 941 read_name (&name); 942 943 ev = XNEW (struct enum_value); 944 ev->next = 0; 945 if (md_p) 946 { 947 value_name = concat (def->name, "_", name.string, NULL); 948 upcase_string (value_name); 949 ev->name = xstrdup (name.string); 950 } 951 else 952 { 953 value_name = xstrdup (name.string); 954 ev->name = value_name; 955 } 956 ev->def = add_constant (get_md_constants (), value_name, 957 md_decimal_string (def->num_values), def); 958 959 *def->tail_ptr = ev; 960 def->tail_ptr = &ev->next; 961 def->num_values++; 962 } 963 } 964 965 /* Try to find the definition of the given enum. Return null on failure. */ 966 967 struct enum_type * 968 md_reader::lookup_enum_type (const char *name) 969 { 970 return (struct enum_type *) htab_find (m_enum_types, &name); 971 } 972 973 /* For every enum definition, call CALLBACK with two arguments: 974 a pointer to the constant definition and INFO. Stop when CALLBACK 975 returns zero. */ 976 977 void 978 md_reader::traverse_enum_types (htab_trav callback, void *info) 979 { 980 htab_traverse (m_enum_types, callback, info); 981 } 982 983 984 /* Constructor for md_reader. */ 985 986 md_reader::md_reader (bool compact) 987 : m_compact (compact), 988 m_toplevel_fname (NULL), 989 m_base_dir (NULL), 990 m_read_md_file (NULL), 991 m_read_md_filename (NULL), 992 m_read_md_lineno (0), 993 m_read_md_colno (0), 994 m_first_dir_md_include (NULL), 995 m_last_dir_md_include_ptr (&m_first_dir_md_include), 996 m_first_line (0), 997 m_last_line (0), 998 m_first_overload (NULL), 999 m_next_overload_ptr (&m_first_overload), 1000 m_overloads_htab (NULL) 1001 { 1002 /* Set the global singleton pointer. */ 1003 md_reader_ptr = this; 1004 1005 obstack_init (&m_string_obstack); 1006 1007 m_ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); 1008 obstack_init (&m_ptr_loc_obstack); 1009 1010 m_joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); 1011 obstack_init (&m_joined_conditions_obstack); 1012 1013 m_md_constants = htab_create (31, leading_string_hash, 1014 leading_string_eq_p, (htab_del) 0); 1015 1016 m_enum_types = htab_create (31, leading_string_hash, 1017 leading_string_eq_p, (htab_del) 0); 1018 1019 /* Unlock the stdio streams. */ 1020 unlock_std_streams (); 1021 } 1022 1023 /* md_reader's destructor. */ 1024 1025 md_reader::~md_reader () 1026 { 1027 free (m_base_dir); 1028 1029 htab_delete (m_enum_types); 1030 1031 htab_delete (m_md_constants); 1032 1033 obstack_free (&m_joined_conditions_obstack, NULL); 1034 htab_delete (m_joined_conditions); 1035 1036 obstack_free (&m_ptr_loc_obstack, NULL); 1037 htab_delete (m_ptr_locs); 1038 1039 obstack_free (&m_string_obstack, NULL); 1040 1041 /* Clear the global singleton pointer. */ 1042 md_reader_ptr = NULL; 1043 } 1044 1045 /* Process an "include" directive, starting with the optional space 1046 after the "include". Read in the file and use HANDLE_DIRECTIVE 1047 to process each unknown directive. LINENO is the line number on 1048 which the "include" occurred. */ 1049 1050 void 1051 md_reader::handle_include (file_location loc) 1052 { 1053 const char *filename; 1054 const char *old_filename; 1055 int old_lineno, old_colno; 1056 char *pathname; 1057 FILE *input_file, *old_file; 1058 1059 filename = read_string (false); 1060 input_file = NULL; 1061 1062 /* If the specified file name is absolute, skip the include stack. */ 1063 if (!IS_ABSOLUTE_PATH (filename)) 1064 { 1065 struct file_name_list *stackp; 1066 1067 /* Search the directory path, trying to open the file. */ 1068 for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next) 1069 { 1070 static const char sep[2] = { DIR_SEPARATOR, '\0' }; 1071 1072 pathname = concat (stackp->fname, sep, filename, NULL); 1073 input_file = fopen (pathname, "r"); 1074 if (input_file != NULL) 1075 break; 1076 free (pathname); 1077 } 1078 } 1079 1080 /* If we haven't managed to open the file yet, try combining the 1081 filename with BASE_DIR. */ 1082 if (input_file == NULL) 1083 { 1084 if (m_base_dir) 1085 pathname = concat (m_base_dir, filename, NULL); 1086 else 1087 pathname = xstrdup (filename); 1088 input_file = fopen (pathname, "r"); 1089 } 1090 1091 if (input_file == NULL) 1092 { 1093 free (pathname); 1094 error_at (loc, "include file `%s' not found", filename); 1095 return; 1096 } 1097 1098 /* Save the old cursor. Note that the LINENO argument to this 1099 function is the beginning of the include statement, while 1100 read_md_lineno has already been advanced. */ 1101 old_file = m_read_md_file; 1102 old_filename = m_read_md_filename; 1103 old_lineno = m_read_md_lineno; 1104 old_colno = m_read_md_colno; 1105 1106 if (include_callback) 1107 include_callback (pathname); 1108 1109 m_read_md_file = input_file; 1110 m_read_md_filename = pathname; 1111 1112 handle_file (); 1113 1114 /* Restore the old cursor. */ 1115 m_read_md_file = old_file; 1116 m_read_md_filename = old_filename; 1117 m_read_md_lineno = old_lineno; 1118 m_read_md_colno = old_colno; 1119 1120 /* Do not free the pathname. It is attached to the various rtx 1121 queue elements. */ 1122 } 1123 1124 /* Process the current file, assuming that read_md_file and 1125 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle 1126 unknown directives. */ 1127 1128 void 1129 md_reader::handle_file () 1130 { 1131 struct md_name directive; 1132 int c; 1133 1134 m_read_md_lineno = 1; 1135 m_read_md_colno = 0; 1136 while ((c = read_skip_spaces ()) != EOF) 1137 { 1138 file_location loc = get_current_location (); 1139 if (c != '(') 1140 fatal_expected_char ('(', c); 1141 1142 read_name (&directive); 1143 if (strcmp (directive.string, "define_constants") == 0) 1144 handle_constants (); 1145 else if (strcmp (directive.string, "define_enum") == 0) 1146 handle_enum (loc, true); 1147 else if (strcmp (directive.string, "define_c_enum") == 0) 1148 handle_enum (loc, false); 1149 else if (strcmp (directive.string, "include") == 0) 1150 handle_include (loc); 1151 else 1152 handle_unknown_directive (loc, directive.string); 1153 1154 require_char_ws (')'); 1155 } 1156 fclose (m_read_md_file); 1157 } 1158 1159 /* Like handle_file, but for top-level files. Set up m_toplevel_fname 1160 and m_base_dir accordingly. */ 1161 1162 void 1163 md_reader::handle_toplevel_file () 1164 { 1165 const char *base; 1166 1167 m_toplevel_fname = m_read_md_filename; 1168 base = lbasename (m_toplevel_fname); 1169 if (base == m_toplevel_fname) 1170 m_base_dir = NULL; 1171 else 1172 m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname); 1173 1174 handle_file (); 1175 } 1176 1177 file_location 1178 md_reader::get_current_location () const 1179 { 1180 return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno); 1181 } 1182 1183 /* Parse a -I option with argument ARG. */ 1184 1185 void 1186 md_reader::add_include_path (const char *arg) 1187 { 1188 struct file_name_list *dirtmp; 1189 1190 dirtmp = XNEW (struct file_name_list); 1191 dirtmp->next = 0; 1192 dirtmp->fname = arg; 1193 *m_last_dir_md_include_ptr = dirtmp; 1194 m_last_dir_md_include_ptr = &dirtmp->next; 1195 } 1196 1197 #ifdef GENERATOR_FILE 1198 1199 /* The main routine for reading .md files. Try to process all the .md 1200 files specified on the command line and return true if no error occurred. 1201 1202 ARGC and ARGV are the arguments to main. 1203 1204 PARSE_OPT, if nonnull, is passed all unknown command-line arguments. 1205 It should return true if it recognizes the argument or false if a 1206 generic error should be reported. */ 1207 1208 bool 1209 md_reader::read_md_files (int argc, const char **argv, 1210 bool (*parse_opt) (const char *)) 1211 { 1212 int i; 1213 bool no_more_options; 1214 bool already_read_stdin; 1215 int num_files; 1216 1217 /* First we loop over all the options. */ 1218 for (i = 1; i < argc; i++) 1219 if (argv[i][0] == '-') 1220 { 1221 /* An argument consisting of exactly one dash is a request to 1222 read stdin. This will be handled in the second loop. */ 1223 if (argv[i][1] == '\0') 1224 continue; 1225 1226 /* An argument consisting of just two dashes causes option 1227 parsing to cease. */ 1228 if (argv[i][1] == '-' && argv[i][2] == '\0') 1229 break; 1230 1231 if (argv[i][1] == 'I') 1232 { 1233 if (argv[i][2] != '\0') 1234 add_include_path (argv[i] + 2); 1235 else if (++i < argc) 1236 add_include_path (argv[i]); 1237 else 1238 fatal ("directory name missing after -I option"); 1239 continue; 1240 } 1241 1242 /* The program may have provided a callback so it can 1243 accept its own options. */ 1244 if (parse_opt && parse_opt (argv[i])) 1245 continue; 1246 1247 fatal ("invalid option `%s'", argv[i]); 1248 } 1249 1250 /* Now loop over all input files. */ 1251 num_files = 0; 1252 no_more_options = false; 1253 already_read_stdin = false; 1254 for (i = 1; i < argc; i++) 1255 { 1256 if (argv[i][0] == '-') 1257 { 1258 if (argv[i][1] == '\0') 1259 { 1260 /* Read stdin. */ 1261 if (already_read_stdin) 1262 fatal ("cannot read standard input twice"); 1263 1264 m_read_md_file = stdin; 1265 m_read_md_filename = "<stdin>"; 1266 handle_toplevel_file (); 1267 already_read_stdin = true; 1268 continue; 1269 } 1270 else if (argv[i][1] == '-' && argv[i][2] == '\0') 1271 { 1272 /* No further arguments are to be treated as options. */ 1273 no_more_options = true; 1274 continue; 1275 } 1276 else if (!no_more_options) 1277 continue; 1278 } 1279 1280 /* If we get here we are looking at a non-option argument, i.e. 1281 a file to be processed. */ 1282 m_read_md_filename = argv[i]; 1283 m_read_md_file = fopen (m_read_md_filename, "r"); 1284 if (m_read_md_file == 0) 1285 { 1286 perror (m_read_md_filename); 1287 return false; 1288 } 1289 handle_toplevel_file (); 1290 num_files++; 1291 } 1292 1293 /* If we get to this point without having seen any files to process, 1294 read the standard input now. */ 1295 if (num_files == 0 && !already_read_stdin) 1296 { 1297 m_read_md_file = stdin; 1298 m_read_md_filename = "<stdin>"; 1299 handle_toplevel_file (); 1300 } 1301 1302 return !have_error; 1303 } 1304 1305 #endif /* #ifdef GENERATOR_FILE */ 1306 1307 /* Read FILENAME. */ 1308 1309 bool 1310 md_reader::read_file (const char *filename) 1311 { 1312 m_read_md_filename = filename; 1313 m_read_md_file = fopen (m_read_md_filename, "r"); 1314 if (m_read_md_file == 0) 1315 { 1316 perror (m_read_md_filename); 1317 return false; 1318 } 1319 handle_toplevel_file (); 1320 return !have_error; 1321 } 1322 1323 /* Read FILENAME, filtering to just the given lines. */ 1324 1325 bool 1326 md_reader::read_file_fragment (const char *filename, 1327 int first_line, 1328 int last_line) 1329 { 1330 m_read_md_filename = filename; 1331 m_read_md_file = fopen (m_read_md_filename, "r"); 1332 if (m_read_md_file == 0) 1333 { 1334 perror (m_read_md_filename); 1335 return false; 1336 } 1337 m_first_line = first_line; 1338 m_last_line = last_line; 1339 handle_toplevel_file (); 1340 return !have_error; 1341 } 1342 1343 /* class noop_reader : public md_reader */ 1344 1345 /* A dummy implementation which skips unknown directives. */ 1346 void 1347 noop_reader::handle_unknown_directive (file_location loc, const char *) 1348 { 1349 read_skip_construct (1, loc); 1350 } 1351