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 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ | 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 | int a, v, size, align, maxalign, c, offset, flexible; | 2911 | int a, v, size, align, maxalign, c, offset, flexible; |
| 2912 | int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; | 2912 | int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; |
| 2913 | Sym *s, *ss, *ass, **ps; | 2913 | Sym *s, *ss, *ass, **ps; |
| 2914 | AttributeDef ad; | 2914 | AttributeDef ad1; |
| 2915 | CType type1, btype; | 2915 | CType type1, btype; |
| 2916 | 2916 | ||
| 2917 | a = tok; /* save decl type */ | 2917 | a = tok; /* save decl type */ |
| 2918 | next(); | 2918 | next(); |
| 2919 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { | ||
| 2920 | parse_attribute(ad); | ||
| 2921 | next(); | ||
| 2922 | } | ||
| 2919 | if (tok != '{') { | 2923 | if (tok != '{') { |
| 2920 | v = tok; | 2924 | v = tok; |
| 2921 | next(); | 2925 | next(); |
| @@ -2983,7 +2987,7 @@ static void struct_decl(CType *type, int u) · 61 unmodified lines | |||
| 2983 | offset = 0; | 2987 | offset = 0; |
| 2984 | flexible = 0; | 2988 | flexible = 0; |
| 2985 | while (tok != '}') { | 2989 | while (tok != '}') { |
| 2986 | parse_btype(&btype, &ad); | 2990 | parse_btype(&btype, &ad1); |
| 2987 | while (1) { | 2991 | while (1) { |
| 2988 | if (flexible) | 2992 | if (flexible) |
| 2989 | tcc_error("flexible array member '%s' not at the end of struct", | 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 | v = 0; | 2996 | v = 0; |
| 2993 | type1 = btype; | 2997 | type1 = btype; |
| 2994 | if (tok != ':') { | 2998 | if (tok != ':') { |
| 2995 | type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); | 2999 | type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT); |
| 2996 | if (v == 0) { | 3000 | if (v == 0) { |
| 2997 | if ((type1.t & VT_BTYPE) != VT_STRUCT) | 3001 | if ((type1.t & VT_BTYPE) != VT_STRUCT) |
| 2998 | expect("identifier"); | 3002 | expect("identifier"); |
| @@ -3028,10 +3032,10 @@ static void struct_decl(CType *type, int u) · 29 unmodified lines | |||
| 3028 | get_tok_str(v, NULL)); | 3032 | get_tok_str(v, NULL)); |
| 3029 | } | 3033 | } |
| 3030 | size = type_size(&type1, &align); | 3034 | size = type_size(&type1, &align); |
| 3031 | if (ad.a.aligned) { | 3035 | if (ad1.a.aligned) { |
| 3032 | if (align < ad.a.aligned) | 3036 | if (align < ad1.a.aligned) |
| 3033 | align = ad.a.aligned; | 3037 | align = ad1.a.aligned; |
| 3034 | } else if (ad.a.packed) { | 3038 | } else if (ad1.a.packed) { |
| 3035 | align = 1; | 3039 | align = 1; |
| 3036 | } else if (*tcc_state->pack_stack_ptr) { | 3040 | } else if (*tcc_state->pack_stack_ptr) { |
| 3037 | if (align > *tcc_state->pack_stack_ptr) | 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 | break; | 3237 | break; |
| 3234 | case TOK_ENUM: | 3238 | case TOK_ENUM: |
| 3235 | struct_decl(&type1, VT_ENUM); | 3239 | struct_decl(&type1, ad, VT_ENUM); |
| 3236 | basic_type2: | 3240 | basic_type2: |
| 3237 | u = type1.t; | 3241 | u = type1.t; |
| 3238 | type->ref = type1.ref; | 3242 | type->ref = type1.ref; |
| 3239 | goto basic_type1; | 3243 | goto basic_type1; |
| 3240 | case TOK_STRUCT: | 3244 | case TOK_STRUCT: |
| 3241 | case TOK_UNION: | 3245 | case TOK_UNION: |
| 3242 | struct_decl(&type1, VT_STRUCT); | 3246 | struct_decl(&type1, ad, VT_STRUCT); |
| 3243 | goto basic_type2; | 3247 | goto basic_type2; |
| 3244 | 3248 | ||
| 3245 | /* type modifiers */ | 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.