Saves some lines of code.
Unified · Split
| @@ -4142,7 +4142,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) · 4141 unmodified lines | |||
| 4142 | mk_pointer(type); | 4142 | mk_pointer(type); |
| 4143 | type->t |= qualifiers; | 4143 | type->t |= qualifiers; |
| 4144 | } | 4144 | } |
| 4145 | 4145 | ||
| 4146 | /* recursive type */ | 4146 | /* recursive type */ |
| 4147 | /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ | 4147 | /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ |
| 4148 | type1.t = 0; /* XXX: same as int */ | 4148 | type1.t = 0; /* XXX: same as int */ |
| @@ -4290,6 +4290,27 @@ static void vpush_tokc(int t) · 141 unmodified lines | |||
| 4290 | vsetc(&type, VT_CONST, &tokc); | 4290 | vsetc(&type, VT_CONST, &tokc); |
| 4291 | } | 4291 | } |
| 4292 | 4292 | ||
| 4293 | static void parse_builtin_params(int nc, const char *args) | ||
| 4294 | { | ||
| 4295 | char c, sep = '('; | ||
| 4296 | CType t; | ||
| 4297 | if (nc) | ||
| 4298 | nocode_wanted++; | ||
| 4299 | next(); | ||
| 4300 | while ((c = *args++)) { | ||
| 4301 | skip(sep); | ||
| 4302 | sep = ','; | ||
| 4303 | switch (c) { | ||
| 4304 | case 'e': expr_eq(); continue; | ||
| 4305 | case 't': parse_type(&t); vpush(&t); continue; | ||
| 4306 | default: tcc_error("internal error"); break; | ||
| 4307 | } | ||
| 4308 | } | ||
| 4309 | skip(')'); | ||
| 4310 | if (nc) | ||
| 4311 | nocode_wanted--; | ||
| 4312 | } | ||
| 4313 | |||
| 4293 | ST_FUNC void unary(void) | 4314 | ST_FUNC void unary(void) |
| 4294 | { | 4315 | { |
| 4295 | int n, t, align, size, r, sizeof_caller; | 4316 | int n, t, align, size, r, sizeof_caller; |
| @@ -4497,30 +4518,17 @@ ST_FUNC void unary(void) · 201 unmodified lines | |||
| 4497 | break; | 4518 | break; |
| 4498 | 4519 | ||
| 4499 | case TOK_builtin_expect: | 4520 | case TOK_builtin_expect: |
| 4500 | { | 4521 | /* __builtin_expect is a no-op for now */ |
| 4501 | /* __builtin_expect is a no-op for now */ | 4522 | parse_builtin_params(0, "ee"); |
| 4502 | next(); | 4523 | vpop(); |
| 4503 | skip('('); | ||
| 4504 | expr_eq(); | ||
| 4505 | skip(','); | ||
| 4506 | expr_eq(); | ||
| 4507 | vpop(); | ||
| 4508 | skip(')'); | ||
| 4509 | } | ||
| 4510 | break; | 4524 | break; |
| 4511 | case TOK_builtin_types_compatible_p: | 4525 | case TOK_builtin_types_compatible_p: |
| 4512 | { | 4526 | parse_builtin_params(0, "tt"); |
| 4513 | CType type1, type2; | 4527 | vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE); |
| 4514 | next(); | 4528 | vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE); |
| 4515 | skip('('); | 4529 | n = is_compatible_types(&vtop[-1].type, &vtop[0].type); |
| 4516 | parse_type(&type1); | 4530 | vtop -= 2; |
| 4517 | skip(','); | 4531 | vpushi(n); |
| 4518 | parse_type(&type2); | ||
| 4519 | skip(')'); | ||
| 4520 | type1.t &= ~(VT_CONSTANT | VT_VOLATILE); | ||
| 4521 | type2.t &= ~(VT_CONSTANT | VT_VOLATILE); | ||
| 4522 | vpushi(is_compatible_types(&type1, &type2)); | ||
| 4523 | } | ||
| 4524 | break; | 4532 | break; |
| 4525 | case TOK_builtin_choose_expr: | 4533 | case TOK_builtin_choose_expr: |
| 4526 | { | 4534 | { |
| @@ -4550,18 +4558,10 @@ ST_FUNC void unary(void) · 23 unmodified lines | |||
| 4550 | } | 4558 | } |
| 4551 | break; | 4559 | break; |
| 4552 | case TOK_builtin_constant_p: | 4560 | case TOK_builtin_constant_p: |
| 4553 | { | 4561 | parse_builtin_params(1, "e"); |
| 4554 | int res; | 4562 | n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 4555 | next(); | 4563 | vtop--; |
| 4556 | skip('('); | 4564 | vpushi(n); |
| 4557 | nocode_wanted++; | ||
| 4558 | expr_eq(); | ||
| 4559 | res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; | ||
| 4560 | vpop(); | ||
| 4561 | nocode_wanted--; | ||
| 4562 | skip(')'); | ||
| 4563 | vpushi(res); | ||
| 4564 | } | ||
| 4565 | break; | 4565 | break; |
| 4566 | case TOK_builtin_frame_address: | 4566 | case TOK_builtin_frame_address: |
| 4567 | case TOK_builtin_return_address: | 4567 | case TOK_builtin_return_address: |
| @@ -4599,43 +4599,27 @@ ST_FUNC void unary(void) · 31 unmodified lines | |||
| 4599 | #ifdef TCC_TARGET_X86_64 | 4599 | #ifdef TCC_TARGET_X86_64 |
| 4600 | #ifdef TCC_TARGET_PE | 4600 | #ifdef TCC_TARGET_PE |
| 4601 | case TOK_builtin_va_start: | 4601 | case TOK_builtin_va_start: |
| 4602 | { | 4602 | parse_builtin_params(0, "ee"); |
| 4603 | next(); | 4603 | if ((vtop->r & VT_VALMASK) != VT_LOCAL) |
| 4604 | skip('('); | 4604 | tcc_error("__builtin_va_start expects a local variable"); |
| 4605 | expr_eq(); | 4605 | vtop->r &= ~VT_LVAL; |
| 4606 | skip(','); | 4606 | vtop->type = char_pointer_type; |
| 4607 | expr_eq(); | 4607 | vtop->c.i += 8; |
| 4608 | skip(')'); | 4608 | vstore(); |
| 4609 | if ((vtop->r & VT_VALMASK) != VT_LOCAL) | ||
| 4610 | tcc_error("__builtin_va_start expects a local variable"); | ||
| 4611 | vtop->r &= ~VT_LVAL; | ||
| 4612 | vtop->type = char_pointer_type; | ||
| 4613 | vtop->c.i += 8; | ||
| 4614 | vstore(); | ||
| 4615 | } | ||
| 4616 | break; | 4609 | break; |
| 4617 | #else | 4610 | #else |
| 4618 | case TOK_builtin_va_arg_types: | 4611 | case TOK_builtin_va_arg_types: |
| 4619 | { | 4612 | parse_builtin_params(0, "t"); |
| 4620 | CType type; | 4613 | vpushi(classify_x86_64_va_arg(&vtop->type)); |
| 4621 | next(); | 4614 | vswap(); |
| 4622 | skip('('); | 4615 | vpop(); |
| 4623 | parse_type(&type); | ||
| 4624 | skip(')'); | ||
| 4625 | vpushi(classify_x86_64_va_arg(&type)); | ||
| 4626 | } | ||
| 4627 | break; | 4616 | break; |
| 4628 | #endif | 4617 | #endif |
| 4629 | #endif | 4618 | #endif |
| 4630 | 4619 | ||
| 4631 | #ifdef TCC_TARGET_ARM64 | 4620 | #ifdef TCC_TARGET_ARM64 |
| 4632 | case TOK___va_start: { | 4621 | case TOK___va_start: { |
| 4633 | next(); | 4622 | parse_builtin_params(0, "ee"); |
| 4634 | skip('('); | ||
| 4635 | expr_eq(); | ||
| 4636 | skip(','); | ||
| 4637 | expr_eq(); | ||
| 4638 | skip(')'); | ||
| 4639 | //xx check types | 4623 | //xx check types |
| 4640 | gen_va_start(); | 4624 | gen_va_start(); |
| 4641 | vpushi(0); | 4625 | vpushi(0); |
| @@ -4644,24 +4628,16 @@ ST_FUNC void unary(void) · 2 unmodified lines | |||
| 4644 | } | 4628 | } |
| 4645 | case TOK___va_arg: { | 4629 | case TOK___va_arg: { |
| 4646 | CType type; | 4630 | CType type; |
| 4647 | next(); | 4631 | parse_builtin_params(0, "et"); |
| 4648 | skip('('); | 4632 | type = vtop->type; |
| 4649 | expr_eq(); | 4633 | vpop(); |
| 4650 | skip(','); | ||
| 4651 | parse_type(&type); | ||
| 4652 | skip(')'); | ||
| 4653 | //xx check types | 4634 | //xx check types |
| 4654 | gen_va_arg(&type); | 4635 | gen_va_arg(&type); |
| 4655 | vtop->type = type; | 4636 | vtop->type = type; |
| 4656 | break; | 4637 | break; |
| 4657 | } | 4638 | } |
| 4658 | case TOK___arm64_clear_cache: { | 4639 | case TOK___arm64_clear_cache: { |
| 4659 | next(); | 4640 | parse_builtin_params(0, "ee"); |
| 4660 | skip('('); | ||
| 4661 | expr_eq(); | ||
| 4662 | skip(','); | ||
| 4663 | expr_eq(); | ||
| 4664 | skip(')'); | ||
| 4665 | gen_clear_cache(); | 4641 | gen_clear_cache(); |
| 4666 | vpushi(0); | 4642 | vpushi(0); |
| 4667 | vtop->type.t = VT_VOID; | 4643 | vtop->type.t = VT_VOID; |
| @@ -4717,7 +4693,7 @@ ST_FUNC void unary(void) · 49 unmodified lines | |||
| 4717 | vpushsym(&s->type, s); | 4693 | vpushsym(&s->type, s); |
| 4718 | next(); | 4694 | next(); |
| 4719 | break; | 4695 | break; |
| 4720 | 4696 | ||
| 4721 | // special qnan , snan and infinity values | 4697 | // special qnan , snan and infinity values |
| 4722 | case TOK___NAN__: | 4698 | case TOK___NAN__: |
| 4723 | vpush64(VT_DOUBLE, 0x7ff8000000000000ULL); | 4699 | vpush64(VT_DOUBLE, 0x7ff8000000000000ULL); |