1 /* 2 * 'sparse' library helper routines. 3 * 4 * Copyright (C) 2003 Transmeta Corp. 5 * 2003-2004 Linus Torvalds 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 #include <ctype.h> 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <stdarg.h> 29 #include <stddef.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <unistd.h> 34 #include <assert.h> 35 36 #include <sys/types.h> 37 38 #include "lib.h" 39 #include "allocate.h" 40 #include "token.h" 41 #include "parse.h" 42 #include "symbol.h" 43 #include "expression.h" 44 #include "evaluate.h" 45 #include "scope.h" 46 #include "linearize.h" 47 #include "target.h" 48 #include "machine.h" 49 #include "version.h" 50 #include "bits.h" 51 52 int verbose, optimize_level, optimize_size, preprocessing; 53 int die_if_error = 0; 54 int parse_error; 55 int has_error = 0; 56 int do_output = 0; 57 58 #ifndef __GNUC__ 59 # define __GNUC__ 2 60 # define __GNUC_MINOR__ 95 61 # define __GNUC_PATCHLEVEL__ 0 62 #endif 63 64 int gcc_major = __GNUC__; 65 int gcc_minor = __GNUC_MINOR__; 66 int gcc_patchlevel = __GNUC_PATCHLEVEL__; 67 68 const char *base_filename; 69 70 static const char *diag_prefix = ""; 71 static const char *gcc_base_dir = GCC_BASE; 72 static const char *multiarch_dir = MULTIARCH_TRIPLET; 73 static const char *outfile = NULL; 74 75 struct token *skip_to(struct token *token, int op) 76 { 77 while (!match_op(token, op) && !eof_token(token)) 78 token = token->next; 79 return token; 80 } 81 82 static struct token bad_token = { .pos.type = TOKEN_BAD }; 83 struct token *expect(struct token *token, int op, const char *where) 84 { 85 if (!match_op(token, op)) { 86 if (token != &bad_token) { 87 bad_token.next = token; 88 sparse_error(token->pos, "Expected %s %s", show_special(op), where); 89 sparse_error(token->pos, "got %s", show_token(token)); 90 } 91 if (op == ';') 92 return skip_to(token, op); 93 return &bad_token; 94 } 95 return token->next; 96 } 97 98 /// 99 // issue an error message on new parsing errors 100 // @token: the current token 101 // @errmsg: the error message 102 // If the current token is from a previous error, an error message 103 // has already been issued, so nothing more is done. 104 // Otherwise, @errmsg is displayed followed by the current token. 105 void unexpected(struct token *token, const char *errmsg) 106 { 107 if (token == &bad_token) 108 return; 109 sparse_error(token->pos, "%s", errmsg); 110 sparse_error(token->pos, "got %s", show_token(token)); 111 } 112 113 unsigned int hexval(unsigned int c) 114 { 115 int retval = 256; 116 switch (c) { 117 case '0'...'9': 118 retval = c - '0'; 119 break; 120 case 'a'...'f': 121 retval = c - 'a' + 10; 122 break; 123 case 'A'...'F': 124 retval = c - 'A' + 10; 125 break; 126 } 127 return retval; 128 } 129 130 static void do_warn(const char *type, struct position pos, const char * fmt, va_list args) 131 { 132 static char buffer[512]; 133 const char *name; 134 135 /* Shut up warnings if position is bad_token.pos */ 136 if (pos.type == TOKEN_BAD) 137 return; 138 139 vsprintf(buffer, fmt, args); 140 name = stream_name(pos.stream); 141 142 fflush(stdout); 143 fprintf(stderr, "%s: %s:%d:%d: %s%s\n", 144 diag_prefix, name, pos.line, pos.pos, type, buffer); 145 } 146 147 unsigned int fmax_warnings = 100; 148 static int show_info = 1; 149 150 void info(struct position pos, const char * fmt, ...) 151 { 152 va_list args; 153 154 if (!show_info) 155 return; 156 va_start(args, fmt); 157 do_warn("", pos, fmt, args); 158 va_end(args); 159 } 160 161 static void do_error(struct position pos, const char * fmt, va_list args) 162 { 163 static int errors = 0; 164 165 parse_error = 1; 166 die_if_error = 1; 167 show_info = 1; 168 /* Shut up warnings if position is bad_token.pos */ 169 if (pos.type == TOKEN_BAD) 170 return; 171 /* Shut up warnings after an error */ 172 has_error |= ERROR_CURR_PHASE; 173 if (errors > 100) { 174 static int once = 0; 175 show_info = 0; 176 if (once) 177 return; 178 fmt = "too many errors"; 179 once = 1; 180 } 181 182 do_warn("error: ", pos, fmt, args); 183 errors++; 184 } 185 186 void warning(struct position pos, const char * fmt, ...) 187 { 188 va_list args; 189 190 if (Wsparse_error) { 191 va_start(args, fmt); 192 do_error(pos, fmt, args); 193 va_end(args); 194 return; 195 } 196 197 if (!fmax_warnings || has_error) { 198 show_info = 0; 199 return; 200 } 201 202 if (!--fmax_warnings) { 203 show_info = 0; 204 fmt = "too many warnings"; 205 } 206 207 va_start(args, fmt); 208 do_warn("warning: ", pos, fmt, args); 209 va_end(args); 210 } 211 212 void sparse_error(struct position pos, const char * fmt, ...) 213 { 214 va_list args; 215 va_start(args, fmt); 216 do_error(pos, fmt, args); 217 va_end(args); 218 } 219 220 void expression_error(struct expression *expr, const char *fmt, ...) 221 { 222 va_list args; 223 va_start(args, fmt); 224 do_error(expr->pos, fmt, args); 225 va_end(args); 226 expr->ctype = &bad_ctype; 227 } 228 229 NORETURN_ATTR 230 void error_die(struct position pos, const char * fmt, ...) 231 { 232 va_list args; 233 va_start(args, fmt); 234 do_warn("error: ", pos, fmt, args); 235 va_end(args); 236 exit(1); 237 } 238 239 NORETURN_ATTR 240 void die(const char *fmt, ...) 241 { 242 va_list args; 243 static char buffer[512]; 244 245 va_start(args, fmt); 246 vsnprintf(buffer, sizeof(buffer), fmt, args); 247 va_end(args); 248 249 fprintf(stderr, "%s: %s\n", diag_prefix, buffer); 250 exit(1); 251 } 252 253 static struct token *pre_buffer_begin = NULL; 254 static struct token *pre_buffer_end = NULL; 255 256 int Waddress = 0; 257 int Waddress_space = 1; 258 int Wbitwise = 1; 259 int Wbitwise_pointer = 0; 260 int Wcast_from_as = 0; 261 int Wcast_to_as = 0; 262 int Wcast_truncate = 1; 263 int Wconstant_suffix = 0; 264 int Wconstexpr_not_const = 0; 265 int Wcontext = 1; 266 int Wdecl = 1; 267 int Wdeclarationafterstatement = -1; 268 int Wdefault_bitfield_sign = 0; 269 int Wdesignated_init = 1; 270 int Wdo_while = 0; 271 int Wimplicit_int = 1; 272 int Winit_cstring = 0; 273 int Wint_to_pointer_cast = 1; 274 int Wenum_mismatch = 1; 275 int Wexternal_function_has_definition = 1; 276 int Wsparse_error = 0; 277 int Wmemcpy_max_count = 1; 278 int Wnon_pointer_null = 1; 279 int Wold_initializer = 1; 280 int Wold_style_definition = 1; 281 int Wone_bit_signed_bitfield = 1; 282 int Woverride_init = 1; 283 int Woverride_init_all = 0; 284 int Woverride_init_whole_range = 0; 285 int Wparen_string = 0; 286 int Wpointer_arith = 0; 287 int Wpointer_to_int_cast = 1; 288 int Wptr_subtraction_blows = 0; 289 int Wreturn_void = 0; 290 int Wshadow = 0; 291 int Wshift_count_negative = 1; 292 int Wshift_count_overflow = 1; 293 int Wsizeof_bool = 0; 294 int Wstrict_prototypes = 1; 295 int Wtautological_compare = 0; 296 int Wtransparent_union = 0; 297 int Wtypesign = 0; 298 int Wundef = 0; 299 int Wuninitialized = 1; 300 int Wunknown_attribute = 0; 301 int Wvla = 1; 302 303 int dump_macro_defs = 0; 304 int dump_macros_only = 0; 305 306 int dbg_compound = 0; 307 int dbg_dead = 0; 308 int dbg_domtree = 0; 309 int dbg_entry = 0; 310 int dbg_ir = 0; 311 int dbg_postorder = 0; 312 313 unsigned long fdump_ir; 314 int fmem_report = 0; 315 unsigned long long fmemcpy_max_count = 100000; 316 unsigned long fpasses = ~0UL; 317 int funsigned_char = UNSIGNED_CHAR; 318 319 int preprocess_only; 320 321 static enum { STANDARD_C89, 322 STANDARD_C94, 323 STANDARD_C99, 324 STANDARD_C11, 325 STANDARD_GNU11, 326 STANDARD_GNU89, 327 STANDARD_GNU99, } standard = STANDARD_GNU89; 328 329 int arch_m64 = ARCH_M64_DEFAULT; 330 int arch_msize_long = 0; 331 int arch_big_endian = ARCH_BIG_ENDIAN; 332 int arch_mach = MACH_NATIVE; 333 334 335 #define CMDLINE_INCLUDE 20 336 static int cmdline_include_nr = 0; 337 static char *cmdline_include[CMDLINE_INCLUDE]; 338 339 340 void add_pre_buffer(const char *fmt, ...) 341 { 342 va_list args; 343 unsigned int size; 344 struct token *begin, *end; 345 char buffer[4096]; 346 347 va_start(args, fmt); 348 size = vsnprintf(buffer, sizeof(buffer), fmt, args); 349 va_end(args); 350 begin = tokenize_buffer(buffer, size, &end); 351 if (!pre_buffer_begin) 352 pre_buffer_begin = begin; 353 if (pre_buffer_end) 354 pre_buffer_end->next = begin; 355 pre_buffer_end = end; 356 } 357 358 static char **handle_switch_D(char *arg, char **next) 359 { 360 const char *name = arg + 1; 361 const char *value = "1"; 362 363 if (!*name) { 364 arg = *++next; 365 if (!arg) 366 die("argument to `-D' is missing"); 367 name = arg; 368 } 369 370 for (;;arg++) { 371 char c; 372 c = *arg; 373 if (!c) 374 break; 375 if (c == '=') { 376 *arg = '\0'; 377 value = arg + 1; 378 break; 379 } 380 } 381 add_pre_buffer("#define %s %s\n", name, value); 382 return next; 383 } 384 385 static char **handle_switch_E(char *arg, char **next) 386 { 387 if (arg[1] == '\0') 388 preprocess_only = 1; 389 return next; 390 } 391 392 static char **handle_switch_I(char *arg, char **next) 393 { 394 char *path = arg+1; 395 396 switch (arg[1]) { 397 case '-': 398 add_pre_buffer("#split_include\n"); 399 break; 400 401 case '\0': /* Plain "-I" */ 402 path = *++next; 403 if (!path) 404 die("missing argument for -I option"); 405 /* Fall through */ 406 default: 407 add_pre_buffer("#add_include \"%s/\"\n", path); 408 } 409 return next; 410 } 411 412 static void add_cmdline_include(char *filename) 413 { 414 if (cmdline_include_nr >= CMDLINE_INCLUDE) 415 die("too many include files for %s\n", filename); 416 cmdline_include[cmdline_include_nr++] = filename; 417 } 418 419 static char **handle_switch_i(char *arg, char **next) 420 { 421 if (*next && !strcmp(arg, "include")) 422 add_cmdline_include(*++next); 423 else if (*next && !strcmp(arg, "imacros")) 424 add_cmdline_include(*++next); 425 else if (*next && !strcmp(arg, "isystem")) { 426 char *path = *++next; 427 if (!path) 428 die("missing argument for -isystem option"); 429 add_pre_buffer("#add_isystem \"%s/\"\n", path); 430 } else if (*next && !strcmp(arg, "idirafter")) { 431 char *path = *++next; 432 if (!path) 433 die("missing argument for -idirafter option"); 434 add_pre_buffer("#add_dirafter \"%s/\"\n", path); 435 } 436 return next; 437 } 438 439 static char **handle_switch_M(char *arg, char **next) 440 { 441 if (!strcmp(arg, "MF") || !strcmp(arg,"MQ") || !strcmp(arg,"MT")) { 442 if (!*next) 443 die("missing argument for -%s option", arg); 444 return next + 1; 445 } 446 return next; 447 } 448 449 static char **handle_multiarch_dir(char *arg, char **next) 450 { 451 multiarch_dir = *++next; 452 if (!multiarch_dir) 453 die("missing argument for -multiarch-dir option"); 454 return next; 455 } 456 457 static char **handle_switch_m(char *arg, char **next) 458 { 459 if (!strcmp(arg, "m64")) { 460 arch_m64 = ARCH_LP64; 461 } else if (!strcmp(arg, "m32") || !strcmp(arg, "m16")) { 462 arch_m64 = ARCH_LP32; 463 } else if (!strcmp(arg, "mx32")) { 464 arch_m64 = ARCH_X32; 465 } else if (!strcmp(arg, "msize-llp64")) { 466 arch_m64 = ARCH_LLP64; 467 } else if (!strcmp(arg, "msize-long")) { 468 arch_msize_long = 1; 469 } else if (!strcmp(arg, "multiarch-dir")) { 470 return handle_multiarch_dir(arg, next); 471 } else if (!strcmp(arg, "mbig-endian")) { 472 arch_big_endian = 1; 473 } else if (!strcmp(arg, "mlittle-endian")) { 474 arch_big_endian = 0; 475 } 476 return next; 477 } 478 479 static void handle_arch_msize_long_finalize(void) 480 { 481 if (arch_msize_long) { 482 size_t_ctype = &ulong_ctype; 483 ssize_t_ctype = &long_ctype; 484 } 485 } 486 487 static void handle_arch_finalize(void) 488 { 489 handle_arch_msize_long_finalize(); 490 } 491 492 static const char *match_option(const char *arg, const char *prefix) 493 { 494 unsigned int n = strlen(prefix); 495 if (strncmp(arg, prefix, n) == 0) 496 return arg + n; 497 return NULL; 498 } 499 500 501 struct mask_map { 502 const char *name; 503 unsigned long mask; 504 }; 505 506 static int apply_mask(unsigned long *val, const char *str, unsigned len, const struct mask_map *map, int neg) 507 { 508 const char *name; 509 510 for (;(name = map->name); map++) { 511 if (!strncmp(name, str, len) && !name[len]) { 512 if (neg == 0) 513 *val |= map->mask; 514 else 515 *val &= ~map->mask; 516 return 0; 517 } 518 } 519 return 1; 520 } 521 522 static int handle_suboption_mask(const char *arg, const char *opt, const struct mask_map *map, unsigned long *flag) 523 { 524 if (*opt == '\0') { 525 apply_mask(flag, "", 0, map, 0); 526 return 1; 527 } 528 if (*opt++ != '=') 529 return 0; 530 while (1) { 531 unsigned int len = strcspn(opt, ",+"); 532 int neg = 0; 533 if (len == 0) 534 goto end; 535 if (!strncmp(opt, "no-", 3)) { 536 opt += 3; 537 len -= 3; 538 neg = 1; 539 } 540 if (apply_mask(flag, opt, len, map, neg)) 541 die("error: wrong option '%.*s' for \'%s\'", len, opt, arg); 542 543 end: 544 opt += len; 545 if (*opt++ == '\0') 546 break; 547 } 548 return 1; 549 } 550 551 552 #define OPT_INVERSE 1 553 struct flag { 554 const char *name; 555 int *flag; 556 int (*fun)(const char *arg, const char *opt, const struct flag *, int options); 557 unsigned long mask; 558 }; 559 560 static int handle_switches(const char *ori, const char *opt, const struct flag *flags) 561 { 562 const char *arg = opt; 563 int val = 1; 564 565 // Prefixe "no-" mean to turn flag off. 566 if (strncmp(arg, "no-", 3) == 0) { 567 arg += 3; 568 val = 0; 569 } 570 571 for (; flags->name; flags++) { 572 const char *opt = match_option(arg, flags->name); 573 int rc; 574 575 if (!opt) 576 continue; 577 578 if (flags->fun) { 579 int options = 0; 580 if (!val) 581 options |= OPT_INVERSE; 582 if ((rc = flags->fun(ori, opt, flags, options))) 583 return rc; 584 } 585 586 // boolean flag 587 if (opt[0] == '\0' && flags->flag) { 588 if (flags->mask & OPT_INVERSE) 589 val = !val; 590 *flags->flag = val; 591 return 1; 592 } 593 } 594 595 // not handled 596 return 0; 597 } 598 599 600 #define OPTNUM_ZERO_IS_INF 1 601 #define OPTNUM_UNLIMITED 2 602 603 #define OPT_NUMERIC(NAME, TYPE, FUNCTION) \ 604 static int opt_##NAME(const char *arg, const char *opt, TYPE *ptr, int flag) \ 605 { \ 606 char *end; \ 607 TYPE val; \ 608 \ 609 val = FUNCTION(opt, &end, 0); \ 610 if (*end != '\0' || end == opt) { \ 611 if ((flag & OPTNUM_UNLIMITED) && !strcmp(opt, "unlimited")) \ 612 val = ~val; \ 613 else \ 614 die("error: wrong argument to \'%s\'", arg); \ 615 } \ 616 if ((flag & OPTNUM_ZERO_IS_INF) && val == 0) \ 617 val = ~val; \ 618 *ptr = val; \ 619 return 1; \ 620 } 621 622 OPT_NUMERIC(ullong, unsigned long long, strtoull) 623 OPT_NUMERIC(uint, unsigned int, strtoul) 624 625 626 static char **handle_switch_o(char *arg, char **next) 627 { 628 if (!strcmp (arg, "o")) { // "-o foo" 629 if (!*++next) 630 die("argument to '-o' is missing"); 631 outfile = *next; 632 } 633 // else "-ofoo" 634 635 return next; 636 } 637 638 static const struct flag warnings[] = { 639 { "address", &Waddress }, 640 { "address-space", &Waddress_space }, 641 { "bitwise", &Wbitwise }, 642 { "bitwise-pointer", &Wbitwise_pointer}, 643 { "cast-from-as", &Wcast_from_as }, 644 { "cast-to-as", &Wcast_to_as }, 645 { "cast-truncate", &Wcast_truncate }, 646 { "constant-suffix", &Wconstant_suffix }, 647 { "constexpr-not-const", &Wconstexpr_not_const}, 648 { "context", &Wcontext }, 649 { "decl", &Wdecl }, 650 { "declaration-after-statement", &Wdeclarationafterstatement }, 651 { "default-bitfield-sign", &Wdefault_bitfield_sign }, 652 { "designated-init", &Wdesignated_init }, 653 { "do-while", &Wdo_while }, 654 { "enum-mismatch", &Wenum_mismatch }, 655 { "external-function-has-definition", &Wexternal_function_has_definition }, 656 { "implicit-int", &Wimplicit_int }, 657 { "init-cstring", &Winit_cstring }, 658 { "int-to-pointer-cast", &Wint_to_pointer_cast }, 659 { "memcpy-max-count", &Wmemcpy_max_count }, 660 { "non-pointer-null", &Wnon_pointer_null }, 661 { "old-initializer", &Wold_initializer }, 662 { "old-style-definition", &Wold_style_definition }, 663 { "one-bit-signed-bitfield", &Wone_bit_signed_bitfield }, 664 { "override-init", &Woverride_init }, 665 { "override-init-all", &Woverride_init_all }, 666 { "paren-string", &Wparen_string }, 667 { "pointer-to-int-cast", &Wpointer_to_int_cast }, 668 { "ptr-subtraction-blows", &Wptr_subtraction_blows }, 669 { "return-void", &Wreturn_void }, 670 { "shadow", &Wshadow }, 671 { "shift-count-negative", &Wshift_count_negative }, 672 { "shift-count-overflow", &Wshift_count_overflow }, 673 { "sizeof-bool", &Wsizeof_bool }, 674 { "strict-prototypes", &Wstrict_prototypes }, 675 { "pointer-arith", &Wpointer_arith }, 676 { "sparse-error", &Wsparse_error }, 677 { "tautological-compare", &Wtautological_compare }, 678 { "transparent-union", &Wtransparent_union }, 679 { "typesign", &Wtypesign }, 680 { "undef", &Wundef }, 681 { "uninitialized", &Wuninitialized }, 682 { "unknown-attribute", &Wunknown_attribute }, 683 { "vla", &Wvla }, 684 }; 685 686 enum { 687 WARNING_OFF, 688 WARNING_ON, 689 WARNING_FORCE_OFF 690 }; 691 692 693 static char **handle_onoff_switch(char *arg, char **next, const struct flag warnings[], int n) 694 { 695 int flag = WARNING_ON; 696 char *p = arg + 1; 697 unsigned i; 698 699 if (!strcmp(p, "sparse-all")) { 700 for (i = 0; i < n; i++) { 701 if (*warnings[i].flag != WARNING_FORCE_OFF && warnings[i].flag != &Wsparse_error) 702 *warnings[i].flag = WARNING_ON; 703 } 704 return NULL; 705 } 706 707 // Prefixes "no" and "no-" mean to turn warning off. 708 if (p[0] == 'n' && p[1] == 'o') { 709 p += 2; 710 if (p[0] == '-') 711 p++; 712 flag = WARNING_FORCE_OFF; 713 } 714 715 for (i = 0; i < n; i++) { 716 if (!strcmp(p,warnings[i].name)) { 717 *warnings[i].flag = flag; 718 return next; 719 } 720 } 721 722 // Unknown. 723 return NULL; 724 } 725 726 static char **handle_switch_W(char *arg, char **next) 727 { 728 char ** ret = handle_onoff_switch(arg, next, warnings, ARRAY_SIZE(warnings)); 729 if (ret) 730 return ret; 731 732 // Unknown. 733 return next; 734 } 735 736 static struct flag debugs[] = { 737 { "compound", &dbg_compound}, 738 { "dead", &dbg_dead}, 739 { "domtree", &dbg_domtree}, 740 { "entry", &dbg_entry}, 741 { "ir", &dbg_ir}, 742 { "postorder", &dbg_postorder}, 743 }; 744 745 746 static char **handle_switch_v(char *arg, char **next) 747 { 748 char ** ret = handle_onoff_switch(arg, next, debugs, ARRAY_SIZE(debugs)); 749 if (ret) 750 return ret; 751 752 // Unknown. 753 do { 754 verbose++; 755 } while (*++arg == 'v'); 756 return next; 757 } 758 759 static char **handle_switch_d(char *arg, char **next) 760 { 761 char *arg_char = arg + 1; 762 763 /* 764 * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded 765 * by a space. If you specify characters whose behaviour conflicts, 766 * the result is undefined. 767 */ 768 while (*arg_char) { 769 switch (*arg_char) { 770 case 'M': /* dump just the macro definitions */ 771 dump_macros_only = 1; 772 dump_macro_defs = 0; 773 break; 774 case 'D': /* like 'M', but also output pre-processed text */ 775 dump_macro_defs = 1; 776 dump_macros_only = 0; 777 break; 778 case 'N': /* like 'D', but only output macro names not bodies */ 779 break; 780 case 'I': /* like 'D', but also output #include directives */ 781 break; 782 case 'U': /* like 'D', but only output expanded macros */ 783 break; 784 } 785 arg_char++; 786 } 787 return next; 788 } 789 790 791 static void handle_onoff_switch_finalize(const struct flag warnings[], int n) 792 { 793 unsigned i; 794 795 for (i = 0; i < n; i++) { 796 if (*warnings[i].flag == WARNING_FORCE_OFF) 797 *warnings[i].flag = WARNING_OFF; 798 } 799 } 800 801 static void handle_switch_W_finalize(void) 802 { 803 handle_onoff_switch_finalize(warnings, ARRAY_SIZE(warnings)); 804 805 /* default Wdeclarationafterstatement based on the C dialect */ 806 if (-1 == Wdeclarationafterstatement) 807 { 808 switch (standard) 809 { 810 case STANDARD_C89: 811 case STANDARD_C94: 812 Wdeclarationafterstatement = 1; 813 break; 814 815 case STANDARD_C99: 816 case STANDARD_GNU89: 817 case STANDARD_GNU99: 818 case STANDARD_C11: 819 case STANDARD_GNU11: 820 Wdeclarationafterstatement = 0; 821 break; 822 823 default: 824 assert (0); 825 } 826 827 } 828 } 829 830 static void handle_switch_v_finalize(void) 831 { 832 handle_onoff_switch_finalize(debugs, ARRAY_SIZE(debugs)); 833 } 834 835 static char **handle_switch_U(char *arg, char **next) 836 { 837 const char *name = arg + 1; 838 if (*name == '\0') 839 name = *++next; 840 add_pre_buffer ("#undef %s\n", name); 841 return next; 842 } 843 844 static char **handle_switch_O(char *arg, char **next) 845 { 846 int level = 1; 847 if (arg[1] >= '0' && arg[1] <= '9') 848 level = arg[1] - '0'; 849 optimize_level = level; 850 optimize_size = arg[1] == 's'; 851 return next; 852 } 853 854 static int handle_ftabstop(const char *arg, const char *opt, const struct flag *flag, int options) 855 { 856 unsigned long val; 857 char *end; 858 859 if (*opt == '\0') 860 die("error: missing argument to \"%s\"", arg); 861 862 /* we silently ignore silly values */ 863 val = strtoul(opt, &end, 10); 864 if (*end == '\0' && 1 <= val && val <= 100) 865 tabstop = val; 866 867 return 1; 868 } 869 870 static int handle_fpasses(const char *arg, const char *opt, const struct flag *flag, int options) 871 { 872 unsigned long mask; 873 874 mask = flag->mask; 875 if (*opt == '\0') { 876 if (options & OPT_INVERSE) 877 fpasses &= ~mask; 878 else 879 fpasses |= mask; 880 return 1; 881 } 882 if (options & OPT_INVERSE) 883 return 0; 884 if (!strcmp(opt, "-enable")) { 885 fpasses |= mask; 886 return 1; 887 } 888 if (!strcmp(opt, "-disable")) { 889 fpasses &= ~mask; 890 return 1; 891 } 892 if (!strcmp(opt, "=last")) { 893 // clear everything above 894 mask |= mask - 1; 895 fpasses &= mask; 896 return 1; 897 } 898 return 0; 899 } 900 901 static int handle_fdiagnostic_prefix(const char *arg, const char *opt, const struct flag *flag, int options) 902 { 903 switch (*opt) { 904 case '\0': 905 diag_prefix = "sparse"; 906 return 1; 907 case '=': 908 diag_prefix = xasprintf("%s", opt+1); 909 return 1; 910 default: 911 return 0; 912 } 913 } 914 915 static int handle_fdump_ir(const char *arg, const char *opt, const struct flag *flag, int options) 916 { 917 static const struct mask_map dump_ir_options[] = { 918 { "", PASS_LINEARIZE }, 919 { "linearize", PASS_LINEARIZE }, 920 { "mem2reg", PASS_MEM2REG }, 921 { "final", PASS_FINAL }, 922 { }, 923 }; 924 925 return handle_suboption_mask(arg, opt, dump_ir_options, &fdump_ir); 926 } 927 928 static int handle_fmemcpy_max_count(const char *arg, const char *opt, const struct flag *flag, int options) 929 { 930 opt_ullong(arg, opt, &fmemcpy_max_count, OPTNUM_ZERO_IS_INF|OPTNUM_UNLIMITED); 931 return 1; 932 } 933 934 static int handle_fmax_warnings(const char *arg, const char *opt, const struct flag *flag, int options) 935 { 936 opt_uint(arg, opt, &fmax_warnings, OPTNUM_UNLIMITED); 937 return 1; 938 } 939 940 static struct flag fflags[] = { 941 { "diagnostic-prefix", NULL, handle_fdiagnostic_prefix }, 942 { "dump-ir", NULL, handle_fdump_ir }, 943 { "linearize", NULL, handle_fpasses, PASS_LINEARIZE }, 944 { "max-warnings=", NULL, handle_fmax_warnings }, 945 { "mem-report", &fmem_report }, 946 { "memcpy-max-count=", NULL, handle_fmemcpy_max_count }, 947 { "tabstop=", NULL, handle_ftabstop }, 948 { "mem2reg", NULL, handle_fpasses, PASS_MEM2REG }, 949 { "optim", NULL, handle_fpasses, PASS_OPTIM }, 950 { "signed-char", &funsigned_char, NULL, OPT_INVERSE }, 951 { "unsigned-char", &funsigned_char, NULL, }, 952 { }, 953 }; 954 955 static char **handle_switch_f(char *arg, char **next) 956 { 957 if (handle_switches(arg-1, arg+1, fflags)) 958 return next; 959 960 return next; 961 } 962 963 static char **handle_switch_G(char *arg, char **next) 964 { 965 if (!strcmp (arg, "G") && *next) 966 return next + 1; // "-G 0" 967 else 968 return next; // "-G0" or (bogus) terminal "-G" 969 } 970 971 static char **handle_switch_a(char *arg, char **next) 972 { 973 if (!strcmp (arg, "ansi")) 974 standard = STANDARD_C89; 975 976 return next; 977 } 978 979 static char **handle_switch_s(const char *arg, char **next) 980 { 981 if ((arg = match_option(arg, "std="))) { 982 if (!strcmp (arg, "c89") || 983 !strcmp (arg, "iso9899:1990")) 984 standard = STANDARD_C89; 985 986 else if (!strcmp (arg, "iso9899:199409")) 987 standard = STANDARD_C94; 988 989 else if (!strcmp (arg, "c99") || 990 !strcmp (arg, "c9x") || 991 !strcmp (arg, "iso9899:1999") || 992 !strcmp (arg, "iso9899:199x")) 993 standard = STANDARD_C99; 994 995 else if (!strcmp (arg, "gnu89")) 996 standard = STANDARD_GNU89; 997 998 else if (!strcmp (arg, "gnu99") || !strcmp (arg, "gnu9x")) 999 standard = STANDARD_GNU99; 1000 1001 else if (!strcmp(arg, "c11") || 1002 !strcmp(arg, "c1x") || 1003 !strcmp(arg, "iso9899:2011")) 1004 standard = STANDARD_C11; 1005 1006 else if (!strcmp(arg, "gnu11")) 1007 standard = STANDARD_GNU11; 1008 1009 else 1010 die ("Unsupported C dialect"); 1011 } 1012 1013 return next; 1014 } 1015 1016 static char **handle_nostdinc(char *arg, char **next) 1017 { 1018 add_pre_buffer("#nostdinc\n"); 1019 return next; 1020 } 1021 1022 static char **handle_switch_n(char *arg, char **next) 1023 { 1024 if (!strcmp (arg, "nostdinc")) 1025 return handle_nostdinc(arg, next); 1026 1027 return next; 1028 } 1029 1030 static char **handle_base_dir(char *arg, char **next) 1031 { 1032 gcc_base_dir = *++next; 1033 if (!gcc_base_dir) 1034 die("missing argument for -gcc-base-dir option"); 1035 return next; 1036 } 1037 1038 static char **handle_no_lineno(char *arg, char **next) 1039 { 1040 no_lineno = 1; 1041 return next; 1042 } 1043 1044 static char **handle_switch_g(char *arg, char **next) 1045 { 1046 if (!strcmp (arg, "gcc-base-dir")) 1047 return handle_base_dir(arg, next); 1048 1049 return next; 1050 } 1051 1052 static char **handle_switch_x(char *arg, char **next) 1053 { 1054 if (!*++next) 1055 die("missing argument for -x option"); 1056 return next; 1057 } 1058 1059 static char **handle_version(char *arg, char **next) 1060 { 1061 printf("%s\n", SPARSE_VERSION); 1062 exit(0); 1063 } 1064 1065 static char **handle_param(char *arg, char **next) 1066 { 1067 char *value = NULL; 1068 1069 /* Ignore smatch's --param-mapper */ 1070 if (strcmp(arg, "-mapper") == 0) 1071 return next; 1072 1073 /* For now just skip any '--param=*' or '--param *' */ 1074 if (*arg == '\0') { 1075 value = *++next; 1076 } else if (isspace((unsigned char)*arg) || *arg == '=') { 1077 value = ++arg; 1078 } 1079 1080 if (!value) 1081 die("missing argument for --param option"); 1082 1083 return next; 1084 } 1085 1086 struct switches { 1087 const char *name; 1088 char **(*fn)(char *, char **); 1089 unsigned int prefix:1; 1090 }; 1091 1092 static char **handle_long_options(char *arg, char **next) 1093 { 1094 static struct switches cmd[] = { 1095 { "param", handle_param, 1 }, 1096 { "version", handle_version }, 1097 { "nostdinc", handle_nostdinc }, 1098 { "gcc-base-dir", handle_base_dir}, 1099 { "no-lineno", handle_no_lineno}, 1100 { NULL, NULL } 1101 }; 1102 struct switches *s = cmd; 1103 1104 while (s->name) { 1105 int optlen = strlen(s->name); 1106 if (!strncmp(s->name, arg, optlen + !s->prefix)) 1107 return s->fn(arg + optlen, next); 1108 s++; 1109 } 1110 return next; 1111 } 1112 1113 static char **handle_switch(char *arg, char **next) 1114 { 1115 switch (*arg) { 1116 case 'a': return handle_switch_a(arg, next); 1117 case 'D': return handle_switch_D(arg, next); 1118 case 'd': return handle_switch_d(arg, next); 1119 case 'E': return handle_switch_E(arg, next); 1120 case 'f': return handle_switch_f(arg, next); 1121 case 'g': return handle_switch_g(arg, next); 1122 case 'G': return handle_switch_G(arg, next); 1123 case 'I': return handle_switch_I(arg, next); 1124 case 'i': return handle_switch_i(arg, next); 1125 case 'M': return handle_switch_M(arg, next); 1126 case 'm': return handle_switch_m(arg, next); 1127 case 'n': return handle_switch_n(arg, next); 1128 case 'o': return handle_switch_o(arg, next); 1129 case 'O': return handle_switch_O(arg, next); 1130 case 's': return handle_switch_s(arg, next); 1131 case 'U': return handle_switch_U(arg, next); 1132 case 'v': return handle_switch_v(arg, next); 1133 case 'W': return handle_switch_W(arg, next); 1134 case 'x': return handle_switch_x(arg, next); 1135 case '-': return handle_long_options(arg + 1, next); 1136 default: 1137 break; 1138 } 1139 1140 /* 1141 * Ignore unknown command line options: 1142 * they're probably gcc switches 1143 */ 1144 return next; 1145 } 1146 1147 #define PTYPE_SIZEOF (1U << 0) 1148 #define PTYPE_T (1U << 1) 1149 #define PTYPE_MAX (1U << 2) 1150 #define PTYPE_MIN (1U << 3) 1151 #define PTYPE_WIDTH (1U << 4) 1152 #define PTYPE_TYPE (1U << 5) 1153 #define PTYPE_ALL (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH) 1154 #define PTYPE_ALL_T (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH|PTYPE_T) 1155 1156 static void predefined_sizeof(const char *name, const char *suffix, unsigned bits) 1157 { 1158 char buf[32]; 1159 1160 snprintf(buf, sizeof(buf), "__SIZEOF_%s%s__", name, suffix); 1161 predefine(buf, 1, "%d", bits/8); 1162 } 1163 1164 static void predefined_width(const char *name, unsigned bits) 1165 { 1166 char buf[32]; 1167 1168 snprintf(buf, sizeof(buf), "__%s_WIDTH__", name); 1169 predefine(buf, 1, "%d", bits); 1170 } 1171 1172 static void predefined_max(const char *name, struct symbol *type) 1173 { 1174 const char *suffix = builtin_type_suffix(type); 1175 unsigned bits = type->bit_size - is_signed_type(type); 1176 unsigned long long max = bits_mask(bits); 1177 char buf[32]; 1178 1179 snprintf(buf, sizeof(buf), "__%s_MAX__", name); 1180 predefine(buf, 1, "%#llx%s", max, suffix); 1181 } 1182 1183 static void predefined_min(const char *name, struct symbol *type) 1184 { 1185 const char *suffix = builtin_type_suffix(type); 1186 char buf[32]; 1187 1188 snprintf(buf, sizeof(buf), "__%s_MIN__", name); 1189 1190 if (is_signed_type(type)) 1191 predefine(buf, 1, "(-__%s_MAX__ - 1)", name); 1192 else 1193 predefine(buf, 1, "0%s", suffix); 1194 } 1195 1196 static void predefined_type(const char *name, struct symbol *type) 1197 { 1198 const char *typename = builtin_typename(type); 1199 add_pre_buffer("#weak_define __%s_TYPE__ %s\n", name, typename); 1200 } 1201 1202 static void predefined_ctype(const char *name, struct symbol *type, int flags) 1203 { 1204 unsigned bits = type->bit_size; 1205 1206 if (flags & PTYPE_SIZEOF) { 1207 const char *suffix = (flags & PTYPE_T) ? "_T" : ""; 1208 predefined_sizeof(name, suffix, bits); 1209 } 1210 if (flags & PTYPE_MAX) 1211 predefined_max(name, type); 1212 if (flags & PTYPE_MIN) 1213 predefined_min(name, type); 1214 if (flags & PTYPE_TYPE) 1215 predefined_type(name, type); 1216 if (flags & PTYPE_WIDTH) 1217 predefined_width(name, bits); 1218 } 1219 1220 static void predefined_macros(void) 1221 { 1222 predefine("__CHECKER__", 0, "1"); 1223 predefine("__GNUC__", 1, "%d", gcc_major); 1224 predefine("__GNUC_MINOR__", 1, "%d", gcc_minor); 1225 predefine("__GNUC_PATCHLEVEL__", 1, "%d", gcc_patchlevel); 1226 1227 predefine("__STDC__", 1, "1"); 1228 switch (standard) { 1229 case STANDARD_C89: 1230 predefine("__STRICT_ANSI__", 1, "1"); 1231 break; 1232 1233 case STANDARD_C94: 1234 predefine("__STDC_VERSION__", 1, "199409L"); 1235 predefine("__STRICT_ANSI__", 1, "1"); 1236 break; 1237 1238 case STANDARD_C99: 1239 predefine("__STDC_VERSION__", 1, "199901L"); 1240 predefine("__STRICT_ANSI__", 1, "1"); 1241 break; 1242 1243 case STANDARD_GNU89: 1244 default: 1245 break; 1246 1247 case STANDARD_GNU99: 1248 predefine("__STDC_VERSION__", 1, "199901L"); 1249 break; 1250 1251 case STANDARD_C11: 1252 predefine("__STRICT_ANSI__", 1, "1"); 1253 case STANDARD_GNU11: 1254 predefine("__STDC_NO_ATOMICS__", 1, "1"); 1255 predefine("__STDC_NO_COMPLEX__", 1, "1"); 1256 predefine("__STDC_NO_THREADS__", 1, "1"); 1257 predefine("__STDC_VERSION__", 1, "201112L"); 1258 break; 1259 } 1260 1261 predefine("__CHAR_BIT__", 1, "%d", bits_in_char); 1262 if (funsigned_char) 1263 predefine("__CHAR_UNSIGNED__", 1, "1"); 1264 1265 predefined_ctype("SHORT", &short_ctype, PTYPE_SIZEOF); 1266 predefined_ctype("SHRT", &short_ctype, PTYPE_MAX|PTYPE_WIDTH); 1267 predefined_ctype("SCHAR", &schar_ctype, PTYPE_MAX|PTYPE_WIDTH); 1268 predefined_ctype("WCHAR", wchar_ctype, PTYPE_ALL_T|PTYPE_MIN|PTYPE_TYPE); 1269 predefined_ctype("WINT", wint_ctype, PTYPE_ALL_T|PTYPE_MIN|PTYPE_TYPE); 1270 predefined_ctype("CHAR16", &ushort_ctype, PTYPE_TYPE); 1271 predefined_ctype("CHAR32", &uint_ctype, PTYPE_TYPE); 1272 1273 predefined_ctype("INT", &int_ctype, PTYPE_ALL); 1274 predefined_ctype("LONG", &long_ctype, PTYPE_ALL); 1275 predefined_ctype("LONG_LONG", &llong_ctype, PTYPE_ALL); 1276 1277 predefined_ctype("INT8", &schar_ctype, PTYPE_MAX|PTYPE_TYPE); 1278 predefined_ctype("UINT8", &uchar_ctype, PTYPE_MAX|PTYPE_TYPE); 1279 predefined_ctype("INT16", &short_ctype, PTYPE_MAX|PTYPE_TYPE); 1280 predefined_ctype("UINT16", &ushort_ctype, PTYPE_MAX|PTYPE_TYPE); 1281 predefined_ctype("INT32", int32_ctype, PTYPE_MAX|PTYPE_TYPE); 1282 predefined_ctype("UINT32", uint32_ctype, PTYPE_MAX|PTYPE_TYPE); 1283 predefined_ctype("INT64", int64_ctype, PTYPE_MAX|PTYPE_TYPE); 1284 predefined_ctype("UINT64", uint64_ctype, PTYPE_MAX|PTYPE_TYPE); 1285 1286 predefined_sizeof("INT128", "", 128); 1287 1288 predefined_ctype("INTMAX", intmax_ctype, PTYPE_MAX|PTYPE_TYPE|PTYPE_WIDTH); 1289 predefined_ctype("UINTMAX", uintmax_ctype, PTYPE_MAX|PTYPE_TYPE); 1290 predefined_ctype("INTPTR", ssize_t_ctype, PTYPE_MAX|PTYPE_TYPE|PTYPE_WIDTH); 1291 predefined_ctype("UINTPTR", size_t_ctype, PTYPE_MAX|PTYPE_TYPE); 1292 predefined_ctype("PTRDIFF", ssize_t_ctype, PTYPE_ALL_T|PTYPE_TYPE); 1293 predefined_ctype("SIZE", size_t_ctype, PTYPE_ALL_T|PTYPE_TYPE); 1294 predefined_ctype("POINTER", &ptr_ctype, PTYPE_SIZEOF); 1295 1296 predefined_sizeof("FLOAT", "", bits_in_float); 1297 predefined_sizeof("DOUBLE", "", bits_in_double); 1298 predefined_sizeof("LONG_DOUBLE", "", bits_in_longdouble); 1299 1300 predefine("__ORDER_LITTLE_ENDIAN__", 1, "1234"); 1301 predefine("__ORDER_BIG_ENDIAN__", 1, "4321"); 1302 predefine("__ORDER_PDP_ENDIAN__", 1, "3412"); 1303 if (arch_big_endian) { 1304 predefine("__BIG_ENDIAN__", 1, "1"); 1305 predefine("__BYTE_ORDER__", 1, "__ORDER_BIG_ENDIAN__"); 1306 } else { 1307 predefine("__LITTLE_ENDIAN__", 1, "1"); 1308 predefine("__BYTE_ORDER__", 1, "__ORDER_LITTLE_ENDIAN__"); 1309 } 1310 1311 if (optimize_level) 1312 predefine("__OPTIMIZE__", 0, "1"); 1313 if (optimize_size) 1314 predefine("__OPTIMIZE_SIZE__", 0, "1"); 1315 1316 // Temporary hacks 1317 predefine("__extension__", 0, NULL); 1318 predefine("__pragma__", 0, NULL); 1319 1320 switch (arch_m64) { 1321 case ARCH_LP32: 1322 break; 1323 case ARCH_X32: 1324 predefine("__ILP32__", 1, "1"); 1325 predefine("_ILP32", 1, "1"); 1326 break; 1327 case ARCH_LP64: 1328 predefine("__LP64__", 1, "1"); 1329 predefine("__LP64", 1, "1"); 1330 predefine("_LP64", 1, "1"); 1331 break; 1332 case ARCH_LLP64: 1333 predefine("__LLP64__", 1, "1"); 1334 break; 1335 } 1336 1337 switch (arch_mach) { 1338 case MACH_ARM64: 1339 predefine("__aarch64__", 1, "1"); 1340 break; 1341 case MACH_ARM: 1342 predefine("__arm__", 1, "1"); 1343 break; 1344 case MACH_M68K: 1345 predefine("__m68k__", 1, "1"); 1346 break; 1347 case MACH_MIPS64: 1348 if (arch_m64 == ARCH_LP64) 1349 predefine("__mips64", 1, "64"); 1350 /* fall-through */ 1351 case MACH_MIPS32: 1352 predefine("__mips", 1, "%d", ptr_ctype.bit_size); 1353 predefine("_MIPS_SZINT", 1, "%d", int_ctype.bit_size); 1354 predefine("_MIPS_SZLONG", 1, "%d", long_ctype.bit_size); 1355 predefine("_MIPS_SZPTR", 1, "%d", ptr_ctype.bit_size); 1356 break; 1357 case MACH_PPC64: 1358 if (arch_m64 == ARCH_LP64) { 1359 predefine("__powerpc64__", 1, "1"); 1360 predefine("__ppc64__", 1, "1"); 1361 predefine("__PPC64__", 1, "1"); 1362 } 1363 /* fall-through */ 1364 case MACH_PPC32: 1365 predefine("__powerpc__", 1, "1"); 1366 predefine("__powerpc", 1, "1"); 1367 predefine("__ppc__", 1, "1"); 1368 predefine("__PPC__", 1, "1"); 1369 break; 1370 case MACH_RISCV64: 1371 case MACH_RISCV32: 1372 predefine("__riscv", 1, "1"); 1373 predefine("__riscv_xlen", 1, "%d", ptr_ctype.bit_size); 1374 break; 1375 case MACH_S390X: 1376 predefine("__zarch__", 1, "1"); 1377 predefine("__s390x__", 1, "1"); 1378 predefine("__s390__", 1, "1"); 1379 break; 1380 case MACH_SPARC64: 1381 if (arch_m64 == ARCH_LP64) { 1382 predefine("__sparc_v9__", 1, "1"); 1383 predefine("__sparcv9__", 1, "1"); 1384 predefine("__sparcv9", 1, "1"); 1385 predefine("__sparc64__", 1, "1"); 1386 predefine("__arch64__", 1, "1"); 1387 } 1388 /* fall-through */ 1389 case MACH_SPARC32: 1390 predefine("__sparc__", 1, "1"); 1391 predefine("__sparc", 1, "1"); 1392 break; 1393 case MACH_X86_64: 1394 if (arch_m64 != ARCH_LP32) { 1395 predefine("__x86_64__", 1, "1"); 1396 predefine("__x86_64", 1, "1"); 1397 break; 1398 } 1399 /* fall-through */ 1400 case MACH_I386: 1401 predefine("__i386__", 1, "1"); 1402 predefine("__i386", 1, "1"); 1403 predefine("i386", 1, "1"); 1404 break; 1405 } 1406 1407 predefine("__PRAGMA_REDEFINE_EXTNAME", 1, "1"); 1408 1409 #ifdef __sun 1410 predefine("__unix__", 1, "1"); 1411 predefine("__unix", 1, "1"); 1412 predefine("unix", 1, "1"); 1413 predefine("__sun__", 1, "1"); 1414 predefine("__sun", 1, "1"); 1415 predefine("sun", 1, "1"); 1416 predefine("__svr4__", 1, "1"); 1417 #endif 1418 } 1419 1420 static void create_builtin_stream(void) 1421 { 1422 // Temporary hack 1423 add_pre_buffer("#define _Pragma(x)\n"); 1424 1425 /* add the multiarch include directories, if any */ 1426 if (multiarch_dir && *multiarch_dir) { 1427 add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir); 1428 add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir); 1429 } 1430 1431 /* We add compiler headers path here because we have to parse 1432 * the arguments to get it, falling back to default. */ 1433 add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir); 1434 add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir); 1435 1436 add_pre_buffer("#define __has_builtin(x) 0\n"); 1437 add_pre_buffer("#define __has_attribute(x) 0\n"); 1438 add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); 1439 add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); 1440 add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n"); 1441 add_pre_buffer("#define __builtin_va_arg(arg,type) ({ type __va_arg_ret = *(type *)(arg); arg += sizeof(type); __va_arg_ret; })\n"); 1442 add_pre_buffer("#define __builtin_va_alist (*(void *)0)\n"); 1443 add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n"); 1444 add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n"); 1445 add_pre_buffer("#define __builtin_ms_va_copy(dest, src) ({ dest = src; (void)0; })\n"); 1446 add_pre_buffer("#define __builtin_va_end(arg)\n"); 1447 add_pre_buffer("#define __builtin_ms_va_end(arg)\n"); 1448 add_pre_buffer("#define __builtin_va_arg_pack()\n"); 1449 } 1450 1451 static struct symbol_list *sparse_tokenstream(struct token *token) 1452 { 1453 int builtin = token && !token->pos.stream; 1454 1455 // Preprocess the stream 1456 token = preprocess(token); 1457 1458 if (dump_macro_defs || dump_macros_only) { 1459 if (!builtin) 1460 dump_macro_definitions(); 1461 if (dump_macros_only) 1462 return NULL; 1463 } 1464 1465 if (preprocess_only) { 1466 while (!eof_token(token)) { 1467 int prec = 1; 1468 struct token *next = token->next; 1469 const char *separator = ""; 1470 if (next->pos.whitespace) 1471 separator = " "; 1472 if (next->pos.newline) { 1473 separator = "\n\t\t\t\t\t"; 1474 prec = next->pos.pos; 1475 if (prec > 4) 1476 prec = 4; 1477 } 1478 printf("%s%.*s", show_token(token), prec, separator); 1479 token = next; 1480 } 1481 putchar('\n'); 1482 1483 return NULL; 1484 } 1485 1486 // Parse the resulting C code 1487 while (!eof_token(token)) 1488 token = external_declaration(token, &translation_unit_used_list, NULL); 1489 return translation_unit_used_list; 1490 } 1491 1492 static struct symbol_list *sparse_file(const char *filename) 1493 { 1494 int fd; 1495 struct token *token; 1496 1497 if (strcmp (filename, "-") == 0) { 1498 fd = 0; 1499 } else { 1500 fd = open(filename, O_RDONLY); 1501 if (fd < 0) 1502 die("No such file: %s", filename); 1503 } 1504 base_filename = filename; 1505 1506 // Tokenize the input stream 1507 token = tokenize(filename, fd, NULL, includepath); 1508 store_all_tokens(token); 1509 close(fd); 1510 1511 return sparse_tokenstream(token); 1512 } 1513 1514 /* 1515 * This handles the "-include" directive etc: we're in global 1516 * scope, and all types/macros etc will affect all the following 1517 * files. 1518 * 1519 * NOTE NOTE NOTE! "#undef" of anything in this stage will 1520 * affect all subsequent files too, i.e. we can have non-local 1521 * behaviour between files! 1522 */ 1523 static struct symbol_list *sparse_initial(void) 1524 { 1525 int i; 1526 1527 // Prepend any "include" file to the stream. 1528 // We're in global scope, it will affect all files! 1529 for (i = 0; i < cmdline_include_nr; i++) 1530 add_pre_buffer("#argv_include \"%s\"\n", cmdline_include[i]); 1531 1532 return sparse_tokenstream(pre_buffer_begin); 1533 } 1534 1535 static int endswith(const char *str, const char *suffix) 1536 { 1537 const char *found = strstr(str, suffix); 1538 return (found && strcmp(found, suffix) == 0); 1539 } 1540 1541 struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **filelist) 1542 { 1543 char **args; 1544 struct symbol_list *list; 1545 1546 // Initialize symbol stream first, so that we can add defines etc 1547 init_symbols(); 1548 init_include_path(); 1549 1550 diag_prefix = argv[0]; 1551 1552 args = argv; 1553 for (;;) { 1554 char *arg = *++args; 1555 if (!arg) 1556 break; 1557 1558 if (arg[0] == '-' && arg[1]) { 1559 args = handle_switch(arg+1, args); 1560 continue; 1561 } 1562 1563 if (endswith(arg, ".a") || endswith(arg, ".so") || 1564 endswith(arg, ".so.1") || endswith(arg, ".o")) 1565 continue; 1566 1567 add_ptr_list(filelist, arg); 1568 } 1569 handle_switch_W_finalize(); 1570 handle_switch_v_finalize(); 1571 1572 // Redirect stdout if needed 1573 if (dump_macro_defs || preprocess_only) 1574 do_output = 1; 1575 if (do_output && outfile && strcmp(outfile, "-")) { 1576 if (!freopen(outfile, "w", stdout)) 1577 die("error: cannot open %s: %s", outfile, strerror(errno)); 1578 } 1579 1580 if (fdump_ir == 0) 1581 fdump_ir = PASS_FINAL; 1582 1583 list = NULL; 1584 if (filelist) { 1585 // Initialize type system 1586 init_target(); 1587 handle_arch_finalize(); 1588 init_ctype(); 1589 1590 predefined_macros(); 1591 create_builtin_stream(); 1592 declare_builtins(); 1593 1594 list = sparse_initial(); 1595 1596 /* 1597 * Protect the initial token allocations, since 1598 * they need to survive all the others 1599 */ 1600 protect_token_alloc(); 1601 } 1602 /* 1603 * Evaluate the complete symbol list 1604 * Note: This is not needed for normal cases. 1605 * These symbols should only be predefined defines and 1606 * declaratons which will be evaluated later, when needed. 1607 * This is also the case when a file is directly included via 1608 * '-include <file>' on the command line *AND* the file only 1609 * contains defines, declarations and inline definitions. 1610 * However, in the rare cases where the given file should 1611 * contain some definitions, these will never be evaluated 1612 * and thus won't be able to be linearized correctly. 1613 * Hence the evaluate_symbol_list() here under. 1614 */ 1615 evaluate_symbol_list(list); 1616 return list; 1617 } 1618 1619 struct symbol_list * sparse_keep_tokens(char *filename) 1620 { 1621 struct symbol_list *res; 1622 1623 /* Clear previous symbol list */ 1624 translation_unit_used_list = NULL; 1625 1626 new_file_scope(); 1627 res = sparse_file(filename); 1628 1629 /* And return it */ 1630 return res; 1631 } 1632 1633 1634 struct symbol_list * __sparse(char *filename) 1635 { 1636 struct symbol_list *res; 1637 1638 res = sparse_keep_tokens(filename); 1639 1640 /* Drop the tokens for this file after parsing */ 1641 clear_token_alloc(); 1642 1643 /* And return it */ 1644 return res; 1645 } 1646 1647 struct symbol_list * sparse(char *filename) 1648 { 1649 struct symbol_list *res = __sparse(filename); 1650 1651 if (has_error & ERROR_CURR_PHASE) 1652 has_error = ERROR_PREV_PHASE; 1653 /* Evaluate the complete symbol list */ 1654 evaluate_symbol_list(res); 1655 1656 return res; 1657 }