Print this page
new smatch

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/lib.c
          +++ new/usr/src/tools/smatch/src/lib.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   *
  17   17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18   18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19   19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20   20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21   21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22   22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23   23   * THE SOFTWARE.
  24   24   */
  25   25  #include <ctype.h>
       26 +#include <errno.h>
  26   27  #include <fcntl.h>
  27   28  #include <stdarg.h>
  28   29  #include <stddef.h>
  29   30  #include <stdio.h>
  30   31  #include <stdlib.h>
  31   32  #include <string.h>
  32   33  #include <unistd.h>
  33   34  #include <assert.h>
  34   35  
  35   36  #include <sys/types.h>
  36   37  
  37   38  #include "lib.h"
  38   39  #include "allocate.h"
  39   40  #include "token.h"
  40   41  #include "parse.h"
  41   42  #include "symbol.h"
  42   43  #include "expression.h"
       44 +#include "evaluate.h"
  43   45  #include "scope.h"
  44   46  #include "linearize.h"
  45   47  #include "target.h"
       48 +#include "machine.h"
  46   49  #include "version.h"
       50 +#include "bits.h"
  47   51  
  48      -static const char *progname;
  49      -
  50      -int sparse_errors = 0;
  51      -int sparse_warnings = 0;
  52      -
  53      -int verbose, optimize, optimize_size, preprocessing;
       52 +int verbose, optimize_level, optimize_size, preprocessing;
  54   53  int die_if_error = 0;
  55   54  int parse_error;
  56   55  int has_error = 0;
       56 +int do_output = 0;
  57   57  
  58   58  #ifndef __GNUC__
  59   59  # define __GNUC__ 2
  60   60  # define __GNUC_MINOR__ 95
  61   61  # define __GNUC_PATCHLEVEL__ 0
  62   62  #endif
  63   63  
  64   64  int gcc_major = __GNUC__;
  65   65  int gcc_minor = __GNUC_MINOR__;
  66   66  int gcc_patchlevel = __GNUC_PATCHLEVEL__;
  67   67  
       68 +const char *base_filename;
       69 +
       70 +static const char *diag_prefix = "";
  68   71  static const char *gcc_base_dir = GCC_BASE;
  69   72  static const char *multiarch_dir = MULTIARCH_TRIPLET;
       73 +static const char *outfile = NULL;
  70   74  
  71   75  struct token *skip_to(struct token *token, int op)
  72   76  {
  73   77          while (!match_op(token, op) && !eof_token(token))
  74   78                  token = token->next;
  75   79          return token;
  76   80  }
  77   81  
       82 +static struct token bad_token = { .pos.type = TOKEN_BAD };
  78   83  struct token *expect(struct token *token, int op, const char *where)
  79   84  {
  80   85          if (!match_op(token, op)) {
  81      -                static struct token bad_token;
  82   86                  if (token != &bad_token) {
  83   87                          bad_token.next = token;
  84   88                          sparse_error(token->pos, "Expected %s %s", show_special(op), where);
  85   89                          sparse_error(token->pos, "got %s", show_token(token));
  86   90                  }
  87   91                  if (op == ';')
  88   92                          return skip_to(token, op);
  89   93                  return &bad_token;
  90   94          }
  91   95          return token->next;
  92   96  }
  93   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 +
  94  113  unsigned int hexval(unsigned int c)
  95  114  {
  96  115          int retval = 256;
  97  116          switch (c) {
  98  117          case '0'...'9':
  99  118                  retval = c - '0';
 100  119                  break;
 101  120          case 'a'...'f':
 102  121                  retval = c - 'a' + 10;
 103  122                  break;
↓ open down ↓ 2 lines elided ↑ open up ↑
 106  125                  break;
 107  126          }
 108  127          return retval;
 109  128  }
 110  129  
 111  130  static void do_warn(const char *type, struct position pos, const char * fmt, va_list args)
 112  131  {
 113  132          static char buffer[512];
 114  133          const char *name;
 115  134  
      135 +        /* Shut up warnings if position is bad_token.pos */
      136 +        if (pos.type == TOKEN_BAD)
      137 +                return;
      138 +
 116  139          vsprintf(buffer, fmt, args);    
 117  140          name = stream_name(pos.stream);
 118  141                  
      142 +        fflush(stdout);
 119  143          fprintf(stderr, "%s: %s:%d:%d: %s%s\n",
 120      -                progname, name, pos.line, pos.pos, type, buffer);
      144 +                diag_prefix, name, pos.line, pos.pos, type, buffer);
 121  145  }
 122  146  
 123      -static int max_warnings = 100;
      147 +unsigned int fmax_warnings = 100;
 124  148  static int show_info = 1;
 125  149  
 126  150  void info(struct position pos, const char * fmt, ...)
 127  151  {
 128  152          va_list args;
 129  153  
 130  154          if (!show_info)
 131  155                  return;
 132  156          va_start(args, fmt);
 133  157          do_warn("", pos, fmt, args);
 134  158          va_end(args);
 135  159  }
 136  160  
 137  161  static void do_error(struct position pos, const char * fmt, va_list args)
 138  162  {
 139  163          static int errors = 0;
 140  164  
 141  165          parse_error = 1;
 142  166          die_if_error = 1;
 143  167          show_info = 1;
      168 +        /* Shut up warnings if position is bad_token.pos */
      169 +        if (pos.type == TOKEN_BAD)
      170 +                return;
 144  171          /* Shut up warnings after an error */
 145  172          has_error |= ERROR_CURR_PHASE;
 146  173          if (errors > 100) {
 147  174                  static int once = 0;
 148  175                  show_info = 0;
 149  176                  if (once)
 150  177                          return;
 151  178                  fmt = "too many errors";
 152  179                  once = 1;
 153  180          }
↓ open down ↓ 6 lines elided ↑ open up ↑
 160  187  {
 161  188          va_list args;
 162  189  
 163  190          if (Wsparse_error) {
 164  191                  va_start(args, fmt);
 165  192                  do_error(pos, fmt, args);
 166  193                  va_end(args);
 167  194                  return;
 168  195          }
 169  196  
 170      -        if (!max_warnings || has_error) {
      197 +        if (!fmax_warnings || has_error) {
 171  198                  show_info = 0;
 172  199                  return;
 173  200          }
 174  201  
 175      -        if (!--max_warnings) {
      202 +        if (!--fmax_warnings) {
 176  203                  show_info = 0;
 177  204                  fmt = "too many warnings";
 178  205          }
 179  206  
 180  207          va_start(args, fmt);
 181  208          do_warn("warning: ", pos, fmt, args);
 182  209          va_end(args);
 183  210  }
 184  211  
 185  212  void sparse_error(struct position pos, const char * fmt, ...)
↓ open down ↓ 26 lines elided ↑ open up ↑
 212  239  NORETURN_ATTR
 213  240  void die(const char *fmt, ...)
 214  241  {
 215  242          va_list args;
 216  243          static char buffer[512];
 217  244  
 218  245          va_start(args, fmt);
 219  246          vsnprintf(buffer, sizeof(buffer), fmt, args);
 220  247          va_end(args);
 221  248  
 222      -        fprintf(stderr, "%s: %s\n", progname, buffer);
      249 +        fprintf(stderr, "%s: %s\n", diag_prefix, buffer);
 223  250          exit(1);
 224  251  }
 225  252  
 226  253  static struct token *pre_buffer_begin = NULL;
 227  254  static struct token *pre_buffer_end = NULL;
 228  255  
 229  256  int Waddress = 0;
 230  257  int Waddress_space = 1;
 231  258  int Wbitwise = 1;
      259 +int Wbitwise_pointer = 0;
      260 +int Wcast_from_as = 0;
 232  261  int Wcast_to_as = 0;
 233  262  int Wcast_truncate = 1;
 234  263  int Wconstant_suffix = 0;
 235  264  int Wconstexpr_not_const = 0;
 236  265  int Wcontext = 1;
 237  266  int Wdecl = 1;
 238  267  int Wdeclarationafterstatement = -1;
 239  268  int Wdefault_bitfield_sign = 0;
 240  269  int Wdesignated_init = 1;
 241  270  int Wdo_while = 0;
 242  271  int Wimplicit_int = 1;
 243  272  int Winit_cstring = 0;
      273 +int Wint_to_pointer_cast = 1;
 244  274  int Wenum_mismatch = 1;
 245  275  int Wexternal_function_has_definition = 1;
 246  276  int Wsparse_error = 0;
 247  277  int Wmemcpy_max_count = 1;
 248  278  int Wnon_pointer_null = 1;
 249  279  int Wold_initializer = 1;
 250  280  int Wold_style_definition = 1;
 251  281  int Wone_bit_signed_bitfield = 1;
 252  282  int Woverride_init = 1;
 253  283  int Woverride_init_all = 0;
 254  284  int Woverride_init_whole_range = 0;
 255  285  int Wparen_string = 0;
 256  286  int Wpointer_arith = 0;
      287 +int Wpointer_to_int_cast = 1;
 257  288  int Wptr_subtraction_blows = 0;
 258  289  int Wreturn_void = 0;
 259  290  int Wshadow = 0;
      291 +int Wshift_count_negative = 1;
      292 +int Wshift_count_overflow = 1;
 260  293  int Wsizeof_bool = 0;
 261  294  int Wstrict_prototypes = 1;
 262  295  int Wtautological_compare = 0;
 263  296  int Wtransparent_union = 0;
 264  297  int Wtypesign = 0;
 265  298  int Wundef = 0;
 266  299  int Wuninitialized = 1;
 267  300  int Wunknown_attribute = 0;
 268  301  int Wvla = 1;
 269  302  
 270  303  int dump_macro_defs = 0;
      304 +int dump_macros_only = 0;
 271  305  
 272      -int dbg_entry = 0;
      306 +int dbg_compound = 0;
 273  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;
 274  312  
      313 +unsigned long fdump_ir;
 275  314  int fmem_report = 0;
 276      -int fdump_linearize;
 277  315  unsigned long long fmemcpy_max_count = 100000;
      316 +unsigned long fpasses = ~0UL;
      317 +int funsigned_char = UNSIGNED_CHAR;
 278  318  
 279  319  int preprocess_only;
 280  320  
 281  321  static enum { STANDARD_C89,
 282  322                STANDARD_C94,
 283  323                STANDARD_C99,
 284  324                STANDARD_C11,
 285  325                STANDARD_GNU11,
 286  326                STANDARD_GNU89,
 287  327                STANDARD_GNU99, } standard = STANDARD_GNU89;
 288  328  
 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  329  int arch_m64 = ARCH_M64_DEFAULT;
 300  330  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  331  int arch_big_endian = ARCH_BIG_ENDIAN;
      332 +int arch_mach = MACH_NATIVE;
 308  333  
 309  334  
 310  335  #define CMDLINE_INCLUDE 20
 311  336  static int cmdline_include_nr = 0;
 312  337  static char *cmdline_include[CMDLINE_INCLUDE];
 313  338  
 314  339  
 315  340  void add_pre_buffer(const char *fmt, ...)
 316  341  {
 317  342          va_list args;
↓ open down ↓ 108 lines elided ↑ open up ↑
 426  451          multiarch_dir = *++next;
 427  452          if (!multiarch_dir)
 428  453                  die("missing argument for -multiarch-dir option");
 429  454          return next;
 430  455  }
 431  456  
 432  457  static char **handle_switch_m(char *arg, char **next)
 433  458  {
 434  459          if (!strcmp(arg, "m64")) {
 435  460                  arch_m64 = ARCH_LP64;
 436      -        } else if (!strcmp(arg, "m32")) {
      461 +        } else if (!strcmp(arg, "m32") || !strcmp(arg, "m16")) {
 437  462                  arch_m64 = ARCH_LP32;
      463 +        } else if (!strcmp(arg, "mx32")) {
      464 +                arch_m64 = ARCH_X32;
 438  465          } else if (!strcmp(arg, "msize-llp64")) {
 439  466                  arch_m64 = ARCH_LLP64;
 440  467          } else if (!strcmp(arg, "msize-long")) {
 441  468                  arch_msize_long = 1;
 442  469          } else if (!strcmp(arg, "multiarch-dir")) {
 443  470                  return handle_multiarch_dir(arg, next);
 444  471          } else if (!strcmp(arg, "mbig-endian")) {
 445  472                  arch_big_endian = 1;
 446  473          } else if (!strcmp(arg, "mlittle-endian")) {
 447  474                  arch_big_endian = 0;
 448  475          }
 449  476          return next;
 450  477  }
 451  478  
 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  479  static void handle_arch_msize_long_finalize(void)
 491  480  {
 492  481          if (arch_msize_long) {
 493  482                  size_t_ctype = &ulong_ctype;
 494  483                  ssize_t_ctype = &long_ctype;
 495  484          }
 496  485  }
 497  486  
 498  487  static void handle_arch_finalize(void)
 499  488  {
 500      -        handle_arch_m64_finalize();
 501  489          handle_arch_msize_long_finalize();
 502  490  }
 503  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 +}
 504  499  
 505      -static int handle_simple_switch(const char *arg, const char *name, int *flag)
      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)
 506  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;
 507  563          int val = 1;
 508  564  
 509  565          // Prefixe "no-" mean to turn flag off.
 510  566          if (strncmp(arg, "no-", 3) == 0) {
 511  567                  arg += 3;
 512  568                  val = 0;
 513  569          }
 514  570  
 515      -        if (strcmp(arg, name) == 0) {
 516      -                *flag = val;
 517      -                return 1;
      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 +                }
 518  593          }
 519  594  
 520  595          // not handled
 521  596          return 0;
 522  597  }
 523  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 +
 524  626  static char **handle_switch_o(char *arg, char **next)
 525  627  {
 526  628          if (!strcmp (arg, "o")) {       // "-o foo"
 527  629                  if (!*++next)
 528  630                          die("argument to '-o' is missing");
      631 +                outfile = *next;
 529  632          }
 530  633          // else "-ofoo"
 531  634  
 532  635          return next;
 533  636  }
 534  637  
 535      -static const struct warning {
 536      -        const char *name;
 537      -        int *flag;
 538      -} warnings[] = {
      638 +static const struct flag warnings[] = {
 539  639          { "address", &Waddress },
 540  640          { "address-space", &Waddress_space },
 541  641          { "bitwise", &Wbitwise },
      642 +        { "bitwise-pointer", &Wbitwise_pointer},
      643 +        { "cast-from-as", &Wcast_from_as },
 542  644          { "cast-to-as", &Wcast_to_as },
 543  645          { "cast-truncate", &Wcast_truncate },
 544  646          { "constant-suffix", &Wconstant_suffix },
 545  647          { "constexpr-not-const", &Wconstexpr_not_const},
 546  648          { "context", &Wcontext },
 547  649          { "decl", &Wdecl },
 548  650          { "declaration-after-statement", &Wdeclarationafterstatement },
 549  651          { "default-bitfield-sign", &Wdefault_bitfield_sign },
 550  652          { "designated-init", &Wdesignated_init },
 551  653          { "do-while", &Wdo_while },
 552  654          { "enum-mismatch", &Wenum_mismatch },
 553  655          { "external-function-has-definition", &Wexternal_function_has_definition },
 554  656          { "implicit-int", &Wimplicit_int },
 555  657          { "init-cstring", &Winit_cstring },
      658 +        { "int-to-pointer-cast", &Wint_to_pointer_cast },
 556  659          { "memcpy-max-count", &Wmemcpy_max_count },
 557  660          { "non-pointer-null", &Wnon_pointer_null },
 558  661          { "old-initializer", &Wold_initializer },
 559  662          { "old-style-definition", &Wold_style_definition },
 560  663          { "one-bit-signed-bitfield", &Wone_bit_signed_bitfield },
 561  664          { "override-init", &Woverride_init },
 562  665          { "override-init-all", &Woverride_init_all },
 563  666          { "paren-string", &Wparen_string },
      667 +        { "pointer-to-int-cast", &Wpointer_to_int_cast },
 564  668          { "ptr-subtraction-blows", &Wptr_subtraction_blows },
 565  669          { "return-void", &Wreturn_void },
 566  670          { "shadow", &Wshadow },
      671 +        { "shift-count-negative", &Wshift_count_negative },
      672 +        { "shift-count-overflow", &Wshift_count_overflow },
 567  673          { "sizeof-bool", &Wsizeof_bool },
 568  674          { "strict-prototypes", &Wstrict_prototypes },
 569  675          { "pointer-arith", &Wpointer_arith },
 570  676          { "sparse-error", &Wsparse_error },
 571  677          { "tautological-compare", &Wtautological_compare },
 572  678          { "transparent-union", &Wtransparent_union },
 573  679          { "typesign", &Wtypesign },
 574  680          { "undef", &Wundef },
 575  681          { "uninitialized", &Wuninitialized },
 576  682          { "unknown-attribute", &Wunknown_attribute },
 577  683          { "vla", &Wvla },
 578  684  };
 579  685  
 580  686  enum {
 581  687          WARNING_OFF,
 582  688          WARNING_ON,
 583  689          WARNING_FORCE_OFF
 584  690  };
 585  691  
 586  692  
 587      -static char **handle_onoff_switch(char *arg, char **next, const struct warning warnings[], int n)
      693 +static char **handle_onoff_switch(char *arg, char **next, const struct flag warnings[], int n)
 588  694  {
 589  695          int flag = WARNING_ON;
 590  696          char *p = arg + 1;
 591  697          unsigned i;
 592  698  
 593  699          if (!strcmp(p, "sparse-all")) {
 594  700                  for (i = 0; i < n; i++) {
 595  701                          if (*warnings[i].flag != WARNING_FORCE_OFF && warnings[i].flag != &Wsparse_error)
 596  702                                  *warnings[i].flag = WARNING_ON;
 597  703                  }
      704 +                return NULL;
 598  705          }
 599  706  
 600  707          // Prefixes "no" and "no-" mean to turn warning off.
 601  708          if (p[0] == 'n' && p[1] == 'o') {
 602  709                  p += 2;
 603  710                  if (p[0] == '-')
 604  711                          p++;
 605  712                  flag = WARNING_FORCE_OFF;
 606  713          }
 607  714  
↓ open down ↓ 11 lines elided ↑ open up ↑
 619  726  static char **handle_switch_W(char *arg, char **next)
 620  727  {
 621  728          char ** ret = handle_onoff_switch(arg, next, warnings, ARRAY_SIZE(warnings));
 622  729          if (ret)
 623  730                  return ret;
 624  731  
 625  732          // Unknown.
 626  733          return next;
 627  734  }
 628  735  
 629      -static struct warning debugs[] = {
 630      -        { "entry", &dbg_entry},
      736 +static struct flag debugs[] = {
      737 +        { "compound", &dbg_compound},
 631  738          { "dead", &dbg_dead},
      739 +        { "domtree", &dbg_domtree},
      740 +        { "entry", &dbg_entry},
      741 +        { "ir", &dbg_ir},
      742 +        { "postorder", &dbg_postorder},
 632  743  };
 633  744  
 634  745  
 635  746  static char **handle_switch_v(char *arg, char **next)
 636  747  {
 637  748          char ** ret = handle_onoff_switch(arg, next, debugs, ARRAY_SIZE(debugs));
 638  749          if (ret)
 639  750                  return ret;
 640  751  
 641  752          // Unknown.
 642  753          do {
 643  754                  verbose++;
 644  755          } while (*++arg == 'v');
 645  756          return next;
 646  757  }
 647  758  
 648      -static struct warning dumps[] = {
 649      -        { "D", &dump_macro_defs},
 650      -};
 651      -
 652  759  static char **handle_switch_d(char *arg, char **next)
 653  760  {
 654      -        char ** ret = handle_onoff_switch(arg, next, dumps, ARRAY_SIZE(dumps));
 655      -        if (ret)
 656      -                return ret;
      761 +        char *arg_char = arg + 1;
 657  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 +        }
 658  787          return next;
 659  788  }
 660  789  
 661  790  
 662      -static void handle_onoff_switch_finalize(const struct warning warnings[], int n)
      791 +static void handle_onoff_switch_finalize(const struct flag warnings[], int n)
 663  792  {
 664  793          unsigned i;
 665  794  
 666  795          for (i = 0; i < n; i++) {
 667  796                  if (*warnings[i].flag == WARNING_FORCE_OFF)
 668  797                          *warnings[i].flag = WARNING_OFF;
 669  798          }
 670  799  }
 671  800  
 672  801  static void handle_switch_W_finalize(void)
↓ open down ↓ 37 lines elided ↑ open up ↑
 710  839                  name = *++next;
 711  840          add_pre_buffer ("#undef %s\n", name);
 712  841          return next;
 713  842  }
 714  843  
 715  844  static char **handle_switch_O(char *arg, char **next)
 716  845  {
 717  846          int level = 1;
 718  847          if (arg[1] >= '0' && arg[1] <= '9')
 719  848                  level = arg[1] - '0';
 720      -        optimize = level;
      849 +        optimize_level = level;
 721  850          optimize_size = arg[1] == 's';
 722  851          return next;
 723  852  }
 724  853  
 725      -static char **handle_switch_fmemcpy_max_count(char *arg, char **next)
      854 +static int handle_ftabstop(const char *arg, const char *opt, const struct flag *flag, int options)
 726  855  {
 727      -        unsigned long long val;
      856 +        unsigned long val;
 728  857          char *end;
 729  858  
 730      -        val = strtoull(arg, &end, 0);
 731      -        if (*end != '\0' || end == arg)
 732      -                die("error: missing argument to \"-fmemcpy-max-count=\"");
      859 +        if (*opt == '\0')
      860 +                die("error: missing argument to \"%s\"", arg);
 733  861  
 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  862          /* we silently ignore silly values */
 749      -        val = strtoul(arg, &end, 10);
      863 +        val = strtoul(opt, &end, 10);
 750  864          if (*end == '\0' && 1 <= val && val <= 100)
 751  865                  tabstop = val;
 752  866  
 753      -        return next;
      867 +        return 1;
 754  868  }
 755  869  
 756      -static int funsigned_char;
 757      -static void handle_funsigned_char(void)
      870 +static int handle_fpasses(const char *arg, const char *opt, const struct flag *flag, int options)
 758  871  {
 759      -        if (funsigned_char) {
 760      -                char_ctype.ctype.modifiers &= ~MOD_SIGNED;
 761      -                char_ctype.ctype.modifiers |= MOD_UNSIGNED;
      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;
 762  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;
 763  899  }
 764  900  
 765      -        static char **handle_switch_fdump(char *arg, char **next)
      901 +static int handle_fdiagnostic_prefix(const char *arg, const char *opt, const struct flag *flag, int options)
 766  902  {
 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;
      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;
 775  912          }
      913 +}
 776  914  
 777      -        /* ignore others flags */
 778      -        return next;
      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 +        };
 779  924  
 780      -err:
 781      -        die("error: unknown flag \"-fdump-%s\"", arg);
      925 +        return handle_suboption_mask(arg, opt, dump_ir_options, &fdump_ir);
 782  926  }
 783  927  
 784      -static char **handle_switch_f(char *arg, char **next)
      928 +static int handle_fmemcpy_max_count(const char *arg, const char *opt, const struct flag *flag, int options)
 785  929  {
 786      -        arg++;
      930 +        opt_ullong(arg, opt, &fmemcpy_max_count, OPTNUM_ZERO_IS_INF|OPTNUM_UNLIMITED);
      931 +        return 1;
      932 +}
 787  933  
 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);
      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 +}
 794  939  
 795      -        if (!strcmp(arg, "unsigned-char")) {
 796      -                funsigned_char = 1;
 797      -                return next;
 798      -        }
      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 +};
 799  954  
 800      -        /* handle switches w/ arguments above, boolean and only boolean below */
 801      -        if (handle_simple_switch(arg, "mem-report", &fmem_report))
      955 +static char **handle_switch_f(char *arg, char **next)
      956 +{
      957 +        if (handle_switches(arg-1, arg+1, fflags))
 802  958                  return next;
 803  959  
 804  960          return next;
 805  961  }
 806  962  
 807  963  static char **handle_switch_G(char *arg, char **next)
 808  964  {
 809  965          if (!strcmp (arg, "G") && *next)
 810  966                  return next + 1; // "-G 0"
 811  967          else
↓ open down ↓ 1 lines elided ↑ open up ↑
 813  969  }
 814  970  
 815  971  static char **handle_switch_a(char *arg, char **next)
 816  972  {
 817  973          if (!strcmp (arg, "ansi"))
 818  974                  standard = STANDARD_C89;
 819  975  
 820  976          return next;
 821  977  }
 822  978  
 823      -static char **handle_switch_s(char *arg, char **next)
      979 +static char **handle_switch_s(const char *arg, char **next)
 824  980  {
 825      -        if (!strncmp (arg, "std=", 4))
 826      -        {
 827      -                arg += 4;
 828      -
      981 +        if ((arg = match_option(arg, "std="))) {
 829  982                  if (!strcmp (arg, "c89") ||
 830  983                      !strcmp (arg, "iso9899:1990"))
 831  984                          standard = STANDARD_C89;
 832  985  
 833  986                  else if (!strcmp (arg, "iso9899:199409"))
 834  987                          standard = STANDARD_C94;
 835  988  
 836  989                  else if (!strcmp (arg, "c99") ||
 837  990                           !strcmp (arg, "c9x") ||
 838  991                           !strcmp (arg, "iso9899:1999") ||
↓ open down ↓ 50 lines elided ↑ open up ↑
 889 1042  }
 890 1043  
 891 1044  static char **handle_switch_g(char *arg, char **next)
 892 1045  {
 893 1046          if (!strcmp (arg, "gcc-base-dir"))
 894 1047                  return handle_base_dir(arg, next);
 895 1048  
 896 1049          return next;
 897 1050  }
 898 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 +
 899 1059  static char **handle_version(char *arg, char **next)
 900 1060  {
 901 1061          printf("%s\n", SPARSE_VERSION);
 902 1062          exit(0);
 903 1063  }
 904 1064  
 905 1065  static char **handle_param(char *arg, char **next)
 906 1066  {
 907 1067          char *value = NULL;
 908 1068  
 909 1069          /* Ignore smatch's --param-mapper */
 910 1070          if (strcmp(arg, "-mapper") == 0)
 911 1071                  return next;
 912 1072  
 913      -
 914 1073          /* For now just skip any '--param=*' or '--param *' */
 915 1074          if (*arg == '\0') {
 916 1075                  value = *++next;
 917 1076          } else if (isspace((unsigned char)*arg) || *arg == '=') {
 918 1077                  value = ++arg;
 919 1078          }
 920 1079  
 921 1080          if (!value)
 922 1081                  die("missing argument for --param option");
 923 1082  
↓ open down ↓ 41 lines elided ↑ open up ↑
 965 1124          case 'i': return handle_switch_i(arg, next);
 966 1125          case 'M': return handle_switch_M(arg, next);
 967 1126          case 'm': return handle_switch_m(arg, next);
 968 1127          case 'n': return handle_switch_n(arg, next);
 969 1128          case 'o': return handle_switch_o(arg, next);
 970 1129          case 'O': return handle_switch_O(arg, next);
 971 1130          case 's': return handle_switch_s(arg, next);
 972 1131          case 'U': return handle_switch_U(arg, next);
 973 1132          case 'v': return handle_switch_v(arg, next);
 974 1133          case 'W': return handle_switch_W(arg, next);
     1134 +        case 'x': return handle_switch_x(arg, next);
 975 1135          case '-': return handle_long_options(arg + 1, next);
 976 1136          default:
 977 1137                  break;
 978 1138          }
 979 1139  
 980 1140          /*
 981 1141           * Ignore unknown command line options:
 982 1142           * they're probably gcc switches
 983 1143           */
 984 1144          return next;
 985 1145  }
 986 1146  
 987      -static void predefined_sizeof(const char *name, unsigned bits)
     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)
 988 1157  {
 989      -        add_pre_buffer("#weak_define __SIZEOF_%s__ %d\n", name, bits/8);
     1158 +        char buf[32];
     1159 +
     1160 +        snprintf(buf, sizeof(buf), "__SIZEOF_%s%s__", name, suffix);
     1161 +        predefine(buf, 1, "%d", bits/8);
 990 1162  }
 991 1163  
 992      -static void predefined_max(const char *name, const char *suffix, unsigned bits)
     1164 +static void predefined_width(const char *name, unsigned bits)
 993 1165  {
 994      -        unsigned long long max = (1ULL << (bits - 1 )) - 1;
     1166 +        char buf[32];
 995 1167  
 996      -        add_pre_buffer("#weak_define __%s_MAX__ %#llx%s\n", name, max, suffix);
     1168 +        snprintf(buf, sizeof(buf), "__%s_WIDTH__", name);
     1169 +        predefine(buf, 1, "%d", bits);
 997 1170  }
 998 1171  
 999      -static void predefined_type_size(const char *name, const char *suffix, unsigned bits)
     1172 +static void predefined_max(const char *name, struct symbol *type)
1000 1173  {
1001      -        predefined_max(name, suffix, bits);
1002      -        predefined_sizeof(name, bits);
     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);
1003 1181  }
1004 1182  
1005      -static void predefined_macros(void)
     1183 +static void predefined_min(const char *name, struct symbol *type)
