* -dt now with lowercase t * test snippets now separated by real preprocessor statements which is valid C also for other compilers #if defined test_xxx < test snippet x > #elif defined test_yyy < test snippet y > #elif ... #endif * simpler implementation, behaves like -run if no 'test_...' macros are seen, works with -E too * for demonstration I combined some of the small tests for errors and warnings (56..63,74) in "60_errors_and_warnings.c"
Unified · Split
| @@ -508,8 +508,9 @@ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) · 507 unmodified lines | ||
| 508 | 508 | |
| 509 | 509 | if (!s1->error_func) { |
| 510 | 510 | /* default case: stderr */ |
| 511 | − if (s1->ppfp) /* print a newline during tcc -E */ | |
| 512 | − fprintf(s1->ppfp, "\n"), fflush(s1->ppfp); | |
| 511 | + if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout) | |
| 512 | + /* print a newline during tcc -E */ | |
| 513 | + printf("\n"), fflush(stdout); | |
| 513 | 514 | fflush(stdout); /* flush -v output */ |
| 514 | 515 | fprintf(stderr, "%s\n", buf); |
| 515 | 516 | fflush(stderr); /* print error/warning now (win32) */ |
| @@ -587,6 +588,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) · 71 unmodified lines | ||
| 587 | 588 | bf->fd = -1; |
| 588 | 589 | bf->prev = file; |
| 589 | 590 | file = bf; |
| 591 | + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | |
| 590 | 592 | } |
| 591 | 593 | |
| 592 | 594 | ST_FUNC void tcc_close(void) |
| @@ -622,36 +624,36 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename) · 29 unmodified lines | ||
| 622 | 624 | return fd; |
| 623 | 625 | } |
| 624 | 626 | |
| 625 | −/* compile the C file opened in 'file'. Return non zero if errors. */ | |
| 627 | +/* compile the file opened in 'file'. Return non zero if errors. */ | |
| 626 | 628 | static int tcc_compile(TCCState *s1) |
| 627 | 629 | { |
| 628 | 630 | Sym *define_start; |
| 631 | + int filetype, is_asm; | |
| 629 | 632 | |
| 630 | 633 | define_start = define_stack; |
| 634 | + filetype = s1->filetype; | |
| 635 | + is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP; | |
| 636 | + | |
| 631 | 637 | if (setjmp(s1->error_jmp_buf) == 0) { |
| 632 | 638 | s1->nb_errors = 0; |
| 633 | 639 | s1->error_set_jmp_enabled = 1; |
| 634 | 640 | |
| 635 | − preprocess_start(s1); | |
| 636 | − tccgen_start(s1); | |
| 637 | −#ifdef INC_DEBUG | |
| 638 | − printf("%s: **** new file\n", file->filename); | |
| 641 | + preprocess_start(s1, is_asm); | |
| 642 | + if (s1->output_type == TCC_OUTPUT_PREPROCESS) { | |
| 643 | + tcc_preprocess(s1); | |
| 644 | + } else if (is_asm) { | |
| 645 | +#ifdef CONFIG_TCC_ASM | |
| 646 | + tcc_assemble(s1, filetype == AFF_TYPE_ASMPP); | |
| 647 | +#else | |
| 648 | + tcc_error_noabort("asm not supported"); | |
| 639 | 649 | #endif |
| 640 | − ch = file->buf_ptr[0]; | |
| 641 | − tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | |
| 642 | − parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; | |
| 643 | − next(); | |
| 644 | − decl(VT_CONST); | |
| 645 | − if (tok != TOK_EOF) | |
| 646 | − expect("declaration"); | |
| 647 | − /* free defines here already on behalf of of M.M.'s possibly existing | |
| 648 | − experimental preprocessor implementation. The normal call below | |
| 649 | − is still there to free after error-longjmp */ | |
| 650 | − free_defines(define_start); | |
| 651 | − tccgen_end(s1); | |
| 650 | + } else { | |
| 651 | + tccgen_compile(s1); | |
| 652 | + } | |
| 652 | 653 | } |
| 653 | 654 | s1->error_set_jmp_enabled = 0; |
| 654 | 655 | |
| 656 | + preprocess_end(s1); | |
| 655 | 657 | free_inline_functions(s1); |
| 656 | 658 | /* reset define stack, but keep -D and built-ins */ |
| 657 | 659 | free_defines(define_start); |
| @@ -689,10 +691,8 @@ LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *valu · 31 unmodified lines | ||
| 689 | 691 | memcpy(file->buffer + len1 + 1, value, len2); |
| 690 | 692 | |
| 691 | 693 | /* parse with define parser */ |
| 692 | − ch = file->buf_ptr[0]; | |
| 693 | 694 | next_nomacro(); |
| 694 | 695 | parse_define(); |
| 695 | − | |
| 696 | 696 | tcc_close(); |
| 697 | 697 | } |
| 698 | 698 | |
| @@ -713,6 +713,8 @@ static void tcc_cleanup(void) · 14 unmodified lines | ||
| 713 | 713 | { |
| 714 | 714 | if (NULL == tcc_state) |
| 715 | 715 | return; |
| 716 | + while (file) | |
| 717 | + tcc_close(); | |
| 716 | 718 | tccpp_delete(tcc_state); |
| 717 | 719 | tcc_state = NULL; |
| 718 | 720 | /* free sym_pools */ |
| @@ -993,26 +995,7 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 274 unmodified lines | ||
| 993 | 995 | |
| 994 | 996 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) |
| 995 | 997 | { |
| 996 | − int ret, filetype; | |
| 997 | − | |
| 998 | − filetype = flags & 0x0F; | |
| 999 | − if (filetype == 0) { | |
| 1000 | − /* use a file extension to detect a filetype */ | |
| 1001 | − const char *ext = tcc_fileextension(filename); | |
| 1002 | − if (ext[0]) { | |
| 1003 | − ext++; | |
| 1004 | − if (!strcmp(ext, "S")) | |
| 1005 | − filetype = AFF_TYPE_ASMPP; | |
| 1006 | − else if (!strcmp(ext, "s")) | |
| 1007 | − filetype = AFF_TYPE_ASM; | |
| 1008 | − else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) | |
| 1009 | − filetype = AFF_TYPE_C; | |
| 1010 | − else | |
| 1011 | − filetype = AFF_TYPE_BIN; | |
| 1012 | − } else { | |
| 1013 | − filetype = AFF_TYPE_C; | |
| 1014 | − } | |
| 1015 | − } | |
| 998 | + int ret; | |
| 1016 | 999 | |
| 1017 | 1000 | /* open the file */ |
| 1018 | 1001 | ret = tcc_open(s1, filename); |
| @@ -1026,26 +1009,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 7 unmodified lines | ||
| 1026 | 1009 | dynarray_add(&s1->target_deps, &s1->nb_target_deps, |
| 1027 | 1010 | tcc_strdup(filename)); |
| 1028 | 1011 | |
| 1029 | − parse_flags = 0; | |
| 1030 | − /* if .S file, define __ASSEMBLER__ like gcc does */ | |
| 1031 | − if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) { | |
| 1032 | − tcc_define_symbol(s1, "__ASSEMBLER__", NULL); | |
| 1033 | − parse_flags = PARSE_FLAG_ASM_FILE; | |
| 1034 | − } | |
| 1035 | − | |
| 1036 | − if (flags & AFF_PREPROCESS) { | |
| 1037 | − ret = tcc_preprocess(s1); | |
| 1038 | − } else if (filetype == AFF_TYPE_C) { | |
| 1039 | − ret = tcc_compile(s1); | |
| 1040 | −#ifdef CONFIG_TCC_ASM | |
| 1041 | − } else if (filetype == AFF_TYPE_ASMPP) { | |
| 1042 | − /* non preprocessed assembler */ | |
| 1043 | − ret = tcc_assemble(s1, 1); | |
| 1044 | − } else if (filetype == AFF_TYPE_ASM) { | |
| 1045 | − /* preprocessed assembler */ | |
| 1046 | − ret = tcc_assemble(s1, 0); | |
| 1047 | −#endif | |
| 1048 | − } else { | |
| 1012 | + if (flags & AFF_TYPE_BIN) { | |
| 1049 | 1013 | ElfW(Ehdr) ehdr; |
| 1050 | 1014 | int fd, obj_type; |
| 1051 | 1015 | |
| @@ -1098,6 +1062,8 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 46 unmodified lines | ||
| 1098 | 1062 | tcc_error_noabort("unrecognized file type"); |
| 1099 | 1063 | break; |
| 1100 | 1064 | } |
| 1065 | + } else { | |
| 1066 | + ret = tcc_compile(s1); | |
| 1101 | 1067 | } |
| 1102 | 1068 | tcc_close(); |
| 1103 | 1069 | return ret; |
| @@ -1105,10 +1071,27 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1 unmodified line | ||
| 1105 | 1071 | |
| 1106 | 1072 | LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) |
| 1107 | 1073 | { |
| 1108 | − if (s->output_type == TCC_OUTPUT_PREPROCESS) | |
| 1109 | − return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype); | |
| 1110 | − else | |
| 1111 | − return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype); | |
| 1074 | + int filetype = s->filetype; | |
| 1075 | + int flags = AFF_PRINT_ERROR; | |
| 1076 | + if (filetype == 0) { | |
| 1077 | + /* use a file extension to detect a filetype */ | |
| 1078 | + const char *ext = tcc_fileextension(filename); | |
| 1079 | + if (ext[0]) { | |
| 1080 | + ext++; | |
| 1081 | + if (!strcmp(ext, "S")) | |
| 1082 | + filetype = AFF_TYPE_ASMPP; | |
| 1083 | + else if (!strcmp(ext, "s")) | |
| 1084 | + filetype = AFF_TYPE_ASM; | |
| 1085 | + else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) | |
| 1086 | + filetype = AFF_TYPE_C; | |
| 1087 | + else | |
| 1088 | + flags |= AFF_TYPE_BIN; | |
| 1089 | + } else { | |
| 1090 | + filetype = AFF_TYPE_C; | |
| 1091 | + } | |
| 1092 | + s->filetype = filetype; | |
| 1093 | + } | |
| 1094 | + return tcc_add_file_internal(s, filename, flags); | |
| 1112 | 1095 | } |
| 1113 | 1096 | |
| 1114 | 1097 | LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) |
| @@ -1799,8 +1782,8 @@ reparse: · 684 unmodified lines | ||
| 1799 | 1782 | s->dflag = 3; |
| 1800 | 1783 | else if (*optarg == 'M') |
| 1801 | 1784 | s->dflag = 7; |
| 1802 | − else if (*optarg == 'T') | |
| 1803 | − s->do_test = argc; | |
| 1785 | + else if (*optarg == 't') | |
| 1786 | + s->dflag = 16; | |
| 1804 | 1787 | else if (isnum(*optarg)) |
| 1805 | 1788 | g_debug = atoi(optarg); |
| 1806 | 1789 | else |
| @@ -91,6 +91,7 @@ static const char help2[] = · 90 unmodified lines | ||
| 91 | 91 | " -static link to static libraries (not recommended)\n" |
| 92 | 92 | " -dumpversion print version\n" |
| 93 | 93 | " -print-search-dirs print search paths\n" |
| 94 | + " -dt with -run/-E: auto-define 'test_...' macros\n" | |
| 94 | 95 | "Ignored options:\n" |
| 95 | 96 | " --param -pedantic -pipe -s -std -traditional\n" |
| 96 | 97 | "-W... warnings:\n" |
| @@ -244,18 +245,21 @@ static unsigned getclock_ms(void) · 147 unmodified lines | ||
| 244 | 245 | #endif |
| 245 | 246 | } |
| 246 | 247 | |
| 247 | −int main(int argc, char **argv) | |
| 248 | +int main(int argc0, char **argv0) | |
| 248 | 249 | { |
| 249 | 250 | TCCState *s; |
| 250 | − int ret, opt, n = 0; | |
| 251 | + int ret, opt, n = 0, t = 0; | |
| 251 | 252 | unsigned start_time = 0; |
| 252 | 253 | const char *first_file; |
| 254 | + int argc; char **argv; | |
| 255 | + FILE *ppfp = stdout; | |
| 253 | 256 | |
| 254 | 257 | redo: |
| 258 | + argc = argc0, argv = argv0; | |
| 255 | 259 | s = tcc_new(); |
| 256 | 260 | opt = tcc_parse_args(s, &argc, &argv, 1); |
| 257 | 261 | |
| 258 | − if (n == 0) { | |
| 262 | + if ((n | t) == 0) { | |
| 259 | 263 | if (opt == OPT_HELP) |
| 260 | 264 | return printf(help), 1; |
| 261 | 265 | if (opt == OPT_HELP2) |
| @@ -282,17 +286,11 @@ redo: · 20 unmodified lines | ||
| 282 | 286 | n = s->nb_files; |
| 283 | 287 | if (n == 0) |
| 284 | 288 | tcc_error("no input files\n"); |
| 285 | −#ifdef TCC_IS_NATIVE | |
| 286 | − if (s->do_test) | |
| 287 | − tcc_tool_test(s, argc, argv); /* maybe never returns */ | |
| 288 | −#endif | |
| 289 | 289 | |
| 290 | 290 | if (s->output_type == TCC_OUTPUT_PREPROCESS) { |
| 291 | − if (!s->outfile) { | |
| 292 | − s->ppfp = stdout; | |
| 293 | − } else { | |
| 294 | − s->ppfp = fopen(s->outfile, "w"); | |
| 295 | − if (!s->ppfp) | |
| 291 | + if (s->outfile) { | |
| 292 | + ppfp = fopen(s->outfile, "w"); | |
| 293 | + if (!ppfp) | |
| 296 | 294 | tcc_error("could not write '%s'", s->outfile); |
| 297 | 295 | } |
| 298 | 296 | } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { |
| @@ -313,6 +311,11 @@ redo: · 14 unmodified lines | ||
| 313 | 311 | if (s->output_type == 0) |
| 314 | 312 | s->output_type = TCC_OUTPUT_EXE; |
| 315 | 313 | tcc_set_output_type(s, s->output_type); |
| 314 | + s->ppfp = ppfp; | |
| 315 | + | |
| 316 | + if ((s->output_type == TCC_OUTPUT_MEMORY | |
| 317 | + || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16)) | |
| 318 | + s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files; | |
| 316 | 319 | |
| 317 | 320 | /* compile or add each files or library */ |
| 318 | 321 | for (first_file = NULL, ret = 0;;) { |
| @@ -338,8 +341,7 @@ redo: · 19 unmodified lines | ||
| 338 | 341 | } |
| 339 | 342 | |
| 340 | 343 | if (s->output_type == TCC_OUTPUT_PREPROCESS) { |
| 341 | − if (s->outfile) | |
| 342 | − fclose(s->ppfp); | |
| 344 | + ; | |
| 343 | 345 | } else if (0 == ret) { |
| 344 | 346 | if (s->output_type == TCC_OUTPUT_MEMORY) { |
| 345 | 347 | #ifdef TCC_IS_NATIVE |
| @@ -355,10 +357,18 @@ redo: · 9 unmodified lines | ||
| 355 | 357 | } |
| 356 | 358 | } |
| 357 | 359 | |
| 358 | − if (s->do_bench && ret == 0 && n == 0) | |
| 360 | + if (t) | |
| 361 | + ret = 0; | |
| 362 | + if (s->run_test) | |
| 363 | + t = 0; | |
| 364 | + if (s->do_bench && (n | t | ret) == 0) | |
| 359 | 365 | tcc_print_stats(s, getclock_ms() - start_time); |
| 360 | 366 | tcc_delete(s); |
| 361 | 367 | if (ret == 0 && n) |
| 362 | 368 | goto redo; /* compile more files with -c */ |
| 369 | + if (t) | |
| 370 | + goto redo; /* run more tests with -dt -run */ | |
| 371 | + if (ppfp && ppfp != stdout) | |
| 372 | + fclose(ppfp); | |
| 363 | 373 | return ret; |
| 364 | 374 | } |
| @@ -556,15 +556,6 @@ typedef struct BufferedFile { · 555 unmodified lines | ||
| 556 | 556 | #define CH_EOB '\\' /* end of buffer or '\0' char in file */ |
| 557 | 557 | #define CH_EOF (-1) /* end of file */ |
| 558 | 558 | |
| 559 | −/* parsing state (used to save parser state to reparse part of the | |
| 560 | − source several times) */ | |
| 561 | −typedef struct ParseState { | |
| 562 | − const int *macro_ptr; | |
| 563 | − int line_num; | |
| 564 | − int tok; | |
| 565 | − CValue tokc; | |
| 566 | −} ParseState; | |
| 567 | − | |
| 568 | 559 | /* used to record tokens */ |
| 569 | 560 | typedef struct TokenString { |
| 570 | 561 | int *str; |
| @@ -572,6 +563,7 @@ typedef struct TokenString { · 1 unmodified line | ||
| 572 | 563 | int lastlen; |
| 573 | 564 | int allocated_len; |
| 574 | 565 | int last_line_num; |
| 566 | + int save_line_num; | |
| 575 | 567 | /* used to chain token-strings with begin/end_macro() */ |
| 576 | 568 | struct TokenString *prev; |
| 577 | 569 | const int *prev_ptr; |
| @@ -675,6 +667,7 @@ struct TCCState { · 97 unmodified lines | ||
| 675 | 667 | #ifdef TCC_TARGET_ARM |
| 676 | 668 | enum float_abi float_abi; /* float ABI of the generated code*/ |
| 677 | 669 | #endif |
| 670 | + int run_test; /* nth test to run with -dt -run */ | |
| 678 | 671 | |
| 679 | 672 | addr_t text_addr; /* address of text section */ |
| 680 | 673 | int has_text_addr; |
| @@ -813,7 +806,6 @@ struct TCCState { · 132 unmodified lines | ||
| 813 | 806 | int option_pthread; /* -pthread option */ |
| 814 | 807 | int argc; |
| 815 | 808 | char **argv; |
| 816 | − int do_test; | |
| 817 | 809 | }; |
| 818 | 810 | |
| 819 | 811 | struct filespec { |
| @@ -1145,14 +1137,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 325 unmodified lines | ||
| 1145 | 1137 | /* flags: */ |
| 1146 | 1138 | #define AFF_PRINT_ERROR 0x10 /* print error if file not found */ |
| 1147 | 1139 | #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */ |
| 1148 | −#define AFF_PREPROCESS 0x40 /* preprocess file */ | |
| 1149 | −/* combined with: */ | |
| 1140 | +#define AFF_TYPE_BIN 0x40 /* file to add is binary */ | |
| 1141 | +/* s->filetype: */ | |
| 1150 | 1142 | #define AFF_TYPE_NONE 0 |
| 1151 | 1143 | #define AFF_TYPE_C 1 |
| 1152 | 1144 | #define AFF_TYPE_ASM 2 |
| 1153 | 1145 | #define AFF_TYPE_ASMPP 3 |
| 1154 | −#define AFF_TYPE_BIN 4 | |
| 1155 | −#define AFF_TYPE_LIB 5 | |
| 1146 | +#define AFF_TYPE_LIB 4 | |
| 1156 | 1147 | /* values from tcc_object_type(...) */ |
| 1157 | 1148 | #define AFF_BINTYPE_REL 1 |
| 1158 | 1149 | #define AFF_BINTYPE_DYN 2 |
| @@ -1220,9 +1211,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len); · 61 unmodified lines | ||
| 1220 | 1211 | ST_FUNC const char *get_tok_str(int v, CValue *cv); |
| 1221 | 1212 | ST_FUNC void begin_macro(TokenString *str, int alloc); |
| 1222 | 1213 | ST_FUNC void end_macro(void); |
| 1223 | −ST_FUNC void set_idnum(int c, int val); | |
| 1224 | −ST_FUNC void save_parse_state(ParseState *s); | |
| 1225 | −ST_FUNC void restore_parse_state(ParseState *s); | |
| 1214 | +ST_FUNC int set_idnum(int c, int val); | |
| 1226 | 1215 | ST_INLN void tok_str_new(TokenString *s); |
| 1227 | 1216 | ST_FUNC TokenString *tok_str_alloc(void); |
| 1228 | 1217 | ST_FUNC void tok_str_free(TokenString *s); |
| @@ -1241,7 +1230,8 @@ ST_FUNC void preprocess(int is_bof); · 12 unmodified lines | ||
| 1241 | 1230 | ST_FUNC void next_nomacro(void); |
| 1242 | 1231 | ST_FUNC void next(void); |
| 1243 | 1232 | ST_INLN void unget_tok(int last_tok); |
| 1244 | −ST_FUNC void preprocess_start(TCCState *s1); | |
| 1233 | +ST_FUNC void preprocess_start(TCCState *s1, int is_asm); | |
| 1234 | +ST_FUNC void preprocess_end(TCCState *s1); | |
| 1245 | 1235 | ST_FUNC void tccpp_new(TCCState *s); |
| 1246 | 1236 | ST_FUNC void tccpp_delete(TCCState *s); |
| 1247 | 1237 | ST_FUNC int tcc_preprocess(TCCState *s1); |
| @@ -1298,9 +1288,7 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym); · 50 unmodified lines | ||
| 1298 | 1288 | ST_FUNC void tcc_debug_funcend(TCCState *s1, int size); |
| 1299 | 1289 | ST_FUNC void tcc_debug_line(TCCState *s1); |
| 1300 | 1290 | |
| 1301 | −ST_FUNC void tccgen_start(TCCState *s1); | |
| 1302 | −ST_FUNC void tccgen_end(TCCState *s1); | |
| 1303 | − | |
| 1291 | +ST_FUNC int tccgen_compile(TCCState *s1); | |
| 1304 | 1292 | ST_FUNC void free_inline_functions(TCCState *s); |
| 1305 | 1293 | ST_FUNC void check_vstack(void); |
| 1306 | 1294 | |
| @@ -1342,7 +1330,6 @@ ST_FUNC void expr_prod(void); · 35 unmodified lines | ||
| 1342 | 1330 | ST_FUNC void expr_sum(void); |
| 1343 | 1331 | ST_FUNC void gexpr(void); |
| 1344 | 1332 | ST_FUNC int expr_const(void); |
| 1345 | −ST_FUNC void decl(int l); | |
| 1346 | 1333 | #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 |
| 1347 | 1334 | ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); |
| 1348 | 1335 | #endif |
| @@ -628,20 +628,16 @@ static void asm_parse_directive(TCCState *s1, int global) · 627 unmodified lines | ||
| 628 | 628 | { |
| 629 | 629 | int repeat; |
| 630 | 630 | TokenString *init_str; |
| 631 | − ParseState saved_parse_state = {0}; | |
| 632 | 631 | next(); |
| 633 | 632 | repeat = asm_int_expr(s1); |
| 634 | 633 | init_str = tok_str_alloc(); |
| 635 | − next(); | |
| 636 | − while ((tok != TOK_ASMDIR_endr) && (tok != CH_EOF)) { | |
| 634 | + while (next(), tok != TOK_ASMDIR_endr) { | |
| 635 | + if (tok == CH_EOF) | |
| 636 | + tcc_error("we at end of file, .endr not found"); | |
| 637 | 637 | tok_str_add_tok(init_str); |
| 638 | − next(); | |
| 639 | 638 | } |
| 640 | − if (tok == CH_EOF) tcc_error("we at end of file, .endr not found"); | |
| 641 | − next(); | |
| 642 | 639 | tok_str_add(init_str, -1); |
| 643 | 640 | tok_str_add(init_str, 0); |
| 644 | − save_parse_state(&saved_parse_state); | |
| 645 | 641 | begin_macro(init_str, 1); |
| 646 | 642 | while (repeat-- > 0) { |
| 647 | 643 | tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS), |
| @@ -649,7 +645,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line | ||
| 649 | 645 | macro_ptr = init_str->str; |
| 650 | 646 | } |
| 651 | 647 | end_macro(); |
| 652 | − restore_parse_state(&saved_parse_state); | |
| 648 | + next(); | |
| 653 | 649 | break; |
| 654 | 650 | } |
| 655 | 651 | case TOK_ASMDIR_org: |
| @@ -917,13 +913,10 @@ static void asm_parse_directive(TCCState *s1, int global) · 261 unmodified lines | ||
| 917 | 913 | static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) |
| 918 | 914 | { |
| 919 | 915 | int opcode; |
| 916 | + int saved_parse_flags = parse_flags; | |
| 920 | 917 | |
| 921 | 918 | /* XXX: undefine C labels */ |
| 922 | − | |
| 923 | − ch = file->buf_ptr[0]; | |
| 924 | − tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | |
| 925 | 919 | parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR; |
| 926 | − set_idnum('.', IS_ID); | |
| 927 | 920 | if (do_preprocess) |
| 928 | 921 | parse_flags |= PARSE_FLAG_PREPROCESS; |
| 929 | 922 | for(;;) { |
| @@ -990,30 +983,22 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 60 unmodified lines | ||
| 990 | 983 | } |
| 991 | 984 | |
| 992 | 985 | asm_free_labels(s1); |
| 986 | + parse_flags = saved_parse_flags; | |
| 993 | 987 | return 0; |
| 994 | 988 | } |
| 995 | 989 | |
| 996 | 990 | /* Assemble the current file */ |
| 997 | 991 | ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) |
| 998 | 992 | { |
| 999 | − Sym *define_start; | |
| 1000 | 993 | int ret; |
| 1001 | − | |
| 1002 | − define_start = define_stack; | |
| 1003 | − preprocess_start(s1); | |
| 1004 | 994 | tcc_debug_start(s1); |
| 1005 | − | |
| 1006 | 995 | /* default section is text */ |
| 1007 | 996 | cur_text_section = text_section; |
| 1008 | 997 | ind = cur_text_section->data_offset; |
| 1009 | 998 | nocode_wanted = 0; |
| 1010 | − | |
| 1011 | 999 | ret = tcc_assemble_internal(s1, do_preprocess, 1); |
| 1012 | − | |
| 1013 | 1000 | cur_text_section->data_offset = ind; |
| 1014 | − | |
| 1015 | 1001 | tcc_debug_end(s1); |
| 1016 | − free_defines(define_start); | |
| 1017 | 1002 | return ret; |
| 1018 | 1003 | } |
| 1019 | 1004 | |
| @@ -1025,21 +1010,16 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 5 unmodified lines | ||
| 1025 | 1010 | end */ |
| 1026 | 1011 | static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global) |
| 1027 | 1012 | { |
| 1028 | − int saved_parse_flags; | |
| 1029 | − const int *saved_macro_ptr; | |
| 1030 | − | |
| 1031 | − saved_parse_flags = parse_flags; | |
| 1032 | − saved_macro_ptr = macro_ptr; | |
| 1013 | + const int *saved_macro_ptr = macro_ptr; | |
| 1014 | + int dotid = set_idnum('.', IS_ID); | |
| 1033 | 1015 | |
| 1034 | 1016 | tcc_open_bf(s1, ":asm:", len); |
| 1035 | 1017 | memcpy(file->buffer, str, len); |
| 1036 | − | |
| 1037 | 1018 | macro_ptr = NULL; |
| 1038 | 1019 | tcc_assemble_internal(s1, 0, global); |
| 1039 | 1020 | tcc_close(); |
| 1040 | 1021 | |
| 1041 | − parse_flags = saved_parse_flags; | |
| 1042 | − set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); | |
| 1022 | + set_idnum('.', dotid); | |
| 1043 | 1023 | macro_ptr = saved_macro_ptr; |
| 1044 | 1024 | } |
| 1045 | 1025 | |
| @@ -84,6 +84,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c); · 83 unmodified lines | ||
| 84 | 84 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); |
| 85 | 85 | static void block(int *bsym, int *csym, int is_expr); |
| 86 | 86 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); |
| 87 | +static void decl(int l); | |
| 87 | 88 | static int decl0(int l, int is_for_loop_init, Sym *); |
| 88 | 89 | static void expr_eq(void); |
| 89 | 90 | static void vla_runtime_type_size(CType *type, int *a); |
| @@ -91,9 +92,9 @@ static void vla_sp_restore(void); · 1 unmodified line | ||
| 91 | 92 | static void vla_sp_restore_root(void); |
| 92 | 93 | static int is_compatible_unqualified_types(CType *type1, CType *type2); |
| 93 | 94 | static inline int64_t expr_const64(void); |
| 94 | −ST_FUNC void vpush64(int ty, unsigned long long v); | |
| 95 | −ST_FUNC void vpush(CType *type); | |
| 96 | −ST_FUNC int gvtst(int inv, int t); | |
| 95 | +static void vpush64(int ty, unsigned long long v); | |
| 96 | +static void vpush(CType *type); | |
| 97 | +static int gvtst(int inv, int t); | |
| 97 | 98 | static void gen_inline_functions(TCCState *s); |
| 98 | 99 | static void skip_or_save_block(TokenString **str); |
| 99 | 100 | static void gv_dup(void); |
| @@ -225,7 +226,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 125 unmodified lines | ||
| 225 | 226 | } |
| 226 | 227 | |
| 227 | 228 | /* ------------------------------------------------------------------------- */ |
| 228 | −ST_FUNC void tccgen_start(TCCState *s1) | |
| 229 | +ST_FUNC int tccgen_compile(TCCState *s1) | |
| 229 | 230 | { |
| 230 | 231 | cur_text_section = NULL; |
| 231 | 232 | funcname = ""; |
| @@ -253,14 +254,22 @@ ST_FUNC void tccgen_start(TCCState *s1) · 21 unmodified lines | ||
| 253 | 254 | #ifdef TCC_TARGET_ARM |
| 254 | 255 | arm_init(s1); |
| 255 | 256 | #endif |
| 256 | −} | |
| 257 | 257 | |
| 258 | −ST_FUNC void tccgen_end(TCCState *s1) | |
| 259 | −{ | |
| 258 | +#ifdef INC_DEBUG | |
| 259 | + printf("%s: **** new file\n", file->filename); | |
| 260 | +#endif | |
| 261 | + | |
| 262 | + parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; | |
| 263 | + next(); | |
| 264 | + decl(VT_CONST); | |
| 265 | + if (tok != TOK_EOF) | |
| 266 | + expect("declaration"); | |
| 267 | + | |
| 260 | 268 | gen_inline_functions(s1); |
| 261 | 269 | check_vstack(); |
| 262 | 270 | /* end of translation unit info */ |
| 263 | 271 | tcc_debug_end(s1); |
| 272 | + return 0; | |
| 264 | 273 | } |
| 265 | 274 | |
| 266 | 275 | /* ------------------------------------------------------------------------- */ |
| @@ -4441,15 +4450,11 @@ static void gfunc_param_typed(Sym *func, Sym *arg) · 4174 unmodified lines | ||
| 4441 | 4450 | } |
| 4442 | 4451 | } |
| 4443 | 4452 | |
| 4444 | −/* parse an expression and return its type without any side effect. | |
| 4445 | − If UNRY we parse an unary expression, otherwise a full one. */ | |
| 4446 | −static void expr_type(CType *type, int unry) | |
| 4453 | +/* parse an expression and return its type without any side effect. */ | |
| 4454 | +static void expr_type(CType *type, void (*expr_fn)(void)) | |
| 4447 | 4455 | { |
| 4448 | 4456 | nocode_wanted++; |
| 4449 | − if (unry) | |
| 4450 | − unary(); | |
| 4451 | − else | |
| 4452 | − gexpr(); | |
| 4457 | + expr_fn(); | |
| 4453 | 4458 | *type = vtop->type; |
| 4454 | 4459 | vpop(); |
| 4455 | 4460 | nocode_wanted--; |
| @@ -4466,7 +4471,7 @@ static void parse_expr_type(CType *type) · 10 unmodified lines | ||
| 4466 | 4471 | if (parse_btype(type, &ad)) { |
| 4467 | 4472 | type_decl(type, &ad, &n, TYPE_ABSTRACT); |
| 4468 | 4473 | } else { |
| 4469 | − expr_type(type, 0); | |
| 4474 | + expr_type(type, gexpr); | |
| 4470 | 4475 | } |
| 4471 | 4476 | skip(')'); |
| 4472 | 4477 | } |
| @@ -4694,7 +4699,7 @@ ST_FUNC void unary(void) · 221 unmodified lines | ||
| 4694 | 4699 | t = tok; |
| 4695 | 4700 | next(); |
| 4696 | 4701 | in_sizeof++; |
| 4697 | − expr_type(&type, 1); // Perform a in_sizeof = 0; | |
| 4702 | + expr_type(&type, unary); /* Perform a in_sizeof = 0; */ | |
| 4698 | 4703 | s = vtop[1].sym; /* hack: accessing previous vtop */ |
| 4699 | 4704 | size = type_size(&type, &align); |
| 4700 | 4705 | if (s && s->a.aligned) |
| @@ -4896,70 +4901,60 @@ ST_FUNC void unary(void) · 195 unmodified lines | ||
| 4896 | 4901 | CType controlling_type; |
| 4897 | 4902 | int has_default = 0; |
| 4898 | 4903 | int has_match = 0; |
| 4899 | − CType cur_type; | |
| 4900 | − AttributeDef ad_tmp; | |
| 4901 | 4904 | int learn = 0; |
| 4902 | 4905 | TokenString *str = NULL; |
| 4903 | − ParseState saved_parse_state; | |
| 4904 | 4906 | |
| 4905 | 4907 | next(); |
| 4906 | 4908 | skip('('); |
| 4907 | − expr_type(&controlling_type, 1); | |
| 4908 | − if (controlling_type.t & VT_ARRAY) | |
| 4909 | − controlling_type.t = VT_PTR; | |
| 4910 | − controlling_type.t &= ~VT_CONSTANT; | |
| 4911 | − controlling_type.t &= ~VT_VOLATILE; | |
| 4909 | + expr_type(&controlling_type, expr_eq); | |
| 4910 | + controlling_type.t &= ~(VT_CONSTANT|VT_VOLATILE|VT_ARRAY); | |
| 4912 | 4911 | for (;;) { |
| 4913 | 4912 | learn = 0; |
| 4914 | 4913 | skip(','); |
| 4915 | 4914 | if (tok == TOK_DEFAULT) { |
| 4916 | 4915 | if (has_default) |
| 4917 | 4916 | tcc_error("too many 'default'"); |
| 4918 | − if (!has_match) { | |
| 4919 | − has_default = 1; | |
| 4917 | + has_default = 1; | |
| 4918 | + if (!has_match) | |
| 4920 | 4919 | learn = 1; |
| 4921 | − } | |
| 4922 | 4920 | next(); |
| 4923 | 4921 | } else { |
| 4922 | + AttributeDef ad_tmp; | |
| 4924 | 4923 | int itmp; |
| 4925 | − | |
| 4924 | + CType cur_type; | |
| 4926 | 4925 | parse_btype(&cur_type, &ad_tmp); |
| 4927 | 4926 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); |
| 4928 | 4927 | if (compare_types(&controlling_type, &cur_type, 0)) { |
| 4929 | 4928 | if (has_match) { |
| 4930 | 4929 | // tcc_error("type match twice"); |
| 4931 | 4930 | } |
| 4932 | − if (str) | |
| 4933 | − tok_str_free(str); | |
| 4934 | 4931 | has_match = 1; |
| 4935 | 4932 | learn = 1; |
| 4936 | 4933 | } |
| 4937 | 4934 | } |
| 4938 | 4935 | skip(':'); |
| 4939 | 4936 | if (learn) { |
| 4937 | + if (str) | |
| 4938 | + tok_str_free(str); | |
| 4940 | 4939 | skip_or_save_block(&str); |
| 4941 | 4940 | } else { |
| 4942 | 4941 | skip_or_save_block(NULL); |
| 4943 | 4942 | } |
| 4944 | − if (tok == ',') | |
| 4945 | − continue; | |
| 4946 | − else if (tok == ')') | |
| 4943 | + if (tok == ')') | |
| 4947 | 4944 | break; |
| 4948 | 4945 | } |
| 4949 | − if (!has_match && !has_default) { | |
| 4950 | − char buf[256]; | |
| 4951 | − | |
| 4952 | − type_to_str(buf, 256, &controlling_type, NULL); | |
| 4953 | − tcc_error("_Generic selector of type '%s' is not compatible with any assosiation", | |
| 4954 | − buf); | |
| 4946 | + if (!str) { | |
| 4947 | + char buf[60]; | |
| 4948 | + type_to_str(buf, sizeof buf, &controlling_type, NULL); | |
| 4949 | + tcc_error("type '%s' does not match any association", buf); | |
| 4955 | 4950 | } |
| 4956 | − skip(')'); | |
| 4957 | − save_parse_state(&saved_parse_state); | |
| 4958 | 4951 | begin_macro(str, 1); |
| 4959 | 4952 | next(); |
| 4960 | 4953 | expr_eq(); |
| 4954 | + if (tok != TOK_EOF) | |
| 4955 | + expect(","); | |
| 4961 | 4956 | end_macro(); |
| 4962 | − restore_parse_state(&saved_parse_state); | |
| 4957 | + next(); | |
| 4963 | 4958 | break; |
| 4964 | 4959 | } |
| 4965 | 4960 | // special qnan , snan and infinity values |
| @@ -5599,7 +5594,9 @@ ST_FUNC void gexpr(void) · 633 unmodified lines | ||
| 5599 | 5594 | static void expr_const1(void) |
| 5600 | 5595 | { |
| 5601 | 5596 | const_wanted++; |
| 5597 | + nocode_wanted++; | |
| 5602 | 5598 | expr_cond(); |
| 5599 | + nocode_wanted--; | |
| 5603 | 5600 | const_wanted--; |
| 5604 | 5601 | } |
| 5605 | 5602 | |
| @@ -6721,8 +6718,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 1115 unmodified lines | ||
| 6721 | 6718 | int has_init, int v, int scope) |
| 6722 | 6719 | { |
| 6723 | 6720 | int size, align, addr; |
| 6724 | − ParseState saved_parse_state = {0}; | |
| 6725 | 6721 | TokenString *init_str = NULL; |
| 6722 | + | |
| 6726 | 6723 | Section *sec; |
| 6727 | 6724 | Sym *flexible_array; |
| 6728 | 6725 | Sym *sym = NULL; |
| @@ -6768,10 +6765,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 39 unmodified lines | ||
| 6768 | 6765 | } else { |
| 6769 | 6766 | skip_or_save_block(&init_str); |
| 6770 | 6767 | } |
| 6771 | − | |
| 6772 | − /* compute size */ | |
| 6773 | − save_parse_state(&saved_parse_state); | |
| 6768 | + unget_tok(0); | |
| 6774 | 6769 | |
| 6770 | + /* compute size */ | |
| 6775 | 6771 | begin_macro(init_str, 1); |
| 6776 | 6772 | next(); |
| 6777 | 6773 | decl_initializer(type, NULL, 0, 1, 1); |
| @@ -6959,7 +6955,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 181 unmodified lines | ||
| 6959 | 6955 | /* restore parse state if needed */ |
| 6960 | 6956 | if (init_str) { |
| 6961 | 6957 | end_macro(); |
| 6962 | − restore_parse_state(&saved_parse_state); | |
| 6958 | + next(); | |
| 6963 | 6959 | } |
| 6964 | 6960 | |
| 6965 | 6961 | nocode_wanted = saved_nocode_wanted; |
| @@ -7328,7 +7324,7 @@ found: · 362 unmodified lines | ||
| 7328 | 7324 | return 0; |
| 7329 | 7325 | } |
| 7330 | 7326 | |
| 7331 | −ST_FUNC void decl(int l) | |
| 7327 | +static void decl(int l) | |
| 7332 | 7328 | { |
| 7333 | 7329 | decl0(l, 0, NULL); |
| 7334 | 7330 | } |
| @@ -820,9 +820,11 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p) · 819 unmodified lines | ||
| 820 | 820 | return p; |
| 821 | 821 | } |
| 822 | 822 | |
| 823 | −ST_FUNC void set_idnum(int c, int val) | |
| 823 | +ST_FUNC int set_idnum(int c, int val) | |
| 824 | 824 | { |
| 825 | + int prev = isidnum_table[c - CH_EOF]; | |
| 825 | 826 | isidnum_table[c - CH_EOF] = val; |
| 827 | + return prev; | |
| 826 | 828 | } |
| 827 | 829 | |
| 828 | 830 | #define cinp minp |
| @@ -999,30 +1001,6 @@ _default: · 170 unmodified lines | ||
| 999 | 1001 | file->buf_ptr = p; |
| 1000 | 1002 | } |
| 1001 | 1003 | |
| 1002 | −/* ParseState handling */ | |
| 1003 | − | |
| 1004 | −/* XXX: currently, no include file info is stored. Thus, we cannot display | |
| 1005 | − accurate messages if the function or data definition spans multiple | |
| 1006 | − files */ | |
| 1007 | − | |
| 1008 | −/* save current parse state in 's' */ | |
| 1009 | −ST_FUNC void save_parse_state(ParseState *s) | |
| 1010 | −{ | |
| 1011 | − s->line_num = file->line_num; | |
| 1012 | − s->macro_ptr = macro_ptr; | |
| 1013 | − s->tok = tok; | |
| 1014 | − s->tokc = tokc; | |
| 1015 | −} | |
| 1016 | − | |
| 1017 | −/* restore parse state from 's' */ | |
| 1018 | −ST_FUNC void restore_parse_state(ParseState *s) | |
| 1019 | −{ | |
| 1020 | − file->line_num = s->line_num; | |
| 1021 | − macro_ptr = s->macro_ptr; | |
| 1022 | − tok = s->tok; | |
| 1023 | − tokc = s->tokc; | |
| 1024 | −} | |
| 1025 | − | |
| 1026 | 1004 | #if 0 |
| 1027 | 1005 | /* return the number of additional 'ints' necessary to store the |
| 1028 | 1006 | token */ |
| @@ -1124,6 +1102,7 @@ ST_FUNC void begin_macro(TokenString *str, int alloc) · 95 unmodified lines | ||
| 1124 | 1102 | str->alloc = alloc; |
| 1125 | 1103 | str->prev = macro_stack; |
| 1126 | 1104 | str->prev_ptr = macro_ptr; |
| 1105 | + str->save_line_num = file->line_num; | |
| 1127 | 1106 | macro_ptr = str->str; |
| 1128 | 1107 | macro_stack = str; |
| 1129 | 1108 | } |
| @@ -1133,6 +1112,7 @@ ST_FUNC void end_macro(void) · 3 unmodified lines | ||
| 1133 | 1112 | TokenString *str = macro_stack; |
| 1134 | 1113 | macro_stack = str->prev; |
| 1135 | 1114 | macro_ptr = str->prev_ptr; |
| 1115 | + file->line_num = str->save_line_num; | |
| 1136 | 1116 | if (str->alloc == 2) { |
| 1137 | 1117 | str->alloc = 3; /* just mark as finished */ |
| 1138 | 1118 | } else { |
| @@ -1402,6 +1382,21 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 263 unmodified lines | ||
| 1402 | 1382 | *ptop = slast; |
| 1403 | 1383 | } |
| 1404 | 1384 | |
| 1385 | +/* fake the nth "#if defined test_..." for tcc -dt -run */ | |
| 1386 | +static void maybe_run_test(TCCState *s, int *c) | |
| 1387 | +{ | |
| 1388 | + const char *p; | |
| 1389 | + if (s->include_stack_ptr != s->include_stack) | |
| 1390 | + return; | |
| 1391 | + p = get_tok_str(tok, NULL); | |
| 1392 | + if (0 != memcmp(p, "test_", 5)) | |
| 1393 | + return; | |
| 1394 | + if (0 != --s->run_test) | |
| 1395 | + return; | |
| 1396 | + fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp); | |
| 1397 | + *c = 1; | |
| 1398 | +} | |
| 1399 | + | |
| 1405 | 1400 | /* eval an expression for #if/#elif */ |
| 1406 | 1401 | static int expr_preprocess(void) |
| 1407 | 1402 | { |
| @@ -1420,6 +1415,8 @@ static int expr_preprocess(void) · 12 unmodified lines | ||
| 1420 | 1415 | if (tok < TOK_IDENT) |
| 1421 | 1416 | expect("identifier"); |
| 1422 | 1417 | c = define_find(tok) != 0; |
| 1418 | + if (tcc_state->run_test) | |
| 1419 | + maybe_run_test(tcc_state, &c); | |
| 1423 | 1420 | if (t == '(') { |
| 1424 | 1421 | next_nomacro(); |
| 1425 | 1422 | if (tok != ')') |
| @@ -1467,7 +1464,7 @@ ST_FUNC void parse_define(void) · 41 unmodified lines | ||
| 1467 | 1464 | /* '(' must be just after macro definition for MACRO_FUNC */ |
| 1468 | 1465 | next_nomacro_spc(); |
| 1469 | 1466 | if (tok == '(') { |
| 1470 | − set_idnum('.', 0); | |
| 1467 | + int dotid = set_idnum('.', 0); | |
| 1471 | 1468 | next_nomacro(); |
| 1472 | 1469 | ps = &first; |
| 1473 | 1470 | if (tok != ')') for (;;) { |
| @@ -1495,6 +1492,7 @@ ST_FUNC void parse_define(void) · 21 unmodified lines | ||
| 1495 | 1492 | } |
| 1496 | 1493 | next_nomacro_spc(); |
| 1497 | 1494 | t = MACRO_FUNC; |
| 1495 | + set_idnum('.', dotid); | |
| 1498 | 1496 | } |
| 1499 | 1497 | |
| 1500 | 1498 | tokstr_buf.len = 0; |
| @@ -1505,7 +1503,6 @@ ST_FUNC void parse_define(void) · 4 unmodified lines | ||
| 1505 | 1503 | ID character in asm mode). But '#' should be retained instead of |
| 1506 | 1504 | regarded as line comment leader, so still don't set ASM_FILE |
| 1507 | 1505 | in parse_flags. */ |
| 1508 | − set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); | |
| 1509 | 1506 | while (tok != TOK_LINEFEED && tok != TOK_EOF) { |
| 1510 | 1507 | /* remove spaces around ## and after '#' */ |
| 1511 | 1508 | if (TOK_TWOSHARPS == tok) { |
| @@ -1613,7 +1610,7 @@ static void pragma_parse(TCCState *s1) · 101 unmodified lines | ||
| 1613 | 1610 | } else if (tok == TOK_once) { |
| 1614 | 1611 | search_cached_include(s1, file->filename, 1)->once = pp_once; |
| 1615 | 1612 | |
| 1616 | − } else if (s1->ppfp) { | |
| 1613 | + } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) { | |
| 1617 | 1614 | /* tcc -E: keep pragmas below unchanged */ |
| 1618 | 1615 | unget_tok(' '); |
| 1619 | 1616 | unget_tok(TOK_PRAGMA); |
| @@ -3043,6 +3040,7 @@ static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) · 1423 unmodified lines | ||
| 3043 | 3040 | |
| 3044 | 3041 | tcc_open_bf(tcc_state, ":paste:", cstr.size); |
| 3045 | 3042 | memcpy(file->buffer, cstr.data, cstr.size); |
| 3043 | + tok_flags = 0; | |
| 3046 | 3044 | for (;;) { |
| 3047 | 3045 | next_nomacro1(); |
| 3048 | 3046 | if (0 == *file->buf_ptr) |
| @@ -3164,6 +3162,8 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str) · 115 unmodified lines | ||
| 3164 | 3162 | break; |
| 3165 | 3163 | ch = ' '; |
| 3166 | 3164 | } |
| 3165 | + if (ch == '\n') | |
| 3166 | + file->line_num++; | |
| 3167 | 3167 | if (!(ch == '\f' || ch == '\v' || ch == '\r')) |
| 3168 | 3168 | tok_str_add(ws_str, ch); |
| 3169 | 3169 | cinp(); |
| @@ -3483,7 +3483,7 @@ ST_INLN void unget_tok(int last_tok) · 313 unmodified lines | ||
| 3483 | 3483 | tok = last_tok; |
| 3484 | 3484 | } |
| 3485 | 3485 | |
| 3486 | −ST_FUNC void preprocess_start(TCCState *s1) | |
| 3486 | +ST_FUNC void preprocess_start(TCCState *s1, int is_asm) | |
| 3487 | 3487 | { |
| 3488 | 3488 | char *buf; |
| 3489 | 3489 | |
| @@ -3496,7 +3496,7 @@ ST_FUNC void preprocess_start(TCCState *s1) · 6 unmodified lines | ||
| 3496 | 3496 | s1->pack_stack_ptr = s1->pack_stack; |
| 3497 | 3497 | |
| 3498 | 3498 | set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0); |
| 3499 | − set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); | |
| 3499 | + set_idnum('.', is_asm ? IS_ID : 0); | |
| 3500 | 3500 | |
| 3501 | 3501 | buf = tcc_malloc(3 + strlen(file->filename)); |
| 3502 | 3502 | sprintf(buf, "\"%s\"", file->filename); |
| @@ -3517,6 +3517,20 @@ ST_FUNC void preprocess_start(TCCState *s1) · 14 unmodified lines | ||
| 3517 | 3517 | memcpy(file->buffer, cstr.data, cstr.size); |
| 3518 | 3518 | cstr_free(&cstr); |
| 3519 | 3519 | } |
| 3520 | + | |
| 3521 | + if (is_asm) | |
| 3522 | + tcc_define_symbol(s1, "__ASSEMBLER__", NULL); | |
| 3523 | + | |
| 3524 | + parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0; | |
| 3525 | + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | |
| 3526 | +} | |
| 3527 | + | |
| 3528 | +/* cleanup from error/setjmp */ | |
| 3529 | +ST_FUNC void preprocess_end(TCCState *s1) | |
| 3530 | +{ | |
| 3531 | + while (macro_stack) | |
| 3532 | + end_macro(); | |
| 3533 | + macro_ptr = NULL; | |
| 3520 | 3534 | } |
| 3521 | 3535 | |
| 3522 | 3536 | ST_FUNC void tccpp_new(TCCState *s) |
| @@ -3526,6 +3540,7 @@ ST_FUNC void tccpp_new(TCCState *s) · 3 unmodified lines | ||
| 3526 | 3540 | |
| 3527 | 3541 | /* might be used in error() before preprocess_start() */ |
| 3528 | 3542 | s->include_stack_ptr = s->include_stack; |
| 3543 | + s->ppfp = stdout; | |
| 3529 | 3544 | |
| 3530 | 3545 | /* init isid table */ |
| 3531 | 3546 | for(i = CH_EOF; i<128; i++) |
| @@ -3570,14 +3585,6 @@ ST_FUNC void tccpp_delete(TCCState *s) · 38 unmodified lines | ||
| 3570 | 3585 | /* free -D and compiler defines */ |
| 3571 | 3586 | free_defines(NULL); |
| 3572 | 3587 | |
| 3573 | − /* cleanup from error/setjmp */ | |
| 3574 | − while (macro_stack) | |
| 3575 | − end_macro(); | |
| 3576 | − macro_ptr = NULL; | |
| 3577 | − | |
| 3578 | − while (file) | |
| 3579 | − tcc_close(); | |
| 3580 | − | |
| 3581 | 3588 | /* free tokens */ |
| 3582 | 3589 | n = tok_ident - TOK_IDENT; |
| 3583 | 3590 | for(i = 0; i < n; i++) |
| @@ -3606,19 +3613,16 @@ ST_FUNC void tccpp_delete(TCCState *s) · 22 unmodified lines | ||
| 3606 | 3613 | static void tok_print(const char *msg, const int *str) |
| 3607 | 3614 | { |
| 3608 | 3615 | FILE *fp; |
| 3609 | − int t; | |
| 3616 | + int t, s = 0; | |
| 3610 | 3617 | CValue cval; |
| 3611 | 3618 | |
| 3612 | 3619 | fp = tcc_state->ppfp; |
| 3613 | − if (!fp || !tcc_state->dflag) | |
| 3614 | − fp = stdout; | |
| 3615 | − | |
| 3616 | − fprintf(fp, "%s ", msg); | |
| 3620 | + fprintf(fp, "%s", msg); | |
| 3617 | 3621 | while (str) { |
| 3618 | 3622 | TOK_GET(&t, &str, &cval); |
| 3619 | 3623 | if (!t) |
| 3620 | 3624 | break; |
| 3621 | − fprintf(fp,"%s", get_tok_str(t, &cval)); | |
| 3625 | + fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1; | |
| 3622 | 3626 | } |
| 3623 | 3627 | fprintf(fp, "\n"); |
| 3624 | 3628 | } |
| @@ -3731,20 +3735,14 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 106 unmodified lines | ||
| 3731 | 3735 | BufferedFile **iptr; |
| 3732 | 3736 | int token_seen, spcs, level; |
| 3733 | 3737 | const char *p; |
| 3734 | − Sym *define_start; | |
| 3738 | + char white[400]; | |
| 3735 | 3739 | |
| 3736 | − define_start = define_stack; | |
| 3737 | − preprocess_start(s1); | |
| 3738 | − | |
| 3739 | − ch = file->buf_ptr[0]; | |
| 3740 | − tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | |
| 3741 | 3740 | parse_flags = PARSE_FLAG_PREPROCESS |
| 3742 | 3741 | | (parse_flags & PARSE_FLAG_ASM_FILE) |
| 3743 | 3742 | | PARSE_FLAG_LINEFEED |
| 3744 | 3743 | | PARSE_FLAG_SPACES |
| 3745 | 3744 | | PARSE_FLAG_ACCEPT_STRAYS |
| 3746 | 3745 | ; |
| 3747 | − | |
| 3748 | 3746 | /* Credits to Fabrice Bellard's initial revision to demonstrate its |
| 3749 | 3747 | capability to compile and run itself, provided all numbers are |
| 3750 | 3748 | given as decimals. tcc -E -P10 will do. */ |
| @@ -3754,7 +3752,6 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 3 unmodified lines | ||
| 3754 | 3752 | #ifdef PP_BENCH |
| 3755 | 3753 | /* for PP benchmarks */ |
| 3756 | 3754 | do next(); while (tok != TOK_EOF); |
| 3757 | − free_defines(define_start); | |
| 3758 | 3755 | return 0; |
| 3759 | 3756 | #endif |
| 3760 | 3757 | |
| @@ -3765,48 +3762,43 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 4 unmodified lines | ||
| 3765 | 3762 | |
| 3766 | 3763 | token_seen = TOK_LINEFEED, spcs = 0; |
| 3767 | 3764 | pp_line(s1, file, 0); |
| 3768 | − | |
| 3769 | 3765 | for (;;) { |
| 3770 | 3766 | iptr = s1->include_stack_ptr; |
| 3771 | 3767 | next(); |
| 3772 | 3768 | if (tok == TOK_EOF) |
| 3773 | 3769 | break; |
| 3770 | + | |
| 3774 | 3771 | level = s1->include_stack_ptr - iptr; |
| 3775 | 3772 | if (level) { |
| 3776 | 3773 | if (level > 0) |
| 3777 | 3774 | pp_line(s1, *iptr, 0); |
| 3778 | 3775 | pp_line(s1, file, level); |
| 3779 | 3776 | } |
| 3780 | − | |
| 3781 | − if (s1->dflag) { | |
| 3777 | + if (s1->dflag & 7) { | |
| 3782 | 3778 | pp_debug_defines(s1); |
| 3783 | 3779 | if (s1->dflag & 4) |
| 3784 | 3780 | continue; |
| 3785 | 3781 | } |
| 3786 | 3782 | |
| 3787 | − if (token_seen == TOK_LINEFEED) { | |
| 3788 | − if (tok == ' ') { | |
| 3789 | − ++spcs; | |
| 3790 | − continue; | |
| 3791 | − } | |
| 3792 | − if (tok == TOK_LINEFEED) { | |
| 3793 | − spcs = 0; | |
| 3794 | − continue; | |
| 3795 | − } | |
| 3796 | − pp_line(s1, file, 0); | |
| 3783 | + if (is_space(tok)) { | |
| 3784 | + if (spcs < sizeof white - 1) | |
| 3785 | + white[spcs++] = tok; | |
| 3786 | + continue; | |
| 3797 | 3787 | } else if (tok == TOK_LINEFEED) { |
| 3788 | + spcs = 0; | |
| 3789 | + if (token_seen == TOK_LINEFEED) | |
| 3790 | + continue; | |
| 3798 | 3791 | ++file->line_ref; |
| 3799 | − } else { | |
| 3800 | − spcs = pp_need_space(token_seen, tok); | |
| 3792 | + } else if (token_seen == TOK_LINEFEED) { | |
| 3793 | + pp_line(s1, file, 0); | |
| 3794 | + } else if (spcs == 0 && pp_need_space(token_seen, tok)) { | |
| 3795 | + white[spcs++] = ' '; | |
| 3801 | 3796 | } |
| 3802 | 3797 | |
| 3803 | − while (spcs) | |
| 3804 | − fputs(" ", s1->ppfp), --spcs; | |
| 3798 | + white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0; | |
| 3805 | 3799 | fputs(p = get_tok_str(tok, &tokc), s1->ppfp); |
| 3806 | − token_seen = pp_check_he0xE(tok, p);; | |
| 3800 | + token_seen = pp_check_he0xE(tok, p); | |
| 3807 | 3801 | } |
| 3808 | − /* reset define stack, but keep -D and built-ins */ | |
| 3809 | − free_defines(define_start); | |
| 3810 | 3802 | return 0; |
| 3811 | 3803 | } |
| 3812 | 3804 | |
| @@ -108,6 +108,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 107 unmodified lines | ||
| 108 | 108 | int (*prog_main)(int, char **); |
| 109 | 109 | |
| 110 | 110 | s1->runtime_main = "main"; |
| 111 | + if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main)) | |
| 112 | + return 0; | |
| 111 | 113 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) |
| 112 | 114 | return -1; |
| 113 | 115 | prog_main = tcc_get_symbol_err(s1, s1->runtime_main); |
| @@ -543,111 +543,4 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) · 542 unmodified lines | ||
| 543 | 543 | fclose(depout); |
| 544 | 544 | } |
| 545 | 545 | |
| 546 | −#ifdef TCC_IS_NATIVE | |
| 547 | −/* -------------------------------------------------------------- */ | |
| 548 | −/* run test snippets from file */ | |
| 549 | − | |
| 550 | −static char *readfile(const char *fname) | |
| 551 | −{ | |
| 552 | − char *buf; | |
| 553 | − int fsize; | |
| 554 | − FILE *fi; | |
| 555 | − fi = fopen(fname, "rb"); | |
| 556 | − if (!fi) | |
| 557 | − return NULL; | |
| 558 | − fseek(fi, 0, SEEK_END); | |
| 559 | − fsize = ftell(fi); | |
| 560 | − fseek(fi, 0, SEEK_SET); | |
| 561 | − buf = tcc_malloc(fsize + 1); | |
| 562 | − fread(buf, fsize, 1, fi); | |
| 563 | − fclose(fi); | |
| 564 | − buf[fsize] = 0; | |
| 565 | − return buf; | |
| 566 | −} | |
| 567 | − | |
| 568 | −static int run_prog(const char *prog, int ac, char **av) | |
| 569 | −{ | |
| 570 | − TCCState *s; | |
| 571 | − int (*func)(int, char**); | |
| 572 | − int ret = -10000; | |
| 573 | − | |
| 574 | − s = tcc_new(); | |
| 575 | − tcc_parse_args(s, &ac, &av, 1); | |
| 576 | − tcc_set_output_type(s, TCC_OUTPUT_MEMORY); | |
| 577 | − if (tcc_compile_string(s, prog) == -1) | |
| 578 | − goto done; | |
| 579 | − if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) | |
| 580 | − goto done; | |
| 581 | − func = tcc_get_symbol(s, "main"); | |
| 582 | − if (!func) | |
| 583 | − goto done; | |
| 584 | − ret = func(ac, av); | |
| 585 | −done: | |
| 586 | − tcc_delete(s); | |
| 587 | − return ret; | |
| 588 | −} | |
| 589 | − | |
| 590 | −static char *trimback(char *a, char *e) | |
| 591 | −{ | |
| 592 | − while (e > a && (unsigned char)e[-1] <= ' ') | |
| 593 | − --e; | |
| 594 | − *e = 0;; | |
| 595 | − return a; | |
| 596 | −} | |
| 597 | − | |
| 598 | −ST_FUNC int tcc_tool_test(TCCState *s, int argc, char **argv) | |
| 599 | −{ | |
| 600 | − const char *fname; | |
| 601 | − char *buf, *p, *a, *b, *e, tmp[100]; | |
| 602 | − int r = 0, c, n; | |
| 603 | − const char sep[] = "/*-* test"; | |
| 604 | − | |
| 605 | − n = s->do_test - argc; | |
| 606 | − if (!n) | |
| 607 | − return 0; | |
| 608 | − fname = argv[0], argv -= n, argc += n; | |
| 609 | − | |
| 610 | − buf = readfile(fname); | |
| 611 | − if (NULL == buf) | |
| 612 | − return -1; | |
| 613 | − p = strstr(buf, sep); | |
| 614 | − if (!p) { | |
| 615 | − tcc_free(buf); | |
| 616 | − return -1; | |
| 617 | − } | |
| 618 | − | |
| 619 | − while (*p) { | |
| 620 | − a = p, p = strchr(p, '\n'); | |
| 621 | − if (NULL == p) | |
| 622 | − break; | |
| 623 | − *p++ = 0; | |
| 624 | − b = p, p = strstr(p, sep); | |
| 625 | − if (NULL == p) | |
| 626 | − p = strchr(b, 0); | |
| 627 | − c = *p, *p = 0; | |
| 628 | − | |
| 629 | − trimback(a, b); | |
| 630 | − if (r) | |
| 631 | − printf("\n"); | |
| 632 | − printf("%s\n", a); | |
| 633 | − fflush(stdout); | |
| 634 | − | |
| 635 | − e = a += sizeof sep - 5; | |
| 636 | − while (*e && *e != ':') | |
| 637 | − ++e; | |
| 638 | − if (!*e || e - a > 32) | |
| 639 | − e = a + 4; | |
| 640 | − n = snprintf(tmp, sizeof tmp, "#line 1 \"%.*s\"\n", (int)(e - a), a); | |
| 641 | − if (b - buf >= n) | |
| 642 | − b = memcpy(b - n, tmp, n); | |
| 643 | − n = run_prog(b, argc, argv); | |
| 644 | − if (n != -10000) | |
| 645 | − printf("returns %d\n", n); | |
| 646 | − *p = c, ++r; | |
| 647 | − } | |
| 648 | − tcc_free(buf); | |
| 649 | − exit(0); | |
| 650 | −} | |
| 651 | −#endif /* TCC_IS_NATIVE */ | |
| 652 | − | |
| 653 | 546 | /* -------------------------------------------------------------- */ |
| @@ -1 +0,0 @@ | ||
| 1 | −struct A {} int i; | |
| @@ -1 +0,0 @@ | ||
| 1 | −56_btype_excess-1.c:1: error: too many basic types | |
| @@ -1 +0,0 @@ | ||
| 1 | −char int i; | |
| @@ -1 +0,0 @@ | ||
| 1 | −57_btype_excess-2.c:1: error: too many basic types | |
| @@ -1,9 +0,0 @@ | ||
| 1 | −int f(void) | |
| 2 | −{ | |
| 3 | − return 0; | |
| 4 | −} | |
| 5 | − | |
| 6 | −int f(void) | |
| 7 | −{ | |
| 8 | − return 1; | |
| 9 | −} | |
| @@ -1 +0,0 @@ | ||
| 1 | −58_function_redefinition.c:7: error: redefinition of 'f' | |
| @@ -1 +0,0 @@ | ||
| 1 | −int (*fct)[42](int x); | |
| @@ -1 +0,0 @@ | ||
| 1 | −59_function_array.c:1: error: declaration of an array of functions | |
| @@ -1,4 +0,0 @@ | ||
| 1 | −enum color {RED, GREEN, BLUE}; | |
| 2 | −enum color {R, G, B}; | |
| 3 | − | |
| 4 | −enum color c; | |
| @@ -1 +0,0 @@ | ||
| 1 | −60_enum_redefinition.c:2: error: struct/union/enum already defined | |
| @@ -0,0 +1,51 @@ | ||
| 1 | +#if defined test_56_btype_excess_1 | |
| 2 | +struct A {} int i; | |
| 3 | + | |
| 4 | +#elif defined test_57_btype_excess_2 | |
| 5 | +char int i; | |
| 6 | + | |
| 7 | +#elif defined test_58_function_redefinition | |
| 8 | +int f(void) { return 0; } | |
| 9 | +int f(void) { return 1; } | |
| 10 | + | |
| 11 | +#elif defined test_global_redefinition | |
| 12 | +int xxx = 1; | |
| 13 | +int xxx; | |
| 14 | +int xxx = 2; | |
| 15 | + | |
| 16 | +#elif defined test_59_function_array | |
| 17 | +int (*fct)[42](int x); | |
| 18 | + | |
| 19 | +#elif defined test_60_enum_redefinition | |
| 20 | +enum color { RED, GREEN, BLUE }; | |
| 21 | +enum color { R, G, B }; | |
| 22 | +enum color c; | |
| 23 | + | |
| 24 | +#elif defined test_62_enumerator_redefinition | |
| 25 | +enum color { RED, GREEN, BLUE }; | |
| 26 | +enum rgb { RED, G, B}; | |
| 27 | +enum color c = RED; | |
| 28 | + | |
| 29 | +#elif defined test_63_local_enumerator_redefinition | |
| 30 | +enum { | |
| 31 | + FOO, | |
| 32 | + BAR | |
| 33 | +}; | |
| 34 | + | |
| 35 | +int main(void) | |
| 36 | +{ | |
| 37 | + enum { | |
| 38 | + FOO = 2, | |
| 39 | + BAR | |
| 40 | + }; | |
| 41 | + | |
| 42 | + return BAR - FOO; | |
| 43 | +} | |
| 44 | + | |
| 45 | +#elif defined test_61_undefined_enum | |
| 46 | +enum rgb3 c = 42; | |
| 47 | + | |
| 48 | +#elif defined test_74_non_const_init | |
| 49 | +int i = i++; | |
| 50 | + | |
| 51 | +#endif | |
| @@ -0,0 +1,28 @@ | ||
| 1 | +[test_56_btype_excess_1] | |
| 2 | +60_errors_and_warnings.c:2: error: too many basic types | |
| 3 | + | |
| 4 | +[test_57_btype_excess_2] | |
| 5 | +60_errors_and_warnings.c:5: error: too many basic types | |
| 6 | + | |
| 7 | +[test_58_function_redefinition] | |
| 8 | +60_errors_and_warnings.c:9: error: redefinition of 'f' | |
| 9 | + | |
| 10 | +[test_global_redefinition] | |
| 11 | +60_errors_and_warnings.c:14: error: redefinition of 'xxx' | |
| 12 | + | |
| 13 | +[test_59_function_array] | |
| 14 | +60_errors_and_warnings.c:17: error: declaration of an array of functions | |
| 15 | + | |
| 16 | +[test_60_enum_redefinition] | |
| 17 | +60_errors_and_warnings.c:21: error: struct/union/enum already defined | |
| 18 | + | |
| 19 | +[test_62_enumerator_redefinition] | |
| 20 | +60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED' | |
| 21 | + | |
| 22 | +[test_63_local_enumerator_redefinition] | |
| 23 | + | |
| 24 | +[test_61_undefined_enum] | |
| 25 | +60_errors_and_warnings.c:46: error: unknown type size | |
| 26 | + | |
| 27 | +[test_74_non_const_init] | |
| 28 | +60_errors_and_warnings.c:49: error: initializer element is not constant | |
| @@ -1 +0,0 @@ | ||
| 1 | −enum rgb c = 42; | |
| @@ -1 +0,0 @@ | ||
| 1 | −61_undefined_enum.c:1: error: unknown type size | |
| @@ -1,4 +0,0 @@ | ||
| 1 | −enum color {RED, GREEN, BLUE}; | |
| 2 | −enum rgb {RED, G, B}; | |
| 3 | − | |
| 4 | −enum color c = RED; | |
| @@ -1 +0,0 @@ | ||
| 1 | −62_enumerator_redefinition.c:2: error: redefinition of enumerator 'RED' | |
| @@ -1,14 +0,0 @@ | ||
| 1 | −enum { | |
| 2 | − FOO, | |
| 3 | − BAR | |
| 4 | −}; | |
| 5 | − | |
| 6 | −int main(void) | |
| 7 | −{ | |
| 8 | − enum { | |
| 9 | − FOO = 2, | |
| 10 | − BAR | |
| 11 | − }; | |
| 12 | − | |
| 13 | − return BAR - FOO; | |
| 14 | −} | |
Empty file deleted.
| @@ -1 +0,0 @@ | ||
| 1 | −int i = i++; | |
| @@ -1 +0,0 @@ | ||
| 1 | −74_nocode_wanted.c:1: error: initializer element is not constant | |
| @@ -1,36 +1,35 @@ | ||
| 1 | 1 | /*****************************************************************************/ |
| 2 | 2 | /* test 'nodata_wanted' data output suppression */ |
| 3 | 3 | |
| 4 | −/*-* test 1: initializer not computable 1 */ | |
| 4 | +#if defined test_static_data_error | |
| 5 | 5 | void foo() { |
| 6 | 6 | if (1) { |
| 7 | − static short w = (int)&foo; /* error */ | |
| 7 | + static short w = (int)&foo; /* initializer not computable */ | |
| 8 | 8 | } |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | −/*-* test 2: initializer not computable 2 */ | |
| 11 | +#elif defined test_static_nodata_error | |
| 12 | 12 | void foo() { |
| 13 | 13 | if (0) { |
| 14 | − static short w = (int)&foo; /* error */ | |
| 14 | + static short w = (int)&foo; /* initializer not computable */ | |
| 15 | 15 | } |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | −/*-* test 3: initializer not computable 3 */ | |
| 18 | +#elif defined test_global_data_error | |
| 19 | 19 | void foo(); |
| 20 | −static short w = (int)&foo; /* error */ | |
| 20 | +static short w = (int)&foo; /* initializer not computable */ | |
| 21 | 21 | |
| 22 | 22 | |
| 23 | −/*-* test 4: 2 cast warnings */ | |
| 23 | +#elif defined test_local_data_noerror | |
| 24 | 24 | void foo() { |
| 25 | − short w = &foo; /* no error */ | |
| 25 | + short w = &foo; /* 2 cast warnings */ | |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | −/*-* test 5; nodata_wanted test */ | |
| 28 | +#elif defined test_data_suppression | |
| 29 | 29 | #include <stdio.h> |
| 30 | 30 | |
| 31 | −#define DATA_LBL(s) \ | |
| 32 | − __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n"); \ | |
| 33 | − extern char d##s[],t##s[]; | |
| 31 | +#define ASMLABELS(s) \ | |
| 32 | + __asm__(".global d"#s",t"#s"\n.data\nd"#s":\n.text\nt"#s":\n") | |
| 34 | 33 | |
| 35 | 34 | #define PROG \ |
| 36 | 35 | static void *p = (void*)&main;\ |
| @@ -47,28 +46,29 @@ void foo() { · 10 unmodified lines | ||
| 47 | 46 | |
| 48 | 47 | int main() |
| 49 | 48 | { |
| 49 | + extern char ds1[],ts1[]; | |
| 50 | + extern char ds2[],ts2[]; | |
| 51 | + extern char de1[],te1[]; | |
| 52 | + extern char de2[],te2[]; | |
| 53 | + | |
| 50 | 54 | printf("suppression off\n"); |
| 51 | − DATA_LBL(s1); | |
| 52 | 55 | if (1) { |
| 56 | + ASMLABELS(s1); | |
| 53 | 57 | PROG |
| 58 | + ASMLABELS(e1); | |
| 54 | 59 | } |
| 55 | − DATA_LBL(e1); | |
| 56 | 60 | printf(" data length is %s\n", de1 - ds1 ? "not 0":"0"); |
| 57 | − //printf(" text length is %s\n", te1 - ts1 ? "not 0":"0"); | |
| 61 | + printf(" text length is %s\n", te1 - ts1 ? "not 0":"0"); | |
| 58 | 62 | |
| 59 | 63 | printf("suppression on\n"); |
| 60 | − DATA_LBL(s2); | |
| 61 | 64 | if (0) { |
| 65 | + ASMLABELS(s2); | |
| 62 | 66 | PROG |
| 67 | + ASMLABELS(e2); | |
| 63 | 68 | } |
| 64 | − DATA_LBL(e2); | |
| 65 | 69 | printf(" data length is %x\n", de2 - ds2); |
| 66 | − //printf(" text length is %X\n", te2 - ts2); | |
| 70 | + printf(" text length is %X\n", te2 - ts2); | |
| 67 | 71 | return 0; |
| 68 | 72 | } |
| 69 | 73 | |
| 70 | −/*-* test 6: some test */ | |
| 71 | −int main() | |
| 72 | −{ | |
| 73 | − return 34; | |
| 74 | −} | |
| 74 | +#endif | |
| @@ -1,24 +1,22 @@ | ||
| 1 | −/*-* test 1: initializer not computable 1 */ | |
| 2 | −test 1:3: error: initializer element is not computable at load time | |
| 1 | +[test_static_data_error] | |
| 2 | +96_nodata_wanted.c:7: error: initializer element is not computable at load time | |
| 3 | 3 | |
| 4 | −/*-* test 2: initializer not computable 2 */ | |
| 5 | −test 2:3: error: initializer element is not computable at load time | |
| 4 | +[test_static_nodata_error] | |
| 5 | +96_nodata_wanted.c:14: error: initializer element is not computable at load time | |
| 6 | 6 | |
| 7 | −/*-* test 3: initializer not computable 3 */ | |
| 8 | −test 3:2: error: initializer element is not computable at load time | |
| 7 | +[test_global_data_error] | |
| 8 | +96_nodata_wanted.c:20: error: initializer element is not computable at load time | |
| 9 | 9 | |
| 10 | −/*-* test 4: 2 cast warnings */ | |
| 11 | −test 4:2: warning: assignment makes integer from pointer without a cast | |
| 12 | −test 4:2: warning: nonportable conversion from pointer to char/short | |
| 10 | +[test_local_data_noerror] | |
| 11 | +96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast | |
| 12 | +96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short | |
| 13 | 13 | |
| 14 | −/*-* test 5; nodata_wanted test */ | |
| 14 | +[test_data_suppression] | |
| 15 | 15 | suppression off |
| 16 | 16 | static data: 8 - 8.0 - 8.0 - main - static string |
| 17 | 17 | static bitfields: 333 44 555555 6 7 |
| 18 | 18 | data length is not 0 |
| 19 | + text length is not 0 | |
| 19 | 20 | suppression on |
| 20 | 21 | data length is 0 |
| 21 | −returns 0 | |
| 22 | − | |
| 23 | −/*-* test 6: some test */ | |
| 24 | −returns 34 | |
| 22 | + text length is 0 | |
| @@ -20,7 +20,7 @@ endif · 19 unmodified lines | ||
| 20 | 20 | ifeq (,$(filter i386 x86_64,$(ARCH))) |
| 21 | 21 | SKIP += 85_asm-outside-function.test |
| 22 | 22 | endif |
| 23 | −ifeq (-$(findstring gcc,$(CC)-)-,--) | |
| 23 | +ifeq (-$(findstring gcc,$(CC))-,--) | |
| 24 | 24 | SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) |
| 25 | 25 | endif |
| 26 | 26 | ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) |
| @@ -40,8 +40,9 @@ NORUN = · 13 unmodified lines | ||
| 40 | 40 | FLAGS = |
| 41 | 41 | 76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers |
| 42 | 42 | |
| 43 | −# run the source file cut into snippets | |
| 44 | −96_nodata_wanted.test : FLAGS = -dT | |
| 43 | +# These tests run several snippets from the same file one by one | |
| 44 | +60_errors_and_warnings.test : FLAGS += -dt | |
| 45 | +96_nodata_wanted.test : FLAGS += -dt | |
| 45 | 46 | |
| 46 | 47 | # Always generate certain .expects (don't put these in the GIT), |
| 47 | 48 | GEN-ALWAYS = |
| @@ -90,8 +91,8 @@ F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" · 42 unmodified lines | ||
| 90 | 91 | @$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1 |
| 91 | 92 | @rm -f *.exe *.obj *.pdb |
| 92 | 93 | |
| 93 | −# using TCC for .expect if -dT in FLAGS | |
| 94 | −GEN = $(if $(findstring -dT,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) | |
| 94 | +# using TCC for .expect if -dt in FLAGS | |
| 95 | +GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) | |
| 95 | 96 | GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS) |
| 96 | 97 | GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS) |
| 97 | 98 | GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe |