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 <fcntl.h> 27 #include <stdarg.h> 28 #include <stddef.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 #include <assert.h> 34 35 #include <sys/types.h> 36 37 #include "lib.h" 38 #include "allocate.h" 39 #include "token.h" 40 #include "parse.h" 41 #include "symbol.h" 42 #include "expression.h" 43 #include "scope.h" 44 #include "linearize.h" 45 #include "target.h" 46 #include "version.h" 47 48 static const char *progname; 49 50 int sparse_errors = 0; 51 int sparse_warnings = 0; 52 53 int verbose, optimize, optimize_size, preprocessing; 54 int die_if_error = 0; 55 int parse_error; 56 int has_error = 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 static const char *gcc_base_dir = GCC_BASE; 69 static const char *multiarch_dir = MULTIARCH_TRIPLET; 70 71 struct token *skip_to(struct token *token, int op) 72 { 73 while (!match_op(token, op) && !eof_token(token)) 74 token = token->next; 75 return token; 76 } 77 78 struct token *expect(struct token *token, int op, const char *where) 79 { 80 if (!match_op(token, op)) { 81 static struct token bad_token; 82 if (token != &bad_token) { 83 bad_token.next = token; 84 sparse_error(token->pos, "Expected %s %s", show_special(op), where); 85 sparse_error(token->pos, "got %s", show_token(token)); 86 } 87 if (op == ';') 88 return skip_to(token, op); 89 return &bad_token; 90 } 91 return token->next; 92 } 93 94 unsigned int hexval(unsigned int c) 95 { 96 int retval = 256; 97 switch (c) { 98 case '0'...'9': 99 retval = c - '0'; 100 break; 101 case 'a'...'f': 102 retval = c - 'a' + 10; 103 break; 104 case 'A'...'F': 105 retval = c - 'A' + 10; 106 break; 107 } 108 return retval; 109 } 110 111 static void do_warn(const char *type, struct position pos, const char * fmt, va_list args) 112 { 113 static char buffer[512]; 114 const char *name; 115 116 vsprintf(buffer, fmt, args); 117 name = stream_name(pos.stream); 118 119 fprintf(stderr, "%s: %s:%d:%d: %s%s\n", 120 progname, name, pos.line, pos.pos, type, buffer); 121 } 122 123 static int max_warnings = 100; 124 static int show_info = 1; 125 126 void info(struct position pos, const char * fmt, ...) 127 { 128 va_list args; 129 130 if (!show_info) 131 return; 132 va_start(args, fmt); 133 do_warn("", pos, fmt, args); 134 va_end(args); 135 } 136 137 static void do_error(struct position pos, const char * fmt, va_list args) 138 { 139 static int errors = 0; 140 141 parse_error = 1; 142 die_if_error = 1; 143 show_info = 1; 144 /* Shut up warnings after an error */ 145 has_error |= ERROR_CURR_PHASE; 146 if (errors > 100) { 147 static int once = 0; 148 show_info = 0; 149 if (once) 150 return; 151 fmt = "too many errors"; 152 once = 1; 153 } 154 155 do_warn("error: ", pos, fmt, args); 156 errors++; 157 } 158 159 void warning(struct position pos, const char * fmt, ...) 160 { 161 va_list args; 162 163 if (Wsparse_error) { 164 va_start(args, fmt); 165 do_error(pos, fmt, args); 166 va_end(args); 167 return; 168 } 169 170 if (!max_warnings || has_error) { 171 show_info = 0; 172 return; 173 } 174 175 if (!--max_warnings) { 176 show_info = 0; 177 fmt = "too many warnings"; 178 } 179 180 va_start(args, fmt); 181 do_warn("warning: ", pos, fmt, args); 182 va_end(args); 183 } 184 185 void sparse_error(struct position pos, const char * fmt, ...) 186 { 187 va_list args; 188 va_start(args, fmt); 189 do_error(pos, fmt, args); 190 va_end(args); 191 } 192 193 void expression_error(struct expression *expr, const char *fmt, ...) 194 { 195 va_list args; 196 va_start(args, fmt); 197 do_error(expr->pos, fmt, args); 198 va_end(args); 199 expr->ctype = &bad_ctype; 200 } 201 202 NORETURN_ATTR 203 void error_die(struct position pos, const char * fmt, ...) 204 { 205 va_list args; 206 va_start(args, fmt); 207 do_warn("error: ", pos, fmt, args); 208 va_end(args); 209 exit(1); 210 } 211 212 NORETURN_ATTR 213 void die(const char *fmt, ...) 214 { 215 va_list args; 216 static char buffer[512]; 217 218 va_start(args, fmt); 219 vsnprintf(buffer, sizeof(buffer), fmt, args); 220 va_end(args); 221 222 fprintf(stderr, "%s: %s\n", progname, buffer); 223 exit(1); 224 } 225 226 static struct token *pre_buffer_begin = NULL; 227 static struct token *pre_buffer_end = NULL; 228 229 int Waddress = 0; 230 int Waddress_space = 1; 231 int Wbitwise = 1; 232 int Wcast_to_as = 0; 233 int Wcast_truncate = 1; 234 int Wconstant_suffix = 0; 235 int Wconstexpr_not_const = 0; 236 int Wcontext = 1; 237 int Wdecl = 1; 238 int Wdeclarationafterstatement = -1; 239 int Wdefault_bitfield_sign = 0; 240 int Wdesignated_init = 1; 241 int Wdo_while = 0; 242 int Wimplicit_int = 1; 243 int Winit_cstring = 0; 244 int Wenum_mismatch = 1; 245 int Wexternal_function_has_definition = 1; 246 int Wsparse_error = 0; 247 int Wmemcpy_max_count = 1; 248 int Wnon_pointer_null = 1; 249 int Wold_initializer = 1; 250 int Wold_style_definition = 1; 251 int Wone_bit_signed_bitfield = 1; 252 int Woverride_init = 1; 253 int Woverride_init_all = 0; 254 int Woverride_init_whole_range = 0; 255 int Wparen_string = 0; 256 int Wpointer_arith = 0; 257 int Wptr_subtraction_blows = 0; 258 int Wreturn_void = 0; 259 int Wshadow = 0; 260 int Wsizeof_bool = 0; 261 int Wstrict_prototypes = 1; 262 int Wtautological_compare = 0; 263 int Wtransparent_union = 0; 264 int Wtypesign = 0; 265 int Wundef = 0; 266 int Wuninitialized = 1; 267 int Wunknown_attribute = 0; 268 int Wvla = 1; 269 270 int dump_macro_defs = 0; 271 272 int dbg_entry = 0; 273 int dbg_dead = 0; 274 275 int fmem_report = 0; 276 int fdump_linearize; 277 unsigned long long fmemcpy_max_count = 100000; 278 279 int preprocess_only; 280 281 static enum { STANDARD_C89, 282 STANDARD_C94, 283 STANDARD_C99, 284 STANDARD_C11, 285 STANDARD_GNU11, 286 STANDARD_GNU89, 287 STANDARD_GNU99, } standard = STANDARD_GNU89; 288 289 #define ARCH_LP32 0 290 #define ARCH_LP64 1 291 #define ARCH_LLP64 2 292 293 #ifdef __x86_64__ 294 #define ARCH_M64_DEFAULT ARCH_LP64 295 #else 296 #define ARCH_M64_DEFAULT ARCH_LP32 297 #endif 298 299 int arch_m64 = ARCH_M64_DEFAULT; 300 int arch_msize_long = 0; 301 302 #ifdef __BIG_ENDIAN__ 303 #define ARCH_BIG_ENDIAN 1 304 #else 305 #define ARCH_BIG_ENDIAN 0 306 #endif 307 int arch_big_endian = ARCH_BIG_ENDIAN; 308 309 310 #define CMDLINE_INCLUDE 20 311 static int cmdline_include_nr = 0; 312 static char *cmdline_include[CMDLINE_INCLUDE]; 313 314 315 void add_pre_buffer(const char *fmt, ...) 316 { 317 va_list args; 318 unsigned int size; 319 struct token *begin, *end; 320 char buffer[4096]; 321 322 va_start(args, fmt); 323 size = vsnprintf(buffer, sizeof(buffer), fmt, args); 324 va_end(args); 325 begin = tokenize_buffer(buffer, size, &end); 326 if (!pre_buffer_begin) 327 pre_buffer_begin = begin; 328 if (pre_buffer_end) 329 pre_buffer_end->next = begin; 330 pre_buffer_end = end; 331 } 332 333 static char **handle_switch_D(char *arg, char **next) 334 { 335 const char *name = arg + 1; 336 const char *value = "1"; 337 338 if (!*name) { 339 arg = *++next; 340 if (!arg) 341 die("argument to `-D' is missing"); 342 name = arg; 343 } 344 345 for (;;arg++) { 346 char c; 347 c = *arg; 348 if (!c) 349 break; 350 if (c == '=') { 351 *arg = '\0'; 352 value = arg + 1; 353 break; 354 } 355 } 356 add_pre_buffer("#define %s %s\n", name, value); 357 return next; 358 } 359 360 static char **handle_switch_E(char *arg, char **next) 361 { 362 if (arg[1] == '\0') 363 preprocess_only = 1; 364 return next; 365 } 366 367 static char **handle_switch_I(char *arg, char **next) 368 { 369 char *path = arg+1; 370 371 switch (arg[1]) { 372 case '-': 373 add_pre_buffer("#split_include\n"); 374 break; 375 376 case '\0': /* Plain "-I" */ 377 path = *++next; 378 if (!path) 379 die("missing argument for -I option"); 380 /* Fall through */ 381 default: 382 add_pre_buffer("#add_include \"%s/\"\n", path); 383 } 384 return next; 385 } 386 387 static void add_cmdline_include(char *filename) 388 { 389 if (cmdline_include_nr >= CMDLINE_INCLUDE) 390 die("too many include files for %s\n", filename); 391 cmdline_include[cmdline_include_nr++] = filename; 392 } 393 394 static char **handle_switch_i(char *arg, char **next) 395 { 396 if (*next && !strcmp(arg, "include")) 397 add_cmdline_include(*++next); 398 else if (*next && !strcmp(arg, "imacros")) 399 add_cmdline_include(*++next); 400 else if (*next && !strcmp(arg, "isystem")) { 401 char *path = *++next; 402 if (!path) 403 die("missing argument for -isystem option"); 404 add_pre_buffer("#add_isystem \"%s/\"\n", path); 405 } else if (*next && !strcmp(arg, "idirafter")) { 406 char *path = *++next; 407 if (!path) 408 die("missing argument for -idirafter option"); 409 add_pre_buffer("#add_dirafter \"%s/\"\n", path); 410 } 411 return next; 412 } 413 414 static char **handle_switch_M(char *arg, char **next) 415 { 416 if (!strcmp(arg, "MF") || !strcmp(arg,"MQ") || !strcmp(arg,"MT")) { 417 if (!*next) 418 die("missing argument for -%s option", arg); 419 return next + 1; 420 } 421 return next; 422 } 423 424 static char **handle_multiarch_dir(char *arg, char **next) 425 { 426 multiarch_dir = *++next; 427 if (!multiarch_dir) 428 die("missing argument for -multiarch-dir option"); 429 return next; 430 } 431 432 static char **handle_switch_m(char *arg, char **next) 433 { 434 if (!strcmp(arg, "m64")) { 435 arch_m64 = ARCH_LP64; 436 } else if (!strcmp(arg, "m32")) { 437 arch_m64 = ARCH_LP32; 438 } else if (!strcmp(arg, "msize-llp64")) { 439 arch_m64 = ARCH_LLP64; 440 } else if (!strcmp(arg, "msize-long")) { 441 arch_msize_long = 1; 442 } else if (!strcmp(arg, "multiarch-dir")) { 443 return handle_multiarch_dir(arg, next); 444 } else if (!strcmp(arg, "mbig-endian")) { 445 arch_big_endian = 1; 446 } else if (!strcmp(arg, "mlittle-endian")) { 447 arch_big_endian = 0; 448 } 449 return next; 450 } 451 452 static void handle_arch_m64_finalize(void) 453 { 454 switch (arch_m64) { 455 case ARCH_LP32: 456 /* default values */ 457 #if defined(__x86_64__) || defined (__i386) 458 add_pre_buffer("#weak_define __i386__ 1\n"); 459 add_pre_buffer("#weak_define __i386 1\n"); 460 add_pre_buffer("#weak_define i386 1\n"); 461 #endif 462 return; 463 case ARCH_LP64: 464 bits_in_long = 64; 465 max_int_alignment = 8; 466 size_t_ctype = &ulong_ctype; 467 ssize_t_ctype = &long_ctype; 468 add_pre_buffer("#weak_define __LP64__ 1\n"); 469 add_pre_buffer("#weak_define __LP64 1\n"); 470 add_pre_buffer("#weak_define _LP64 1\n"); 471 goto case_64bit_common; 472 case ARCH_LLP64: 473 bits_in_long = 32; 474 max_int_alignment = 4; 475 size_t_ctype = &ullong_ctype; 476 ssize_t_ctype = &llong_ctype; 477 add_pre_buffer("#weak_define __LLP64__ 1\n"); 478 goto case_64bit_common; 479 case_64bit_common: 480 bits_in_pointer = 64; 481 pointer_alignment = 8; 482 #if defined(__x86_64__) || defined (__i386) 483 add_pre_buffer("#weak_define __x86_64__ 1\n"); 484 add_pre_buffer("#weak_define __x86_64 1\n"); 485 #endif 486 break; 487 } 488 } 489 490 static void handle_arch_msize_long_finalize(void) 491 { 492 if (arch_msize_long) { 493 size_t_ctype = &ulong_ctype; 494 ssize_t_ctype = &long_ctype; 495 } 496 } 497 498 static void handle_arch_finalize(void) 499 { 500 handle_arch_m64_finalize(); 501 handle_arch_msize_long_finalize(); 502 } 503 504 505 static int handle_simple_switch(const char *arg, const char *name, int *flag) 506 { 507 int val = 1; 508 509 // Prefixe "no-" mean to turn flag off. 510 if (strncmp(arg, "no-", 3) == 0) { 511 arg += 3; 512 val = 0; 513 } 514 515 if (strcmp(arg, name) == 0) { 516 *flag = val; 517 return 1; 518 } 519 520 // not handled 521 return 0; 522 } 523 524 static char **handle_switch_o(char *arg, char **next) 525 { 526 if (!strcmp (arg, "o")) { // "-o foo" 527 if (!*++next) 528 die("argument to '-o' is missing"); 529 } 530 // else "-ofoo" 531 532 return next; 533 } 534 535 static const struct warning { 536 const char *name; 537 int *flag; 538 } warnings[] = { 539 { "address", &Waddress }, 540 { "address-space", &Waddress_space }, 541 { "bitwise", &Wbitwise }, 542 { "cast-to-as", &Wcast_to_as }, 543 { "cast-truncate", &Wcast_truncate }, 544 { "constant-suffix", &Wconstant_suffix }, 545 { "constexpr-not-const", &Wconstexpr_not_const}, 546 { "context", &Wcontext }, 547 { "decl", &Wdecl }, 548 { "declaration-after-statement", &Wdeclarationafterstatement }, 549 { "default-bitfield-sign", &Wdefault_bitfield_sign }, 550 { "designated-init", &Wdesignated_init }, 551 { "do-while", &Wdo_while }, 552 { "enum-mismatch", &Wenum_mismatch }, 553 { "external-function-has-definition", &Wexternal_function_has_definition }, 554 { "implicit-int", &Wimplicit_int }, 555 { "init-cstring", &Winit_cstring }, 556 { "memcpy-max-count", &Wmemcpy_max_count }, 557 { "non-pointer-null", &Wnon_pointer_null }, 558 { "old-initializer", &Wold_initializer }, 559 { "old-style-definition", &Wold_style_definition }, 560 { "one-bit-signed-bitfield", &Wone_bit_signed_bitfield }, 561 { "override-init", &Woverride_init }, 562 { "override-init-all", &Woverride_init_all }, 563 { "paren-string", &Wparen_string }, 564 { "ptr-subtraction-blows", &Wptr_subtraction_blows }, 565 { "return-void", &Wreturn_void }, 566 { "shadow", &Wshadow }, 567 { "sizeof-bool", &Wsizeof_bool }, 568 { "strict-prototypes", &Wstrict_prototypes }, 569 { "pointer-arith", &Wpointer_arith }, 570 { "sparse-error", &Wsparse_error }, 571 { "tautological-compare", &Wtautological_compare }, 572 { "transparent-union", &Wtransparent_union }, 573 { "typesign", &Wtypesign }, 574 { "undef", &Wundef }, 575 { "uninitialized", &Wuninitialized }, 576 { "unknown-attribute", &Wunknown_attribute }, 577 { "vla", &Wvla }, 578 }; 579 580 enum { 581 WARNING_OFF, 582 WARNING_ON, 583 WARNING_FORCE_OFF 584 }; 585 586 587 static char **handle_onoff_switch(char *arg, char **next, const struct warning warnings[], int n) 588 { 589 int flag = WARNING_ON; 590 char *p = arg + 1; 591 unsigned i; 592 593 if (!strcmp(p, "sparse-all")) { 594 for (i = 0; i < n; i++) { 595 if (*warnings[i].flag != WARNING_FORCE_OFF && warnings[i].flag != &Wsparse_error) 596 *warnings[i].flag = WARNING_ON; 597 } 598 } 599 600 // Prefixes "no" and "no-" mean to turn warning off. 601 if (p[0] == 'n' && p[1] == 'o') { 602 p += 2; 603 if (p[0] == '-') 604 p++; 605 flag = WARNING_FORCE_OFF; 606 } 607 608 for (i = 0; i < n; i++) { 609 if (!strcmp(p,warnings[i].name)) { 610 *warnings[i].flag = flag; 611 return next; 612 } 613 } 614 615 // Unknown. 616 return NULL; 617 } 618 619 static char **handle_switch_W(char *arg, char **next) 620 { 621 char ** ret = handle_onoff_switch(arg, next, warnings, ARRAY_SIZE(warnings)); 622 if (ret) 623 return ret; 624 625 // Unknown. 626 return next; 627 } 628 629 static struct warning debugs[] = { 630 { "entry", &dbg_entry}, 631 { "dead", &dbg_dead}, 632 }; 633 634 635 static char **handle_switch_v(char *arg, char **next) 636 { 637 char ** ret = handle_onoff_switch(arg, next, debugs, ARRAY_SIZE(debugs)); 638 if (ret) 639 return ret; 640 641 // Unknown. 642 do { 643 verbose++; 644 } while (*++arg == 'v'); 645 return next; 646 } 647 648 static struct warning dumps[] = { 649 { "D", &dump_macro_defs}, 650 }; 651 652 static char **handle_switch_d(char *arg, char **next) 653 { 654 char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps)); 655 if (ret) 656 return ret; 657 658 return next; 659 } 660 661 662 static void handle_onoff_switch_finalize(const struct warning warnings[], int n) 663 { 664 unsigned i; 665 666 for (i = 0; i < n; i++) { 667 if (*warnings[i].flag == WARNING_FORCE_OFF) 668 *warnings[i].flag = WARNING_OFF; 669 } 670 } 671 672 static void handle_switch_W_finalize(void) 673 { 674 handle_onoff_switch_finalize(warnings, ARRAY_SIZE(warnings)); 675 676 /* default Wdeclarationafterstatement based on the C dialect */ 677 if (-1 == Wdeclarationafterstatement) 678 { 679 switch (standard) 680 { 681 case STANDARD_C89: 682 case STANDARD_C94: 683 Wdeclarationafterstatement = 1; 684 break; 685 686 case STANDARD_C99: 687 case STANDARD_GNU89: 688 case STANDARD_GNU99: 689 case STANDARD_C11: 690 case STANDARD_GNU11: 691 Wdeclarationafterstatement = 0; 692 break; 693 694 default: 695 assert (0); 696 } 697 698 } 699 } 700 701 static void handle_switch_v_finalize(void) 702 { 703 handle_onoff_switch_finalize(debugs, ARRAY_SIZE(debugs)); 704 } 705 706 static char **handle_switch_U(char *arg, char **next) 707 { 708 const char *name = arg + 1; 709 if (*name == '\0') 710 name = *++next; 711 add_pre_buffer ("#undef %s\n", name); 712 return next; 713 } 714 715 static char **handle_switch_O(char *arg, char **next) 716 { 717 int level = 1; 718 if (arg[1] >= '0' && arg[1] <= '9') 719 level = arg[1] - '0'; 720 optimize = level; 721 optimize_size = arg[1] == 's'; 722 return next; 723 } 724 725 static char **handle_switch_fmemcpy_max_count(char *arg, char **next) 726 { 727 unsigned long long val; 728 char *end; 729 730 val = strtoull(arg, &end, 0); 731 if (*end != '\0' || end == arg) 732 die("error: missing argument to \"-fmemcpy-max-count=\""); 733 734 if (val == 0) 735 val = ~0ULL; 736 fmemcpy_max_count = val; 737 return next; 738 } 739 740 static char **handle_switch_ftabstop(char *arg, char **next) 741 { 742 char *end; 743 unsigned long val; 744 745 if (*arg == '\0') 746 die("error: missing argument to \"-ftabstop=\""); 747 748 /* we silently ignore silly values */ 749 val = strtoul(arg, &end, 10); 750 if (*end == '\0' && 1 <= val && val <= 100) 751 tabstop = val; 752 753 return next; 754 } 755 756 static int funsigned_char; 757 static void handle_funsigned_char(void) 758 { 759 if (funsigned_char) { 760 char_ctype.ctype.modifiers &= ~MOD_SIGNED; 761 char_ctype.ctype.modifiers |= MOD_UNSIGNED; 762 } 763 } 764 765 static char **handle_switch_fdump(char *arg, char **next) 766 { 767 if (!strncmp(arg, "linearize", 9)) { 768 arg += 9; 769 if (*arg == '\0') 770 fdump_linearize = 1; 771 else if (!strcmp(arg, "=only")) 772 fdump_linearize = 2; 773 else 774 goto err; 775 } 776 777 /* ignore others flags */ 778 return next; 779 780 err: 781 die("error: unknown flag \"-fdump-%s\"", arg); 782 } 783 784 static char **handle_switch_f(char *arg, char **next) 785 { 786 arg++; 787 788 if (!strncmp(arg, "tabstop=", 8)) 789 return handle_switch_ftabstop(arg+8, next); 790 if (!strncmp(arg, "dump-", 5)) 791 return handle_switch_fdump(arg+5, next); 792 if (!strncmp(arg, "memcpy-max-count=", 17)) 793 return handle_switch_fmemcpy_max_count(arg+17, next); 794 795 if (!strcmp(arg, "unsigned-char")) { 796 funsigned_char = 1; 797 return next; 798 } 799 800 /* handle switches w/ arguments above, boolean and only boolean below */ 801 if (handle_simple_switch(arg, "mem-report", &fmem_report)) 802 return next; 803 804 return next; 805 } 806 807 static char **handle_switch_G(char *arg, char **next) 808 { 809 if (!strcmp (arg, "G") && *next) 810 return next + 1; // "-G 0" 811 else 812 return next; // "-G0" or (bogus) terminal "-G" 813 } 814 815 static char **handle_switch_a(char *arg, char **next) 816 { 817 if (!strcmp (arg, "ansi")) 818 standard = STANDARD_C89; 819 820 return next; 821 } 822 823 static char **handle_switch_s(char *arg, char **next) 824 { 825 if (!strncmp (arg, "std=", 4)) 826 { 827 arg += 4; 828 829 if (!strcmp (arg, "c89") || 830 !strcmp (arg, "iso9899:1990")) 831 standard = STANDARD_C89; 832 833 else if (!strcmp (arg, "iso9899:199409")) 834 standard = STANDARD_C94; 835 836 else if (!strcmp (arg, "c99") || 837 !strcmp (arg, "c9x") || 838 !strcmp (arg, "iso9899:1999") || 839 !strcmp (arg, "iso9899:199x")) 840 standard = STANDARD_C99; 841 842 else if (!strcmp (arg, "gnu89")) 843 standard = STANDARD_GNU89; 844 845 else if (!strcmp (arg, "gnu99") || !strcmp (arg, "gnu9x")) 846 standard = STANDARD_GNU99; 847 848 else if (!strcmp(arg, "c11") || 849 !strcmp(arg, "c1x") || 850 !strcmp(arg, "iso9899:2011")) 851 standard = STANDARD_C11; 852 853 else if (!strcmp(arg, "gnu11")) 854 standard = STANDARD_GNU11; 855 856 else 857 die ("Unsupported C dialect"); 858 } 859 860 return next; 861 } 862 863 static char **handle_nostdinc(char *arg, char **next) 864 { 865 add_pre_buffer("#nostdinc\n"); 866 return next; 867 } 868 869 static char **handle_switch_n(char *arg, char **next) 870 { 871 if (!strcmp (arg, "nostdinc")) 872 return handle_nostdinc(arg, next); 873 874 return next; 875 } 876 877 static char **handle_base_dir(char *arg, char **next) 878 { 879 gcc_base_dir = *++next; 880 if (!gcc_base_dir) 881 die("missing argument for -gcc-base-dir option"); 882 return next; 883 } 884 885 static char **handle_no_lineno(char *arg, char **next) 886 { 887 no_lineno = 1; 888 return next; 889 } 890 891 static char **handle_switch_g(char *arg, char **next) 892 { 893 if (!strcmp (arg, "gcc-base-dir")) 894 return handle_base_dir(arg, next); 895 896 return next; 897 } 898 899 static char **handle_version(char *arg, char **next) 900 { 901 printf("%s\n", SPARSE_VERSION); 902 exit(0); 903 } 904 905 static char **handle_param(char *arg, char **next) 906 { 907 char *value = NULL; 908 909 /* Ignore smatch's --param-mapper */ 910 if (strcmp(arg, "-mapper") == 0) 911 return next; 912 913 914 /* For now just skip any '--param=*' or '--param *' */ 915 if (*arg == '\0') { 916 value = *++next; 917 } else if (isspace((unsigned char)*arg) || *arg == '=') { 918 value = ++arg; 919 } 920 921 if (!value) 922 die("missing argument for --param option"); 923 924 return next; 925 } 926 927 struct switches { 928 const char *name; 929 char **(*fn)(char *, char **); 930 unsigned int prefix:1; 931 }; 932 933 static char **handle_long_options(char *arg, char **next) 934 { 935 static struct switches cmd[] = { 936 { "param", handle_param, 1 }, 937 { "version", handle_version }, 938 { "nostdinc", handle_nostdinc }, 939 { "gcc-base-dir", handle_base_dir}, 940 { "no-lineno", handle_no_lineno}, 941 { NULL, NULL } 942 }; 943 struct switches *s = cmd; 944 945 while (s->name) { 946 int optlen = strlen(s->name); 947 if (!strncmp(s->name, arg, optlen + !s->prefix)) 948 return s->fn(arg + optlen, next); 949 s++; 950 } 951 return next; 952 } 953 954 static char **handle_switch(char *arg, char **next) 955 { 956 switch (*arg) { 957 case 'a': return handle_switch_a(arg, next); 958 case 'D': return handle_switch_D(arg, next); 959 case 'd': return handle_switch_d(arg, next); 960 case 'E': return handle_switch_E(arg, next); 961 case 'f': return handle_switch_f(arg, next); 962 case 'g': return handle_switch_g(arg, next); 963 case 'G': return handle_switch_G(arg, next); 964 case 'I': return handle_switch_I(arg, next); 965 case 'i': return handle_switch_i(arg, next); 966 case 'M': return handle_switch_M(arg, next); 967 case 'm': return handle_switch_m(arg, next); 968 case 'n': return handle_switch_n(arg, next); 969 case 'o': return handle_switch_o(arg, next); 970 case 'O': return handle_switch_O(arg, next); 971 case 's': return handle_switch_s(arg, next); 972 case 'U': return handle_switch_U(arg, next); 973 case 'v': return handle_switch_v(arg, next); 974 case 'W': return handle_switch_W(arg, next); 975 case '-': return handle_long_options(arg + 1, next); 976 default: 977 break; 978 } 979 980 /* 981 * Ignore unknown command line options: 982 * they're probably gcc switches 983 */ 984 return next; 985 } 986 987 static void predefined_sizeof(const char *name, unsigned bits) 988 { 989 add_pre_buffer("#weak_define __SIZEOF_%s__ %d\n", name, bits/8); 990 } 991 992 static void predefined_max(const char *name, const char *suffix, unsigned bits) 993 { 994 unsigned long long max = (1ULL << (bits - 1 )) - 1; 995 996 add_pre_buffer("#weak_define __%s_MAX__ %#llx%s\n", name, max, suffix); 997 } 998 999 static void predefined_type_size(const char *name, const char *suffix, unsigned bits) 1000 { 1001 predefined_max(name, suffix, bits); 1002 predefined_sizeof(name, bits); 1003 } 1004 1005 static void predefined_macros(void) 1006 { 1007 add_pre_buffer("#define __CHECKER__ 1\n"); 1008 1009 predefined_sizeof("SHORT", bits_in_short); 1010 predefined_max("SHRT", "", bits_in_short); 1011 predefined_max("SCHAR", "", bits_in_char); 1012 predefined_max("WCHAR", "", bits_in_wchar); 1013 add_pre_buffer("#weak_define __CHAR_BIT__ %d\n", bits_in_char); 1014 1015 predefined_type_size("INT", "", bits_in_int); 1016 predefined_type_size("LONG", "L", bits_in_long); 1017 predefined_type_size("LONG_LONG", "LL", bits_in_longlong); 1018 1019 predefined_sizeof("INT128", 128); 1020 1021 predefined_sizeof("SIZE_T", bits_in_pointer); 1022 predefined_sizeof("PTRDIFF_T", bits_in_pointer); 1023 predefined_sizeof("POINTER", bits_in_pointer); 1024 1025 predefined_sizeof("FLOAT", bits_in_float); 1026 predefined_sizeof("DOUBLE", bits_in_double); 1027 predefined_sizeof("LONG_DOUBLE", bits_in_longdouble); 1028 1029 add_pre_buffer("#weak_define __%s_ENDIAN__ 1\n", 1030 arch_big_endian ? "BIG" : "LITTLE"); 1031 1032 add_pre_buffer("#weak_define __ORDER_LITTLE_ENDIAN__ 1234\n"); 1033 add_pre_buffer("#weak_define __ORDER_BIG_ENDIAN__ 4321\n"); 1034 add_pre_buffer("#weak_define __ORDER_PDP_ENDIAN__ 3412\n"); 1035 add_pre_buffer("#weak_define __BYTE_ORDER__ __ORDER_%s_ENDIAN__\n", 1036 arch_big_endian ? "BIG" : "LITTLE"); 1037 1038 add_pre_buffer("#weak_define __PRAGMA_REDEFINE_EXTNAME 1\n"); 1039 1040 /* 1041 * This is far from perfect... 1042 */ 1043 #ifdef __sun 1044 add_pre_buffer("#weak_define __unix__ 1\n"); 1045 add_pre_buffer("#weak_define __unix 1\n"); 1046 add_pre_buffer("#weak_define unix 1\n"); 1047 add_pre_buffer("#weak_define __sun__ 1\n"); 1048 add_pre_buffer("#weak_define __sun 1\n"); 1049 add_pre_buffer("#weak_define sun 1\n"); 1050 add_pre_buffer("#weak_define __svr4__ 1\n"); 1051 #endif 1052 } 1053 1054 void declare_builtin_functions(void) 1055 { 1056 /* Gaah. gcc knows tons of builtin <string.h> functions */ 1057 add_pre_buffer("extern void *__builtin_memchr(const void *, int, __SIZE_TYPE__);\n"); 1058 add_pre_buffer("extern void *__builtin_memcpy(void *, const void *, __SIZE_TYPE__);\n"); 1059 add_pre_buffer("extern void *__builtin_mempcpy(void *, const void *, __SIZE_TYPE__);\n"); 1060 add_pre_buffer("extern void *__builtin_memmove(void *, const void *, __SIZE_TYPE__);\n"); 1061 add_pre_buffer("extern void *__builtin_memset(void *, int, __SIZE_TYPE__);\n"); 1062 add_pre_buffer("extern int __builtin_memcmp(const void *, const void *, __SIZE_TYPE__);\n"); 1063 add_pre_buffer("extern char *__builtin_strcat(char *, const char *);\n"); 1064 add_pre_buffer("extern char *__builtin_strncat(char *, const char *, __SIZE_TYPE__);\n"); 1065 add_pre_buffer("extern int __builtin_strcmp(const char *, const char *);\n"); 1066 add_pre_buffer("extern int __builtin_strncmp(const char *, const char *, __SIZE_TYPE__);\n"); 1067 add_pre_buffer("extern int __builtin_strcasecmp(const char *, const char *);\n"); 1068 add_pre_buffer("extern int __builtin_strncasecmp(const char *, const char *, __SIZE_TYPE__);\n"); 1069 add_pre_buffer("extern char *__builtin_strchr(const char *, int);\n"); 1070 add_pre_buffer("extern char *__builtin_strrchr(const char *, int);\n"); 1071 add_pre_buffer("extern char *__builtin_strcpy(char *, const char *);\n"); 1072 add_pre_buffer("extern char *__builtin_strncpy(char *, const char *, __SIZE_TYPE__);\n"); 1073 add_pre_buffer("extern char *__builtin_strdup(const char *);\n"); 1074 add_pre_buffer("extern char *__builtin_strndup(const char *, __SIZE_TYPE__);\n"); 1075 add_pre_buffer("extern __SIZE_TYPE__ __builtin_strspn(const char *, const char *);\n"); 1076 add_pre_buffer("extern __SIZE_TYPE__ __builtin_strcspn(const char *, const char *);\n"); 1077 add_pre_buffer("extern char * __builtin_strpbrk(const char *, const char *);\n"); 1078 add_pre_buffer("extern char* __builtin_stpcpy(const char *, const char*);\n"); 1079 add_pre_buffer("extern char* __builtin_stpncpy(const char *, const char*, __SIZE_TYPE__);\n"); 1080 add_pre_buffer("extern __SIZE_TYPE__ __builtin_strlen(const char *);\n"); 1081 add_pre_buffer("extern char *__builtin_strstr(const char *, const char *);\n"); 1082 add_pre_buffer("extern char *__builtin_strcasestr(const char *, const char *);\n"); 1083 add_pre_buffer("extern char *__builtin_strnstr(const char *, const char *, __SIZE_TYPE__);\n"); 1084 1085 /* And even some from <strings.h> */ 1086 add_pre_buffer("extern int __builtin_bcmp(const void *, const void *, __SIZE_TYPE__);\n"); 1087 add_pre_buffer("extern void __builtin_bcopy(const void *, void *, __SIZE_TYPE__);\n"); 1088 add_pre_buffer("extern void __builtin_bzero(void *, __SIZE_TYPE__);\n"); 1089 add_pre_buffer("extern char*__builtin_index(const char *, int);\n"); 1090 add_pre_buffer("extern char*__builtin_rindex(const char *, int);\n"); 1091 1092 /* And bitwise operations.. */ 1093 add_pre_buffer("extern int __builtin_clrsb(int);\n"); 1094 add_pre_buffer("extern int __builtin_clrsbl(long);\n"); 1095 add_pre_buffer("extern int __builtin_clrsbll(long long);\n"); 1096 add_pre_buffer("extern int __builtin_clz(int);\n"); 1097 add_pre_buffer("extern int __builtin_clzl(long);\n"); 1098 add_pre_buffer("extern int __builtin_clzll(long long);\n"); 1099 add_pre_buffer("extern int __builtin_ctz(int);\n"); 1100 add_pre_buffer("extern int __builtin_ctzl(long);\n"); 1101 add_pre_buffer("extern int __builtin_ctzll(long long);\n"); 1102 add_pre_buffer("extern int __builtin_ffs(int);\n"); 1103 add_pre_buffer("extern int __builtin_ffsl(long);\n"); 1104 add_pre_buffer("extern int __builtin_ffsll(long long);\n"); 1105 add_pre_buffer("extern int __builtin_parity(unsigned int);\n"); 1106 add_pre_buffer("extern int __builtin_parityl(unsigned long);\n"); 1107 add_pre_buffer("extern int __builtin_parityll(unsigned long long);\n"); 1108 add_pre_buffer("extern int __builtin_popcount(unsigned int);\n"); 1109 add_pre_buffer("extern int __builtin_popcountl(unsigned long);\n"); 1110 add_pre_buffer("extern int __builtin_popcountll(unsigned long long);\n"); 1111 1112 /* And byte swaps.. */ 1113 add_pre_buffer("extern unsigned short __builtin_bswap16(unsigned short);\n"); 1114 add_pre_buffer("extern unsigned int __builtin_bswap32(unsigned int);\n"); 1115 add_pre_buffer("extern unsigned long long __builtin_bswap64(unsigned long long);\n"); 1116 1117 /* And atomic memory access functions.. */ 1118 add_pre_buffer("extern int __sync_fetch_and_add(void *, ...);\n"); 1119 add_pre_buffer("extern int __sync_fetch_and_sub(void *, ...);\n"); 1120 add_pre_buffer("extern int __sync_fetch_and_or(void *, ...);\n"); 1121 add_pre_buffer("extern int __sync_fetch_and_and(void *, ...);\n"); 1122 add_pre_buffer("extern int __sync_fetch_and_xor(void *, ...);\n"); 1123 add_pre_buffer("extern int __sync_fetch_and_nand(void *, ...);\n"); 1124 add_pre_buffer("extern int __sync_add_and_fetch(void *, ...);\n"); 1125 add_pre_buffer("extern int __sync_sub_and_fetch(void *, ...);\n"); 1126 add_pre_buffer("extern int __sync_or_and_fetch(void *, ...);\n"); 1127 add_pre_buffer("extern int __sync_and_and_fetch(void *, ...);\n"); 1128 add_pre_buffer("extern int __sync_xor_and_fetch(void *, ...);\n"); 1129 add_pre_buffer("extern int __sync_nand_and_fetch(void *, ...);\n"); 1130 add_pre_buffer("extern int __sync_bool_compare_and_swap(void *, ...);\n"); 1131 add_pre_buffer("extern int __sync_val_compare_and_swap(void *, ...);\n"); 1132 add_pre_buffer("extern void __sync_synchronize();\n"); 1133 add_pre_buffer("extern int __sync_lock_test_and_set(void *, ...);\n"); 1134 add_pre_buffer("extern void __sync_lock_release(void *, ...);\n"); 1135 1136 /* And some random ones.. */ 1137 add_pre_buffer("extern void *__builtin_return_address(unsigned int);\n"); 1138 add_pre_buffer("extern void *__builtin_extract_return_addr(void *);\n"); 1139 add_pre_buffer("extern void *__builtin_frame_address(unsigned int);\n"); 1140 add_pre_buffer("extern void __builtin_trap(void);\n"); 1141 add_pre_buffer("extern void *__builtin_alloca(__SIZE_TYPE__);\n"); 1142 add_pre_buffer("extern void __builtin_prefetch (const void *, ...);\n"); 1143 add_pre_buffer("extern long __builtin_alpha_extbl(long, long);\n"); 1144 add_pre_buffer("extern long __builtin_alpha_extwl(long, long);\n"); 1145 add_pre_buffer("extern long __builtin_alpha_insbl(long, long);\n"); 1146 add_pre_buffer("extern long __builtin_alpha_inswl(long, long);\n"); 1147 add_pre_buffer("extern long __builtin_alpha_insql(long, long);\n"); 1148 add_pre_buffer("extern long __builtin_alpha_inslh(long, long);\n"); 1149 add_pre_buffer("extern long __builtin_alpha_cmpbge(long, long);\n"); 1150 add_pre_buffer("extern int __builtin_abs(int);\n"); 1151 add_pre_buffer("extern long __builtin_labs(long);\n"); 1152 add_pre_buffer("extern long long __builtin_llabs(long long);\n"); 1153 add_pre_buffer("extern double __builtin_fabs(double);\n"); 1154 add_pre_buffer("extern __SIZE_TYPE__ __builtin_va_arg_pack_len(void);\n"); 1155 1156 /* Add Blackfin-specific stuff */ 1157 add_pre_buffer( 1158 "#ifdef __bfin__\n" 1159 "extern void __builtin_bfin_csync(void);\n" 1160 "extern void __builtin_bfin_ssync(void);\n" 1161 "extern int __builtin_bfin_norm_fr1x32(int);\n" 1162 "#endif\n" 1163 ); 1164 1165 /* And some floating point stuff.. */ 1166 add_pre_buffer("extern int __builtin_isgreater(float, float);\n"); 1167 add_pre_buffer("extern int __builtin_isgreaterequal(float, float);\n"); 1168 add_pre_buffer("extern int __builtin_isless(float, float);\n"); 1169 add_pre_buffer("extern int __builtin_islessequal(float, float);\n"); 1170 add_pre_buffer("extern int __builtin_islessgreater(float, float);\n"); 1171 add_pre_buffer("extern int __builtin_isunordered(float, float);\n"); 1172 1173 /* And some INFINITY / NAN stuff.. */ 1174 add_pre_buffer("extern double __builtin_huge_val(void);\n"); 1175 add_pre_buffer("extern float __builtin_huge_valf(void);\n"); 1176 add_pre_buffer("extern long double __builtin_huge_vall(void);\n"); 1177 add_pre_buffer("extern double __builtin_inf(void);\n"); 1178 add_pre_buffer("extern float __builtin_inff(void);\n"); 1179 add_pre_buffer("extern long double __builtin_infl(void);\n"); 1180 add_pre_buffer("extern double __builtin_nan(const char *);\n"); 1181 add_pre_buffer("extern float __builtin_nanf(const char *);\n"); 1182 add_pre_buffer("extern long double __builtin_nanl(const char *);\n"); 1183 add_pre_buffer("extern int __builtin_isinf_sign(float);\n"); 1184 add_pre_buffer("extern int __builtin_isfinite(float);\n"); 1185 add_pre_buffer("extern int __builtin_isnan(float);\n"); 1186 1187 /* And some __FORTIFY_SOURCE ones.. */ 1188 add_pre_buffer ("extern __SIZE_TYPE__ __builtin_object_size(const void *, int);\n"); 1189 add_pre_buffer ("extern void * __builtin___memcpy_chk(void *, const void *, __SIZE_TYPE__, __SIZE_TYPE__);\n"); 1190 add_pre_buffer ("extern void * __builtin___memmove_chk(void *, const void *, __SIZE_TYPE__, __SIZE_TYPE__);\n"); 1191 add_pre_buffer ("extern void * __builtin___mempcpy_chk(void *, const void *, __SIZE_TYPE__, __SIZE_TYPE__);\n"); 1192 add_pre_buffer ("extern void * __builtin___memset_chk(void *, int, __SIZE_TYPE__, __SIZE_TYPE__);\n"); 1193 add_pre_buffer ("extern int __builtin___sprintf_chk(char *, int, __SIZE_TYPE__, const char *, ...);\n"); 1194 add_pre_buffer ("extern int __builtin___snprintf_chk(char *, __SIZE_TYPE__, int , __SIZE_TYPE__, const char *, ...);\n"); 1195 add_pre_buffer ("extern char * __builtin___stpcpy_chk(char *, const char *, __SIZE_TYPE__);\n"); 1196 add_pre_buffer ("extern char * __builtin___strcat_chk(char *, const char *, __SIZE_TYPE__);\n"); 1197 add_pre_buffer ("extern char * __builtin___strcpy_chk(char *, const char *, __SIZE_TYPE__);\n"); 1198 add_pre_buffer ("extern char * __builtin___strncat_chk(char *, const char *, __SIZE_TYPE__, __SIZE_TYPE__);\n"); 1199 add_pre_buffer ("extern char * __builtin___strncpy_chk(char *, const char *, __SIZE_TYPE__, __SIZE_TYPE__);\n"); 1200 add_pre_buffer ("extern int __builtin___vsprintf_chk(char *, int, __SIZE_TYPE__, const char *, __builtin_va_list);\n"); 1201 add_pre_buffer ("extern int __builtin___vsnprintf_chk(char *, __SIZE_TYPE__, int, __SIZE_TYPE__, const char *, __builtin_va_list ap);\n"); 1202 add_pre_buffer ("extern void __builtin_unreachable(void);\n"); 1203 1204 /* And some from <stdlib.h> */ 1205 add_pre_buffer("extern void __builtin_abort(void);\n"); 1206 add_pre_buffer("extern void *__builtin_calloc(__SIZE_TYPE__, __SIZE_TYPE__);\n"); 1207 add_pre_buffer("extern void __builtin_exit(int);\n"); 1208 add_pre_buffer("extern void *__builtin_malloc(__SIZE_TYPE__);\n"); 1209 add_pre_buffer("extern void *__builtin_realloc(void *, __SIZE_TYPE__);\n"); 1210 add_pre_buffer("extern void __builtin_free(void *);\n"); 1211 1212 /* And some from <stdio.h> */ 1213 add_pre_buffer("extern int __builtin_printf(const char *, ...);\n"); 1214 add_pre_buffer("extern int __builtin_sprintf(char *, const char *, ...);\n"); 1215 add_pre_buffer("extern int __builtin_snprintf(char *, __SIZE_TYPE__, const char *, ...);\n"); 1216 add_pre_buffer("extern int __builtin_puts(const char *);\n"); 1217 add_pre_buffer("extern int __builtin_vprintf(const char *, __builtin_va_list);\n"); 1218 add_pre_buffer("extern int __builtin_vsprintf(char *, const char *, __builtin_va_list);\n"); 1219 add_pre_buffer("extern int __builtin_vsnprintf(char *, __SIZE_TYPE__, const char *, __builtin_va_list ap);\n"); 1220 } 1221 1222 void create_builtin_stream(void) 1223 { 1224 add_pre_buffer("#weak_define __GNUC__ %d\n", gcc_major); 1225 add_pre_buffer("#weak_define __GNUC_MINOR__ %d\n", gcc_minor); 1226 add_pre_buffer("#weak_define __GNUC_PATCHLEVEL__ %d\n", gcc_patchlevel); 1227 1228 /* add the multiarch include directories, if any */ 1229 if (multiarch_dir && *multiarch_dir) { 1230 add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir); 1231 add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir); 1232 } 1233 1234 /* We add compiler headers path here because we have to parse 1235 * the arguments to get it, falling back to default. */ 1236 add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir); 1237 add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir); 1238 1239 add_pre_buffer("#define __extension__\n"); 1240 add_pre_buffer("#define __pragma__\n"); 1241 add_pre_buffer("#define _Pragma(x)\n"); 1242 1243 // gcc defines __SIZE_TYPE__ to be size_t. For linux/i86 and 1244 // solaris/sparc that is really "unsigned int" and for linux/x86_64 1245 // it is "long unsigned int". In either case we can probably 1246 // get away with this. We need the #weak_define as cgcc will define 1247 // the right __SIZE_TYPE__. 1248 if (size_t_ctype == &ulong_ctype) 1249 add_pre_buffer("#weak_define __SIZE_TYPE__ long unsigned int\n"); 1250 else 1251 add_pre_buffer("#weak_define __SIZE_TYPE__ unsigned int\n"); 1252 add_pre_buffer("#weak_define __STDC__ 1\n"); 1253 1254 switch (standard) 1255 { 1256 case STANDARD_C89: 1257 add_pre_buffer("#weak_define __STRICT_ANSI__\n"); 1258 break; 1259 1260 case STANDARD_C94: 1261 add_pre_buffer("#weak_define __STDC_VERSION__ 199409L\n"); 1262 add_pre_buffer("#weak_define __STRICT_ANSI__\n"); 1263 break; 1264 1265 case STANDARD_C99: 1266 add_pre_buffer("#weak_define __STDC_VERSION__ 199901L\n"); 1267 add_pre_buffer("#weak_define __STRICT_ANSI__\n"); 1268 break; 1269 1270 case STANDARD_GNU89: 1271 break; 1272 1273 case STANDARD_GNU99: 1274 add_pre_buffer("#weak_define __STDC_VERSION__ 199901L\n"); 1275 break; 1276 1277 case STANDARD_C11: 1278 add_pre_buffer("#weak_define __STRICT_ANSI__ 1\n"); 1279 case STANDARD_GNU11: 1280 add_pre_buffer("#weak_define __STDC_NO_ATOMICS__ 1\n"); 1281 add_pre_buffer("#weak_define __STDC_NO_COMPLEX__ 1\n"); 1282 add_pre_buffer("#weak_define __STDC_NO_THREADS__ 1\n"); 1283 add_pre_buffer("#weak_define __STDC_VERSION__ 201112L\n"); 1284 break; 1285 1286 default: 1287 assert (0); 1288 } 1289 1290 add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); 1291 add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); 1292 add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n"); 1293 add_pre_buffer("#define __builtin_va_arg(arg,type) ({ type __va_arg_ret = *(type *)(arg); arg += sizeof(type); __va_arg_ret; })\n"); 1294 add_pre_buffer("#define __builtin_va_alist (*(void *)0)\n"); 1295 add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n"); 1296 add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n"); 1297 add_pre_buffer("#define __builtin_ms_va_copy(dest, src) ({ dest = src; (void)0; })\n"); 1298 add_pre_buffer("#define __builtin_va_end(arg)\n"); 1299 add_pre_buffer("#define __builtin_ms_va_end(arg)\n"); 1300 add_pre_buffer("#define __builtin_va_arg_pack()\n"); 1301 1302 /* FIXME! We need to do these as special magic macros at expansion time! */ 1303 add_pre_buffer("#define __BASE_FILE__ \"base_file.c\"\n"); 1304 1305 if (optimize) 1306 add_pre_buffer("#define __OPTIMIZE__ 1\n"); 1307 if (optimize_size) 1308 add_pre_buffer("#define __OPTIMIZE_SIZE__ 1\n"); 1309 } 1310 1311 static struct symbol_list *sparse_tokenstream(struct token *token) 1312 { 1313 int builtin = token && !token->pos.stream; 1314 1315 // Preprocess the stream 1316 token = preprocess(token); 1317 1318 if (dump_macro_defs && !builtin) 1319 dump_macro_definitions(); 1320 1321 if (preprocess_only) { 1322 while (!eof_token(token)) { 1323 int prec = 1; 1324 struct token *next = token->next; 1325 const char *separator = ""; 1326 if (next->pos.whitespace) 1327 separator = " "; 1328 if (next->pos.newline) { 1329 separator = "\n\t\t\t\t\t"; 1330 prec = next->pos.pos; 1331 if (prec > 4) 1332 prec = 4; 1333 } 1334 printf("%s%.*s", show_token(token), prec, separator); 1335 token = next; 1336 } 1337 putchar('\n'); 1338 1339 return NULL; 1340 } 1341 1342 // Parse the resulting C code 1343 while (!eof_token(token)) 1344 token = external_declaration(token, &translation_unit_used_list, NULL); 1345 return translation_unit_used_list; 1346 } 1347 1348 static struct symbol_list *sparse_file(const char *filename) 1349 { 1350 int fd; 1351 struct token *token; 1352 1353 if (strcmp (filename, "-") == 0) { 1354 fd = 0; 1355 } else { 1356 fd = open(filename, O_RDONLY); 1357 if (fd < 0) 1358 die("No such file: %s", filename); 1359 } 1360 1361 // Tokenize the input stream 1362 token = tokenize(filename, fd, NULL, includepath); 1363 store_all_tokens(token); 1364 close(fd); 1365 1366 return sparse_tokenstream(token); 1367 } 1368 1369 static int endswith(const char *str, const char *suffix) 1370 { 1371 const char *found = strstr(str, suffix); 1372 return (found && strcmp(found, suffix) == 0); 1373 } 1374 1375 /* 1376 * This handles the "-include" directive etc: we're in global 1377 * scope, and all types/macros etc will affect all the following 1378 * files. 1379 * 1380 * NOTE NOTE NOTE! "#undef" of anything in this stage will 1381 * affect all subsequent files too, i.e. we can have non-local 1382 * behaviour between files! 1383 */ 1384 static struct symbol_list *sparse_initial(void) 1385 { 1386 int i; 1387 1388 // Prepend any "include" file to the stream. 1389 // We're in global scope, it will affect all files! 1390 for (i = 0; i < cmdline_include_nr; i++) 1391 add_pre_buffer("#argv_include \"%s\"\n", cmdline_include[i]); 1392 1393 return sparse_tokenstream(pre_buffer_begin); 1394 } 1395 1396 struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **filelist) 1397 { 1398 char **args; 1399 struct symbol_list *list; 1400 1401 // Initialize symbol stream first, so that we can add defines etc 1402 init_symbols(); 1403 init_include_path(); 1404 1405 progname = argv[0]; 1406 1407 args = argv; 1408 for (;;) { 1409 char *arg = *++args; 1410 if (!arg) 1411 break; 1412 1413 if (arg[0] == '-' && arg[1]) { 1414 args = handle_switch(arg+1, args); 1415 continue; 1416 } 1417 1418 if (endswith(arg, ".a") || endswith(arg, ".so") || 1419 endswith(arg, ".so.1") || endswith(arg, ".o")) 1420 continue; 1421 1422 add_ptr_list_notag(filelist, arg); 1423 } 1424 handle_switch_W_finalize(); 1425 handle_switch_v_finalize(); 1426 1427 handle_arch_finalize(); 1428 1429 list = NULL; 1430 if (!ptr_list_empty(filelist)) { 1431 // Initialize type system 1432 init_ctype(); 1433 handle_funsigned_char(); 1434 1435 create_builtin_stream(); 1436 predefined_macros(); 1437 if (!preprocess_only) 1438 declare_builtin_functions(); 1439 1440 list = sparse_initial(); 1441 1442 /* 1443 * Protect the initial token allocations, since 1444 * they need to survive all the others 1445 */ 1446 protect_token_alloc(); 1447 } 1448 /* 1449 * Evaluate the complete symbol list 1450 * Note: This is not needed for normal cases. 1451 * These symbols should only be predefined defines and 1452 * declaratons which will be evaluated later, when needed. 1453 * This is also the case when a file is directly included via 1454 * '-include <file>' on the command line *AND* the file only 1455 * contains defines, declarations and inline definitions. 1456 * However, in the rare cases where the given file should 1457 * contain some definitions, these will never be evaluated 1458 * and thus won't be able to be linearized correctly. 1459 * Hence the evaluate_symbol_list() here under. 1460 */ 1461 evaluate_symbol_list(list); 1462 return list; 1463 } 1464 1465 struct symbol_list * sparse_keep_tokens(char *filename) 1466 { 1467 struct symbol_list *res; 1468 1469 /* Clear previous symbol list */ 1470 translation_unit_used_list = NULL; 1471 1472 new_file_scope(); 1473 res = sparse_file(filename); 1474 1475 /* And return it */ 1476 return res; 1477 } 1478 1479 1480 struct symbol_list * __sparse(char *filename) 1481 { 1482 struct symbol_list *res; 1483 1484 res = sparse_keep_tokens(filename); 1485 1486 /* Drop the tokens for this file after parsing */ 1487 clear_token_alloc(); 1488 1489 /* And return it */ 1490 return res; 1491 } 1492 1493 struct symbol_list * sparse(char *filename) 1494 { 1495 struct symbol_list *res = __sparse(filename); 1496 1497 if (has_error & ERROR_CURR_PHASE) 1498 has_error = ERROR_PREV_PHASE; 1499 /* Evaluate the complete symbol list */ 1500 evaluate_symbol_list(res); 1501 1502 return res; 1503 }