2 * 'sparse' library helper routines.
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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
36 #include <sys/types.h>
43 #include "expression.h"
46 #include "linearize.h"
52 int verbose
, optimize_level
, optimize_size
, preprocessing
;
60 # define __GNUC_MINOR__ 95
61 # define __GNUC_PATCHLEVEL__ 0
64 int gcc_major
= __GNUC__
;
65 int gcc_minor
= __GNUC_MINOR__
;
66 int gcc_patchlevel
= __GNUC_PATCHLEVEL__
;
68 const char *base_filename
;
70 static const char *diag_prefix
= "";
71 static const char *gcc_base_dir
= GCC_BASE
;
72 static const char *multiarch_dir
= MULTIARCH_TRIPLET
;
73 static const char *outfile
= NULL
;
75 struct token
*skip_to(struct token
*token
, int op
)
77 while (!match_op(token
, op
) && !eof_token(token
))
82 static struct token bad_token
= { .pos
.type
= TOKEN_BAD
};
83 struct token
*expect(struct token
*token
, int op
, const char *where
)
85 if (!match_op(token
, op
)) {
86 if (token
!= &bad_token
) {
87 bad_token
.next
= token
;
88 sparse_error(token
->pos
, "Expected %s %s", show_special(op
), where
);
89 sparse_error(token
->pos
, "got %s", show_token(token
));
92 return skip_to(token
, op
);
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
)
107 if (token
== &bad_token
)
109 sparse_error(token
->pos
, "%s", errmsg
);
110 sparse_error(token
->pos
, "got %s", show_token(token
));
113 unsigned int hexval(unsigned int c
)
121 retval
= c
- 'a' + 10;
124 retval
= c
- 'A' + 10;
130 static void do_warn(const char *type
, struct position pos
, const char * fmt
, va_list args
)
132 static char buffer
[512];
135 /* Shut up warnings if position is bad_token.pos */
136 if (pos
.type
== TOKEN_BAD
)
139 vsprintf(buffer
, fmt
, args
);
140 name
= stream_name(pos
.stream
);
143 fprintf(stderr
, "%s:%d:%d: %s%s%s\n",
144 name
, pos
.line
, pos
.pos
, diag_prefix
, type
, buffer
);
147 unsigned int fmax_warnings
= 100;
148 static int show_info
= 1;
150 void info(struct position pos
, const char * fmt
, ...)
157 do_warn("", pos
, fmt
, args
);
161 static void do_error(struct position pos
, const char * fmt
, va_list args
)
163 static int errors
= 0;
168 /* Shut up warnings if position is bad_token.pos */
169 if (pos
.type
== TOKEN_BAD
)
171 /* Shut up warnings after an error */
172 has_error
|= ERROR_CURR_PHASE
;
178 fmt
= "too many errors";
182 do_warn("error: ", pos
, fmt
, args
);
186 void warning(struct position pos
, const char * fmt
, ...)
192 do_error(pos
, fmt
, args
);
197 if (!fmax_warnings
|| has_error
) {
202 if (!--fmax_warnings
) {
204 fmt
= "too many warnings";
208 do_warn("warning: ", pos
, fmt
, args
);
212 void sparse_error(struct position pos
, const char * fmt
, ...)
216 do_error(pos
, fmt
, args
);
220 void expression_error(struct expression
*expr
, const char *fmt
, ...)
224 do_error(expr
->pos
, fmt
, args
);
226 expr
->ctype
= &bad_ctype
;
230 void error_die(struct position pos
, const char * fmt
, ...)
234 do_warn("error: ", pos
, fmt
, args
);
240 void die(const char *fmt
, ...)
243 static char buffer
[512];
246 vsnprintf(buffer
, sizeof(buffer
), fmt
, args
);
249 fprintf(stderr
, "%s%s\n", diag_prefix
, buffer
);
253 static struct token
*pre_buffer_begin
= NULL
;
254 static struct token
*pre_buffer_end
= NULL
;
257 int Waddress_space
= 1;
259 int Wbitwise_pointer
= 0;
260 int Wcast_from_as
= 0;
262 int Wcast_truncate
= 1;
263 int Wconstant_suffix
= 0;
264 int Wconstexpr_not_const
= 0;
267 int Wdeclarationafterstatement
= -1;
268 int Wdefault_bitfield_sign
= 0;
269 int Wdesignated_init
= 1;
271 int Wimplicit_int
= 1;
272 int Winit_cstring
= 0;
273 int Wint_to_pointer_cast
= 1;
274 int Wenum_mismatch
= 1;
275 int Wexternal_function_has_definition
= 1;
276 int Wsparse_error
= 0;
277 int Wmemcpy_max_count
= 1;
278 int Wnon_pointer_null
= 1;
279 int Wold_initializer
= 1;
280 int Wold_style_definition
= 1;
281 int Wone_bit_signed_bitfield
= 1;
282 int Woverride_init
= 1;
283 int Woverride_init_all
= 0;
284 int Woverride_init_whole_range
= 0;
285 int Wparen_string
= 0;
286 int Wpointer_arith
= 0;
287 int Wpointer_to_int_cast
= 1;
288 int Wptr_subtraction_blows
= 0;
289 int Wreturn_void
= 0;
291 int Wshift_count_negative
= 1;
292 int Wshift_count_overflow
= 1;
293 int Wsizeof_bool
= 0;
294 int Wstrict_prototypes
= 1;
295 int Wtautological_compare
= 0;
296 int Wtransparent_union
= 0;
299 int Wuninitialized
= 1;
300 int Wunknown_attribute
= 0;
303 int dump_macro_defs
= 0;
304 int dump_macros_only
= 0;
306 int dbg_compound
= 0;
311 int dbg_postorder
= 0;
313 unsigned long fdump_ir
;
315 unsigned long long fmemcpy_max_count
= 100000;
316 unsigned long fpasses
= ~0UL;
317 int funsigned_char
= UNSIGNED_CHAR
;
321 enum standard standard
= STANDARD_GNU89
;
323 int arch_m64
= ARCH_M64_DEFAULT
;
324 int arch_msize_long
= 0;
325 int arch_big_endian
= ARCH_BIG_ENDIAN
;
326 int arch_mach
= MACH_NATIVE
;
329 #define CMDLINE_INCLUDE 20
330 static int cmdline_include_nr
= 0;
331 static char *cmdline_include
[CMDLINE_INCLUDE
];
334 void add_pre_buffer(const char *fmt
, ...)
338 struct token
*begin
, *end
;
342 size
= vsnprintf(buffer
, sizeof(buffer
), fmt
, args
);
344 begin
= tokenize_buffer(buffer
, size
, &end
);
345 if (!pre_buffer_begin
)
346 pre_buffer_begin
= begin
;
348 pre_buffer_end
->next
= begin
;
349 pre_buffer_end
= end
;
352 static char **handle_switch_D(char *arg
, char **next
)
354 const char *name
= arg
+ 1;
355 const char *value
= "1";
360 die("argument to `-D' is missing");
375 add_pre_buffer("#define %s %s\n", name
, value
);
379 static char **handle_switch_E(char *arg
, char **next
)
386 static char **handle_switch_I(char *arg
, char **next
)
392 add_pre_buffer("#split_include\n");
395 case '\0': /* Plain "-I" */
398 die("missing argument for -I option");
401 add_pre_buffer("#add_include \"%s/\"\n", path
);
406 static void add_cmdline_include(char *filename
)
408 if (cmdline_include_nr
>= CMDLINE_INCLUDE
)
409 die("too many include files for %s\n", filename
);
410 cmdline_include
[cmdline_include_nr
++] = filename
;
413 static char **handle_switch_i(char *arg
, char **next
)
415 if (*next
&& !strcmp(arg
, "include"))
416 add_cmdline_include(*++next
);
417 else if (*next
&& !strcmp(arg
, "imacros"))
418 add_cmdline_include(*++next
);
419 else if (*next
&& !strcmp(arg
, "isystem")) {
420 char *path
= *++next
;
422 die("missing argument for -isystem option");
423 add_pre_buffer("#add_isystem \"%s/\"\n", path
);
424 } else if (*next
&& !strcmp(arg
, "idirafter")) {
425 char *path
= *++next
;
427 die("missing argument for -idirafter option");
428 add_pre_buffer("#add_dirafter \"%s/\"\n", path
);
433 static char **handle_switch_M(char *arg
, char **next
)
435 if (!strcmp(arg
, "MF") || !strcmp(arg
,"MQ") || !strcmp(arg
,"MT")) {
437 die("missing argument for -%s option", arg
);
443 static char **handle_multiarch_dir(char *arg
, char **next
)
445 multiarch_dir
= *++next
;
447 die("missing argument for -multiarch-dir option");
451 static char **handle_switch_m(char *arg
, char **next
)
453 if (!strcmp(arg
, "m64")) {
454 arch_m64
= ARCH_LP64
;
455 } else if (!strcmp(arg
, "m32") || !strcmp(arg
, "m16")) {
456 arch_m64
= ARCH_LP32
;
457 } else if (!strcmp(arg
, "mx32")) {
459 } else if (!strcmp(arg
, "msize-llp64")) {
460 arch_m64
= ARCH_LLP64
;
461 } else if (!strcmp(arg
, "msize-long")) {
463 } else if (!strcmp(arg
, "multiarch-dir")) {
464 return handle_multiarch_dir(arg
, next
);
465 } else if (!strcmp(arg
, "mbig-endian")) {
467 } else if (!strcmp(arg
, "mlittle-endian")) {
473 static void handle_arch_msize_long_finalize(void)
475 if (arch_msize_long
) {
476 size_t_ctype
= &ulong_ctype
;
477 ssize_t_ctype
= &long_ctype
;
481 static void handle_arch_finalize(void)
483 handle_arch_msize_long_finalize();
486 static const char *match_option(const char *arg
, const char *prefix
)
488 unsigned int n
= strlen(prefix
);
489 if (strncmp(arg
, prefix
, n
) == 0)
500 static int apply_mask(unsigned long *val
, const char *str
, unsigned len
, const struct mask_map
*map
, int neg
)
504 for (;(name
= map
->name
); map
++) {
505 if (!strncmp(name
, str
, len
) && !name
[len
]) {
516 static int handle_suboption_mask(const char *arg
, const char *opt
, const struct mask_map
*map
, unsigned long *flag
)
519 apply_mask(flag
, "", 0, map
, 0);
525 unsigned int len
= strcspn(opt
, ",+");
529 if (!strncmp(opt
, "no-", 3)) {
534 if (apply_mask(flag
, opt
, len
, map
, neg
))
535 die("error: wrong option '%.*s' for \'%s\'", len
, opt
, arg
);
546 #define OPT_INVERSE 1
550 int (*fun
)(const char *arg
, const char *opt
, const struct flag
*, int options
);
554 static int handle_switches(const char *ori
, const char *opt
, const struct flag
*flags
)
556 const char *arg
= opt
;
559 // Prefixe "no-" mean to turn flag off.
560 if (strncmp(arg
, "no-", 3) == 0) {
565 for (; flags
->name
; flags
++) {
566 const char *opt
= match_option(arg
, flags
->name
);
575 options
|= OPT_INVERSE
;
576 if ((rc
= flags
->fun(ori
, opt
, flags
, options
)))
581 if (opt
[0] == '\0' && flags
->flag
) {
582 if (flags
->mask
& OPT_INVERSE
)
594 #define OPTNUM_ZERO_IS_INF 1
595 #define OPTNUM_UNLIMITED 2
597 #define OPT_NUMERIC(NAME, TYPE, FUNCTION) \
598 static int opt_##NAME(const char *arg, const char *opt, TYPE *ptr, int flag) \
603 val = FUNCTION(opt, &end, 0); \
604 if (*end != '\0' || end == opt) { \
605 if ((flag & OPTNUM_UNLIMITED) && !strcmp(opt, "unlimited")) \
608 die("error: wrong argument to \'%s\'", arg); \
610 if ((flag & OPTNUM_ZERO_IS_INF) && val == 0) \
616 OPT_NUMERIC(ullong
, unsigned long long, strtoull
)
617 OPT_NUMERIC(uint
, unsigned int, strtoul
)
620 static char **handle_switch_o(char *arg
, char **next
)
622 if (!strcmp (arg
, "o")) { // "-o foo"
624 die("argument to '-o' is missing");
632 static const struct flag warnings
[] = {
633 { "address", &Waddress
},
634 { "address-space", &Waddress_space
},
635 { "bitwise", &Wbitwise
},
636 { "bitwise-pointer", &Wbitwise_pointer
},
637 { "cast-from-as", &Wcast_from_as
},
638 { "cast-to-as", &Wcast_to_as
},
639 { "cast-truncate", &Wcast_truncate
},
640 { "constant-suffix", &Wconstant_suffix
},
641 { "constexpr-not-const", &Wconstexpr_not_const
},
642 { "context", &Wcontext
},
644 { "declaration-after-statement", &Wdeclarationafterstatement
},
645 { "default-bitfield-sign", &Wdefault_bitfield_sign
},
646 { "designated-init", &Wdesignated_init
},
647 { "do-while", &Wdo_while
},
648 { "enum-mismatch", &Wenum_mismatch
},
649 { "external-function-has-definition", &Wexternal_function_has_definition
},
650 { "implicit-int", &Wimplicit_int
},
651 { "init-cstring", &Winit_cstring
},
652 { "int-to-pointer-cast", &Wint_to_pointer_cast
},
653 { "memcpy-max-count", &Wmemcpy_max_count
},
654 { "non-pointer-null", &Wnon_pointer_null
},
655 { "old-initializer", &Wold_initializer
},
656 { "old-style-definition", &Wold_style_definition
},
657 { "one-bit-signed-bitfield", &Wone_bit_signed_bitfield
},
658 { "override-init", &Woverride_init
},
659 { "override-init-all", &Woverride_init_all
},
660 { "paren-string", &Wparen_string
},
661 { "pointer-to-int-cast", &Wpointer_to_int_cast
},
662 { "ptr-subtraction-blows", &Wptr_subtraction_blows
},
663 { "return-void", &Wreturn_void
},
664 { "shadow", &Wshadow
},
665 { "shift-count-negative", &Wshift_count_negative
},
666 { "shift-count-overflow", &Wshift_count_overflow
},
667 { "sizeof-bool", &Wsizeof_bool
},
668 { "strict-prototypes", &Wstrict_prototypes
},
669 { "pointer-arith", &Wpointer_arith
},
670 { "sparse-error", &Wsparse_error
},
671 { "tautological-compare", &Wtautological_compare
},
672 { "transparent-union", &Wtransparent_union
},
673 { "typesign", &Wtypesign
},
674 { "undef", &Wundef
},
675 { "uninitialized", &Wuninitialized
},
676 { "unknown-attribute", &Wunknown_attribute
},
687 static char **handle_onoff_switch(char *arg
, char **next
, const struct flag warnings
[], int n
)
689 int flag
= WARNING_ON
;
693 if (!strcmp(p
, "sparse-all")) {
694 for (i
= 0; i
< n
; i
++) {
695 if (*warnings
[i
].flag
!= WARNING_FORCE_OFF
&& warnings
[i
].flag
!= &Wsparse_error
)
696 *warnings
[i
].flag
= WARNING_ON
;
701 // Prefixes "no" and "no-" mean to turn warning off.
702 if (p
[0] == 'n' && p
[1] == 'o') {
706 flag
= WARNING_FORCE_OFF
;
709 for (i
= 0; i
< n
; i
++) {
710 if (!strcmp(p
,warnings
[i
].name
)) {
711 *warnings
[i
].flag
= flag
;
720 static char **handle_switch_W(char *arg
, char **next
)
722 char ** ret
= handle_onoff_switch(arg
, next
, warnings
, ARRAY_SIZE(warnings
));
730 static struct flag debugs
[] = {
731 { "compound", &dbg_compound
},
732 { "dead", &dbg_dead
},
733 { "domtree", &dbg_domtree
},
734 { "entry", &dbg_entry
},
736 { "postorder", &dbg_postorder
},
740 static char **handle_switch_v(char *arg
, char **next
)
742 char ** ret
= handle_onoff_switch(arg
, next
, debugs
, ARRAY_SIZE(debugs
));
749 } while (*++arg
== 'v');
753 static char **handle_switch_d(char *arg
, char **next
)
755 char *arg_char
= arg
+ 1;
758 * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded
759 * by a space. If you specify characters whose behaviour conflicts,
760 * the result is undefined.
764 case 'M': /* dump just the macro definitions */
765 dump_macros_only
= 1;
768 case 'D': /* like 'M', but also output pre-processed text */
770 dump_macros_only
= 0;
772 case 'N': /* like 'D', but only output macro names not bodies */
774 case 'I': /* like 'D', but also output #include directives */
776 case 'U': /* like 'D', but only output expanded macros */
785 static void handle_onoff_switch_finalize(const struct flag warnings
[], int n
)
789 for (i
= 0; i
< n
; i
++) {
790 if (*warnings
[i
].flag
== WARNING_FORCE_OFF
)
791 *warnings
[i
].flag
= WARNING_OFF
;
795 static void handle_switch_W_finalize(void)
797 handle_onoff_switch_finalize(warnings
, ARRAY_SIZE(warnings
));
799 /* default Wdeclarationafterstatement based on the C dialect */
800 if (-1 == Wdeclarationafterstatement
)
806 Wdeclarationafterstatement
= 1;
814 Wdeclarationafterstatement
= 0;
824 static void handle_switch_v_finalize(void)
826 handle_onoff_switch_finalize(debugs
, ARRAY_SIZE(debugs
));
829 static char **handle_switch_U(char *arg
, char **next
)
831 const char *name
= arg
+ 1;
834 add_pre_buffer ("#undef %s\n", name
);
838 static char **handle_switch_O(char *arg
, char **next
)
841 if (arg
[1] >= '0' && arg
[1] <= '9')
842 level
= arg
[1] - '0';
843 optimize_level
= level
;
844 optimize_size
= arg
[1] == 's';
848 static int handle_ftabstop(const char *arg
, const char *opt
, const struct flag
*flag
, int options
)
854 die("error: missing argument to \"%s\"", arg
);
856 /* we silently ignore silly values */
857 val
= strtoul(opt
, &end
, 10);
858 if (*end
== '\0' && 1 <= val
&& val
<= 100)
864 static int handle_fpasses(const char *arg
, const char *opt
, const struct flag
*flag
, int options
)
870 if (options
& OPT_INVERSE
)
876 if (options
& OPT_INVERSE
)
878 if (!strcmp(opt
, "-enable")) {
882 if (!strcmp(opt
, "-disable")) {
886 if (!strcmp(opt
, "=last")) {
887 // clear everything above
895 static int handle_fdiagnostic_prefix(const char *arg
, const char *opt
, const struct flag
*flag
, int options
)
899 diag_prefix
= "sparse: ";
902 diag_prefix
= xasprintf("%s: ", opt
+1);
909 static int handle_fdump_ir(const char *arg
, const char *opt
, const struct flag
*flag
, int options
)
911 static const struct mask_map dump_ir_options
[] = {
912 { "", PASS_LINEARIZE
},
913 { "linearize", PASS_LINEARIZE
},
914 { "mem2reg", PASS_MEM2REG
},
915 { "final", PASS_FINAL
},
919 return handle_suboption_mask(arg
, opt
, dump_ir_options
, &fdump_ir
);
922 static int handle_fmemcpy_max_count(const char *arg
, const char *opt
, const struct flag
*flag
, int options
)
924 opt_ullong(arg
, opt
, &fmemcpy_max_count
, OPTNUM_ZERO_IS_INF
|OPTNUM_UNLIMITED
);
928 static int handle_fmax_warnings(const char *arg
, const char *opt
, const struct flag
*flag
, int options
)
930 opt_uint(arg
, opt
, &fmax_warnings
, OPTNUM_UNLIMITED
);
934 static struct flag fflags
[] = {
935 { "diagnostic-prefix", NULL
, handle_fdiagnostic_prefix
},
936 { "dump-ir", NULL
, handle_fdump_ir
},
937 { "linearize", NULL
, handle_fpasses
, PASS_LINEARIZE
},
938 { "max-warnings=", NULL
, handle_fmax_warnings
},
939 { "mem-report", &fmem_report
},
940 { "memcpy-max-count=", NULL
, handle_fmemcpy_max_count
},
941 { "tabstop=", NULL
, handle_ftabstop
},
942 { "mem2reg", NULL
, handle_fpasses
, PASS_MEM2REG
},
943 { "optim", NULL
, handle_fpasses
, PASS_OPTIM
},
944 { "signed-char", &funsigned_char
, NULL
, OPT_INVERSE
},
945 { "unsigned-char", &funsigned_char
, NULL
, },
949 static char **handle_switch_f(char *arg
, char **next
)
951 if (handle_switches(arg
-1, arg
+1, fflags
))
957 static char **handle_switch_G(char *arg
, char **next
)
959 if (!strcmp (arg
, "G") && *next
)
960 return next
+ 1; // "-G 0"
962 return next
; // "-G0" or (bogus) terminal "-G"
965 static char **handle_switch_a(char *arg
, char **next
)
967 if (!strcmp (arg
, "ansi"))
968 standard
= STANDARD_C89
;
973 static char **handle_switch_s(const char *arg
, char **next
)
975 if ((arg
= match_option(arg
, "std="))) {
976 if (!strcmp (arg
, "c89") ||
977 !strcmp (arg
, "iso9899:1990"))
978 standard
= STANDARD_C89
;
980 else if (!strcmp (arg
, "iso9899:199409"))
981 standard
= STANDARD_C94
;
983 else if (!strcmp (arg
, "c99") ||
984 !strcmp (arg
, "c9x") ||
985 !strcmp (arg
, "iso9899:1999") ||
986 !strcmp (arg
, "iso9899:199x"))
987 standard
= STANDARD_C99
;
989 else if (!strcmp (arg
, "gnu89"))
990 standard
= STANDARD_GNU89
;
992 else if (!strcmp (arg
, "gnu99") || !strcmp (arg
, "gnu9x"))
993 standard
= STANDARD_GNU99
;
995 else if (!strcmp(arg
, "c11") ||
996 !strcmp(arg
, "c1x") ||
997 !strcmp(arg
, "iso9899:2011"))
998 standard
= STANDARD_C11
;
1000 else if (!strcmp(arg
, "gnu11"))
1001 standard
= STANDARD_GNU11
;
1004 die ("Unsupported C dialect");
1010 static char **handle_nostdinc(char *arg
, char **next
)
1012 add_pre_buffer("#nostdinc\n");
1016 static char **handle_switch_n(char *arg
, char **next
)
1018 if (!strcmp (arg
, "nostdinc"))
1019 return handle_nostdinc(arg
, next
);
1024 static char **handle_base_dir(char *arg
, char **next
)
1026 gcc_base_dir
= *++next
;
1028 die("missing argument for -gcc-base-dir option");
1032 static char **handle_no_lineno(char *arg
, char **next
)
1038 static char **handle_switch_g(char *arg
, char **next
)
1040 if (!strcmp (arg
, "gcc-base-dir"))
1041 return handle_base_dir(arg
, next
);
1046 static char **handle_switch_x(char *arg
, char **next
)
1049 die("missing argument for -x option");
1053 static char **handle_version(char *arg
, char **next
)
1055 printf("%s\n", SPARSE_VERSION
);
1059 static char **handle_param(char *arg
, char **next
)
1063 /* For now just skip any '--param=*' or '--param *' */
1066 } else if (isspace((unsigned char)*arg
) || *arg
== '=') {
1071 die("missing argument for --param option");
1078 char **(*fn
)(char *, char **);
1079 unsigned int prefix
:1;
1082 static char **handle_long_options(char *arg
, char **next
)
1084 static struct switches cmd
[] = {
1085 { "param", handle_param
, 1 },
1086 { "version", handle_version
},
1087 { "nostdinc", handle_nostdinc
},
1088 { "gcc-base-dir", handle_base_dir
},
1089 { "no-lineno", handle_no_lineno
},
1092 struct switches
*s
= cmd
;
1095 int optlen
= strlen(s
->name
);
1096 if (!strncmp(s
->name
, arg
, optlen
+ !s
->prefix
))
1097 return s
->fn(arg
+ optlen
, next
);
1103 static char **handle_switch(char *arg
, char **next
)
1106 case 'a': return handle_switch_a(arg
, next
);
1107 case 'D': return handle_switch_D(arg
, next
);
1108 case 'd': return handle_switch_d(arg
, next
);
1109 case 'E': return handle_switch_E(arg
, next
);
1110 case 'f': return handle_switch_f(arg
, next
);
1111 case 'g': return handle_switch_g(arg
, next
);
1112 case 'G': return handle_switch_G(arg
, next
);
1113 case 'I': return handle_switch_I(arg
, next
);
1114 case 'i': return handle_switch_i(arg
, next
);
1115 case 'M': return handle_switch_M(arg
, next
);
1116 case 'm': return handle_switch_m(arg
, next
);
1117 case 'n': return handle_switch_n(arg
, next
);
1118 case 'o': return handle_switch_o(arg
, next
);
1119 case 'O': return handle_switch_O(arg
, next
);
1120 case 's': return handle_switch_s(arg
, next
);
1121 case 'U': return handle_switch_U(arg
, next
);
1122 case 'v': return handle_switch_v(arg
, next
);
1123 case 'W': return handle_switch_W(arg
, next
);
1124 case 'x': return handle_switch_x(arg
, next
);
1125 case '-': return handle_long_options(arg
+ 1, next
);
1131 * Ignore unknown command line options:
1132 * they're probably gcc switches
1137 #define PTYPE_SIZEOF (1U << 0)
1138 #define PTYPE_T (1U << 1)
1139 #define PTYPE_MAX (1U << 2)
1140 #define PTYPE_MIN (1U << 3)
1141 #define PTYPE_WIDTH (1U << 4)
1142 #define PTYPE_TYPE (1U << 5)
1143 #define PTYPE_ALL (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH)
1144 #define PTYPE_ALL_T (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH|PTYPE_T)
1146 static void predefined_sizeof(const char *name
, const char *suffix
, unsigned bits
)
1150 snprintf(buf
, sizeof(buf
), "__SIZEOF_%s%s__", name
, suffix
);
1151 predefine(buf
, 1, "%d", bits
/8);
1154 static void predefined_width(const char *name
, unsigned bits
)
1158 snprintf(buf
, sizeof(buf
), "__%s_WIDTH__", name
);
1159 predefine(buf
, 1, "%d", bits
);
1162 static void predefined_max(const char *name
, struct symbol
*type
)
1164 const char *suffix
= builtin_type_suffix(type
);
1165 unsigned bits
= type
->bit_size
- is_signed_type(type
);
1166 unsigned long long max
= bits_mask(bits
);
1169 snprintf(buf
, sizeof(buf
), "__%s_MAX__", name
);
1170 predefine(buf
, 1, "%#llx%s", max
, suffix
);
1173 static void predefined_min(const char *name
, struct symbol
*type
)
1175 const char *suffix
= builtin_type_suffix(type
);
1178 snprintf(buf
, sizeof(buf
), "__%s_MIN__", name
);
1180 if (is_signed_type(type
))
1181 predefine(buf
, 1, "(-__%s_MAX__ - 1)", name
);
1183 predefine(buf
, 1, "0%s", suffix
);
1186 static void predefined_type(const char *name
, struct symbol
*type
)
1188 const char *typename
= builtin_typename(type
);
1189 add_pre_buffer("#weak_define __%s_TYPE__ %s\n", name
, typename
);
1192 static void predefined_ctype(const char *name
, struct symbol
*type
, int flags
)
1194 unsigned bits
= type
->bit_size
;
1196 if (flags
& PTYPE_SIZEOF
) {
1197 const char *suffix
= (flags
& PTYPE_T
) ? "_T" : "";
1198 predefined_sizeof(name
, suffix
, bits
);
1200 if (flags
& PTYPE_MAX
)
1201 predefined_max(name
, type
);
1202 if (flags
& PTYPE_MIN
)
1203 predefined_min(name
, type
);
1204 if (flags
& PTYPE_TYPE
)
1205 predefined_type(name
, type
);
1206 if (flags
& PTYPE_WIDTH
)
1207 predefined_width(name
, bits
);
1210 static void predefined_macros(void)
1212 predefine("__CHECKER__", 0, "1");
1213 predefine("__GNUC__", 1, "%d", gcc_major
);
1214 predefine("__GNUC_MINOR__", 1, "%d", gcc_minor
);
1215 predefine("__GNUC_PATCHLEVEL__", 1, "%d", gcc_patchlevel
);
1217 predefine("__STDC__", 1, "1");
1220 predefine("__STRICT_ANSI__", 1, "1");
1224 predefine("__STDC_VERSION__", 1, "199409L");
1225 predefine("__STRICT_ANSI__", 1, "1");
1229 predefine("__STDC_VERSION__", 1, "199901L");
1230 predefine("__STRICT_ANSI__", 1, "1");
1233 case STANDARD_GNU89
:
1237 case STANDARD_GNU99
:
1238 predefine("__STDC_VERSION__", 1, "199901L");
1242 predefine("__STRICT_ANSI__", 1, "1");
1243 case STANDARD_GNU11
:
1244 predefine("__STDC_NO_ATOMICS__", 1, "1");
1245 predefine("__STDC_NO_COMPLEX__", 1, "1");
1246 predefine("__STDC_NO_THREADS__", 1, "1");
1247 predefine("__STDC_VERSION__", 1, "201112L");
1251 predefine("__CHAR_BIT__", 1, "%d", bits_in_char
);
1253 predefine("__CHAR_UNSIGNED__", 1, "1");
1255 predefined_ctype("SHORT", &short_ctype
, PTYPE_SIZEOF
);
1256 predefined_ctype("SHRT", &short_ctype
, PTYPE_MAX
|PTYPE_WIDTH
);
1257 predefined_ctype("SCHAR", &schar_ctype
, PTYPE_MAX
|PTYPE_WIDTH
);
1258 predefined_ctype("WCHAR", wchar_ctype
, PTYPE_ALL_T
|PTYPE_MIN
|PTYPE_TYPE
);
1259 predefined_ctype("WINT", wint_ctype
, PTYPE_ALL_T
|PTYPE_MIN
|PTYPE_TYPE
);
1260 predefined_ctype("CHAR16", &ushort_ctype
, PTYPE_TYPE
);
1261 predefined_ctype("CHAR32", &uint_ctype
, PTYPE_TYPE
);
1263 predefined_ctype("INT", &int_ctype
, PTYPE_ALL
);
1264 predefined_ctype("LONG", &long_ctype
, PTYPE_ALL
);
1265 predefined_ctype("LONG_LONG", &llong_ctype
, PTYPE_ALL
);
1267 predefined_ctype("INT8", &schar_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1268 predefined_ctype("UINT8", &uchar_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1269 predefined_ctype("INT16", &short_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1270 predefined_ctype("UINT16", &ushort_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1271 predefined_ctype("INT32", int32_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1272 predefined_ctype("UINT32", uint32_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1273 predefined_ctype("INT64", int64_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1274 predefined_ctype("UINT64", uint64_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1276 predefined_sizeof("INT128", "", 128);
1278 predefined_ctype("INTMAX", intmax_ctype
, PTYPE_MAX
|PTYPE_TYPE
|PTYPE_WIDTH
);
1279 predefined_ctype("UINTMAX", uintmax_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1280 predefined_ctype("INTPTR", ssize_t_ctype
, PTYPE_MAX
|PTYPE_TYPE
|PTYPE_WIDTH
);
1281 predefined_ctype("UINTPTR", size_t_ctype
, PTYPE_MAX
|PTYPE_TYPE
);
1282 predefined_ctype("PTRDIFF", ssize_t_ctype
, PTYPE_ALL_T
|PTYPE_TYPE
);
1283 predefined_ctype("SIZE", size_t_ctype
, PTYPE_ALL_T
|PTYPE_TYPE
);
1284 predefined_ctype("POINTER", &ptr_ctype
, PTYPE_SIZEOF
);
1286 predefined_sizeof("FLOAT", "", bits_in_float
);
1287 predefined_sizeof("DOUBLE", "", bits_in_double
);
1288 predefined_sizeof("LONG_DOUBLE", "", bits_in_longdouble
);
1290 predefine("__ORDER_LITTLE_ENDIAN__", 1, "1234");
1291 predefine("__ORDER_BIG_ENDIAN__", 1, "4321");
1292 predefine("__ORDER_PDP_ENDIAN__", 1, "3412");
1293 if (arch_big_endian
) {
1294 predefine("__BIG_ENDIAN__", 1, "1");
1295 predefine("__BYTE_ORDER__", 1, "__ORDER_BIG_ENDIAN__");
1297 predefine("__LITTLE_ENDIAN__", 1, "1");
1298 predefine("__BYTE_ORDER__", 1, "__ORDER_LITTLE_ENDIAN__");
1302 predefine("__OPTIMIZE__", 0, "1");
1304 predefine("__OPTIMIZE_SIZE__", 0, "1");
1306 predefine("__PRAGMA_REDEFINE_EXTNAME", 1, "1");
1309 predefine("__extension__", 0, NULL
);
1310 predefine("__pragma__", 0, NULL
);
1316 predefine("__ILP32__", 1, "1");
1317 predefine("_ILP32", 1, "1");
1320 predefine("__LP64__", 1, "1");
1321 predefine("_LP64", 1, "1");
1324 predefine("__LLP64__", 1, "1");
1328 switch (arch_mach
) {
1330 predefine("__aarch64__", 1, "1");
1333 predefine("__arm__", 1, "1");
1336 predefine("__m68k__", 1, "1");
1339 if (arch_m64
== ARCH_LP64
)
1340 predefine("__mips64", 1, "64");
1343 predefine("__mips", 1, "%d", ptr_ctype
.bit_size
);
1344 predefine("_MIPS_SZINT", 1, "%d", int_ctype
.bit_size
);
1345 predefine("_MIPS_SZLONG", 1, "%d", long_ctype
.bit_size
);
1346 predefine("_MIPS_SZPTR", 1, "%d", ptr_ctype
.bit_size
);
1349 if (arch_m64
== ARCH_LP64
) {
1350 predefine("__powerpc64__", 1, "1");
1351 predefine("__ppc64__", 1, "1");
1352 predefine("__PPC64__", 1, "1");
1356 predefine("__powerpc__", 1, "1");
1357 predefine("__powerpc", 1, "1");
1358 predefine("__ppc__", 1, "1");
1359 predefine("__PPC__", 1, "1");
1363 predefine("__riscv", 1, "1");
1364 predefine("__riscv_xlen", 1, "%d", ptr_ctype
.bit_size
);
1367 predefine("__zarch__", 1, "1");
1368 predefine("__s390x__", 1, "1");
1369 predefine("__s390__", 1, "1");
1372 if (arch_m64
== ARCH_LP64
) {
1373 predefine("__sparc_v9__", 1, "1");
1374 predefine("__sparcv9__", 1, "1");
1375 predefine("__sparcv9", 1, "1");
1376 predefine("__sparc64__", 1, "1");
1377 predefine("__arch64__", 1, "1");
1381 predefine("__sparc__", 1, "1");
1382 predefine("__sparc", 1, "1");
1383 predefine_nostd("sparc");
1386 if (arch_m64
!= ARCH_LP32
) {
1387 predefine("__x86_64__", 1, "1");
1388 predefine("__x86_64", 1, "1");
1389 predefine("__amd64__", 1, "1");
1390 predefine("__amd64", 1, "1");
1395 predefine("__i386__", 1, "1");
1396 predefine("__i386", 1, "1");
1397 predefine_nostd("i386");
1401 #if defined(__unix__)
1402 predefine("__unix__", 1, "1");
1403 predefine("__unix", 1, "1");
1404 predefine_nostd("unix");
1408 #if defined(__sun__) || defined(__sun)
1409 predefine("__sun__", 1, "1");
1410 predefine("__sun", 1, "1");
1411 predefine_nostd("sun");
1412 predefine("__svr4__", 1, "1");
1417 static void create_builtin_stream(void)
1420 add_pre_buffer("#define _Pragma(x)\n");
1422 /* add the multiarch include directories, if any */
1423 if (multiarch_dir
&& *multiarch_dir
) {
1424 add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir
);
1425 add_pre_buffer("#add_system \"/usr/local/include/%s\"\n", multiarch_dir
);
1428 /* We add compiler headers path here because we have to parse
1429 * the arguments to get it, falling back to default. */
1430 add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir
);
1431 add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir
);
1433 add_pre_buffer("#define __has_builtin(x) 0\n");
1434 add_pre_buffer("#define __has_attribute(x) 0\n");
1435 add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
1436 add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
1437 add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n");
1438 add_pre_buffer("#define __builtin_va_arg(arg,type) ({ type __va_arg_ret = *(type *)(arg); arg += sizeof(type); __va_arg_ret; })\n");
1439 add_pre_buffer("#define __builtin_va_alist (*(void *)0)\n");
1440 add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n");
1441 add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n");
1442 add_pre_buffer("#define __builtin_ms_va_copy(dest, src) ({ dest = src; (void)0; })\n");
1443 add_pre_buffer("#define __builtin_va_end(arg)\n");
1444 add_pre_buffer("#define __builtin_ms_va_end(arg)\n");
1445 add_pre_buffer("#define __builtin_va_arg_pack()\n");
1448 static struct symbol_list
*sparse_tokenstream(struct token
*token
)
1450 int builtin
= token
&& !token
->pos
.stream
;
1452 // Preprocess the stream
1453 token
= preprocess(token
);
1455 if (dump_macro_defs
|| dump_macros_only
) {
1457 dump_macro_definitions();
1458 if (dump_macros_only
)
1462 if (preprocess_only
) {
1463 while (!eof_token(token
)) {
1465 struct token
*next
= token
->next
;
1466 const char *separator
= "";
1467 if (next
->pos
.whitespace
)
1469 if (next
->pos
.newline
) {
1470 separator
= "\n\t\t\t\t\t";
1471 prec
= next
->pos
.pos
;
1475 printf("%s%.*s", show_token(token
), prec
, separator
);
1483 // Parse the resulting C code
1484 while (!eof_token(token
))
1485 token
= external_declaration(token
, &translation_unit_used_list
, NULL
);
1486 return translation_unit_used_list
;
1489 static struct symbol_list
*sparse_file(const char *filename
)
1492 struct token
*token
;
1494 if (strcmp (filename
, "-") == 0) {
1497 fd
= open(filename
, O_RDONLY
);
1499 die("No such file: %s", filename
);
1501 base_filename
= filename
;
1503 // Tokenize the input stream
1504 token
= tokenize(filename
, fd
, NULL
, includepath
);
1505 store_all_tokens(token
);
1508 return sparse_tokenstream(token
);
1512 * This handles the "-include" directive etc: we're in global
1513 * scope, and all types/macros etc will affect all the following
1516 * NOTE NOTE NOTE! "#undef" of anything in this stage will
1517 * affect all subsequent files too, i.e. we can have non-local
1518 * behaviour between files!
1520 static struct symbol_list
*sparse_initial(void)
1524 // Prepend any "include" file to the stream.
1525 // We're in global scope, it will affect all files!
1526 for (i
= 0; i
< cmdline_include_nr
; i
++)
1527 add_pre_buffer("#argv_include \"%s\"\n", cmdline_include
[i
]);
1529 return sparse_tokenstream(pre_buffer_begin
);
1532 struct symbol_list
*sparse_initialize(int argc
, char **argv
, struct string_list
**filelist
)
1535 struct symbol_list
*list
;
1537 // Initialize symbol stream first, so that we can add defines etc
1539 init_include_path();
1543 char *arg
= *++args
;
1547 if (arg
[0] == '-' && arg
[1]) {
1548 args
= handle_switch(arg
+1, args
);
1551 add_ptr_list(filelist
, arg
);
1553 handle_switch_W_finalize();
1554 handle_switch_v_finalize();
1556 // Redirect stdout if needed
1557 if (dump_macro_defs
|| preprocess_only
)
1559 if (do_output
&& outfile
&& strcmp(outfile
, "-")) {
1560 if (!freopen(outfile
, "w", stdout
))
1561 die("error: cannot open %s: %s", outfile
, strerror(errno
));
1565 fdump_ir
= PASS_FINAL
;
1569 // Initialize type system
1571 handle_arch_finalize();
1574 predefined_macros();
1575 create_builtin_stream();
1578 list
= sparse_initial();
1581 * Protect the initial token allocations, since
1582 * they need to survive all the others
1584 protect_token_alloc();
1587 * Evaluate the complete symbol list
1588 * Note: This is not needed for normal cases.
1589 * These symbols should only be predefined defines and
1590 * declaratons which will be evaluated later, when needed.
1591 * This is also the case when a file is directly included via
1592 * '-include <file>' on the command line *AND* the file only
1593 * contains defines, declarations and inline definitions.
1594 * However, in the rare cases where the given file should
1595 * contain some definitions, these will never be evaluated
1596 * and thus won't be able to be linearized correctly.
1597 * Hence the evaluate_symbol_list() here under.
1599 evaluate_symbol_list(list
);
1603 struct symbol_list
* sparse_keep_tokens(char *filename
)
1605 struct symbol_list
*res
;
1607 /* Clear previous symbol list */
1608 translation_unit_used_list
= NULL
;
1611 res
= sparse_file(filename
);
1618 struct symbol_list
* __sparse(char *filename
)
1620 struct symbol_list
*res
;
1622 res
= sparse_keep_tokens(filename
);
1624 /* Drop the tokens for this file after parsing */
1625 clear_token_alloc();
1631 struct symbol_list
* sparse(char *filename
)
1633 struct symbol_list
*res
= __sparse(filename
);
1635 if (has_error
& ERROR_CURR_PHASE
)
1636 has_error
= ERROR_PREV_PHASE
;
1637 /* Evaluate the complete symbol list */
1638 evaluate_symbol_list(res
);