From gcc docs: "You may also specify attributes between the enum, struct or union tag and the name of the type rather than after the closing brace." Adds `82_attribs_position.c` in `tests/tests2`
Unified · Split
| @@ -2906,16 +2906,20 @@ static void parse_attribute(AttributeDef *ad) · 2905 unmodified lines | ||
| 2906 | 2906 | } |
| 2907 | 2907 | |
| 2908 | 2908 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ |
| 2909 | −static void struct_decl(CType *type, int u) | |
| 2909 | +static void struct_decl(CType *type, AttributeDef *ad, int u) | |
| 2910 | 2910 | { |
| 2911 | 2911 | int a, v, size, align, maxalign, c, offset, flexible; |
| 2912 | 2912 | int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; |
| 2913 | 2913 | Sym *s, *ss, *ass, **ps; |
| 2914 | − AttributeDef ad; | |
| 2914 | + AttributeDef ad1; | |
| 2915 | 2915 | CType type1, btype; |
| 2916 | 2916 | |
| 2917 | 2917 | a = tok; /* save decl type */ |
| 2918 | 2918 | next(); |
| 2919 | + if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { | |
| 2920 | + parse_attribute(ad); | |
| 2921 | + next(); | |
| 2922 | + } | |
| 2919 | 2923 | if (tok != '{') { |
| 2920 | 2924 | v = tok; |
| 2921 | 2925 | next(); |
| @@ -2983,7 +2987,7 @@ static void struct_decl(CType *type, int u) · 61 unmodified lines | ||
| 2983 | 2987 | offset = 0; |
| 2984 | 2988 | flexible = 0; |
| 2985 | 2989 | while (tok != '}') { |
| 2986 | − parse_btype(&btype, &ad); | |
| 2990 | + parse_btype(&btype, &ad1); | |
| 2987 | 2991 | while (1) { |
| 2988 | 2992 | if (flexible) |
| 2989 | 2993 | tcc_error("flexible array member '%s' not at the end of struct", |
| @@ -2992,7 +2996,7 @@ static void struct_decl(CType *type, int u) · 2 unmodified lines | ||
| 2992 | 2996 | v = 0; |
| 2993 | 2997 | type1 = btype; |
| 2994 | 2998 | if (tok != ':') { |
| 2995 | − type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); | |
| 2999 | + type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT); | |
| 2996 | 3000 | if (v == 0) { |
| 2997 | 3001 | if ((type1.t & VT_BTYPE) != VT_STRUCT) |
| 2998 | 3002 | expect("identifier"); |
| @@ -3028,10 +3032,10 @@ static void struct_decl(CType *type, int u) · 29 unmodified lines | ||
| 3028 | 3032 | get_tok_str(v, NULL)); |
| 3029 | 3033 | } |
| 3030 | 3034 | size = type_size(&type1, &align); |
| 3031 | − if (ad.a.aligned) { | |
| 3032 | − if (align < ad.a.aligned) | |
| 3033 | − align = ad.a.aligned; | |
| 3034 | − } else if (ad.a.packed) { | |
| 3035 | + if (ad1.a.aligned) { | |
| 3036 | + if (align < ad1.a.aligned) | |
| 3037 | + align = ad1.a.aligned; | |
| 3038 | + } else if (ad1.a.packed) { | |
| 3035 | 3039 | align = 1; |
| 3036 | 3040 | } else if (*tcc_state->pack_stack_ptr) { |
| 3037 | 3041 | if (align > *tcc_state->pack_stack_ptr) |
| @@ -3232,14 +3236,14 @@ static int parse_btype(CType *type, AttributeDef *ad) · 194 unmodified lines | ||
| 3232 | 3236 | } |
| 3233 | 3237 | break; |
| 3234 | 3238 | case TOK_ENUM: |
| 3235 | − struct_decl(&type1, VT_ENUM); | |
| 3239 | + struct_decl(&type1, ad, VT_ENUM); | |
| 3236 | 3240 | basic_type2: |
| 3237 | 3241 | u = type1.t; |
| 3238 | 3242 | type->ref = type1.ref; |
| 3239 | 3243 | goto basic_type1; |
| 3240 | 3244 | case TOK_STRUCT: |
| 3241 | 3245 | case TOK_UNION: |
| 3242 | − struct_decl(&type1, VT_STRUCT); | |
| 3246 | + struct_decl(&type1, ad, VT_STRUCT); | |
| 3243 | 3247 | goto basic_type2; |
| 3244 | 3248 | |
| 3245 | 3249 | /* type modifiers */ |
| @@ -0,0 +1,14 @@ | ||
| 1 | +typedef unsigned short uint16_t; | |
| 2 | +typedef unsigned char uint8_t; | |
| 3 | + | |
| 4 | +typedef union Unaligned16a { | |
| 5 | + uint16_t u; | |
| 6 | + uint8_t b[2]; | |
| 7 | +} __attribute__((packed)) Unaligned16a; | |
| 8 | + | |
| 9 | +typedef union __attribute__((packed)) Unaligned16b { | |
| 10 | + uint16_t u; | |
| 11 | + uint8_t b[2]; | |
| 12 | +} Unaligned16b; | |
| 13 | + | |
| 14 | +int main () { return 0; } | |
Empty file added.