Print this page
11972 resync smatch


   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;


 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;


 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:


 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") ||


 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)


 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.




   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;


 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;


 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:


 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") ||


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)


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.