- call TOK_GET() as a function only for tokens with values - get rid of 'next_nomacro_spc()' - be sligtly more efficient in next() This made about 4-5%+ speed in my tests.
Unified · Split
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <time.h> |
| 36 | 36 | |
| 37 | 37 | #ifndef _WIN32 |
| 38 | +# define WIN32_LEAN_AND_MEAN 1 | |
| 38 | 39 | # include <unistd.h> |
| 39 | 40 | # include <sys/time.h> |
| 40 | 41 | # ifndef CONFIG_TCC_STATIC |
| @@ -1009,6 +1010,9 @@ struct filespec { · 968 unmodified lines | ||
| 1009 | 1010 | |
| 1010 | 1011 | /* token values */ |
| 1011 | 1012 | |
| 1013 | +/* conditional ops */ | |
| 1014 | +#define TOK_LAND 0x90 | |
| 1015 | +#define TOK_LOR 0x91 | |
| 1012 | 1016 | /* warning: the following compare tokens depend on i386 asm code */ |
| 1013 | 1017 | #define TOK_ULT 0x92 |
| 1014 | 1018 | #define TOK_UGE 0x93 |
| @@ -1023,62 +1027,65 @@ struct filespec { · 8 unmodified lines | ||
| 1023 | 1027 | #define TOK_LE 0x9e |
| 1024 | 1028 | #define TOK_GT 0x9f |
| 1025 | 1029 | |
| 1026 | −#define TOK_LAND 0xa0 | |
| 1027 | −#define TOK_LOR 0xa1 | |
| 1028 | −#define TOK_DEC 0xa2 | |
| 1029 | −#define TOK_MID 0xa3 /* inc/dec, to void constant */ | |
| 1030 | −#define TOK_INC 0xa4 | |
| 1031 | −#define TOK_UDIV 0xb0 /* unsigned division */ | |
| 1032 | −#define TOK_UMOD 0xb1 /* unsigned modulo */ | |
| 1033 | −#define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */ | |
| 1030 | +#define TOK_ISCOND(t) (t >= TOK_LAND && t <= TOK_GT) | |
| 1031 | + | |
| 1032 | +#define TOK_DEC 0x80 /* -- */ | |
| 1033 | +#define TOK_MID 0x81 /* inc/dec, to void constant */ | |
| 1034 | +#define TOK_INC 0x82 /* ++ */ | |
| 1035 | +#define TOK_UDIV 0x83 /* unsigned division */ | |
| 1036 | +#define TOK_UMOD 0x84 /* unsigned modulo */ | |
| 1037 | +#define TOK_PDIV 0x85 /* fast division with undefined rounding for pointers */ | |
| 1038 | +#define TOK_UMULL 0x86 /* unsigned 32x32 -> 64 mul */ | |
| 1039 | +#define TOK_ADDC1 0x87 /* add with carry generation */ | |
| 1040 | +#define TOK_ADDC2 0x88 /* add with carry use */ | |
| 1041 | +#define TOK_SUBC1 0x89 /* add with carry generation */ | |
| 1042 | +#define TOK_SUBC2 0x8a /* add with carry use */ | |
| 1043 | +#define TOK_SHL '<' /* shift left */ | |
| 1044 | +#define TOK_SAR '>' /* signed shift right */ | |
| 1045 | +#define TOK_SHR 0x8b /* unsigned shift right */ | |
| 1046 | + | |
| 1047 | +#define TOK_ARROW 0xa0 /* -> */ | |
| 1048 | +#define TOK_DOTS 0xa1 /* three dots */ | |
| 1049 | +#define TOK_TWODOTS 0xa2 /* C++ token ? */ | |
| 1050 | +#define TOK_TWOSHARPS 0xa3 /* ## preprocessing token */ | |
| 1051 | +#define TOK_PLCHLDR 0xa4 /* placeholder token as defined in C99 */ | |
| 1052 | +#define TOK_NOSUBST 0xa5 /* means following token has already been pp'd */ | |
| 1053 | +#define TOK_PPJOIN 0xa6 /* A '##' in the right position to mean pasting */ | |
| 1054 | + | |
| 1055 | +/* assignment operators */ | |
| 1056 | +#define TOK_A_ADD 0xb0 | |
| 1057 | +#define TOK_A_SUB 0xb1 | |
| 1058 | +#define TOK_A_MUL 0xb2 | |
| 1059 | +#define TOK_A_DIV 0xb3 | |
| 1060 | +#define TOK_A_MOD 0xb4 | |
| 1061 | +#define TOK_A_AND 0xb5 | |
| 1062 | +#define TOK_A_OR 0xb6 | |
| 1063 | +#define TOK_A_XOR 0xb7 | |
| 1064 | +#define TOK_A_SHL 0xb8 | |
| 1065 | +#define TOK_A_SAR 0xb9 | |
| 1066 | + | |
| 1067 | +#define TOK_ASSIGN(t) (t >= TOK_A_ADD && t <= TOK_A_SAR) | |
| 1068 | +#define TOK_ASSIGN_OP(t) ("+-*/%&|^<>"[t - TOK_A_ADD]) | |
| 1034 | 1069 | |
| 1035 | 1070 | /* tokens that carry values (in additional token string space / tokc) --> */ |
| 1036 | −#define TOK_CCHAR 0xb3 /* char constant in tokc */ | |
| 1037 | −#define TOK_LCHAR 0xb4 | |
| 1038 | −#define TOK_CINT 0xb5 /* number in tokc */ | |
| 1039 | −#define TOK_CUINT 0xb6 /* unsigned int constant */ | |
| 1040 | −#define TOK_CLLONG 0xb7 /* long long constant */ | |
| 1041 | −#define TOK_CULLONG 0xb8 /* unsigned long long constant */ | |
| 1042 | −#define TOK_STR 0xb9 /* pointer to string in tokc */ | |
| 1043 | −#define TOK_LSTR 0xba | |
| 1044 | −#define TOK_CFLOAT 0xbb /* float constant */ | |
| 1045 | −#define TOK_CDOUBLE 0xbc /* double constant */ | |
| 1046 | −#define TOK_CLDOUBLE 0xbd /* long double constant */ | |
| 1047 | −#define TOK_PPNUM 0xbe /* preprocessor number */ | |
| 1048 | −#define TOK_PPSTR 0xbf /* preprocessor string */ | |
| 1049 | −#define TOK_LINENUM 0xc0 /* line number info */ | |
| 1050 | −#define TOK_TWODOTS 0xa8 /* C++ token ? */ | |
| 1051 | −/* <-- */ | |
| 1052 | − | |
| 1053 | −#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */ | |
| 1054 | −#define TOK_ADDC1 0xc3 /* add with carry generation */ | |
| 1055 | −#define TOK_ADDC2 0xc4 /* add with carry use */ | |
| 1056 | −#define TOK_SUBC1 0xc5 /* add with carry generation */ | |
| 1057 | −#define TOK_SUBC2 0xc6 /* add with carry use */ | |
| 1058 | −#define TOK_ARROW 0xc7 | |
| 1059 | −#define TOK_DOTS 0xc8 /* three dots */ | |
| 1060 | −#define TOK_SHR 0xc9 /* unsigned shift right */ | |
| 1061 | −#define TOK_TWOSHARPS 0xca /* ## preprocessing token */ | |
| 1062 | −#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */ | |
| 1063 | −#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */ | |
| 1064 | −#define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */ | |
| 1065 | −#define TOK_CLONG 0xce /* long constant */ | |
| 1066 | −#define TOK_CULONG 0xcf /* unsigned long constant */ | |
| 1067 | − | |
| 1068 | −#define TOK_SHL 0x01 /* shift left */ | |
| 1069 | −#define TOK_SAR 0x02 /* signed shift right */ | |
| 1070 | − | |
| 1071 | −/* assignment operators : normal operator or 0x80 */ | |
| 1072 | −#define TOK_A_MOD 0xa5 | |
| 1073 | −#define TOK_A_AND 0xa6 | |
| 1074 | −#define TOK_A_MUL 0xaa | |
| 1075 | −#define TOK_A_ADD 0xab | |
| 1076 | −#define TOK_A_SUB 0xad | |
| 1077 | −#define TOK_A_DIV 0xaf | |
| 1078 | −#define TOK_A_XOR 0xde | |
| 1079 | −#define TOK_A_OR 0xfc | |
| 1080 | −#define TOK_A_SHL 0x81 | |
| 1081 | −#define TOK_A_SAR 0x82 | |
| 1071 | +#define TOK_CCHAR 0xc0 /* char constant in tokc */ | |
| 1072 | +#define TOK_LCHAR 0xc1 | |
| 1073 | +#define TOK_CINT 0xc2 /* number in tokc */ | |
| 1074 | +#define TOK_CUINT 0xc3 /* unsigned int constant */ | |
| 1075 | +#define TOK_CLLONG 0xc4 /* long long constant */ | |
| 1076 | +#define TOK_CULLONG 0xc5 /* unsigned long long constant */ | |
| 1077 | +#define TOK_CLONG 0xc6 /* long constant */ | |
| 1078 | +#define TOK_CULONG 0xc7 /* unsigned long constant */ | |
| 1079 | +#define TOK_STR 0xc8 /* pointer to string in tokc */ | |
| 1080 | +#define TOK_LSTR 0xc9 | |
| 1081 | +#define TOK_CFLOAT 0xca /* float constant */ | |
| 1082 | +#define TOK_CDOUBLE 0xcb /* double constant */ | |
| 1083 | +#define TOK_CLDOUBLE 0xcc /* long double constant */ | |
| 1084 | +#define TOK_PPNUM 0xcd /* preprocessor number */ | |
| 1085 | +#define TOK_PPSTR 0xce /* preprocessor string */ | |
| 1086 | +#define TOK_LINENUM 0xcf /* line number info */ | |
| 1087 | + | |
| 1088 | +#define TOK_HAS_VALUE(t) (t >= TOK_CCHAR && t <= TOK_LINENUM) | |
| 1082 | 1089 | |
| 1083 | 1090 | #define TOK_EOF (-1) /* end of file */ |
| 1084 | 1091 | #define TOK_LINEFEED 10 /* line feed */ |
| @@ -1346,7 +1353,6 @@ ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); · 261 unmodified lines | ||
| 1346 | 1353 | ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep); |
| 1347 | 1354 | ST_FUNC void parse_define(void); |
| 1348 | 1355 | ST_FUNC void preprocess(int is_bof); |
| 1349 | −ST_FUNC void next_nomacro(void); | |
| 1350 | 1356 | ST_FUNC void next(void); |
| 1351 | 1357 | ST_INLN void unget_tok(int last_tok); |
| 1352 | 1358 | ST_FUNC void preprocess_start(TCCState *s1, int is_asm); |
| @@ -3064,7 +3064,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 3063 unmodified lines | ||
| 3064 | 3064 | else if (bt1 != bt2) { |
| 3065 | 3065 | /* accept comparison or cond-expr between pointer and integer |
| 3066 | 3066 | with a warning */ |
| 3067 | − if ((op == '?' || (op >= TOK_ULT && op <= TOK_LOR)) | |
| 3067 | + if ((op == '?' || TOK_ISCOND(op)) | |
| 3068 | 3068 | && (is_integer_btype(bt1) || is_integer_btype(bt2))) |
| 3069 | 3069 | tcc_warning("pointer/integer mismatch in %s", |
| 3070 | 3070 | op == '?' ? "conditional expression" : "comparison"); |
| @@ -3079,7 +3079,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 8 unmodified lines | ||
| 3079 | 3079 | int newquals, copied = 0; |
| 3080 | 3080 | if (pbt1 != VT_VOID && pbt2 != VT_VOID |
| 3081 | 3081 | && !compare_types(pt1, pt2, 1/*unqualif*/)) { |
| 3082 | − if (op != '?' && (op < TOK_ULT || op > TOK_LOR)) | |
| 3082 | + if (op != '?' && !TOK_ISCOND(op)) | |
| 3083 | 3083 | ret = 0; |
| 3084 | 3084 | else |
| 3085 | 3085 | type_incompatibility_warning(type1, type2, |
| @@ -3120,7 +3120,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 34 unmodified lines | ||
| 3120 | 3120 | } |
| 3121 | 3121 | } |
| 3122 | 3122 | } |
| 3123 | − if (op >= TOK_ULT && op <= TOK_LOR) | |
| 3123 | + if (TOK_ISCOND(op)) | |
| 3124 | 3124 | type.t = VT_SIZE_T; |
| 3125 | 3125 | } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { |
| 3126 | 3126 | if (op != '?' || !compare_types(type1, type2, 1)) |
| @@ -3188,7 +3188,7 @@ redo: · 61 unmodified lines | ||
| 3188 | 3188 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { |
| 3189 | 3189 | /* at least one operand is a pointer */ |
| 3190 | 3190 | /* relational op: must be both pointers */ |
| 3191 | − if (op >= TOK_ULT && op <= TOK_LOR) | |
| 3191 | + if (TOK_ISCOND(op)) | |
| 3192 | 3192 | goto std_op; |
| 3193 | 3193 | /* if both pointers, then it must be the '-' op */ |
| 3194 | 3194 | if (bt1 == VT_PTR && bt2 == VT_PTR) { |
| @@ -3256,7 +3256,7 @@ redo: · 61 unmodified lines | ||
| 3256 | 3256 | /* floats can only be used for a few operations */ |
| 3257 | 3257 | if (is_float(combtype.t) |
| 3258 | 3258 | && op != '+' && op != '-' && op != '*' && op != '/' |
| 3259 | − && (op < TOK_ULT || op > TOK_LOR)) | |
| 3259 | + && !TOK_ISCOND(op)) | |
| 3260 | 3260 | tcc_error("invalid operands for binary operation"); |
| 3261 | 3261 | else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) { |
| 3262 | 3262 | t = bt1 == VT_LLONG ? VT_LLONG : VT_INT; |
| @@ -3297,7 +3297,7 @@ redo: · 34 unmodified lines | ||
| 3297 | 3297 | gen_opif(op); |
| 3298 | 3298 | else |
| 3299 | 3299 | gen_opic(op); |
| 3300 | − if (op >= TOK_ULT && op <= TOK_LOR) { | |
| 3300 | + if (TOK_ISCOND(op)) { | |
| 3301 | 3301 | /* relational op: the result is an int */ |
| 3302 | 3302 | vtop->type.t = VT_INT; |
| 3303 | 3303 | } else { |
| @@ -4065,13 +4065,8 @@ redo: · 761 unmodified lines | ||
| 4065 | 4065 | tcc_warning("implicit declaration of function '%s'", |
| 4066 | 4066 | get_tok_str(tok, &tokc)); |
| 4067 | 4067 | s = external_global_sym(tok, &func_old_type); |
| 4068 | − } | |
| 4069 | − else if ((s->type.t & VT_BTYPE) == VT_FUNC) { | |
| 4070 | − ad->cleanup_func = s; | |
| 4071 | − } | |
| 4072 | − else { | |
| 4068 | + } else if ((s->type.t & VT_BTYPE) != VT_FUNC) | |
| 4073 | 4069 | tcc_error("'%s' is not declared as function", get_tok_str(tok, &tokc)); |
| 4074 | − } | |
| 4075 | 4070 | ad->cleanup_func = s; |
| 4076 | 4071 | next(); |
| 4077 | 4072 | skip(')'); |
| @@ -5937,11 +5932,8 @@ special_math_val: · 1859 unmodified lines | ||
| 5937 | 5932 | test_lvalue(); |
| 5938 | 5933 | gaddrof(); |
| 5939 | 5934 | /* expect pointer on structure */ |
| 5940 | − if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) { | |
| 5941 | − char got[256]; | |
| 5942 | − type_to_str(got, sizeof got, &vtop->type, NULL); | |
| 5943 | − tcc_error("expected struct or union but not '%s'", got); | |
| 5944 | − } | |
| 5935 | + if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) | |
| 5936 | + expect("struct or union"); | |
| 5945 | 5937 | if (tok == TOK_CDOUBLE) |
| 5946 | 5938 | expect("field name"); |
| 5947 | 5939 | next(); |
| @@ -6487,10 +6479,7 @@ static void expr_eq(void) · 539 unmodified lines | ||
| 6487 | 6479 | int t; |
| 6488 | 6480 | |
| 6489 | 6481 | expr_cond(); |
| 6490 | − if ((t = tok) == '=' | |
| 6491 | − || (t >= TOK_A_MOD && t <= TOK_A_DIV) | |
| 6492 | − || t == TOK_A_XOR || t == TOK_A_OR | |
| 6493 | − || t == TOK_A_SHL || t == TOK_A_SAR) { | |
| 6482 | + if ((t = tok) == '=' || TOK_ASSIGN(t)) { | |
| 6494 | 6483 | test_lvalue(); |
| 6495 | 6484 | next(); |
| 6496 | 6485 | if (t == '=') { |
| @@ -6498,7 +6487,7 @@ static void expr_eq(void) · 1 unmodified line | ||
| 6498 | 6487 | } else { |
| 6499 | 6488 | vdup(); |
| 6500 | 6489 | expr_eq(); |
| 6501 | − gen_op(t & 0x7f); | |
| 6490 | + gen_op(TOK_ASSIGN_OP(t)); | |
| 6502 | 6491 | } |
| 6503 | 6492 | vstore(); |
| 6504 | 6493 | } |
| @@ -92,7 +92,7 @@ static const unsigned char tok_two_chars[] = · 91 unmodified lines | ||
| 92 | 92 | 0 |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | −static void next_nomacro_spc(void); | |
| 95 | +static void next_nomacro(void); | |
| 96 | 96 | |
| 97 | 97 | ST_FUNC void skip(int c) |
| 98 | 98 | { |
| @@ -1230,7 +1230,7 @@ ST_FUNC void tok_str_add_tok(TokenString *s) · 1131 unmodified lines | ||
| 1230 | 1230 | } |
| 1231 | 1231 | |
| 1232 | 1232 | /* get a token from an integer array and increment pointer. */ |
| 1233 | −static inline void TOK_GET(int *t, const int **pp, CValue *cv) | |
| 1233 | +static inline void tok_get(int *t, const int **pp, CValue *cv) | |
| 1234 | 1234 | { |
| 1235 | 1235 | const int *p = *pp; |
| 1236 | 1236 | int n, *tab; |
| @@ -1293,6 +1293,18 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 56 unmodified lines | ||
| 1293 | 1293 | *pp = p; |
| 1294 | 1294 | } |
| 1295 | 1295 | |
| 1296 | +#if 0 | |
| 1297 | +# define TOK_GET(t,p,c) tok_get(t,p,c) | |
| 1298 | +#else | |
| 1299 | +# define TOK_GET(t,p,c) do { \ | |
| 1300 | + int _t = **(p); \ | |
| 1301 | + if (TOK_HAS_VALUE(_t)) \ | |
| 1302 | + tok_get(t, p, c); \ | |
| 1303 | + else \ | |
| 1304 | + *(t) = _t, ++*(p); \ | |
| 1305 | + } while (0) | |
| 1306 | +#endif | |
| 1307 | + | |
| 1296 | 1308 | static int macro_is_equal(const int *a, const int *b) |
| 1297 | 1309 | { |
| 1298 | 1310 | CValue cv; |
| @@ -1493,7 +1505,8 @@ ST_FUNC void parse_define(void) · 194 unmodified lines | ||
| 1493 | 1505 | character. */ |
| 1494 | 1506 | parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES); |
| 1495 | 1507 | /* '(' must be just after macro definition for MACRO_FUNC */ |
| 1496 | − next_nomacro_spc(); | |
| 1508 | + next_nomacro(); | |
| 1509 | + parse_flags &= ~PARSE_FLAG_SPACES; | |
| 1497 | 1510 | if (tok == '(') { |
| 1498 | 1511 | int dotid = set_idnum('.', 0); |
| 1499 | 1512 | next_nomacro(); |
| @@ -1521,7 +1534,8 @@ ST_FUNC void parse_define(void) · 21 unmodified lines | ||
| 1521 | 1534 | goto bad_list; |
| 1522 | 1535 | next_nomacro(); |
| 1523 | 1536 | } |
| 1524 | − next_nomacro_spc(); | |
| 1537 | + parse_flags |= PARSE_FLAG_SPACES; | |
| 1538 | + next_nomacro(); | |
| 1525 | 1539 | t = MACRO_FUNC; |
| 1526 | 1540 | set_idnum('.', dotid); |
| 1527 | 1541 | } |
| @@ -1550,7 +1564,7 @@ ST_FUNC void parse_define(void) · 22 unmodified lines | ||
| 1550 | 1564 | } |
| 1551 | 1565 | tok_str_add2(&tokstr_buf, tok, &tokc); |
| 1552 | 1566 | skip: |
| 1553 | − next_nomacro_spc(); | |
| 1567 | + next_nomacro(); | |
| 1554 | 1568 | } |
| 1555 | 1569 | |
| 1556 | 1570 | parse_flags = saved_parse_flags; |
| @@ -2586,6 +2600,7 @@ static inline void next_nomacro1(void) · 1029 unmodified lines | ||
| 2586 | 2600 | case '\t': |
| 2587 | 2601 | tok = c; |
| 2588 | 2602 | p++; |
| 2603 | + maybe_space: | |
| 2589 | 2604 | if (parse_flags & PARSE_FLAG_SPACES) |
| 2590 | 2605 | goto keep_tok_flags; |
| 2591 | 2606 | while (isidnum_table[*p - CH_EOF] & IS_SPC) |
| @@ -2932,11 +2947,11 @@ maybe_newline: · 340 unmodified lines | ||
| 2932 | 2947 | p = parse_comment(p); |
| 2933 | 2948 | /* comments replaced by a blank */ |
| 2934 | 2949 | tok = ' '; |
| 2935 | − goto keep_tok_flags; | |
| 2950 | + goto maybe_space; | |
| 2936 | 2951 | } else if (c == '/') { |
| 2937 | 2952 | p = parse_line_comment(p); |
| 2938 | 2953 | tok = ' '; |
| 2939 | − goto keep_tok_flags; | |
| 2954 | + goto maybe_space; | |
| 2940 | 2955 | } else if (c == '=') { |
| 2941 | 2956 | p++; |
| 2942 | 2957 | tok = TOK_A_DIV; |
| @@ -2978,34 +2993,6 @@ keep_tok_flags: · 35 unmodified lines | ||
| 2978 | 2993 | #endif |
| 2979 | 2994 | } |
| 2980 | 2995 | |
| 2981 | −/* return next token without macro substitution. Can read input from | |
| 2982 | − macro_ptr buffer */ | |
| 2983 | −static void next_nomacro_spc(void) | |
| 2984 | −{ | |
| 2985 | − if (macro_ptr) { | |
| 2986 | − redo: | |
| 2987 | − tok = *macro_ptr; | |
| 2988 | − if (tok) { | |
| 2989 | − TOK_GET(&tok, ¯o_ptr, &tokc); | |
| 2990 | − if (tok == TOK_LINENUM) { | |
| 2991 | − file->line_num = tokc.i; | |
| 2992 | − goto redo; | |
| 2993 | − } | |
| 2994 | − } | |
| 2995 | − } else { | |
| 2996 | − next_nomacro1(); | |
| 2997 | − } | |
| 2998 | − //printf("token = %s\n", get_tok_str(tok, &tokc)); | |
| 2999 | −} | |
| 3000 | − | |
| 3001 | −ST_FUNC void next_nomacro(void) | |
| 3002 | −{ | |
| 3003 | − do { | |
| 3004 | − next_nomacro_spc(); | |
| 3005 | − } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC)); | |
| 3006 | −} | |
| 3007 | − | |
| 3008 | − | |
| 3009 | 2996 | static void macro_subst( |
| 3010 | 2997 | TokenString *tok_str, |
| 3011 | 2998 | Sym **nested_list, |
| @@ -3281,7 +3268,7 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str) · 269 unmodified lines | ||
| 3281 | 3268 | |
| 3282 | 3269 | if (ws_str) |
| 3283 | 3270 | return t; |
| 3284 | − next_nomacro_spc(); | |
| 3271 | + next_nomacro(); | |
| 3285 | 3272 | return tok; |
| 3286 | 3273 | } |
| 3287 | 3274 | } |
| @@ -3372,7 +3359,7 @@ static int macro_subst_tok( · 84 unmodified lines | ||
| 3372 | 3359 | } |
| 3373 | 3360 | do { |
| 3374 | 3361 | next_nomacro(); /* eat '(' */ |
| 3375 | − } while (tok == TOK_PLCHLDR); | |
| 3362 | + } while (tok == TOK_PLCHLDR || is_space(tok)); | |
| 3376 | 3363 | |
| 3377 | 3364 | /* argument macro */ |
| 3378 | 3365 | args = NULL; |
| @@ -3533,29 +3520,59 @@ no_subst: · 154 unmodified lines | ||
| 3533 | 3520 | } |
| 3534 | 3521 | } |
| 3535 | 3522 | |
| 3523 | +/* return next token without macro substitution. Can read input from | |
| 3524 | + macro_ptr buffer */ | |
| 3525 | +static void next_nomacro(void) | |
| 3526 | +{ | |
| 3527 | + int t; | |
| 3528 | + if (macro_ptr) { | |
| 3529 | + redo: | |
| 3530 | + t = *macro_ptr; | |
| 3531 | + if (TOK_HAS_VALUE(t)) { | |
| 3532 | + tok_get(&tok, ¯o_ptr, &tokc); | |
| 3533 | + if (t == TOK_LINENUM) { | |
| 3534 | + file->line_num = tokc.i; | |
| 3535 | + goto redo; | |
| 3536 | + } | |
| 3537 | + } else { | |
| 3538 | + macro_ptr++; | |
| 3539 | + if (t < TOK_IDENT) { | |
| 3540 | + if (!(parse_flags & PARSE_FLAG_SPACES) | |
| 3541 | + && (isidnum_table[t - CH_EOF] & IS_SPC)) | |
| 3542 | + goto redo; | |
| 3543 | + } | |
| 3544 | + tok = t; | |
| 3545 | + } | |
| 3546 | + } else { | |
| 3547 | + next_nomacro1(); | |
| 3548 | + } | |
| 3549 | +} | |
| 3550 | + | |
| 3536 | 3551 | /* return next token with macro substitution */ |
| 3537 | 3552 | ST_FUNC void next(void) |
| 3538 | 3553 | { |
| 3554 | + int t; | |
| 3539 | 3555 | redo: |
| 3540 | − if (parse_flags & PARSE_FLAG_SPACES) | |
| 3541 | − next_nomacro_spc(); | |
| 3542 | − else | |
| 3543 | − next_nomacro(); | |
| 3544 | − | |
| 3556 | + next_nomacro(); | |
| 3557 | + t = tok; | |
| 3545 | 3558 | if (macro_ptr) { |
| 3546 | − if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) { | |
| 3547 | − /* discard preprocessor markers */ | |
| 3548 | − goto redo; | |
| 3549 | − } else if (tok == 0) { | |
| 3550 | − /* end of macro or unget token string */ | |
| 3551 | − end_macro(); | |
| 3552 | − goto redo; | |
| 3553 | − } else if (tok == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS)) | |
| 3554 | − tcc_error("stray '\\' in program"); | |
| 3555 | − } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) { | |
| 3556 | − Sym *s; | |
| 3559 | + if (!TOK_HAS_VALUE(t)) { | |
| 3560 | + if (t == TOK_NOSUBST || t == TOK_PLCHLDR) { | |
| 3561 | + /* discard preprocessor markers */ | |
| 3562 | + goto redo; | |
| 3563 | + } else if (t == 0) { | |
| 3564 | + /* end of macro or unget token string */ | |
| 3565 | + end_macro(); | |
| 3566 | + goto redo; | |
| 3567 | + } else if (t == '\\') { | |
| 3568 | + if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS)) | |
| 3569 | + tcc_error("stray '\\' in program"); | |
| 3570 | + } | |
| 3571 | + return; | |
| 3572 | + } | |
| 3573 | + } else if (t >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) { | |
| 3557 | 3574 | /* if reading from file, try to substitute macros */ |
| 3558 | − s = define_find(tok); | |
| 3575 | + Sym *s = define_find(t); | |
| 3559 | 3576 | if (s) { |
| 3560 | 3577 | Sym *nested_list = NULL; |
| 3561 | 3578 | tokstr_buf.len = 0; |
| @@ -3564,12 +3581,13 @@ ST_FUNC void next(void) · 2 unmodified lines | ||
| 3564 | 3581 | begin_macro(&tokstr_buf, 0); |
| 3565 | 3582 | goto redo; |
| 3566 | 3583 | } |
| 3584 | + return; | |
| 3567 | 3585 | } |
| 3568 | 3586 | /* convert preprocessor tokens into C tokens */ |
| 3569 | − if (tok == TOK_PPNUM) { | |
| 3587 | + if (t == TOK_PPNUM) { | |
| 3570 | 3588 | if (parse_flags & PARSE_FLAG_TOK_NUM) |
| 3571 | 3589 | parse_number((char *)tokc.str.data); |
| 3572 | − } else if (tok == TOK_PPSTR) { | |
| 3590 | + } else if (t == TOK_PPSTR) { | |
| 3573 | 3591 | if (parse_flags & PARSE_FLAG_TOK_STR) |
| 3574 | 3592 | parse_string((char *)tokc.str.data, tokc.str.size - 1); |
| 3575 | 3593 | } |