1006 1184  {
1007      -        add_pre_buffer("#define __CHECKER__ 1\n");
     1185 +        const char *suffix = builtin_type_suffix(type);
     1186 +        char buf[32];
1008 1187  
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);
     1188 +        snprintf(buf, sizeof(buf), "__%s_MIN__", name);
1014 1189  
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);
     1190 +        if (is_signed_type(type))
     1191 +                predefine(buf, 1, "(-__%s_MAX__ - 1)", name);
     1192 +        else
     1193 +                predefine(buf, 1, "0%s", suffix);
     1194 +}
1018 1195  
1019      -        predefined_sizeof("INT128", 128);
     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 +}
1020 1201  
1021      -        predefined_sizeof("SIZE_T", bits_in_pointer);
1022      -        predefined_sizeof("PTRDIFF_T", bits_in_pointer);
1023      -        predefined_sizeof("POINTER", bits_in_pointer);
     1202 +static void predefined_ctype(const char *name, struct symbol *type, int flags)
     1203 +{
     1204 +        unsigned bits = type->bit_size;
1024 1205  
1025      -        predefined_sizeof("FLOAT", bits_in_float);
1026      -        predefined_sizeof("DOUBLE", bits_in_double);
1027      -        predefined_sizeof("LONG_DOUBLE", bits_in_longdouble);
     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 +}
