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