| @@ -86,7 +86,7 @@ static void expr_eq(void); · 85 unmodified lines |
| 86 | 86 | static void vla_runtime_type_size(CType *type, int *a); |
| 87 | 87 | static void vla_sp_restore(void); |
| 88 | 88 | static void vla_sp_restore_root(void); |
| 89 | | −static int is_compatible_parameter_types(CType *type1, CType *type2); |
| 89 | +static int is_compatible_unqualified_types(CType *type1, CType *type2); |
| 90 | 90 | static inline int64_t expr_const64(void); |
| 91 | 91 | ST_FUNC void vpush64(int ty, unsigned long long v); |
| 92 | 92 | ST_FUNC void vpush(CType *type); |
| @@ -1087,10 +1087,8 @@ ST_FUNC int gv(int rc) · 994 unmodified lines |
| 1087 | 1087 | bits = 64; |
| 1088 | 1088 | } else |
| 1089 | 1089 | type.t = VT_INT; |
| 1090 | | − if((vtop->type.t & VT_UNSIGNED) || |
| 1091 | | − (vtop->type.t & VT_BTYPE) == VT_BOOL || |
| 1092 | | − (((vtop->type.t & VT_BTYPE) == VT_ENUM) && |
| 1093 | | − vtop->type.ref->a.unsigned_enum)) |
| 1090 | + if((vtop->type.t & VT_UNSIGNED) |
| 1091 | + || (vtop->type.t & VT_BTYPE) == VT_BOOL) |
| 1094 | 1092 | type.t |= VT_UNSIGNED; |
| 1095 | 1093 | gen_cast(&type); |
| 1096 | 1094 | /* generate shifts */ |
| @@ -2479,6 +2477,8 @@ ST_FUNC int type_size(CType *type, int *a) · 1382 unmodified lines |
| 2479 | 2477 | *a = PTR_SIZE; |
| 2480 | 2478 | return PTR_SIZE; |
| 2481 | 2479 | } |
| 2480 | + } else if (IS_ENUM(type->t) && type->ref->c == -1) { |
| 2481 | + return -1; /* incomplete enum */ |
| 2482 | 2482 | } else if (bt == VT_LDOUBLE) { |
| 2483 | 2483 | *a = LDOUBLE_ALIGN; |
| 2484 | 2484 | return LDOUBLE_SIZE; |
| @@ -2508,10 +2508,6 @@ ST_FUNC int type_size(CType *type, int *a) · 23 unmodified lines |
| 2508 | 2508 | } else if (bt == VT_QLONG || bt == VT_QFLOAT) { |
| 2509 | 2509 | *a = 8; |
| 2510 | 2510 | return 16; |
| 2511 | | − } else if (bt == VT_ENUM) { |
| 2512 | | − *a = 4; |
| 2513 | | − /* Enums might be incomplete, so don't just return '4' here. */ |
| 2514 | | − return type->ref->c; |
| 2515 | 2511 | } else { |
| 2516 | 2512 | /* char, void, function, _Bool */ |
| 2517 | 2513 | *a = 1; |
| @@ -2554,7 +2550,7 @@ ST_FUNC void mk_pointer(CType *type) · 36 unmodified lines |
| 2554 | 2550 | { |
| 2555 | 2551 | Sym *s; |
| 2556 | 2552 | s = sym_push(SYM_FIELD, type, 0, -1); |
| 2557 | | − type->t = VT_PTR | (type->t & ~VT_TYPE); |
| 2553 | + type->t = VT_PTR | (type->t & VT_STORAGE); |
| 2558 | 2554 | type->ref = s; |
| 2559 | 2555 | } |
| 2560 | 2556 | |
| @@ -2578,7 +2574,7 @@ static int is_compatible_func(CType *type1, CType *type2) · 17 unmodified lines |
| 2578 | 2574 | while (s1 != NULL) { |
| 2579 | 2575 | if (s2 == NULL) |
| 2580 | 2576 | return 0; |
| 2581 | | − if (!is_compatible_parameter_types(&s1->type, &s2->type)) |
| 2577 | + if (!is_compatible_unqualified_types(&s1->type, &s2->type)) |
| 2582 | 2578 | return 0; |
| 2583 | 2579 | s1 = s1->next; |
| 2584 | 2580 | s2 = s2->next; |
| @@ -2609,21 +2605,7 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 24 unmodified lines |
| 2609 | 2605 | t1 &= ~VT_DEFSIGN; |
| 2610 | 2606 | t2 &= ~VT_DEFSIGN; |
| 2611 | 2607 | } |
| 2612 | | − /* An enum is compatible with (unsigned) int. Ideally we would |
| 2613 | | − store the enums signedness in type->ref.a.<some_bit> and |
| 2614 | | − only accept unsigned enums with unsigned int and vice versa. |
| 2615 | | − But one of our callers (gen_assign_cast) always strips VT_UNSIGNED |
| 2616 | | − from pointer target types, so we can't add it here either. */ |
| 2617 | | − if ((t1 & VT_BTYPE) == VT_ENUM) { |
| 2618 | | − t1 = VT_INT; |
| 2619 | | − if (type1->ref->a.unsigned_enum) |
| 2620 | | − t1 |= VT_UNSIGNED; |
| 2621 | | − } |
| 2622 | | − if ((t2 & VT_BTYPE) == VT_ENUM) { |
| 2623 | | − t2 = VT_INT; |
| 2624 | | − if (type2->ref->a.unsigned_enum) |
| 2625 | | − t2 |= VT_UNSIGNED; |
| 2626 | | − } |
| 2608 | + |
| 2627 | 2609 | /* XXX: bitfields ? */ |
| 2628 | 2610 | if (t1 != t2) |
| 2629 | 2611 | return 0; |
| @@ -2652,7 +2634,7 @@ static int is_compatible_types(CType *type1, CType *type2) · 22 unmodified lines |
| 2652 | 2634 | |
| 2653 | 2635 | /* return true if type1 and type2 are the same (ignoring qualifiers). |
| 2654 | 2636 | */ |
| 2655 | | −static int is_compatible_parameter_types(CType *type1, CType *type2) |
| 2637 | +static int is_compatible_unqualified_types(CType *type1, CType *type2) |
| 2656 | 2638 | { |
| 2657 | 2639 | return compare_types(type1,type2,1); |
| 2658 | 2640 | } |
| @@ -2690,6 +2672,10 @@ static void type_to_str(char *buf, int buf_size, · 31 unmodified lines |
| 2690 | 2672 | pstrcat(buf, buf_size, "inline "); |
| 2691 | 2673 | buf_size -= strlen(buf); |
| 2692 | 2674 | buf += strlen(buf); |
| 2675 | + if (IS_ENUM(type->t)) { |
| 2676 | + tstr = "enum "; |
| 2677 | + goto tstruct; |
| 2678 | + } |
| 2693 | 2679 | switch(bt) { |
| 2694 | 2680 | case VT_VOID: |
| 2695 | 2681 | tstr = "void"; |
| @@ -2723,12 +2709,11 @@ static void type_to_str(char *buf, int buf_size, · 27 unmodified lines |
| 2723 | 2709 | add_tstr: |
| 2724 | 2710 | pstrcat(buf, buf_size, tstr); |
| 2725 | 2711 | break; |
| 2726 | | − case VT_ENUM: |
| 2727 | 2712 | case VT_STRUCT: |
| 2728 | | − if (bt == VT_STRUCT) |
| 2729 | | − tstr = "struct "; |
| 2730 | | − else |
| 2731 | | − tstr = "enum "; |
| 2713 | + tstr = "struct "; |
| 2714 | + if (IS_UNION(t)) |
| 2715 | + tstr = "union "; |
| 2716 | + tstruct: |
| 2732 | 2717 | pstrcat(buf, buf_size, tstr); |
| 2733 | 2718 | v = type->ref->v & ~SYM_STRUCT; |
| 2734 | 2719 | if (v >= SYM_FIRST_ANOM) |
| @@ -2827,21 +2812,16 @@ static void gen_assign_cast(CType *dt) · 92 unmodified lines |
| 2827 | 2812 | (type2->t & VT_BTYPE) == VT_VOID) { |
| 2828 | 2813 | /* void * can match anything */ |
| 2829 | 2814 | } else { |
| 2815 | + //printf("types %08x %08x\n", type1->t, type2->t); |
| 2830 | 2816 | /* exact type match, except for qualifiers */ |
| 2831 | | − tmp_type1 = *type1; |
| 2832 | | − tmp_type2 = *type2; |
| 2833 | | − tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); |
| 2834 | | − tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); |
| 2835 | | − if (!is_compatible_types(&tmp_type1, &tmp_type2)) { |
| 2817 | + if (!is_compatible_unqualified_types(type1, type2)) { |
| 2836 | 2818 | /* Like GCC don't warn by default for merely changes |
| 2837 | 2819 | in pointer target signedness. Do warn for different |
| 2838 | 2820 | base types, though, in particular for unsigned enums |
| 2839 | 2821 | and signed int targets. */ |
| 2840 | | − if ((tmp_type1.t & (VT_DEFSIGN | VT_UNSIGNED)) != |
| 2841 | | − (tmp_type2.t & (VT_DEFSIGN | VT_UNSIGNED)) && |
| 2842 | | − (tmp_type1.t & VT_BTYPE) == (tmp_type2.t & VT_BTYPE)) |
| 2843 | | − ; |
| 2844 | | − else |
| 2822 | + if ((type1->t & VT_BTYPE) != (type2->t & VT_BTYPE) |
| 2823 | + || IS_ENUM(type1->t) || IS_ENUM(type2->t) |
| 2824 | + ) |
| 2845 | 2825 | tcc_warning("assignment from incompatible pointer type"); |
| 2846 | 2826 | } |
| 2847 | 2827 | } |
| @@ -3486,7 +3466,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 638 unmodified lines |
| 3486 | 3466 | tcc_warning("will touch memory past end of the struct (internal limitation)"); |
| 3487 | 3467 | } |
| 3488 | 3468 | |
| 3489 | | −/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ |
| 3469 | +/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ |
| 3490 | 3470 | static void struct_decl(CType *type, int u) |
| 3491 | 3471 | { |
| 3492 | 3472 | int v, c, size, align, flexible, alignoverride; |
| @@ -3506,9 +3486,11 @@ static void struct_decl(CType *type, int u) · 13 unmodified lines |
| 3506 | 3486 | expect("struct/union/enum name"); |
| 3507 | 3487 | s = struct_find(v); |
| 3508 | 3488 | if (s && (s->sym_scope == local_scope || tok != '{')) { |
| 3509 | | − if ((s->type.t & (VT_BTYPE|VT_UNION)) != u) |
| 3510 | | − tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); |
| 3511 | | − goto do_decl; |
| 3489 | + if (u == s->type.t) |
| 3490 | + goto do_decl; |
| 3491 | + if (u == VT_ENUM && IS_ENUM(s->type.t)) |
| 3492 | + goto do_decl; |
| 3493 | + tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); |
| 3512 | 3494 | } |
| 3513 | 3495 | } else { |
| 3514 | 3496 | v = anon_sym++; |
| @@ -3520,7 +3502,7 @@ static void struct_decl(CType *type, int u) · 5 unmodified lines |
| 3520 | 3502 | s = sym_push(v | SYM_STRUCT, &type1, 0, -1); |
| 3521 | 3503 | s->r = 0; /* default alignment is zero as gcc */ |
| 3522 | 3504 | do_decl: |
| 3523 | | − type->t = u & VT_BTYPE; /* VT_UNION becomes VT_STRUCT */ |
| 3505 | + type->t = s->type.t; |
| 3524 | 3506 | type->ref = s; |
| 3525 | 3507 | |
| 3526 | 3508 | if (tok == '{') { |
| @@ -3528,13 +3510,15 @@ do_decl: · 1 unmodified line |
| 3528 | 3510 | if (s->c != -1) |
| 3529 | 3511 | tcc_error("struct/union/enum already defined"); |
| 3530 | 3512 | /* cannot be empty */ |
| 3531 | | − c = 0; |
| 3532 | 3513 | /* non empty enums are not allowed */ |
| 3514 | + ps = &s->next; |
| 3533 | 3515 | if (u == VT_ENUM) { |
| 3534 | | − int seen_neg = 0; |
| 3535 | | − int seen_wide = 0; |
| 3516 | + long long ll = 0, pl = 0, nl = 0; |
| 3517 | + CType t; |
| 3518 | + t.ref = s; |
| 3519 | + /* enum symbols have static storage */ |
| 3520 | + t.t = VT_INT|VT_STATIC|VT_ENUM_VAL; |
| 3536 | 3521 | for(;;) { |
| 3537 | | − CType *t = &int_type; |
| 3538 | 3522 | v = tok; |
| 3539 | 3523 | if (v < TOK_UIDENT) |
| 3540 | 3524 | expect("identifier"); |
| @@ -3545,38 +3529,48 @@ do_decl: · 4 unmodified lines |
| 3545 | 3529 | next(); |
| 3546 | 3530 | if (tok == '=') { |
| 3547 | 3531 | next(); |
| 3548 | | −#if PTR_SIZE == 8 |
| 3549 | | − c = expr_const64(); |
| 3550 | | −#else |
| 3551 | | − /* We really want to support long long enums |
| 3552 | | − on i386 as well, but the Sym structure only |
| 3553 | | − holds a 'long' for associated constants, |
| 3554 | | − and enlarging it would bump its size (no |
| 3555 | | − available padding). So punt for now. */ |
| 3556 | | − c = expr_const(); |
| 3557 | | −#endif |
| 3532 | + ll = expr_const64(); |
| 3558 | 3533 | } |
| 3559 | | − if (c < 0) |
| 3560 | | − seen_neg = 1; |
| 3561 | | − if (c != (int)c && (unsigned long)c != (unsigned int)c) |
| 3562 | | − seen_wide = 1, t = &size_type; |
| 3563 | | − /* enum symbols have static storage */ |
| 3564 | | − ss = sym_push(v, t, VT_CONST, c); |
| 3565 | | − ss->type.t |= VT_STATIC; |
| 3534 | + ss = sym_push(v, &t, VT_CONST, 0); |
| 3535 | + ss->enum_val = ll; |
| 3536 | + *ps = ss, ps = &ss->next; |
| 3537 | + if (ll < nl) |
| 3538 | + nl = ll; |
| 3539 | + if (ll > pl) |
| 3540 | + pl = ll; |
| 3566 | 3541 | if (tok != ',') |
| 3567 | 3542 | break; |
| 3568 | 3543 | next(); |
| 3569 | | − c++; |
| 3544 | + ll++; |
| 3570 | 3545 | /* NOTE: we accept a trailing comma */ |
| 3571 | 3546 | if (tok == '}') |
| 3572 | 3547 | break; |
| 3573 | 3548 | } |
| 3574 | | − if (!seen_neg) |
| 3575 | | − s->a.unsigned_enum = 1; |
| 3576 | | − s->c = type_size(seen_wide ? &size_type : &int_type, &align); |
| 3577 | 3549 | skip('}'); |
| 3550 | + /* set integral type of the enum */ |
| 3551 | + t.t = VT_INT; |
| 3552 | + if (nl == 0) { |
| 3553 | + if (pl != (unsigned)pl) |
| 3554 | + t.t = VT_LLONG; |
| 3555 | + t.t |= VT_UNSIGNED; |
| 3556 | + } else if (pl != (int)pl || nl != (int)nl) |
| 3557 | + t.t = VT_LLONG; |
| 3558 | + s->type.t = type->t = t.t | VT_ENUM; |
| 3559 | + s->c = 0; |
| 3560 | + /* set type for enum members */ |
| 3561 | + for (ss = s->next; ss; ss = ss->next) { |
| 3562 | + ll = ss->enum_val; |
| 3563 | + if (ll == (int)ll) /* default is int if it fits */ |
| 3564 | + continue; |
| 3565 | + if (t.t & VT_UNSIGNED) { |
| 3566 | + ss->type.t |= VT_UNSIGNED; |
| 3567 | + if (ll == (unsigned)ll) |
| 3568 | + continue; |
| 3569 | + } |
| 3570 | + ss->type.t = (ss->type.t & ~VT_BTYPE) | VT_LLONG; |
| 3571 | + } |
| 3578 | 3572 | } else { |
| 3579 | | − ps = &s->next; |
| 3573 | + c = 0; |
| 3580 | 3574 | flexible = 0; |
| 3581 | 3575 | while (tok != '}') { |
| 3582 | 3576 | if (!parse_btype(&btype, &ad1)) { |
| @@ -3646,7 +3640,6 @@ do_decl: · 63 unmodified lines |
| 3646 | 3640 | bt != VT_BYTE && |
| 3647 | 3641 | bt != VT_SHORT && |
| 3648 | 3642 | bt != VT_BOOL && |
| 3649 | | − bt != VT_ENUM && |
| 3650 | 3643 | bt != VT_LLONG) |
| 3651 | 3644 | tcc_error("bitfields must have scalar type"); |
| 3652 | 3645 | bsize = size * 8; |
| @@ -3657,9 +3650,9 @@ do_decl: · 4 unmodified lines |
| 3657 | 3650 | /* no need for bit fields */ |
| 3658 | 3651 | ; |
| 3659 | 3652 | } else { |
| 3660 | | − type1.t |= VT_BITFIELD | |
| 3661 | | − (0 << VT_STRUCT_SHIFT) | |
| 3662 | | − (bit_size << (VT_STRUCT_SHIFT + 6)); |
| 3653 | + type1.t = (type1.t & ~VT_STRUCT_MASK) |
| 3654 | + | VT_BITFIELD |
| 3655 | + | (bit_size << (VT_STRUCT_SHIFT + 6)); |
| 3663 | 3656 | } |
| 3664 | 3657 | } |
| 3665 | 3658 | if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) { |
| @@ -4124,6 +4117,7 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) · 458 unmodified lines |
| 4124 | 4117 | storage = type->t & VT_STORAGE; |
| 4125 | 4118 | type->t &= ~VT_STORAGE; |
| 4126 | 4119 | post = ret = type; |
| 4120 | + |
| 4127 | 4121 | while (tok == '*') { |
| 4128 | 4122 | qualifiers = 0; |
| 4129 | 4123 | redo: |
| @@ -4813,8 +4807,11 @@ ST_FUNC void unary(void) · 683 unmodified lines |
| 4813 | 4807 | Will be used by at least the x86 inline asm parser for |
| 4814 | 4808 | regvars. */ |
| 4815 | 4809 | vtop->sym = s; |
| 4816 | | − if (vtop->r & VT_SYM) { |
| 4810 | + |
| 4811 | + if (r & VT_SYM) { |
| 4817 | 4812 | vtop->c.i = 0; |
| 4813 | + } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) { |
| 4814 | + vtop->c.i = s->enum_val; |
| 4818 | 4815 | } |
| 4819 | 4816 | break; |
| 4820 | 4817 | } |
| @@ -6352,7 +6349,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 1531 unmodified lines |
| 6352 | 6349 | /* Use i_c_parameter_t, to strip toplevel qualifiers. |
| 6353 | 6350 | The source type might have VT_CONSTANT set, which is |
| 6354 | 6351 | of course assignable to non-const elements. */ |
| 6355 | | − is_compatible_parameter_types(type, &vtop->type)) { |
| 6352 | + is_compatible_unqualified_types(type, &vtop->type)) { |
| 6356 | 6353 | init_putv(type, sec, c); |
| 6357 | 6354 | } else if (type->t & VT_ARRAY) { |
| 6358 | 6355 | s = type->ref; |
| @@ -6858,16 +6855,18 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 499 unmodified lines |
| 6858 | 6855 | break; |
| 6859 | 6856 | btype.t = VT_INT; |
| 6860 | 6857 | } |
| 6861 | | − if (((btype.t & VT_BTYPE) == VT_ENUM || |
| 6862 | | − (btype.t & VT_BTYPE) == VT_STRUCT) && |
| 6863 | | − tok == ';') { |
| 6858 | + if (tok == ';') { |
| 6864 | 6859 | if ((btype.t & VT_BTYPE) == VT_STRUCT) { |
| 6865 | 6860 | int v = btype.ref->v; |
| 6866 | 6861 | if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) |
| 6867 | 6862 | tcc_warning("unnamed struct/union that defines no instances"); |
| 6863 | + next(); |
| 6864 | + continue; |
| 6868 | 6865 | } |
| 6869 | | − next(); |
| 6870 | | − continue; |
| 6866 | + if (IS_ENUM(btype.t)) { |
| 6867 | + next(); |
| 6868 | + continue; |
| 6869 | + } |
| 6871 | 6870 | } |
| 6872 | 6871 | while (1) { /* iterate thru each declaration */ |
| 6873 | 6872 | type = btype; |