1028 1219  
1029      -        add_pre_buffer("#weak_define __%s_ENDIAN__ 1\n",
1030      -                arch_big_endian ? "BIG" : "LITTLE");
     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);
1031 1226  
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");
     1227 +        predefine("__STDC__", 1, "1");
     1228 +        switch (standard) {
     1229 +        case STANDARD_C89:
     1230 +                predefine("__STRICT_ANSI__", 1, "1");
     1231 +                break;
1037 1232  
1038      -        add_pre_buffer("#weak_define __PRAGMA_REDEFINE_EXTNAME 1\n");
     1233 +        case STANDARD_C94:
     1234 +                predefine("__STDC_VERSION__", 1, "199409L");
     1235 +                predefine("__STRICT_ANSI__", 1, "1");
     1236 +                break;
1039 1237  
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      -}
     1238 +        case STANDARD_C99:
     1239 +                predefine("__STDC_VERSION__", 1, "199901L");
     1240 +                predefine("__STRICT_ANSI__", 1, "1");
     1241 +                break;
1053 1242  
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");
     1243 +        case STANDARD_GNU89:
     1244 +        default:
     1245 +                break;
1084 1246  
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");
     1247 +        case STANDARD_GNU99:
     1248 +                predefine("__STDC_VERSION__", 1, "199901L");
     1249 +                break;
