| @@ -245,7 +245,14 @@ PUB_FUNC void tcc_memstats(int bench) · 244 unmodified lines |
| 245 | | 245 | |
| 246 | #define MEM_DEBUG_MAGIC1 0xFEEDDEB1 | 246 | #define MEM_DEBUG_MAGIC1 0xFEEDDEB1 |
| 247 | #define MEM_DEBUG_MAGIC2 0xFEEDDEB2 | 247 | #define MEM_DEBUG_MAGIC2 0xFEEDDEB2 |
| 248 | #define MEM_DEBUG_FILE_LEN 15 | 248 | #define MEM_DEBUG_MAGIC3 0xFEEDDEB3 |
| | 249 | #define MEM_DEBUG_FILE_LEN 40 |
| | 250 | #define MEM_DEBUG_CHECK3(header) \ |
| | 251 | ((mem_debug_header_t*)((char*)header + header->size))->magic3 |
| | 252 | #define MEM_USER_PTR(header) \ |
| | 253 | ((char *)header + offsetof(mem_debug_header_t, magic3)) |
| | 254 | #define MEM_HEADER_PTR(ptr) \ |
| | 255 | (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3)) |
| 249 | | 256 | |
| 250 | struct mem_debug_header { | 257 | struct mem_debug_header { |
| 251 | unsigned magic1; | 258 | unsigned magic1; |
| @@ -255,6 +262,7 @@ struct mem_debug_header { · 3 unmodified lines |
| 255 | int line_num; | 262 | int line_num; |
| 256 | char file_name[MEM_DEBUG_FILE_LEN + 1]; | 263 | char file_name[MEM_DEBUG_FILE_LEN + 1]; |
| 257 | unsigned magic2; | 264 | unsigned magic2; |
| | 265 | unsigned magic3; |
| 258 | }; | 266 | }; |
| 259 | | 267 | |
| 260 | typedef struct mem_debug_header mem_debug_header_t; | 268 | typedef struct mem_debug_header mem_debug_header_t; |
| @@ -263,76 +271,70 @@ static mem_debug_header_t *mem_debug_chain; · 2 unmodified lines |
| 263 | static unsigned mem_cur_size; | 271 | static unsigned mem_cur_size; |
| 264 | static unsigned mem_max_size; | 272 | static unsigned mem_max_size; |
| 265 | | 273 | |
| | 274 | static mem_debug_header_t *malloc_check(void *ptr, const char *msg) |
| | 275 | { |
| | 276 | mem_debug_header_t * header = MEM_HEADER_PTR(ptr); |
| | 277 | if (header->magic1 != MEM_DEBUG_MAGIC1 || |
| | 278 | header->magic2 != MEM_DEBUG_MAGIC2 || |
| | 279 | MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 || |
| | 280 | header->size == (unsigned)-1) { |
| | 281 | fprintf(stderr, "%s check failed\n", msg); |
| | 282 | if (header->magic1 == MEM_DEBUG_MAGIC1) |
| | 283 | fprintf(stderr, "%s:%u: block allocated here.\n", |
| | 284 | header->file_name, header->line_num); |
| | 285 | exit(1); |
| | 286 | } |
| | 287 | return header; |
| | 288 | } |
| | 289 | |
| 266 | PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) | 290 | PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) |
| 267 | { | 291 | { |
| 268 | void *ptr; | | |
| 269 | int ofs; | 292 | int ofs; |
| 270 | | | |
| 271 | mem_debug_header_t *header; | 293 | mem_debug_header_t *header; |
| 272 | | 294 | |
| 273 | ptr = malloc(sizeof(mem_debug_header_t) + size); | 295 | header = malloc(sizeof(mem_debug_header_t) + size); |
| 274 | if (!ptr) | 296 | if (!header) |
| 275 | tcc_error("memory full (malloc)"); | 297 | tcc_error("memory full (malloc)"); |
| 276 | | 298 | |
| 277 | mem_cur_size += size; | | |
| 278 | if (mem_cur_size > mem_max_size) | | |
| 279 | mem_max_size = mem_cur_size; | | |
| 280 | | | |
| 281 | header = (mem_debug_header_t *)ptr; | | |
| 282 | | | |
| 283 | header->magic1 = MEM_DEBUG_MAGIC1; | 299 | header->magic1 = MEM_DEBUG_MAGIC1; |
| 284 | header->magic2 = MEM_DEBUG_MAGIC2; | 300 | header->magic2 = MEM_DEBUG_MAGIC2; |
| 285 | header->size = size; | 301 | header->size = size; |
| | 302 | MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3; |
| 286 | header->line_num = line; | 303 | header->line_num = line; |
| 287 | | | |
| 288 | ofs = strlen(file) - MEM_DEBUG_FILE_LEN; | 304 | ofs = strlen(file) - MEM_DEBUG_FILE_LEN; |
| 289 | strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN); | 305 | strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN); |
| 290 | header->file_name[MEM_DEBUG_FILE_LEN] = 0; | 306 | header->file_name[MEM_DEBUG_FILE_LEN] = 0; |
| 291 | | 307 | |
| 292 | header->next = mem_debug_chain; | 308 | header->next = mem_debug_chain; |
| 293 | header->prev = NULL; | 309 | header->prev = NULL; |
| 294 | | | |
| 295 | if (header->next) | 310 | if (header->next) |
| 296 | header->next->prev = header; | 311 | header->next->prev = header; |
| 297 | | | |
| 298 | mem_debug_chain = header; | 312 | mem_debug_chain = header; |
| 299 | | 313 | |
| 300 | ptr = (char *)ptr + sizeof(mem_debug_header_t); | 314 | mem_cur_size += size; |
| 301 | return ptr; | 315 | if (mem_cur_size > mem_max_size) |
| | 316 | mem_max_size = mem_cur_size; |
| | 317 | |
| | 318 | return MEM_USER_PTR(header); |
| 302 | } | 319 | } |
| 303 | | 320 | |
| 304 | PUB_FUNC void tcc_free_debug(void *ptr) | 321 | PUB_FUNC void tcc_free_debug(void *ptr) |
| 305 | { | 322 | { |
| 306 | mem_debug_header_t *header; | 323 | mem_debug_header_t *header; |
| 307 | | | |
| 308 | if (!ptr) | 324 | if (!ptr) |
| 309 | return; | 325 | return; |
| 310 | | 326 | header = malloc_check(ptr, "tcc_free"); |
| 311 | ptr = (char *)ptr - sizeof(mem_debug_header_t); | | |
| 312 | header = (mem_debug_header_t *)ptr; | | |
| 313 | if (header->magic1 != MEM_DEBUG_MAGIC1 || | | |
| 314 | header->magic2 != MEM_DEBUG_MAGIC2 || | | |
| 315 | header->size == (unsigned)-1 ) | | |
| 316 | { | | |
| 317 | tcc_error("tcc_free check failed"); | | |
| 318 | } | | |
| 319 | | | |
| 320 | mem_cur_size -= header->size; | 327 | mem_cur_size -= header->size; |
| 321 | header->size = (unsigned)-1; | 328 | header->size = (unsigned)-1; |
| 322 | | | |
| 323 | if (header->next) | 329 | if (header->next) |
| 324 | header->next->prev = header->prev; | 330 | header->next->prev = header->prev; |
| 325 | | | |
| 326 | if (header->prev) | 331 | if (header->prev) |
| 327 | header->prev->next = header->next; | 332 | header->prev->next = header->next; |
| 328 | | | |
| 329 | if (header == mem_debug_chain) | 333 | if (header == mem_debug_chain) |
| 330 | mem_debug_chain = header->next; | 334 | mem_debug_chain = header->next; |
| 331 | | 335 | free(header); |
| 332 | free(ptr); | | |
| 333 | } | 336 | } |
| 334 | | 337 | |
| 335 | | | |
| 336 | PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line) | 338 | PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line) |
| 337 | { | 339 | { |
| 338 | void *ptr; | 340 | void *ptr; |
| @@ -345,52 +347,26 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 6 unmodified lines |
| 345 | { | 347 | { |
| 346 | mem_debug_header_t *header; | 348 | mem_debug_header_t *header; |
| 347 | int mem_debug_chain_update = 0; | 349 | int mem_debug_chain_update = 0; |
| 348 | | | |
| 349 | if (!ptr) { | | |
| 350 | ptr = tcc_malloc_debug(size, file, line); | | |
| 351 | return ptr; | | |
| 352 | } | | |
| 353 | | | |
| 354 | ptr = (char *)ptr - sizeof(mem_debug_header_t); | | |
| 355 | header = (mem_debug_header_t *)ptr; | | |
| 356 | if (header->magic1 != MEM_DEBUG_MAGIC1 || | | |
| 357 | header->magic2 != MEM_DEBUG_MAGIC2 || | | |
| 358 | header->size == (unsigned)-1 ) | | |
| 359 | { | | |
| 360 | check_error: | | |
| 361 | tcc_error("tcc_realloc check failed"); | | |
| 362 | } | | |
| 363 | | | |
| 364 | mem_debug_chain_update = (header == mem_debug_chain); | | |
| 365 | | | |
| 366 | mem_cur_size -= header->size; | | |
| 367 | ptr = realloc(ptr, sizeof(mem_debug_header_t) + size); | | |
| 368 | if (!ptr) | 350 | if (!ptr) |
| | 351 | return tcc_malloc_debug(size, file, line); |
| | 352 | header = malloc_check(ptr, "tcc_realloc"); |
| | 353 | mem_cur_size -= header->size; |
| | 354 | mem_debug_chain_update = (header == mem_debug_chain); |
| | 355 | header = realloc(header, sizeof(mem_debug_header_t) + size); |
| | 356 | if (!header) |
| 369 | tcc_error("memory full (realloc)"); | 357 | tcc_error("memory full (realloc)"); |
| 370 | | | |
| 371 | header = (mem_debug_header_t *)ptr; | | |
| 372 | if (header->magic1 != MEM_DEBUG_MAGIC1 || | | |
| 373 | header->magic2 != MEM_DEBUG_MAGIC2) | | |
| 374 | { | | |
| 375 | goto check_error; | | |
| 376 | } | | |
| 377 | | | |
| 378 | mem_cur_size += size; | | |
| 379 | if (mem_cur_size > mem_max_size) | | |
| 380 | mem_max_size = mem_cur_size; | | |
| 381 | | | |
| 382 | header->size = size; | 358 | header->size = size; |
| | 359 | MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3; |
| 383 | if (header->next) | 360 | if (header->next) |
| 384 | header->next->prev = header; | 361 | header->next->prev = header; |
| 385 | | | |
| 386 | if (header->prev) | 362 | if (header->prev) |
| 387 | header->prev->next = header; | 363 | header->prev->next = header; |
| 388 | | | |
| 389 | if (mem_debug_chain_update) | 364 | if (mem_debug_chain_update) |
| 390 | mem_debug_chain = header; | 365 | mem_debug_chain = header; |
| 391 | | 366 | mem_cur_size += size; |
| 392 | ptr = (char *)ptr + sizeof(mem_debug_header_t); | 367 | if (mem_cur_size > mem_max_size) |
| 393 | return ptr; | 368 | mem_max_size = mem_cur_size; |
| | 369 | return MEM_USER_PTR(header); |
| 394 | } | 370 | } |
| 395 | | 371 | |
| 396 | PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) | 372 | PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) |
| @@ -405,10 +381,8 @@ PUB_FUNC void tcc_memstats(int bench) · 8 unmodified lines |
| 405 | { | 381 | { |
| 406 | if (mem_cur_size) { | 382 | if (mem_cur_size) { |
| 407 | mem_debug_header_t *header = mem_debug_chain; | 383 | mem_debug_header_t *header = mem_debug_chain; |
| 408 | | | |
| 409 | fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n", | 384 | fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n", |
| 410 | mem_cur_size, mem_max_size); | 385 | mem_cur_size, mem_max_size); |
| 411 | | | |
| 412 | while (header) { | 386 | while (header) { |
| 413 | fprintf(stderr, "%s:%u: error: %u bytes leaked\n", | 387 | fprintf(stderr, "%s:%u: error: %u bytes leaked\n", |
| 414 | header->file_name, header->line_num, header->size); | 388 | header->file_name, header->line_num, header->size); |
| @@ -417,16 +391,10 @@ PUB_FUNC void tcc_memstats(int bench) · 2 unmodified lines |
| 417 | #if MEM_DEBUG-0 == 2 | 391 | #if MEM_DEBUG-0 == 2 |
| 418 | exit(2); | 392 | exit(2); |
| 419 | #endif | 393 | #endif |
| 420 | } | 394 | } else if (bench) |
| 421 | else if (bench) | | |
| 422 | fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size); | 395 | fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size); |
| 423 | } | 396 | } |
| 424 | | 397 | #endif /* MEM_DEBUG */ |
| 425 | #undef MEM_DEBUG_MAGIC1 | | |
| 426 | #undef MEM_DEBUG_MAGIC2 | | |
| 427 | #undef MEM_DEBUG_FILE_LEN | | |
| 428 | | | |
| 429 | #endif | | |
| 430 | | 398 | |
| 431 | #define free(p) use_tcc_free(p) | 399 | #define free(p) use_tcc_free(p) |
| 432 | #define malloc(s) use_tcc_malloc(s) | 400 | #define malloc(s) use_tcc_malloc(s) |
| @@ -760,7 +728,6 @@ LIBTCCAPI TCCState *tcc_new(void) · 327 unmodified lines |
| 760 | s->alacarte_link = 1; | 728 | s->alacarte_link = 1; |
| 761 | s->nocommon = 1; | 729 | s->nocommon = 1; |
| 762 | s->warn_implicit_function_declaration = 1; | 730 | s->warn_implicit_function_declaration = 1; |
| 763 | s->ms_bitfields = 0; | | |
| 764 | | 731 | |
| 765 | #ifdef CHAR_IS_UNSIGNED | 732 | #ifdef CHAR_IS_UNSIGNED |
| 766 | s->char_is_unsigned = 1; | 733 | s->char_is_unsigned = 1; |
| @@ -1231,14 +1198,6 @@ typedef struct FlagDef { · 464 unmodified lines |
| 1231 | const char *name; | 1198 | const char *name; |
| 1232 | } FlagDef; | 1199 | } FlagDef; |
| 1233 | | 1200 | |
| 1234 | static const FlagDef warning_defs[] = { | | |
| 1235 | { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, | | |
| 1236 | { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, | | |
| 1237 | { offsetof(TCCState, warn_error), 0, "error" }, | | |
| 1238 | { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, | | |
| 1239 | "implicit-function-declaration" }, | | |
| 1240 | }; | | |
| 1241 | | | |
| 1242 | static int no_flag(const char **pp) | 1201 | static int no_flag(const char **pp) |
| 1243 | { | 1202 | { |
| 1244 | const char *p = *pp; | 1203 | const char *p = *pp; |
| @@ -1248,73 +1207,35 @@ static int no_flag(const char **pp) · 3 unmodified lines |
| 1248 | return 1; | 1207 | return 1; |
| 1249 | } | 1208 | } |
| 1250 | | 1209 | |
| 1251 | ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, | 1210 | ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name) |
| 1252 | const char *name, int value) | | |
| 1253 | { | 1211 | { |
| 1254 | int i; | 1212 | int value, ret; |
| 1255 | const FlagDef *p; | 1213 | const FlagDef *p; |
| 1256 | const char *r; | 1214 | const char *r; |
| 1257 | | 1215 | |
| | 1216 | value = 1; |
| 1258 | r = name; | 1217 | r = name; |
| 1259 | if (no_flag(&r)) | 1218 | if (no_flag(&r)) |
| 1260 | value = !value; | 1219 | value = 0; |
| 1261 | | | |
| 1262 | for(i = 0, p = flags; i < nb_flags; i++, p++) { | | |
| 1263 | if (!strcmp(r, p->name)) | | |
| 1264 | goto found; | | |
| 1265 | } | | |
| 1266 | return -1; | | |
| 1267 | found: | | |
| 1268 | if (p->flags & FD_INVERT) | | |
| 1269 | value = !value; | | |
| 1270 | *(int *)((uint8_t *)s + p->offset) = value; | | |
| 1271 | return 0; | | |
| 1272 | } | | |
| 1273 | | 1220 | |
| 1274 | /* set/reset a warning */ | 1221 | for (ret = -1, p = flags; p->name; ++p) { |
| 1275 | static int tcc_set_warning(TCCState *s, const char *warning_name, int value) | 1222 | if (ret) { |
| 1276 | { | 1223 | if (strcmp(r, p->name)) |
| 1277 | int i; | 1224 | continue; |
| 1278 | const FlagDef *p; | 1225 | } else { |
| 1279 | | 1226 | if (0 == (p->flags & WD_ALL)) |
| 1280 | if (!strcmp(warning_name, "all")) { | 1227 | continue; |
| 1281 | for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) { | 1228 | } |
| 1282 | if (p->flags & WD_ALL) | 1229 | if (p->offset) { |
| 1283 | *(int *)((uint8_t *)s + p->offset) = 1; | 1230 | *(int*)((char *)s + p->offset) = |
| | 1231 | p->flags & FD_INVERT ? !value : value; |
| | 1232 | if (ret) |
| | 1233 | return 0; |
| | 1234 | } else { |
| | 1235 | ret = 0; |
| 1284 | } | 1236 | } |
| 1285 | return 0; | | |
| 1286 | } else { | | |
| 1287 | return set_flag(s, warning_defs, countof(warning_defs), | | |
| 1288 | warning_name, value); | | |
| 1289 | } | 1237 | } |
| 1290 | } | 1238 | return ret; |
| 1291 | | | |
| 1292 | static const FlagDef flag_defs[] = { | | |
| 1293 | { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" }, | | |
| 1294 | { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" }, | | |
| 1295 | { offsetof(TCCState, nocommon), FD_INVERT, "common" }, | | |
| 1296 | { offsetof(TCCState, leading_underscore), 0, "leading-underscore" }, | | |
| 1297 | { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, | | |
| 1298 | { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" }, | | |
| 1299 | { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" }, | | |
| 1300 | }; | | |
| 1301 | | | |
| 1302 | /* set/reset a flag */ | | |
| 1303 | static int tcc_set_flag(TCCState *s, const char *flag_name, int value) | | |
| 1304 | { | | |
| 1305 | return set_flag(s, flag_defs, countof(flag_defs), | | |
| 1306 | flag_name, value); | | |
| 1307 | } | | |
| 1308 | | | |
| 1309 | static const FlagDef m_defs[] = { | | |
| 1310 | #ifdef TCC_TARGET_X86_64 | | |
| 1311 | { offsetof(TCCState, nosse), FD_INVERT, "sse" }, | | |
| 1312 | #endif | | |
| 1313 | { 0, 0, " no flag" }, | | |
| 1314 | }; | | |
| 1315 | static int tcc_set_m_flag(TCCState *s, const char *flag_name, int value) | | |
| 1316 | { | | |
| 1317 | return set_flag(s, m_defs, countof(m_defs), flag_name, value); | | |
| 1318 | } | 1239 | } |
| 1319 | | 1240 | |
| 1320 | static int strstart(const char *val, const char **str) | 1241 | static int strstart(const char *val, const char **str) |
| @@ -1517,7 +1438,6 @@ enum { · 196 unmodified lines |
| 1517 | TCC_OPTION_c, | 1438 | TCC_OPTION_c, |
| 1518 | TCC_OPTION_dumpversion, | 1439 | TCC_OPTION_dumpversion, |
| 1519 | TCC_OPTION_d, | 1440 | TCC_OPTION_d, |
| 1520 | TCC_OPTION_float_abi, | | |
| 1521 | TCC_OPTION_static, | 1441 | TCC_OPTION_static, |
| 1522 | TCC_OPTION_std, | 1442 | TCC_OPTION_std, |
| 1523 | TCC_OPTION_shared, | 1443 | TCC_OPTION_shared, |
| @@ -1530,7 +1450,7 @@ enum { · 6 unmodified lines |
| 1530 | TCC_OPTION_Wp, | 1450 | TCC_OPTION_Wp, |
| 1531 | TCC_OPTION_W, | 1451 | TCC_OPTION_W, |
| 1532 | TCC_OPTION_O, | 1452 | TCC_OPTION_O, |
| 1533 | TCC_OPTION_mms_bitfields, | 1453 | TCC_OPTION_mfloat_abi, |
| 1534 | TCC_OPTION_m, | 1454 | TCC_OPTION_m, |
| 1535 | TCC_OPTION_f, | 1455 | TCC_OPTION_f, |
| 1536 | TCC_OPTION_isystem, | 1456 | TCC_OPTION_isystem, |
| @@ -1578,9 +1498,6 @@ static const TCCOption tcc_options[] = { · 41 unmodified lines |
| 1578 | { "c", TCC_OPTION_c, 0 }, | 1498 | { "c", TCC_OPTION_c, 0 }, |
| 1579 | { "dumpversion", TCC_OPTION_dumpversion, 0}, | 1499 | { "dumpversion", TCC_OPTION_dumpversion, 0}, |
| 1580 | { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1500 | { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1581 | #ifdef TCC_TARGET_ARM | | |
| 1582 | { "mfloat-abi", TCC_OPTION_float_abi, TCC_OPTION_HAS_ARG }, | | |
| 1583 | #endif | | |
| 1584 | { "static", TCC_OPTION_static, 0 }, | 1501 | { "static", TCC_OPTION_static, 0 }, |
| 1585 | { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1502 | { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1586 | { "shared", TCC_OPTION_shared, 0 }, | 1503 | { "shared", TCC_OPTION_shared, 0 }, |
| @@ -1598,8 +1515,10 @@ static const TCCOption tcc_options[] = { · 11 unmodified lines |
| 1598 | { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1515 | { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1599 | { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1516 | { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1600 | { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1517 | { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1601 | { "mms-bitfields", TCC_OPTION_mms_bitfields, 0}, /* must go before option 'm' */ | 1518 | #ifdef TCC_TARGET_ARM |
| 1602 | { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, | 1519 | { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG }, |
| | 1520 | #endif |
| | 1521 | { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1603 | { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, | 1522 | { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, |
| 1604 | { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, | 1523 | { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, |
| 1605 | { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG }, | 1524 | { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG }, |
| @@ -1617,6 +1536,35 @@ static const TCCOption tcc_options[] = { · 11 unmodified lines |
| 1617 | { NULL, 0, 0 }, | 1536 | { NULL, 0, 0 }, |
| 1618 | }; | 1537 | }; |
| 1619 | | 1538 | |
| | 1539 | static const FlagDef options_W[] = { |
| | 1540 | { 0, 0, "all" }, |
| | 1541 | { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, |
| | 1542 | { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, |
| | 1543 | { offsetof(TCCState, warn_error), 0, "error" }, |
| | 1544 | { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, |
| | 1545 | "implicit-function-declaration" }, |
| | 1546 | { 0, 0, NULL } |
| | 1547 | }; |
| | 1548 | |
| | 1549 | static const FlagDef options_f[] = { |
| | 1550 | { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" }, |
| | 1551 | { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" }, |
| | 1552 | { offsetof(TCCState, nocommon), FD_INVERT, "common" }, |
| | 1553 | { offsetof(TCCState, leading_underscore), 0, "leading-underscore" }, |
| | 1554 | { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, |
| | 1555 | { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" }, |
| | 1556 | { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" }, |
| | 1557 | { 0, 0, NULL } |
| | 1558 | }; |
| | 1559 | |
| | 1560 | static const FlagDef options_m[] = { |
| | 1561 | { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" }, |
| | 1562 | #ifdef TCC_TARGET_X86_64 |
| | 1563 | { offsetof(TCCState, nosse), FD_INVERT, "sse" }, |
| | 1564 | #endif |
| | 1565 | { 0, 0, NULL } |
| | 1566 | }; |
| | 1567 | |
| 1620 | static void parse_option_D(TCCState *s1, const char *optarg) | 1568 | static void parse_option_D(TCCState *s1, const char *optarg) |
| 1621 | { | 1569 | { |
| 1622 | char *sym = tcc_strdup(optarg); | 1570 | char *sym = tcc_strdup(optarg); |
| @@ -1766,18 +1714,6 @@ reparse: · 143 unmodified lines |
| 1766 | else | 1714 | else |
| 1767 | goto unsupported_option; | 1715 | goto unsupported_option; |
| 1768 | break; | 1716 | break; |
| 1769 | #ifdef TCC_TARGET_ARM | | |
| 1770 | case TCC_OPTION_float_abi: | | |
| 1771 | /* tcc doesn't support soft float yet */ | | |
| 1772 | if (!strcmp(optarg, "softfp")) { | | |
| 1773 | s->float_abi = ARM_SOFTFP_FLOAT; | | |
| 1774 | tcc_undefine_symbol(s, "__ARM_PCS_VFP"); | | |
| 1775 | } else if (!strcmp(optarg, "hard")) | | |
| 1776 | s->float_abi = ARM_HARD_FLOAT; | | |
| 1777 | else | | |
| 1778 | tcc_error("unsupported float abi '%s'", optarg); | | |
| 1779 | break; | | |
| 1780 | #endif | | |
| 1781 | case TCC_OPTION_static: | 1717 | case TCC_OPTION_static: |
| 1782 | s->static_link = 1; | 1718 | s->static_link = 1; |
| 1783 | break; | 1719 | break; |
| @@ -1791,12 +1727,6 @@ reparse: · 7 unmodified lines |
| 1791 | case TCC_OPTION_soname: | 1727 | case TCC_OPTION_soname: |
| 1792 | s->soname = tcc_strdup(optarg); | 1728 | s->soname = tcc_strdup(optarg); |
| 1793 | break; | 1729 | break; |
| 1794 | case TCC_OPTION_m: | | |
| 1795 | if (!strcmp(optarg, "32") || !strcmp(optarg, "64")) | | |
| 1796 | s->option_m = tcc_strdup(optarg); | | |
| 1797 | else if (tcc_set_m_flag(s, optarg, 1) < 0) | | |
| 1798 | goto unsupported_option; | | |
| 1799 | break; | | |
| 1800 | case TCC_OPTION_o: | 1730 | case TCC_OPTION_o: |
| 1801 | if (s->outfile) { | 1731 | if (s->outfile) { |
| 1802 | tcc_warning("multiple -o option"); | 1732 | tcc_warning("multiple -o option"); |
| @@ -1841,11 +1771,31 @@ reparse: · 38 unmodified lines |
| 1841 | do ++s->verbose; while (*optarg++ == 'v'); | 1771 | do ++s->verbose; while (*optarg++ == 'v'); |
| 1842 | break; | 1772 | break; |
| 1843 | case TCC_OPTION_f: | 1773 | case TCC_OPTION_f: |
| 1844 | if (tcc_set_flag(s, optarg, 1) < 0) | 1774 | if (set_flag(s, options_f, optarg) < 0) |
| | 1775 | goto unsupported_option; |
| | 1776 | break; |
| | 1777 | #ifdef TCC_TARGET_ARM |
| | 1778 | case TCC_OPTION_mfloat_abi: |
| | 1779 | /* tcc doesn't support soft float yet */ |
| | 1780 | if (!strcmp(optarg, "softfp")) { |
| | 1781 | s->float_abi = ARM_SOFTFP_FLOAT; |
| | 1782 | tcc_undefine_symbol(s, "__ARM_PCS_VFP"); |
| | 1783 | } else if (!strcmp(optarg, "hard")) |
| | 1784 | s->float_abi = ARM_HARD_FLOAT; |
| | 1785 | else |
| | 1786 | tcc_error("unsupported float abi '%s'", optarg); |
| | 1787 | break; |
| | 1788 | #endif |
| | 1789 | case TCC_OPTION_m: |
| | 1790 | if (set_flag(s, options_m, optarg) == 0) |
| | 1791 | break; |
| | 1792 | else if (x = atoi(optarg), x == 32 || x == 64) |
| | 1793 | s->cross_target = x; |
| | 1794 | else |
| 1845 | goto unsupported_option; | 1795 | goto unsupported_option; |
| 1846 | break; | 1796 | break; |
| 1847 | case TCC_OPTION_W: | 1797 | case TCC_OPTION_W: |
| 1848 | if (tcc_set_warning(s, optarg, 1) < 0) | 1798 | if (set_flag(s, options_W, optarg) < 0) |
| 1849 | goto unsupported_option; | 1799 | goto unsupported_option; |
| 1850 | break; | 1800 | break; |
| 1851 | case TCC_OPTION_w: | 1801 | case TCC_OPTION_w: |
| @@ -1893,9 +1843,6 @@ reparse: · 41 unmodified lines |
| 1893 | case TCC_OPTION_O: | 1843 | case TCC_OPTION_O: |
| 1894 | last_o = atoi(optarg); | 1844 | last_o = atoi(optarg); |
| 1895 | break; | 1845 | break; |
| 1896 | case TCC_OPTION_mms_bitfields: | | |
| 1897 | s->ms_bitfields = 1; | | |
| 1898 | break; | | |
| 1899 | case TCC_OPTION_traditional: | 1846 | case TCC_OPTION_traditional: |
| 1900 | case TCC_OPTION_pedantic: | 1847 | case TCC_OPTION_pedantic: |
| 1901 | case TCC_OPTION_pipe: | 1848 | case TCC_OPTION_pipe: |