1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: MIT 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * 'sparse' library helper routines. 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp. 6f08c3bdfSopenharmony_ci * 2003-2004 Linus Torvalds 7f08c3bdfSopenharmony_ci * 2017-2020 Luc Van Oostenryck 8f08c3bdfSopenharmony_ci */ 9f08c3bdfSopenharmony_ci 10f08c3bdfSopenharmony_ci#include "options.h" 11f08c3bdfSopenharmony_ci#include "lib.h" 12f08c3bdfSopenharmony_ci#include "machine.h" 13f08c3bdfSopenharmony_ci#include "target.h" 14f08c3bdfSopenharmony_ci#include <ctype.h> 15f08c3bdfSopenharmony_ci#include <stdio.h> 16f08c3bdfSopenharmony_ci#include <stdlib.h> 17f08c3bdfSopenharmony_ci#include <string.h> 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#ifndef __GNUC__ 21f08c3bdfSopenharmony_ci# define __GNUC__ 2 22f08c3bdfSopenharmony_ci# define __GNUC_MINOR__ 95 23f08c3bdfSopenharmony_ci# define __GNUC_PATCHLEVEL__ 0 24f08c3bdfSopenharmony_ci#endif 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_cienum flag_type { 27f08c3bdfSopenharmony_ci FLAG_OFF, 28f08c3bdfSopenharmony_ci FLAG_ON, 29f08c3bdfSopenharmony_ci FLAG_FORCE_OFF 30f08c3bdfSopenharmony_ci}; 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_ciint die_if_error = 0; 33f08c3bdfSopenharmony_ciint do_output = 1; 34f08c3bdfSopenharmony_ciint gcc_major = __GNUC__; 35f08c3bdfSopenharmony_ciint gcc_minor = __GNUC_MINOR__; 36f08c3bdfSopenharmony_ciint gcc_patchlevel = __GNUC_PATCHLEVEL__; 37f08c3bdfSopenharmony_ciint has_error = 0; 38f08c3bdfSopenharmony_ciint optimize_level; 39f08c3bdfSopenharmony_ciint optimize_size; 40f08c3bdfSopenharmony_ciint preprocess_only; 41f08c3bdfSopenharmony_ciint preprocessing; 42f08c3bdfSopenharmony_ciint verbose; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci#define CMDLINE_INCLUDE 20 45f08c3bdfSopenharmony_ciint cmdline_include_nr = 0; 46f08c3bdfSopenharmony_cichar *cmdline_include[CMDLINE_INCLUDE]; 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ciconst char *base_filename; 49f08c3bdfSopenharmony_ciconst char *diag_prefix = ""; 50f08c3bdfSopenharmony_ciconst char *gcc_base_dir = GCC_BASE; 51f08c3bdfSopenharmony_ciconst char *multiarch_dir = MULTIARCH_TRIPLET; 52f08c3bdfSopenharmony_ciconst char *outfile = NULL; 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_cienum standard standard = STANDARD_GNU89; 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ciint arch_big_endian = ARCH_BIG_ENDIAN; 57f08c3bdfSopenharmony_ciint arch_cmodel = CMODEL_UNKNOWN; 58f08c3bdfSopenharmony_ciint arch_fp_abi = FP_ABI_NATIVE; 59f08c3bdfSopenharmony_ciint arch_m64 = ARCH_M64_DEFAULT; 60f08c3bdfSopenharmony_ciint arch_msize_long = 0; 61f08c3bdfSopenharmony_ciint arch_os = OS_NATIVE; 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ciint dbg_compound = 0; 64f08c3bdfSopenharmony_ciint dbg_dead = 0; 65f08c3bdfSopenharmony_ciint dbg_domtree = 0; 66f08c3bdfSopenharmony_ciint dbg_entry = 0; 67f08c3bdfSopenharmony_ciint dbg_ir = 0; 68f08c3bdfSopenharmony_ciint dbg_postorder = 0; 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ciint dump_macro_defs = 0; 71f08c3bdfSopenharmony_ciint dump_macros_only = 0; 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ciunsigned long fdump_ir; 74f08c3bdfSopenharmony_ciint fhosted = 1; 75f08c3bdfSopenharmony_ciunsigned int fmax_errors = 100; 76f08c3bdfSopenharmony_ciunsigned int fmax_warnings = 100; 77f08c3bdfSopenharmony_ciint fmem_report = 0; 78f08c3bdfSopenharmony_ciunsigned long long fmemcpy_max_count = 100000; 79f08c3bdfSopenharmony_ciunsigned long fpasses = ~0UL; 80f08c3bdfSopenharmony_ciint fpic = 0; 81f08c3bdfSopenharmony_ciint fpie = 0; 82f08c3bdfSopenharmony_ciint fshort_wchar = 0; 83f08c3bdfSopenharmony_ciint funsigned_bitfields = 0; 84f08c3bdfSopenharmony_ciint funsigned_char = 0; 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ciint Waddress = 0; 87f08c3bdfSopenharmony_ciint Waddress_space = 1; 88f08c3bdfSopenharmony_ciint Wbitwise = 1; 89f08c3bdfSopenharmony_ciint Wbitwise_pointer = 0; 90f08c3bdfSopenharmony_ciint Wcast_from_as = 0; 91f08c3bdfSopenharmony_ciint Wcast_to_as = 0; 92f08c3bdfSopenharmony_ciint Wcast_truncate = 1; 93f08c3bdfSopenharmony_ciint Wconstant_suffix = 0; 94f08c3bdfSopenharmony_ciint Wconstexpr_not_const = 0; 95f08c3bdfSopenharmony_ciint Wcontext = 1; 96f08c3bdfSopenharmony_ciint Wdecl = 1; 97f08c3bdfSopenharmony_ciint Wdeclarationafterstatement = -1; 98f08c3bdfSopenharmony_ciint Wdefault_bitfield_sign = 0; 99f08c3bdfSopenharmony_ciint Wdesignated_init = 1; 100f08c3bdfSopenharmony_ciint Wdo_while = 0; 101f08c3bdfSopenharmony_ciint Wenum_mismatch = 1; 102f08c3bdfSopenharmony_ciint Wexternal_function_has_definition = 1; 103f08c3bdfSopenharmony_ciint Wflexible_array_array = 1; 104f08c3bdfSopenharmony_ciint Wflexible_array_nested = 0; 105f08c3bdfSopenharmony_ciint Wflexible_array_sizeof = 0; 106f08c3bdfSopenharmony_ciint Wflexible_array_union = 0; 107f08c3bdfSopenharmony_ciint Wimplicit_int = 1; 108f08c3bdfSopenharmony_ciint Winit_cstring = 0; 109f08c3bdfSopenharmony_ciint Wint_to_pointer_cast = 1; 110f08c3bdfSopenharmony_ciint Wmemcpy_max_count = 1; 111f08c3bdfSopenharmony_ciint Wnewline_eof = 1; 112f08c3bdfSopenharmony_ciint Wnon_pointer_null = 1; 113f08c3bdfSopenharmony_ciint Wold_initializer = 1; 114f08c3bdfSopenharmony_ciint Wold_style_definition = 1; 115f08c3bdfSopenharmony_ciint Wone_bit_signed_bitfield = 1; 116f08c3bdfSopenharmony_ciint Woverride_init = 1; 117f08c3bdfSopenharmony_ciint Woverride_init_all = 0; 118f08c3bdfSopenharmony_ciint Woverride_init_whole_range = 0; 119f08c3bdfSopenharmony_ciint Wparen_string = 0; 120f08c3bdfSopenharmony_ciint Wpast_deep_designator = 0; 121f08c3bdfSopenharmony_ciint Wpedantic = 0; 122f08c3bdfSopenharmony_ciint Wpointer_arith = 0; 123f08c3bdfSopenharmony_ciint Wpointer_to_int_cast = 1; 124f08c3bdfSopenharmony_ciint Wptr_subtraction_blows = 0; 125f08c3bdfSopenharmony_ciint Wreturn_void = 0; 126f08c3bdfSopenharmony_ciint Wshadow = 0; 127f08c3bdfSopenharmony_ciint Wshift_count_negative = 1; 128f08c3bdfSopenharmony_ciint Wshift_count_overflow = 1; 129f08c3bdfSopenharmony_ciint Wsizeof_bool = 0; 130f08c3bdfSopenharmony_ciint Wsparse_error = FLAG_FORCE_OFF; 131f08c3bdfSopenharmony_ciint Wstrict_prototypes = 1; 132f08c3bdfSopenharmony_ciint Wtautological_compare = 0; 133f08c3bdfSopenharmony_ciint Wtransparent_union = 0; 134f08c3bdfSopenharmony_ciint Wtypesign = 0; 135f08c3bdfSopenharmony_ciint Wundef = 0; 136f08c3bdfSopenharmony_ciint Wuninitialized = 1; 137f08c3bdfSopenharmony_ciint Wunion_cast = 0; 138f08c3bdfSopenharmony_ciint Wuniversal_initializer = 0; 139f08c3bdfSopenharmony_ciint Wunknown_attribute = 0; 140f08c3bdfSopenharmony_ciint Wvla = 1; 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 143f08c3bdfSopenharmony_ci// Helpers for option parsing 144f08c3bdfSopenharmony_ci 145f08c3bdfSopenharmony_cistatic const char *match_option(const char *arg, const char *prefix) 146f08c3bdfSopenharmony_ci{ 147f08c3bdfSopenharmony_ci unsigned int n = strlen(prefix); 148f08c3bdfSopenharmony_ci if (strncmp(arg, prefix, n) == 0) 149f08c3bdfSopenharmony_ci return arg + n; 150f08c3bdfSopenharmony_ci return NULL; 151f08c3bdfSopenharmony_ci} 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci 154f08c3bdfSopenharmony_cistruct val_map { 155f08c3bdfSopenharmony_ci const char *name; 156f08c3bdfSopenharmony_ci int val; 157f08c3bdfSopenharmony_ci}; 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_cistatic int handle_subopt_val(const char *opt, const char *arg, const struct val_map *map, int *flag) 160f08c3bdfSopenharmony_ci{ 161f08c3bdfSopenharmony_ci const char *name; 162f08c3bdfSopenharmony_ci 163f08c3bdfSopenharmony_ci if (*arg++ != '=') 164f08c3bdfSopenharmony_ci die("missing argument for option '%s'", opt); 165f08c3bdfSopenharmony_ci for (;(name = map->name); map++) { 166f08c3bdfSopenharmony_ci if (strcmp(name, arg) == 0 || strcmp(name, "*") == 0) { 167f08c3bdfSopenharmony_ci *flag = map->val; 168f08c3bdfSopenharmony_ci return 1; 169f08c3bdfSopenharmony_ci } 170f08c3bdfSopenharmony_ci if (strcmp(name, "?") == 0) 171f08c3bdfSopenharmony_ci die("invalid argument '%s' in option '%s'", arg, opt); 172f08c3bdfSopenharmony_ci } 173f08c3bdfSopenharmony_ci return 0; 174f08c3bdfSopenharmony_ci} 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_cistruct mask_map { 178f08c3bdfSopenharmony_ci const char *name; 179f08c3bdfSopenharmony_ci unsigned long mask; 180f08c3bdfSopenharmony_ci}; 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_cistatic int apply_mask(unsigned long *val, const char *str, unsigned len, const struct mask_map *map, int neg) 183f08c3bdfSopenharmony_ci{ 184f08c3bdfSopenharmony_ci const char *name; 185f08c3bdfSopenharmony_ci 186f08c3bdfSopenharmony_ci for (;(name = map->name); map++) { 187f08c3bdfSopenharmony_ci if (!strncmp(name, str, len) && !name[len]) { 188f08c3bdfSopenharmony_ci if (neg == 0) 189f08c3bdfSopenharmony_ci *val |= map->mask; 190f08c3bdfSopenharmony_ci else 191f08c3bdfSopenharmony_ci *val &= ~map->mask; 192f08c3bdfSopenharmony_ci return 0; 193f08c3bdfSopenharmony_ci } 194f08c3bdfSopenharmony_ci } 195f08c3bdfSopenharmony_ci return 1; 196f08c3bdfSopenharmony_ci} 197f08c3bdfSopenharmony_ci 198f08c3bdfSopenharmony_cistatic int handle_suboption_mask(const char *arg, const char *opt, const struct mask_map *map, unsigned long *flag) 199f08c3bdfSopenharmony_ci{ 200f08c3bdfSopenharmony_ci if (*opt == '\0') { 201f08c3bdfSopenharmony_ci apply_mask(flag, "", 0, map, 0); 202f08c3bdfSopenharmony_ci return 1; 203f08c3bdfSopenharmony_ci } 204f08c3bdfSopenharmony_ci if (*opt++ != '=') 205f08c3bdfSopenharmony_ci return 0; 206f08c3bdfSopenharmony_ci while (1) { 207f08c3bdfSopenharmony_ci unsigned int len = strcspn(opt, ",+"); 208f08c3bdfSopenharmony_ci int neg = 0; 209f08c3bdfSopenharmony_ci if (len == 0) 210f08c3bdfSopenharmony_ci goto end; 211f08c3bdfSopenharmony_ci if (!strncmp(opt, "no-", 3)) { 212f08c3bdfSopenharmony_ci opt += 3; 213f08c3bdfSopenharmony_ci len -= 3; 214f08c3bdfSopenharmony_ci neg = 1; 215f08c3bdfSopenharmony_ci } 216f08c3bdfSopenharmony_ci if (apply_mask(flag, opt, len, map, neg)) 217f08c3bdfSopenharmony_ci die("error: wrong option '%.*s' for \'%s\'", len, opt, arg); 218f08c3bdfSopenharmony_ci 219f08c3bdfSopenharmony_ciend: 220f08c3bdfSopenharmony_ci opt += len; 221f08c3bdfSopenharmony_ci if (*opt++ == '\0') 222f08c3bdfSopenharmony_ci break; 223f08c3bdfSopenharmony_ci } 224f08c3bdfSopenharmony_ci return 1; 225f08c3bdfSopenharmony_ci} 226f08c3bdfSopenharmony_ci 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci#define OPT_INVERSE 1 229f08c3bdfSopenharmony_ci#define OPT_VAL 2 230f08c3bdfSopenharmony_cistruct flag { 231f08c3bdfSopenharmony_ci const char *name; 232f08c3bdfSopenharmony_ci int *flag; 233f08c3bdfSopenharmony_ci int (*fun)(const char *arg, const char *opt, const struct flag *, int options); 234f08c3bdfSopenharmony_ci unsigned long mask; 235f08c3bdfSopenharmony_ci int val; 236f08c3bdfSopenharmony_ci}; 237f08c3bdfSopenharmony_ci 238f08c3bdfSopenharmony_cistatic int handle_switches(const char *ori, const char *opt, const struct flag *flags) 239f08c3bdfSopenharmony_ci{ 240f08c3bdfSopenharmony_ci const char *arg = opt; 241f08c3bdfSopenharmony_ci int val = 1; 242f08c3bdfSopenharmony_ci 243f08c3bdfSopenharmony_ci // Prefixe "no-" mean to turn flag off. 244f08c3bdfSopenharmony_ci if (strncmp(arg, "no-", 3) == 0) { 245f08c3bdfSopenharmony_ci arg += 3; 246f08c3bdfSopenharmony_ci val = 0; 247f08c3bdfSopenharmony_ci } 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci for (; flags->name; flags++) { 250f08c3bdfSopenharmony_ci const char *opt = match_option(arg, flags->name); 251f08c3bdfSopenharmony_ci int rc; 252f08c3bdfSopenharmony_ci 253f08c3bdfSopenharmony_ci if (!opt) 254f08c3bdfSopenharmony_ci continue; 255f08c3bdfSopenharmony_ci 256f08c3bdfSopenharmony_ci if (flags->fun) { 257f08c3bdfSopenharmony_ci int options = 0; 258f08c3bdfSopenharmony_ci if (!val) 259f08c3bdfSopenharmony_ci options |= OPT_INVERSE; 260f08c3bdfSopenharmony_ci if ((rc = flags->fun(ori, opt, flags, options))) 261f08c3bdfSopenharmony_ci return rc; 262f08c3bdfSopenharmony_ci } 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci // boolean flag 265f08c3bdfSopenharmony_ci if (opt[0] == '\0' && flags->flag) { 266f08c3bdfSopenharmony_ci if (flags->mask & OPT_VAL) 267f08c3bdfSopenharmony_ci val = flags->val; 268f08c3bdfSopenharmony_ci if (flags->mask & OPT_INVERSE) 269f08c3bdfSopenharmony_ci val = !val; 270f08c3bdfSopenharmony_ci *flags->flag = val; 271f08c3bdfSopenharmony_ci return 1; 272f08c3bdfSopenharmony_ci } 273f08c3bdfSopenharmony_ci } 274f08c3bdfSopenharmony_ci 275f08c3bdfSopenharmony_ci // not handled 276f08c3bdfSopenharmony_ci return 0; 277f08c3bdfSopenharmony_ci} 278f08c3bdfSopenharmony_ci 279f08c3bdfSopenharmony_cistatic char **handle_onoff_switch(char *arg, char **next, const struct flag flags[]) 280f08c3bdfSopenharmony_ci{ 281f08c3bdfSopenharmony_ci int flag = FLAG_ON; 282f08c3bdfSopenharmony_ci char *p = arg + 1; 283f08c3bdfSopenharmony_ci unsigned i; 284f08c3bdfSopenharmony_ci 285f08c3bdfSopenharmony_ci // Prefixes "no" and "no-" mean to turn warning off. 286f08c3bdfSopenharmony_ci if (p[0] == 'n' && p[1] == 'o') { 287f08c3bdfSopenharmony_ci p += 2; 288f08c3bdfSopenharmony_ci if (p[0] == '-') 289f08c3bdfSopenharmony_ci p++; 290f08c3bdfSopenharmony_ci flag = FLAG_FORCE_OFF; 291f08c3bdfSopenharmony_ci } 292f08c3bdfSopenharmony_ci 293f08c3bdfSopenharmony_ci for (i = 0; flags[i].name; i++) { 294f08c3bdfSopenharmony_ci if (!strcmp(p,flags[i].name)) { 295f08c3bdfSopenharmony_ci *flags[i].flag = flag; 296f08c3bdfSopenharmony_ci return next; 297f08c3bdfSopenharmony_ci } 298f08c3bdfSopenharmony_ci } 299f08c3bdfSopenharmony_ci 300f08c3bdfSopenharmony_ci // Unknown. 301f08c3bdfSopenharmony_ci return NULL; 302f08c3bdfSopenharmony_ci} 303f08c3bdfSopenharmony_ci 304f08c3bdfSopenharmony_cistatic void handle_onoff_switch_finalize(const struct flag flags[]) 305f08c3bdfSopenharmony_ci{ 306f08c3bdfSopenharmony_ci unsigned i; 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_ci for (i = 0; flags[i].name; i++) { 309f08c3bdfSopenharmony_ci if (*flags[i].flag == FLAG_FORCE_OFF) 310f08c3bdfSopenharmony_ci *flags[i].flag = FLAG_OFF; 311f08c3bdfSopenharmony_ci } 312f08c3bdfSopenharmony_ci} 313f08c3bdfSopenharmony_ci 314f08c3bdfSopenharmony_cistatic int handle_switch_setval(const char *arg, const char *opt, const struct flag *flag, int options) 315f08c3bdfSopenharmony_ci{ 316f08c3bdfSopenharmony_ci *(flag->flag) = flag->mask; 317f08c3bdfSopenharmony_ci return 1; 318f08c3bdfSopenharmony_ci} 319f08c3bdfSopenharmony_ci 320f08c3bdfSopenharmony_ci 321f08c3bdfSopenharmony_ci#define OPTNUM_ZERO_IS_INF 1 322f08c3bdfSopenharmony_ci#define OPTNUM_UNLIMITED 2 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_ci#define OPT_NUMERIC(NAME, TYPE, FUNCTION) \ 325f08c3bdfSopenharmony_cistatic int opt_##NAME(const char *arg, const char *opt, TYPE *ptr, int flag) \ 326f08c3bdfSopenharmony_ci{ \ 327f08c3bdfSopenharmony_ci char *end; \ 328f08c3bdfSopenharmony_ci TYPE val; \ 329f08c3bdfSopenharmony_ci \ 330f08c3bdfSopenharmony_ci val = FUNCTION(opt, &end, 0); \ 331f08c3bdfSopenharmony_ci if (*end != '\0' || end == opt) { \ 332f08c3bdfSopenharmony_ci if ((flag & OPTNUM_UNLIMITED) && !strcmp(opt, "unlimited")) \ 333f08c3bdfSopenharmony_ci val = ~val; \ 334f08c3bdfSopenharmony_ci else \ 335f08c3bdfSopenharmony_ci die("error: wrong argument to \'%s\'", arg); \ 336f08c3bdfSopenharmony_ci } \ 337f08c3bdfSopenharmony_ci if ((flag & OPTNUM_ZERO_IS_INF) && val == 0) \ 338f08c3bdfSopenharmony_ci val = ~val; \ 339f08c3bdfSopenharmony_ci *ptr = val; \ 340f08c3bdfSopenharmony_ci return 1; \ 341f08c3bdfSopenharmony_ci} 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_ciOPT_NUMERIC(ullong, unsigned long long, strtoull) 344f08c3bdfSopenharmony_ciOPT_NUMERIC(uint, unsigned int, strtoul) 345f08c3bdfSopenharmony_ci 346f08c3bdfSopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 347f08c3bdfSopenharmony_ci// Option parsing 348f08c3bdfSopenharmony_ci 349f08c3bdfSopenharmony_cistatic char **handle_switch_a(char *arg, char **next) 350f08c3bdfSopenharmony_ci{ 351f08c3bdfSopenharmony_ci if (!strcmp(arg, "ansi")) 352f08c3bdfSopenharmony_ci standard = STANDARD_C89; 353f08c3bdfSopenharmony_ci 354f08c3bdfSopenharmony_ci return next; 355f08c3bdfSopenharmony_ci} 356f08c3bdfSopenharmony_ci 357f08c3bdfSopenharmony_cistatic char **handle_switch_D(char *arg, char **next) 358f08c3bdfSopenharmony_ci{ 359f08c3bdfSopenharmony_ci const char *name = arg + 1; 360f08c3bdfSopenharmony_ci const char *value = "1"; 361f08c3bdfSopenharmony_ci 362f08c3bdfSopenharmony_ci if (!*name) { 363f08c3bdfSopenharmony_ci arg = *++next; 364f08c3bdfSopenharmony_ci if (!arg) 365f08c3bdfSopenharmony_ci die("argument to `-D' is missing"); 366f08c3bdfSopenharmony_ci name = arg; 367f08c3bdfSopenharmony_ci } 368f08c3bdfSopenharmony_ci 369f08c3bdfSopenharmony_ci for (;;arg++) { 370f08c3bdfSopenharmony_ci char c; 371f08c3bdfSopenharmony_ci c = *arg; 372f08c3bdfSopenharmony_ci if (!c) 373f08c3bdfSopenharmony_ci break; 374f08c3bdfSopenharmony_ci if (c == '=') { 375f08c3bdfSopenharmony_ci *arg = '\0'; 376f08c3bdfSopenharmony_ci value = arg + 1; 377f08c3bdfSopenharmony_ci break; 378f08c3bdfSopenharmony_ci } 379f08c3bdfSopenharmony_ci } 380f08c3bdfSopenharmony_ci add_pre_buffer("#define %s %s\n", name, value); 381f08c3bdfSopenharmony_ci return next; 382f08c3bdfSopenharmony_ci} 383f08c3bdfSopenharmony_ci 384f08c3bdfSopenharmony_cistatic char **handle_switch_d(char *arg, char **next) 385f08c3bdfSopenharmony_ci{ 386f08c3bdfSopenharmony_ci char *arg_char = arg + 1; 387f08c3bdfSopenharmony_ci 388f08c3bdfSopenharmony_ci /* 389f08c3bdfSopenharmony_ci * -d<CHARS>, where <CHARS> is a sequence of characters, not preceded 390f08c3bdfSopenharmony_ci * by a space. If you specify characters whose behaviour conflicts, 391f08c3bdfSopenharmony_ci * the result is undefined. 392f08c3bdfSopenharmony_ci */ 393f08c3bdfSopenharmony_ci while (*arg_char) { 394f08c3bdfSopenharmony_ci switch (*arg_char) { 395f08c3bdfSopenharmony_ci case 'M': /* dump just the macro definitions */ 396f08c3bdfSopenharmony_ci dump_macros_only = 1; 397f08c3bdfSopenharmony_ci dump_macro_defs = 0; 398f08c3bdfSopenharmony_ci break; 399f08c3bdfSopenharmony_ci case 'D': /* like 'M', but also output pre-processed text */ 400f08c3bdfSopenharmony_ci dump_macro_defs = 1; 401f08c3bdfSopenharmony_ci dump_macros_only = 0; 402f08c3bdfSopenharmony_ci break; 403f08c3bdfSopenharmony_ci case 'N': /* like 'D', but only output macro names not bodies */ 404f08c3bdfSopenharmony_ci break; 405f08c3bdfSopenharmony_ci case 'I': /* like 'D', but also output #include directives */ 406f08c3bdfSopenharmony_ci break; 407f08c3bdfSopenharmony_ci case 'U': /* like 'D', but only output expanded macros */ 408f08c3bdfSopenharmony_ci break; 409f08c3bdfSopenharmony_ci } 410f08c3bdfSopenharmony_ci arg_char++; 411f08c3bdfSopenharmony_ci } 412f08c3bdfSopenharmony_ci return next; 413f08c3bdfSopenharmony_ci} 414f08c3bdfSopenharmony_ci 415f08c3bdfSopenharmony_cistatic char **handle_switch_E(char *arg, char **next) 416f08c3bdfSopenharmony_ci{ 417f08c3bdfSopenharmony_ci if (arg[1] == '\0') 418f08c3bdfSopenharmony_ci preprocess_only = 1; 419f08c3bdfSopenharmony_ci return next; 420f08c3bdfSopenharmony_ci} 421f08c3bdfSopenharmony_ci 422f08c3bdfSopenharmony_cistatic int handle_ftabstop(const char *arg, const char *opt, const struct flag *flag, int options) 423f08c3bdfSopenharmony_ci{ 424f08c3bdfSopenharmony_ci unsigned long val; 425f08c3bdfSopenharmony_ci char *end; 426f08c3bdfSopenharmony_ci 427f08c3bdfSopenharmony_ci if (*opt == '\0') 428f08c3bdfSopenharmony_ci die("error: missing argument to \"%s\"", arg); 429f08c3bdfSopenharmony_ci 430f08c3bdfSopenharmony_ci /* we silently ignore silly values */ 431f08c3bdfSopenharmony_ci val = strtoul(opt, &end, 10); 432f08c3bdfSopenharmony_ci if (*end == '\0' && 1 <= val && val <= 100) 433f08c3bdfSopenharmony_ci tabstop = val; 434f08c3bdfSopenharmony_ci 435f08c3bdfSopenharmony_ci return 1; 436f08c3bdfSopenharmony_ci} 437f08c3bdfSopenharmony_ci 438f08c3bdfSopenharmony_cistatic int handle_fpasses(const char *arg, const char *opt, const struct flag *flag, int options) 439f08c3bdfSopenharmony_ci{ 440f08c3bdfSopenharmony_ci unsigned long mask; 441f08c3bdfSopenharmony_ci 442f08c3bdfSopenharmony_ci mask = flag->mask; 443f08c3bdfSopenharmony_ci if (*opt == '\0') { 444f08c3bdfSopenharmony_ci if (options & OPT_INVERSE) 445f08c3bdfSopenharmony_ci fpasses &= ~mask; 446f08c3bdfSopenharmony_ci else 447f08c3bdfSopenharmony_ci fpasses |= mask; 448f08c3bdfSopenharmony_ci return 1; 449f08c3bdfSopenharmony_ci } 450f08c3bdfSopenharmony_ci if (options & OPT_INVERSE) 451f08c3bdfSopenharmony_ci return 0; 452f08c3bdfSopenharmony_ci if (!strcmp(opt, "-enable")) { 453f08c3bdfSopenharmony_ci fpasses |= mask; 454f08c3bdfSopenharmony_ci return 1; 455f08c3bdfSopenharmony_ci } 456f08c3bdfSopenharmony_ci if (!strcmp(opt, "-disable")) { 457f08c3bdfSopenharmony_ci fpasses &= ~mask; 458f08c3bdfSopenharmony_ci return 1; 459f08c3bdfSopenharmony_ci } 460f08c3bdfSopenharmony_ci if (!strcmp(opt, "=last")) { 461f08c3bdfSopenharmony_ci // clear everything above 462f08c3bdfSopenharmony_ci mask |= mask - 1; 463f08c3bdfSopenharmony_ci fpasses &= mask; 464f08c3bdfSopenharmony_ci return 1; 465f08c3bdfSopenharmony_ci } 466f08c3bdfSopenharmony_ci return 0; 467f08c3bdfSopenharmony_ci} 468f08c3bdfSopenharmony_ci 469f08c3bdfSopenharmony_cistatic int handle_fdiagnostic_prefix(const char *arg, const char *opt, const struct flag *flag, int options) 470f08c3bdfSopenharmony_ci{ 471f08c3bdfSopenharmony_ci switch (*opt) { 472f08c3bdfSopenharmony_ci case '\0': 473f08c3bdfSopenharmony_ci diag_prefix = "sparse: "; 474f08c3bdfSopenharmony_ci return 1; 475f08c3bdfSopenharmony_ci case '=': 476f08c3bdfSopenharmony_ci diag_prefix = xasprintf("%s: ", opt+1); 477f08c3bdfSopenharmony_ci return 1; 478f08c3bdfSopenharmony_ci default: 479f08c3bdfSopenharmony_ci return 0; 480f08c3bdfSopenharmony_ci } 481f08c3bdfSopenharmony_ci} 482f08c3bdfSopenharmony_ci 483f08c3bdfSopenharmony_cistatic int handle_fdump_ir(const char *arg, const char *opt, const struct flag *flag, int options) 484f08c3bdfSopenharmony_ci{ 485f08c3bdfSopenharmony_ci static const struct mask_map dump_ir_options[] = { 486f08c3bdfSopenharmony_ci { "", PASS_LINEARIZE }, 487f08c3bdfSopenharmony_ci { "linearize", PASS_LINEARIZE }, 488f08c3bdfSopenharmony_ci { "mem2reg", PASS_MEM2REG }, 489f08c3bdfSopenharmony_ci { "final", PASS_FINAL }, 490f08c3bdfSopenharmony_ci { }, 491f08c3bdfSopenharmony_ci }; 492f08c3bdfSopenharmony_ci 493f08c3bdfSopenharmony_ci return handle_suboption_mask(arg, opt, dump_ir_options, &fdump_ir); 494f08c3bdfSopenharmony_ci} 495f08c3bdfSopenharmony_ci 496f08c3bdfSopenharmony_cistatic int handle_fmemcpy_max_count(const char *arg, const char *opt, const struct flag *flag, int options) 497f08c3bdfSopenharmony_ci{ 498f08c3bdfSopenharmony_ci opt_ullong(arg, opt, &fmemcpy_max_count, OPTNUM_ZERO_IS_INF|OPTNUM_UNLIMITED); 499f08c3bdfSopenharmony_ci return 1; 500f08c3bdfSopenharmony_ci} 501f08c3bdfSopenharmony_ci 502f08c3bdfSopenharmony_cistatic int handle_fmax_errors(const char *arg, const char *opt, const struct flag *flag, int options) 503f08c3bdfSopenharmony_ci{ 504f08c3bdfSopenharmony_ci opt_uint(arg, opt, &fmax_errors, OPTNUM_UNLIMITED); 505f08c3bdfSopenharmony_ci return 1; 506f08c3bdfSopenharmony_ci} 507f08c3bdfSopenharmony_ci 508f08c3bdfSopenharmony_cistatic int handle_fmax_warnings(const char *arg, const char *opt, const struct flag *flag, int options) 509f08c3bdfSopenharmony_ci{ 510f08c3bdfSopenharmony_ci opt_uint(arg, opt, &fmax_warnings, OPTNUM_UNLIMITED); 511f08c3bdfSopenharmony_ci return 1; 512f08c3bdfSopenharmony_ci} 513f08c3bdfSopenharmony_ci 514f08c3bdfSopenharmony_cistatic struct flag fflags[] = { 515f08c3bdfSopenharmony_ci { "diagnostic-prefix", NULL, handle_fdiagnostic_prefix }, 516f08c3bdfSopenharmony_ci { "dump-ir", NULL, handle_fdump_ir }, 517f08c3bdfSopenharmony_ci { "freestanding", &fhosted, NULL, OPT_INVERSE }, 518f08c3bdfSopenharmony_ci { "hosted", &fhosted }, 519f08c3bdfSopenharmony_ci { "linearize", NULL, handle_fpasses, PASS_LINEARIZE }, 520f08c3bdfSopenharmony_ci { "max-errors=", NULL, handle_fmax_errors }, 521f08c3bdfSopenharmony_ci { "max-warnings=", NULL, handle_fmax_warnings }, 522f08c3bdfSopenharmony_ci { "mem-report", &fmem_report }, 523f08c3bdfSopenharmony_ci { "memcpy-max-count=", NULL, handle_fmemcpy_max_count }, 524f08c3bdfSopenharmony_ci { "tabstop=", NULL, handle_ftabstop }, 525f08c3bdfSopenharmony_ci { "mem2reg", NULL, handle_fpasses, PASS_MEM2REG }, 526f08c3bdfSopenharmony_ci { "optim", NULL, handle_fpasses, PASS_OPTIM }, 527f08c3bdfSopenharmony_ci { "pic", &fpic, handle_switch_setval, 1 }, 528f08c3bdfSopenharmony_ci { "PIC", &fpic, handle_switch_setval, 2 }, 529f08c3bdfSopenharmony_ci { "pie", &fpie, handle_switch_setval, 1 }, 530f08c3bdfSopenharmony_ci { "PIE", &fpie, handle_switch_setval, 2 }, 531f08c3bdfSopenharmony_ci { "signed-bitfields", &funsigned_bitfields, NULL, OPT_INVERSE }, 532f08c3bdfSopenharmony_ci { "unsigned-bitfields", &funsigned_bitfields, NULL, }, 533f08c3bdfSopenharmony_ci { "signed-char", &funsigned_char, NULL, OPT_INVERSE }, 534f08c3bdfSopenharmony_ci { "short-wchar", &fshort_wchar }, 535f08c3bdfSopenharmony_ci { "unsigned-char", &funsigned_char, NULL, }, 536f08c3bdfSopenharmony_ci { }, 537f08c3bdfSopenharmony_ci}; 538f08c3bdfSopenharmony_ci 539f08c3bdfSopenharmony_cistatic char **handle_switch_f(char *arg, char **next) 540f08c3bdfSopenharmony_ci{ 541f08c3bdfSopenharmony_ci if (handle_switches(arg-1, arg+1, fflags)) 542f08c3bdfSopenharmony_ci return next; 543f08c3bdfSopenharmony_ci 544f08c3bdfSopenharmony_ci return next; 545f08c3bdfSopenharmony_ci} 546f08c3bdfSopenharmony_ci 547f08c3bdfSopenharmony_cistatic char **handle_switch_G(char *arg, char **next) 548f08c3bdfSopenharmony_ci{ 549f08c3bdfSopenharmony_ci if (!strcmp(arg, "G") && *next) 550f08c3bdfSopenharmony_ci return next + 1; // "-G 0" 551f08c3bdfSopenharmony_ci else 552f08c3bdfSopenharmony_ci return next; // "-G0" or (bogus) terminal "-G" 553f08c3bdfSopenharmony_ci} 554f08c3bdfSopenharmony_ci 555f08c3bdfSopenharmony_cistatic char **handle_base_dir(char *arg, char **next) 556f08c3bdfSopenharmony_ci{ 557f08c3bdfSopenharmony_ci gcc_base_dir = *++next; 558f08c3bdfSopenharmony_ci if (!gcc_base_dir) 559f08c3bdfSopenharmony_ci die("missing argument for -gcc-base-dir option"); 560f08c3bdfSopenharmony_ci return next; 561f08c3bdfSopenharmony_ci} 562f08c3bdfSopenharmony_ci 563f08c3bdfSopenharmony_cistatic char **handle_switch_g(char *arg, char **next) 564f08c3bdfSopenharmony_ci{ 565f08c3bdfSopenharmony_ci if (!strcmp(arg, "gcc-base-dir")) 566f08c3bdfSopenharmony_ci return handle_base_dir(arg, next); 567f08c3bdfSopenharmony_ci 568f08c3bdfSopenharmony_ci return next; 569f08c3bdfSopenharmony_ci} 570f08c3bdfSopenharmony_ci 571f08c3bdfSopenharmony_cistatic char **handle_switch_I(char *arg, char **next) 572f08c3bdfSopenharmony_ci{ 573f08c3bdfSopenharmony_ci char *path = arg+1; 574f08c3bdfSopenharmony_ci 575f08c3bdfSopenharmony_ci switch (arg[1]) { 576f08c3bdfSopenharmony_ci case '-': 577f08c3bdfSopenharmony_ci add_pre_buffer("#split_include\n"); 578f08c3bdfSopenharmony_ci break; 579f08c3bdfSopenharmony_ci 580f08c3bdfSopenharmony_ci case '\0': /* Plain "-I" */ 581f08c3bdfSopenharmony_ci path = *++next; 582f08c3bdfSopenharmony_ci if (!path) 583f08c3bdfSopenharmony_ci die("missing argument for -I option"); 584f08c3bdfSopenharmony_ci /* Fall through */ 585f08c3bdfSopenharmony_ci default: 586f08c3bdfSopenharmony_ci add_pre_buffer("#add_include \"%s/\"\n", path); 587f08c3bdfSopenharmony_ci } 588f08c3bdfSopenharmony_ci return next; 589f08c3bdfSopenharmony_ci} 590f08c3bdfSopenharmony_ci 591f08c3bdfSopenharmony_cistatic void add_cmdline_include(char *filename) 592f08c3bdfSopenharmony_ci{ 593f08c3bdfSopenharmony_ci if (cmdline_include_nr >= CMDLINE_INCLUDE) 594f08c3bdfSopenharmony_ci die("too many include files for %s\n", filename); 595f08c3bdfSopenharmony_ci cmdline_include[cmdline_include_nr++] = filename; 596f08c3bdfSopenharmony_ci} 597f08c3bdfSopenharmony_ci 598f08c3bdfSopenharmony_cistatic char **handle_switch_i(char *arg, char **next) 599f08c3bdfSopenharmony_ci{ 600f08c3bdfSopenharmony_ci if (*next && !strcmp(arg, "include")) 601f08c3bdfSopenharmony_ci add_cmdline_include(*++next); 602f08c3bdfSopenharmony_ci else if (*next && !strcmp(arg, "imacros")) 603f08c3bdfSopenharmony_ci add_cmdline_include(*++next); 604f08c3bdfSopenharmony_ci else if (*next && !strcmp(arg, "isystem")) { 605f08c3bdfSopenharmony_ci char *path = *++next; 606f08c3bdfSopenharmony_ci if (!path) 607f08c3bdfSopenharmony_ci die("missing argument for -isystem option"); 608f08c3bdfSopenharmony_ci add_pre_buffer("#add_isystem \"%s/\"\n", path); 609f08c3bdfSopenharmony_ci } else if (*next && !strcmp(arg, "idirafter")) { 610f08c3bdfSopenharmony_ci char *path = *++next; 611f08c3bdfSopenharmony_ci if (!path) 612f08c3bdfSopenharmony_ci die("missing argument for -idirafter option"); 613f08c3bdfSopenharmony_ci add_pre_buffer("#add_dirafter \"%s/\"\n", path); 614f08c3bdfSopenharmony_ci } 615f08c3bdfSopenharmony_ci return next; 616f08c3bdfSopenharmony_ci} 617f08c3bdfSopenharmony_ci 618f08c3bdfSopenharmony_cistatic char **handle_switch_M(char *arg, char **next) 619f08c3bdfSopenharmony_ci{ 620f08c3bdfSopenharmony_ci if (!strcmp(arg, "MF") || !strcmp(arg,"MQ") || !strcmp(arg,"MT")) { 621f08c3bdfSopenharmony_ci if (!*next) 622f08c3bdfSopenharmony_ci die("missing argument for -%s option", arg); 623f08c3bdfSopenharmony_ci return next + 1; 624f08c3bdfSopenharmony_ci } 625f08c3bdfSopenharmony_ci return next; 626f08c3bdfSopenharmony_ci} 627f08c3bdfSopenharmony_ci 628f08c3bdfSopenharmony_cistatic int handle_march(const char *opt, const char *arg, const struct flag *flag, int options) 629f08c3bdfSopenharmony_ci{ 630f08c3bdfSopenharmony_ci if (arch_target->parse_march) 631f08c3bdfSopenharmony_ci arch_target->parse_march(arg); 632f08c3bdfSopenharmony_ci return 1; 633f08c3bdfSopenharmony_ci} 634f08c3bdfSopenharmony_ci 635f08c3bdfSopenharmony_cistatic int handle_mcmodel(const char *opt, const char *arg, const struct flag *flag, int options) 636f08c3bdfSopenharmony_ci{ 637f08c3bdfSopenharmony_ci static const struct val_map cmodels[] = { 638f08c3bdfSopenharmony_ci { "kernel", CMODEL_KERNEL }, 639f08c3bdfSopenharmony_ci { "large", CMODEL_LARGE }, 640f08c3bdfSopenharmony_ci { "medany", CMODEL_MEDANY }, 641f08c3bdfSopenharmony_ci { "medium", CMODEL_MEDIUM }, 642f08c3bdfSopenharmony_ci { "medlow", CMODEL_MEDLOW }, 643f08c3bdfSopenharmony_ci { "small", CMODEL_SMALL }, 644f08c3bdfSopenharmony_ci { "tiny", CMODEL_TINY }, 645f08c3bdfSopenharmony_ci { }, 646f08c3bdfSopenharmony_ci }; 647f08c3bdfSopenharmony_ci return handle_subopt_val(opt, arg, cmodels, flag->flag); 648f08c3bdfSopenharmony_ci} 649f08c3bdfSopenharmony_ci 650f08c3bdfSopenharmony_cistatic int handle_mfloat_abi(const char *opt, const char *arg, const struct flag *flag, int options) { 651f08c3bdfSopenharmony_ci static const struct val_map fp_abis[] = { 652f08c3bdfSopenharmony_ci { "hard", FP_ABI_HARD }, 653f08c3bdfSopenharmony_ci { "soft", FP_ABI_SOFT }, 654f08c3bdfSopenharmony_ci { "softfp", FP_ABI_HYBRID }, 655f08c3bdfSopenharmony_ci { "?" }, 656f08c3bdfSopenharmony_ci }; 657f08c3bdfSopenharmony_ci return handle_subopt_val(opt, arg, fp_abis, flag->flag); 658f08c3bdfSopenharmony_ci} 659f08c3bdfSopenharmony_ci 660f08c3bdfSopenharmony_cistatic char **handle_multiarch_dir(char *arg, char **next) 661f08c3bdfSopenharmony_ci{ 662f08c3bdfSopenharmony_ci multiarch_dir = *++next; 663f08c3bdfSopenharmony_ci if (!multiarch_dir) 664f08c3bdfSopenharmony_ci die("missing argument for -multiarch-dir option"); 665f08c3bdfSopenharmony_ci return next; 666f08c3bdfSopenharmony_ci} 667f08c3bdfSopenharmony_ci 668f08c3bdfSopenharmony_cistatic const struct flag mflags[] = { 669f08c3bdfSopenharmony_ci { "64", &arch_m64, NULL, OPT_VAL, ARCH_LP64 }, 670f08c3bdfSopenharmony_ci { "32", &arch_m64, NULL, OPT_VAL, ARCH_LP32 }, 671f08c3bdfSopenharmony_ci { "31", &arch_m64, NULL, OPT_VAL, ARCH_LP32 }, 672f08c3bdfSopenharmony_ci { "16", &arch_m64, NULL, OPT_VAL, ARCH_LP32 }, 673f08c3bdfSopenharmony_ci { "x32",&arch_m64, NULL, OPT_VAL, ARCH_X32 }, 674f08c3bdfSopenharmony_ci { "size-llp64", &arch_m64, NULL, OPT_VAL, ARCH_LLP64 }, 675f08c3bdfSopenharmony_ci { "size-long", &arch_msize_long }, 676f08c3bdfSopenharmony_ci { "arch=", NULL, handle_march }, 677f08c3bdfSopenharmony_ci { "big-endian", &arch_big_endian, NULL }, 678f08c3bdfSopenharmony_ci { "little-endian", &arch_big_endian, NULL, OPT_INVERSE }, 679f08c3bdfSopenharmony_ci { "cmodel", &arch_cmodel, handle_mcmodel }, 680f08c3bdfSopenharmony_ci { "float-abi", &arch_fp_abi, handle_mfloat_abi }, 681f08c3bdfSopenharmony_ci { "hard-float", &arch_fp_abi, NULL, OPT_VAL, FP_ABI_HARD }, 682f08c3bdfSopenharmony_ci { "soft-float", &arch_fp_abi, NULL, OPT_VAL, FP_ABI_SOFT }, 683f08c3bdfSopenharmony_ci { } 684f08c3bdfSopenharmony_ci}; 685f08c3bdfSopenharmony_ci 686f08c3bdfSopenharmony_cistatic char **handle_switch_m(char *arg, char **next) 687f08c3bdfSopenharmony_ci{ 688f08c3bdfSopenharmony_ci if (!strcmp(arg, "multiarch-dir")) { 689f08c3bdfSopenharmony_ci return handle_multiarch_dir(arg, next); 690f08c3bdfSopenharmony_ci } else { 691f08c3bdfSopenharmony_ci handle_switches(arg-1, arg+1, mflags); 692f08c3bdfSopenharmony_ci } 693f08c3bdfSopenharmony_ci 694f08c3bdfSopenharmony_ci return next; 695f08c3bdfSopenharmony_ci} 696f08c3bdfSopenharmony_ci 697f08c3bdfSopenharmony_cistatic char **handle_nostdinc(char *arg, char **next) 698f08c3bdfSopenharmony_ci{ 699f08c3bdfSopenharmony_ci add_pre_buffer("#nostdinc\n"); 700f08c3bdfSopenharmony_ci return next; 701f08c3bdfSopenharmony_ci} 702f08c3bdfSopenharmony_ci 703f08c3bdfSopenharmony_cistatic char **handle_switch_n(char *arg, char **next) 704f08c3bdfSopenharmony_ci{ 705f08c3bdfSopenharmony_ci if (!strcmp(arg, "nostdinc")) 706f08c3bdfSopenharmony_ci return handle_nostdinc(arg, next); 707f08c3bdfSopenharmony_ci 708f08c3bdfSopenharmony_ci return next; 709f08c3bdfSopenharmony_ci} 710f08c3bdfSopenharmony_ci 711f08c3bdfSopenharmony_cistatic char **handle_switch_O(char *arg, char **next) 712f08c3bdfSopenharmony_ci{ 713f08c3bdfSopenharmony_ci int level = 1; 714f08c3bdfSopenharmony_ci if (arg[1] >= '0' && arg[1] <= '9') 715f08c3bdfSopenharmony_ci level = arg[1] - '0'; 716f08c3bdfSopenharmony_ci optimize_level = level; 717f08c3bdfSopenharmony_ci optimize_size = arg[1] == 's'; 718f08c3bdfSopenharmony_ci return next; 719f08c3bdfSopenharmony_ci} 720f08c3bdfSopenharmony_ci 721f08c3bdfSopenharmony_cistatic char **handle_switch_o(char *arg, char **next) 722f08c3bdfSopenharmony_ci{ 723f08c3bdfSopenharmony_ci if (!strcmp(arg, "o")) { // "-o foo" 724f08c3bdfSopenharmony_ci if (!*++next) 725f08c3bdfSopenharmony_ci die("argument to '-o' is missing"); 726f08c3bdfSopenharmony_ci outfile = *next; 727f08c3bdfSopenharmony_ci } 728f08c3bdfSopenharmony_ci // else "-ofoo" 729f08c3bdfSopenharmony_ci 730f08c3bdfSopenharmony_ci return next; 731f08c3bdfSopenharmony_ci} 732f08c3bdfSopenharmony_ci 733f08c3bdfSopenharmony_cistatic const struct flag pflags[] = { 734f08c3bdfSopenharmony_ci { "pedantic", &Wpedantic, NULL, OPT_VAL, FLAG_ON }, 735f08c3bdfSopenharmony_ci { } 736f08c3bdfSopenharmony_ci}; 737f08c3bdfSopenharmony_ci 738f08c3bdfSopenharmony_cistatic char **handle_switch_p(char *arg, char **next) 739f08c3bdfSopenharmony_ci{ 740f08c3bdfSopenharmony_ci handle_switches(arg-1, arg, pflags); 741f08c3bdfSopenharmony_ci return next; 742f08c3bdfSopenharmony_ci} 743f08c3bdfSopenharmony_ci 744f08c3bdfSopenharmony_cistatic char **handle_switch_s(const char *arg, char **next) 745f08c3bdfSopenharmony_ci{ 746f08c3bdfSopenharmony_ci if ((arg = match_option(arg, "std="))) { 747f08c3bdfSopenharmony_ci if (!strcmp(arg, "c89") || 748f08c3bdfSopenharmony_ci !strcmp(arg, "iso9899:1990")) 749f08c3bdfSopenharmony_ci standard = STANDARD_C89; 750f08c3bdfSopenharmony_ci 751f08c3bdfSopenharmony_ci else if (!strcmp(arg, "iso9899:199409")) 752f08c3bdfSopenharmony_ci standard = STANDARD_C94; 753f08c3bdfSopenharmony_ci 754f08c3bdfSopenharmony_ci else if (!strcmp(arg, "c99") || 755f08c3bdfSopenharmony_ci !strcmp(arg, "c9x") || 756f08c3bdfSopenharmony_ci !strcmp(arg, "iso9899:1999") || 757f08c3bdfSopenharmony_ci !strcmp(arg, "iso9899:199x")) 758f08c3bdfSopenharmony_ci standard = STANDARD_C99; 759f08c3bdfSopenharmony_ci 760f08c3bdfSopenharmony_ci else if (!strcmp(arg, "gnu89")) 761f08c3bdfSopenharmony_ci standard = STANDARD_GNU89; 762f08c3bdfSopenharmony_ci 763f08c3bdfSopenharmony_ci else if (!strcmp(arg, "gnu99") || !strcmp(arg, "gnu9x")) 764f08c3bdfSopenharmony_ci standard = STANDARD_GNU99; 765f08c3bdfSopenharmony_ci 766f08c3bdfSopenharmony_ci else if (!strcmp(arg, "c11") || 767f08c3bdfSopenharmony_ci !strcmp(arg, "c1x") || 768f08c3bdfSopenharmony_ci !strcmp(arg, "iso9899:2011")) 769f08c3bdfSopenharmony_ci standard = STANDARD_C11; 770f08c3bdfSopenharmony_ci 771f08c3bdfSopenharmony_ci else if (!strcmp(arg, "gnu11")) 772f08c3bdfSopenharmony_ci standard = STANDARD_GNU11; 773f08c3bdfSopenharmony_ci 774f08c3bdfSopenharmony_ci else if (!strcmp(arg, "c17") || 775f08c3bdfSopenharmony_ci !strcmp(arg, "c18") || 776f08c3bdfSopenharmony_ci !strcmp(arg, "iso9899:2017") || 777f08c3bdfSopenharmony_ci !strcmp(arg, "iso9899:2018")) 778f08c3bdfSopenharmony_ci standard = STANDARD_C17; 779f08c3bdfSopenharmony_ci else if (!strcmp(arg, "gnu17") || 780f08c3bdfSopenharmony_ci !strcmp(arg, "gnu18")) 781f08c3bdfSopenharmony_ci standard = STANDARD_GNU17; 782f08c3bdfSopenharmony_ci 783f08c3bdfSopenharmony_ci else 784f08c3bdfSopenharmony_ci die("Unsupported C dialect"); 785f08c3bdfSopenharmony_ci } 786f08c3bdfSopenharmony_ci 787f08c3bdfSopenharmony_ci return next; 788f08c3bdfSopenharmony_ci} 789f08c3bdfSopenharmony_ci 790f08c3bdfSopenharmony_cistatic char **handle_switch_U(char *arg, char **next) 791f08c3bdfSopenharmony_ci{ 792f08c3bdfSopenharmony_ci const char *name = arg + 1; 793f08c3bdfSopenharmony_ci 794f08c3bdfSopenharmony_ci if (*name == '\0') { 795f08c3bdfSopenharmony_ci name = *++next; 796f08c3bdfSopenharmony_ci if (!name) 797f08c3bdfSopenharmony_ci die("argument to `-U' is missing"); 798f08c3bdfSopenharmony_ci } 799f08c3bdfSopenharmony_ci add_pre_buffer("#undef %s\n", name); 800f08c3bdfSopenharmony_ci return next; 801f08c3bdfSopenharmony_ci} 802f08c3bdfSopenharmony_ci 803f08c3bdfSopenharmony_cistatic struct flag debugs[] = { 804f08c3bdfSopenharmony_ci { "compound", &dbg_compound}, 805f08c3bdfSopenharmony_ci { "dead", &dbg_dead}, 806f08c3bdfSopenharmony_ci { "domtree", &dbg_domtree}, 807f08c3bdfSopenharmony_ci { "entry", &dbg_entry}, 808f08c3bdfSopenharmony_ci { "ir", &dbg_ir}, 809f08c3bdfSopenharmony_ci { "postorder", &dbg_postorder}, 810f08c3bdfSopenharmony_ci { } 811f08c3bdfSopenharmony_ci}; 812f08c3bdfSopenharmony_ci 813f08c3bdfSopenharmony_cistatic char **handle_switch_v(char *arg, char **next) 814f08c3bdfSopenharmony_ci{ 815f08c3bdfSopenharmony_ci char ** ret = handle_onoff_switch(arg, next, debugs); 816f08c3bdfSopenharmony_ci if (ret) 817f08c3bdfSopenharmony_ci return ret; 818f08c3bdfSopenharmony_ci 819f08c3bdfSopenharmony_ci // Unknown. 820f08c3bdfSopenharmony_ci do { 821f08c3bdfSopenharmony_ci verbose++; 822f08c3bdfSopenharmony_ci } while (*++arg == 'v'); 823f08c3bdfSopenharmony_ci return next; 824f08c3bdfSopenharmony_ci} 825f08c3bdfSopenharmony_ci 826f08c3bdfSopenharmony_cistatic void handle_switch_v_finalize(void) 827f08c3bdfSopenharmony_ci{ 828f08c3bdfSopenharmony_ci handle_onoff_switch_finalize(debugs); 829f08c3bdfSopenharmony_ci} 830f08c3bdfSopenharmony_ci 831f08c3bdfSopenharmony_cistatic const struct flag warnings[] = { 832f08c3bdfSopenharmony_ci { "address", &Waddress }, 833f08c3bdfSopenharmony_ci { "address-space", &Waddress_space }, 834f08c3bdfSopenharmony_ci { "bitwise", &Wbitwise }, 835f08c3bdfSopenharmony_ci { "bitwise-pointer", &Wbitwise_pointer}, 836f08c3bdfSopenharmony_ci { "cast-from-as", &Wcast_from_as }, 837f08c3bdfSopenharmony_ci { "cast-to-as", &Wcast_to_as }, 838f08c3bdfSopenharmony_ci { "cast-truncate", &Wcast_truncate }, 839f08c3bdfSopenharmony_ci { "constant-suffix", &Wconstant_suffix }, 840f08c3bdfSopenharmony_ci { "constexpr-not-const", &Wconstexpr_not_const}, 841f08c3bdfSopenharmony_ci { "context", &Wcontext }, 842f08c3bdfSopenharmony_ci { "decl", &Wdecl }, 843f08c3bdfSopenharmony_ci { "declaration-after-statement", &Wdeclarationafterstatement }, 844f08c3bdfSopenharmony_ci { "default-bitfield-sign", &Wdefault_bitfield_sign }, 845f08c3bdfSopenharmony_ci { "designated-init", &Wdesignated_init }, 846f08c3bdfSopenharmony_ci { "do-while", &Wdo_while }, 847f08c3bdfSopenharmony_ci { "enum-mismatch", &Wenum_mismatch }, 848f08c3bdfSopenharmony_ci { "external-function-has-definition", &Wexternal_function_has_definition }, 849f08c3bdfSopenharmony_ci { "flexible-array-array", &Wflexible_array_array }, 850f08c3bdfSopenharmony_ci { "flexible-array-nested", &Wflexible_array_nested }, 851f08c3bdfSopenharmony_ci { "flexible-array-sizeof", &Wflexible_array_sizeof }, 852f08c3bdfSopenharmony_ci { "flexible-array-union", &Wflexible_array_union }, 853f08c3bdfSopenharmony_ci { "implicit-int", &Wimplicit_int }, 854f08c3bdfSopenharmony_ci { "init-cstring", &Winit_cstring }, 855f08c3bdfSopenharmony_ci { "int-to-pointer-cast", &Wint_to_pointer_cast }, 856f08c3bdfSopenharmony_ci { "memcpy-max-count", &Wmemcpy_max_count }, 857f08c3bdfSopenharmony_ci { "non-pointer-null", &Wnon_pointer_null }, 858f08c3bdfSopenharmony_ci { "newline-eof", &Wnewline_eof }, 859f08c3bdfSopenharmony_ci { "old-initializer", &Wold_initializer }, 860f08c3bdfSopenharmony_ci { "old-style-definition", &Wold_style_definition }, 861f08c3bdfSopenharmony_ci { "one-bit-signed-bitfield", &Wone_bit_signed_bitfield }, 862f08c3bdfSopenharmony_ci { "override-init", &Woverride_init }, 863f08c3bdfSopenharmony_ci { "override-init-all", &Woverride_init_all }, 864f08c3bdfSopenharmony_ci { "paren-string", &Wparen_string }, 865f08c3bdfSopenharmony_ci { "past-deep-designator", &Wpast_deep_designator }, 866f08c3bdfSopenharmony_ci { "pedantic", &Wpedantic }, 867f08c3bdfSopenharmony_ci { "pointer-to-int-cast", &Wpointer_to_int_cast }, 868f08c3bdfSopenharmony_ci { "ptr-subtraction-blows", &Wptr_subtraction_blows }, 869f08c3bdfSopenharmony_ci { "return-void", &Wreturn_void }, 870f08c3bdfSopenharmony_ci { "shadow", &Wshadow }, 871f08c3bdfSopenharmony_ci { "shift-count-negative", &Wshift_count_negative }, 872f08c3bdfSopenharmony_ci { "shift-count-overflow", &Wshift_count_overflow }, 873f08c3bdfSopenharmony_ci { "sizeof-bool", &Wsizeof_bool }, 874f08c3bdfSopenharmony_ci { "strict-prototypes", &Wstrict_prototypes }, 875f08c3bdfSopenharmony_ci { "pointer-arith", &Wpointer_arith }, 876f08c3bdfSopenharmony_ci { "sparse-error", &Wsparse_error }, 877f08c3bdfSopenharmony_ci { "tautological-compare", &Wtautological_compare }, 878f08c3bdfSopenharmony_ci { "transparent-union", &Wtransparent_union }, 879f08c3bdfSopenharmony_ci { "typesign", &Wtypesign }, 880f08c3bdfSopenharmony_ci { "undef", &Wundef }, 881f08c3bdfSopenharmony_ci { "uninitialized", &Wuninitialized }, 882f08c3bdfSopenharmony_ci { "union-cast", &Wunion_cast }, 883f08c3bdfSopenharmony_ci { "universal-initializer", &Wuniversal_initializer }, 884f08c3bdfSopenharmony_ci { "unknown-attribute", &Wunknown_attribute }, 885f08c3bdfSopenharmony_ci { "vla", &Wvla }, 886f08c3bdfSopenharmony_ci { } 887f08c3bdfSopenharmony_ci}; 888f08c3bdfSopenharmony_ci 889f08c3bdfSopenharmony_cistatic char **handle_switch_W(char *arg, char **next) 890f08c3bdfSopenharmony_ci{ 891f08c3bdfSopenharmony_ci char ** ret = handle_onoff_switch(arg, next, warnings); 892f08c3bdfSopenharmony_ci if (ret) 893f08c3bdfSopenharmony_ci return ret; 894f08c3bdfSopenharmony_ci 895f08c3bdfSopenharmony_ci if (!strcmp(arg, "Wsparse-all")) { 896f08c3bdfSopenharmony_ci int i; 897f08c3bdfSopenharmony_ci for (i = 0; warnings[i].name; i++) { 898f08c3bdfSopenharmony_ci if (*warnings[i].flag != FLAG_FORCE_OFF) 899f08c3bdfSopenharmony_ci *warnings[i].flag = FLAG_ON; 900f08c3bdfSopenharmony_ci } 901f08c3bdfSopenharmony_ci } 902f08c3bdfSopenharmony_ci 903f08c3bdfSopenharmony_ci // Unknown. 904f08c3bdfSopenharmony_ci return next; 905f08c3bdfSopenharmony_ci} 906f08c3bdfSopenharmony_ci 907f08c3bdfSopenharmony_cistatic void handle_switch_W_finalize(void) 908f08c3bdfSopenharmony_ci{ 909f08c3bdfSopenharmony_ci handle_onoff_switch_finalize(warnings); 910f08c3bdfSopenharmony_ci 911f08c3bdfSopenharmony_ci /* default Wdeclarationafterstatement based on the C dialect */ 912f08c3bdfSopenharmony_ci if (-1 == Wdeclarationafterstatement) { 913f08c3bdfSopenharmony_ci switch (standard) { 914f08c3bdfSopenharmony_ci case STANDARD_C89: 915f08c3bdfSopenharmony_ci case STANDARD_C94: 916f08c3bdfSopenharmony_ci Wdeclarationafterstatement = 1; 917f08c3bdfSopenharmony_ci break; 918f08c3bdfSopenharmony_ci default: 919f08c3bdfSopenharmony_ci Wdeclarationafterstatement = 0; 920f08c3bdfSopenharmony_ci break; 921f08c3bdfSopenharmony_ci } 922f08c3bdfSopenharmony_ci } 923f08c3bdfSopenharmony_ci} 924f08c3bdfSopenharmony_ci 925f08c3bdfSopenharmony_cistatic char **handle_switch_x(char *arg, char **next) 926f08c3bdfSopenharmony_ci{ 927f08c3bdfSopenharmony_ci if (!*++next) 928f08c3bdfSopenharmony_ci die("missing argument for -x option"); 929f08c3bdfSopenharmony_ci return next; 930f08c3bdfSopenharmony_ci} 931f08c3bdfSopenharmony_ci 932f08c3bdfSopenharmony_ci 933f08c3bdfSopenharmony_cistatic char **handle_arch(char *arg, char **next) 934f08c3bdfSopenharmony_ci{ 935f08c3bdfSopenharmony_ci enum machine mach; 936f08c3bdfSopenharmony_ci 937f08c3bdfSopenharmony_ci if (*arg++ != '=') 938f08c3bdfSopenharmony_ci die("missing argument for --arch option"); 939f08c3bdfSopenharmony_ci 940f08c3bdfSopenharmony_ci mach = target_parse(arg); 941f08c3bdfSopenharmony_ci if (mach != MACH_UNKNOWN) 942f08c3bdfSopenharmony_ci target_config(mach); 943f08c3bdfSopenharmony_ci 944f08c3bdfSopenharmony_ci return next; 945f08c3bdfSopenharmony_ci} 946f08c3bdfSopenharmony_ci 947f08c3bdfSopenharmony_cistatic char **handle_param(char *arg, char **next) 948f08c3bdfSopenharmony_ci{ 949f08c3bdfSopenharmony_ci char *value = NULL; 950f08c3bdfSopenharmony_ci 951f08c3bdfSopenharmony_ci /* For now just skip any '--param=*' or '--param *' */ 952f08c3bdfSopenharmony_ci if (*arg == '\0') { 953f08c3bdfSopenharmony_ci value = *++next; 954f08c3bdfSopenharmony_ci } else if (isspace((unsigned char)*arg) || *arg == '=') { 955f08c3bdfSopenharmony_ci value = ++arg; 956f08c3bdfSopenharmony_ci } 957f08c3bdfSopenharmony_ci 958f08c3bdfSopenharmony_ci if (!value) 959f08c3bdfSopenharmony_ci die("missing argument for --param option"); 960f08c3bdfSopenharmony_ci 961f08c3bdfSopenharmony_ci return next; 962f08c3bdfSopenharmony_ci} 963f08c3bdfSopenharmony_ci 964f08c3bdfSopenharmony_cistatic char **handle_os(char *arg, char **next) 965f08c3bdfSopenharmony_ci{ 966f08c3bdfSopenharmony_ci if (*arg++ != '=') 967f08c3bdfSopenharmony_ci die("missing argument for --os option"); 968f08c3bdfSopenharmony_ci 969f08c3bdfSopenharmony_ci target_os(arg); 970f08c3bdfSopenharmony_ci 971f08c3bdfSopenharmony_ci return next; 972f08c3bdfSopenharmony_ci} 973f08c3bdfSopenharmony_ci 974f08c3bdfSopenharmony_cistatic char **handle_version(char *arg, char **next) 975f08c3bdfSopenharmony_ci{ 976f08c3bdfSopenharmony_ci printf("%s\n", sparse_version); 977f08c3bdfSopenharmony_ci exit(0); 978f08c3bdfSopenharmony_ci} 979f08c3bdfSopenharmony_ci 980f08c3bdfSopenharmony_cistruct switches { 981f08c3bdfSopenharmony_ci const char *name; 982f08c3bdfSopenharmony_ci char **(*fn)(char *, char **); 983f08c3bdfSopenharmony_ci unsigned int prefix:1; 984f08c3bdfSopenharmony_ci}; 985f08c3bdfSopenharmony_ci 986f08c3bdfSopenharmony_cistatic char **handle_long_options(char *arg, char **next) 987f08c3bdfSopenharmony_ci{ 988f08c3bdfSopenharmony_ci static struct switches cmd[] = { 989f08c3bdfSopenharmony_ci { "arch", handle_arch, 1 }, 990f08c3bdfSopenharmony_ci { "os", handle_os, 1 }, 991f08c3bdfSopenharmony_ci { "param", handle_param, 1 }, 992f08c3bdfSopenharmony_ci { "version", handle_version }, 993f08c3bdfSopenharmony_ci { NULL, NULL } 994f08c3bdfSopenharmony_ci }; 995f08c3bdfSopenharmony_ci struct switches *s = cmd; 996f08c3bdfSopenharmony_ci 997f08c3bdfSopenharmony_ci while (s->name) { 998f08c3bdfSopenharmony_ci int optlen = strlen(s->name); 999f08c3bdfSopenharmony_ci if (!strncmp(s->name, arg, optlen + !s->prefix)) 1000f08c3bdfSopenharmony_ci return s->fn(arg + optlen, next); 1001f08c3bdfSopenharmony_ci s++; 1002f08c3bdfSopenharmony_ci } 1003f08c3bdfSopenharmony_ci return next; 1004f08c3bdfSopenharmony_ci} 1005f08c3bdfSopenharmony_ci 1006f08c3bdfSopenharmony_cichar **handle_switch(char *arg, char **next) 1007f08c3bdfSopenharmony_ci{ 1008f08c3bdfSopenharmony_ci switch (*arg) { 1009f08c3bdfSopenharmony_ci case 'a': return handle_switch_a(arg, next); 1010f08c3bdfSopenharmony_ci case 'D': return handle_switch_D(arg, next); 1011f08c3bdfSopenharmony_ci case 'd': return handle_switch_d(arg, next); 1012f08c3bdfSopenharmony_ci case 'E': return handle_switch_E(arg, next); 1013f08c3bdfSopenharmony_ci case 'f': return handle_switch_f(arg, next); 1014f08c3bdfSopenharmony_ci case 'g': return handle_switch_g(arg, next); 1015f08c3bdfSopenharmony_ci case 'G': return handle_switch_G(arg, next); 1016f08c3bdfSopenharmony_ci case 'I': return handle_switch_I(arg, next); 1017f08c3bdfSopenharmony_ci case 'i': return handle_switch_i(arg, next); 1018f08c3bdfSopenharmony_ci case 'M': return handle_switch_M(arg, next); 1019f08c3bdfSopenharmony_ci case 'm': return handle_switch_m(arg, next); 1020f08c3bdfSopenharmony_ci case 'n': return handle_switch_n(arg, next); 1021f08c3bdfSopenharmony_ci case 'o': return handle_switch_o(arg, next); 1022f08c3bdfSopenharmony_ci case 'O': return handle_switch_O(arg, next); 1023f08c3bdfSopenharmony_ci case 'p': return handle_switch_p(arg, next); 1024f08c3bdfSopenharmony_ci case 's': return handle_switch_s(arg, next); 1025f08c3bdfSopenharmony_ci case 'U': return handle_switch_U(arg, next); 1026f08c3bdfSopenharmony_ci case 'v': return handle_switch_v(arg, next); 1027f08c3bdfSopenharmony_ci case 'W': return handle_switch_W(arg, next); 1028f08c3bdfSopenharmony_ci case 'x': return handle_switch_x(arg, next); 1029f08c3bdfSopenharmony_ci case '-': return handle_long_options(arg + 1, next); 1030f08c3bdfSopenharmony_ci default: 1031f08c3bdfSopenharmony_ci break; 1032f08c3bdfSopenharmony_ci } 1033f08c3bdfSopenharmony_ci 1034f08c3bdfSopenharmony_ci /* 1035f08c3bdfSopenharmony_ci * Ignore unknown command line options: 1036f08c3bdfSopenharmony_ci * they're probably gcc switches 1037f08c3bdfSopenharmony_ci */ 1038f08c3bdfSopenharmony_ci return next; 1039f08c3bdfSopenharmony_ci} 1040f08c3bdfSopenharmony_ci 1041f08c3bdfSopenharmony_civoid handle_switch_finalize(void) 1042f08c3bdfSopenharmony_ci{ 1043f08c3bdfSopenharmony_ci handle_switch_v_finalize(); 1044f08c3bdfSopenharmony_ci handle_switch_W_finalize(); 1045f08c3bdfSopenharmony_ci} 1046