1091 1250  
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");
     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 +        }
1111 1260  
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");
     1261 +        predefine("__CHAR_BIT__", 1, "%d", bits_in_char);
     1262 +        if (funsigned_char)
     1263 +                predefine("__CHAR_UNSIGNED__", 1, "1");
1116 1264  
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");
     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);
1135 1272  
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");
     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);
1155 1276  
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      -        );
     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);
1164 1285  
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");
     1286 +        predefined_sizeof("INT128", "", 128);
1172 1287  
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");
     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);
1186 1295  
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");
     1296 +        predefined_sizeof("FLOAT", "", bits_in_float);
     1297 +        predefined_sizeof("DOUBLE", "", bits_in_double);
     1298 +        predefined_sizeof("LONG_DOUBLE", "", bits_in_longdouble);
1203 1299  
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");
     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 +        }
1211 1310  
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");
     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
1220 1418  }
1221 1419  
1222      -void create_builtin_stream(void)
     1420 +static void create_builtin_stream(void)
1223 1421  {
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);
     1422 +        // Temporary hack
     1423 +        add_pre_buffer("#define _Pragma(x)\n");
1227 1424  
1228 1425          /* add the multiarch include directories, if any */
1229 1426          if (multiarch_dir && *multiarch_dir) {
1230 1427                  add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
1231 1428                  add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir);
1232 1429          }
1233 1430  
1234 1431          /* We add compiler headers path here because we have to parse
1235 1432           * the arguments to get it, falling back to default. */
1236 1433          add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir);
1237 1434          add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir);
1238 1435  
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      -
     1436 +        add_pre_buffer("#define __has_builtin(x) 0\n");
     1437 +        add_pre_buffer("#define __has_attribute(x) 0\n");
1290 1438          add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
1291 1439          add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
1292 1440          add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n");
1293 1441          add_pre_buffer("#define __builtin_va_arg(arg,type)  ({ type __va_arg_ret = *(type *)(arg); arg += sizeof(type); __va_arg_ret; })\n");
1294 1442          add_pre_buffer("#define __builtin_va_alist (*(void *)0)\n");
1295 1443          add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n");
1296 1444          add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n");
1297 1445          add_pre_buffer("#define __builtin_ms_va_copy(dest, src) ({ dest = src; (void)0; })\n");
1298 1446          add_pre_buffer("#define __builtin_va_end(arg)\n");
1299 1447          add_pre_buffer("#define __builtin_ms_va_end(arg)\n");
1300 1448          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 1449  }
1310 1450  
1311 1451  static struct symbol_list *sparse_tokenstream(struct token *token)
1312 1452  {
1313 1453          int builtin = token && !token->pos.stream;
1314 1454  
1315 1455          // Preprocess the stream
1316 1456          token = preprocess(token);
1317 1457  
1318      -        if (dump_macro_defs && !builtin)
1319      -                dump_macro_definitions();
     1458 +        if (dump_macro_defs || dump_macros_only) {
     1459 +                if (!builtin)
     1460 +                        dump_macro_definitions();
     1461 +                if (dump_macros_only)
     1462 +                        return NULL;
     1463 +        }
1320 1464  
1321 1465          if (preprocess_only) {
1322 1466                  while (!eof_token(token)) {
1323 1467                          int prec = 1;
1324 1468                          struct token *next = token->next;
1325 1469                          const char *separator = "";
1326 1470                          if (next->pos.whitespace)
1327 1471                                  separator = " ";
1328 1472                          if (next->pos.newline) {
1329 1473                                  separator = "\n\t\t\t\t\t";
↓ open down ↓ 20 lines elided ↑ open up ↑
1350 1494          int fd;
1351 1495          struct token *token;
1352 1496  
1353 1497          if (strcmp (filename, "-") == 0) {
1354 1498                  fd = 0;
1355 1499          } else {
1356 1500                  fd = open(filename, O_RDONLY);
1357 1501                  if (fd < 0)
1358 1502                          die("No such file: %s", filename);
1359 1503          }
     1504 +        base_filename = filename;
1360 1505  
1361 1506          // Tokenize the input stream
1362 1507          token = tokenize(filename, fd, NULL, includepath);
1363 1508          store_all_tokens(token);
1364 1509          close(fd);
1365 1510  
1366 1511          return sparse_tokenstream(token);
1367 1512  }
1368 1513  
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 1514  /*
1376 1515   * This handles the "-include" directive etc: we're in global
1377 1516   * scope, and all types/macros etc will affect all the following
1378 1517   * files.
1379 1518   *
1380 1519   * NOTE NOTE NOTE! "#undef" of anything in this stage will
1381 1520   * affect all subsequent files too, i.e. we can have non-local
1382 1521   * behaviour between files!
1383 1522   */
1384 1523  static struct symbol_list *sparse_initial(void)
↓ open down ↓ 1 lines elided ↑ open up ↑
1386 1525          int i;
1387 1526  
1388 1527          // Prepend any "include" file to the stream.
1389 1528          // We're in global scope, it will affect all files!
1390 1529          for (i = 0; i < cmdline_include_nr; i++)
1391 1530                  add_pre_buffer("#argv_include \"%s\"\n", cmdline_include[i]);
1392 1531  
1393 1532          return sparse_tokenstream(pre_buffer_begin);
1394 1533  }
1395 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 +
1396 1541  struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **filelist)
1397 1542  {
1398 1543          char **args;
1399 1544          struct symbol_list *list;
1400 1545  
1401 1546          // Initialize symbol stream first, so that we can add defines etc
1402 1547          init_symbols();
1403 1548          init_include_path();
1404 1549  
1405      -        progname = argv[0];
     1550 +        diag_prefix = argv[0];
1406 1551  
1407 1552          args = argv;
1408 1553          for (;;) {
1409 1554                  char *arg = *++args;
1410 1555                  if (!arg)
1411 1556                          break;
1412 1557  
1413 1558                  if (arg[0] == '-' && arg[1]) {
1414 1559                          args = handle_switch(arg+1, args);
1415 1560                          continue;
1416 1561                  }
1417 1562  
1418 1563                  if (endswith(arg, ".a") || endswith(arg, ".so") ||
1419 1564                      endswith(arg, ".so.1") || endswith(arg, ".o"))
1420 1565                          continue;
1421 1566  
1422      -                add_ptr_list_notag(filelist, arg);
     1567 +                add_ptr_list(filelist, arg);
1423 1568          }
1424 1569          handle_switch_W_finalize();
1425 1570          handle_switch_v_finalize();
1426 1571  
1427      -        handle_arch_finalize();
     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 +        }
1428 1579  
     1580 +        if (fdump_ir == 0)
     1581 +                fdump_ir = PASS_FINAL;
     1582 +
1429 1583          list = NULL;
1430      -        if (!ptr_list_empty(filelist)) {
     1584 +        if (filelist) {
1431 1585                  // Initialize type system
     1586 +                init_target();
     1587 +                handle_arch_finalize();
1432 1588                  init_ctype();
1433      -                handle_funsigned_char();
1434 1589  
1435      -                create_builtin_stream();
1436 1590                  predefined_macros();
1437      -                if (!preprocess_only)
1438      -                        declare_builtin_functions();
     1591 +                create_builtin_stream();
     1592 +                declare_builtins();
1439 1593  
1440 1594                  list = sparse_initial();
1441 1595  
1442 1596                  /*
1443 1597                   * Protect the initial token allocations, since
1444 1598                   * they need to survive all the others
1445 1599                   */
1446 1600                  protect_token_alloc();
1447 1601          }
1448 1602          /*
↓ open down ↓ 55 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX