From 0691b7630b89bf3de5f7691802cb923bd7c1fd99 Mon Sep 17 00:00:00 2001 From: Vlad Vissoultchev Date: Mon, 4 Apr 2016 15:30:26 +0300 Subject: [PATCH] tccgen.c: Allow type attributes to prefix enum/struct/union name 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` --- tccgen.c | 24 ++++++++++++++---------- tests/tests2/82_attribs_position.c | 14 ++++++++++++++ tests/tests2/82_attribs_position.expect | 0 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 tests/tests2/82_attribs_position.c create mode 100644 tests/tests2/82_attribs_position.expect diff --git a/tccgen.c b/tccgen.c index c1d5cae..4b2893a 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2906,16 +2906,20 @@ static void parse_attribute(AttributeDef *ad) } /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ -static void struct_decl(CType *type, int u) +static void struct_decl(CType *type, AttributeDef *ad, int u) { int a, v, size, align, maxalign, c, offset, flexible; int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; Sym *s, *ss, *ass, **ps; - AttributeDef ad; + AttributeDef ad1; CType type1, btype; a = tok; /* save decl type */ next(); + if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { + parse_attribute(ad); + next(); + } if (tok != '{') { v = tok; next(); @@ -2983,7 +2987,7 @@ static void struct_decl(CType *type, int u) offset = 0; flexible = 0; while (tok != '}') { - parse_btype(&btype, &ad); + parse_btype(&btype, &ad1); while (1) { if (flexible) tcc_error("flexible array member '%s' not at the end of struct", @@ -2992,7 +2996,7 @@ static void struct_decl(CType *type, int u) v = 0; type1 = btype; if (tok != ':') { - type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); + type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT); if (v == 0) { if ((type1.t & VT_BTYPE) != VT_STRUCT) expect("identifier"); @@ -3028,10 +3032,10 @@ static void struct_decl(CType *type, int u) get_tok_str(v, NULL)); } size = type_size(&type1, &align); - if (ad.a.aligned) { - if (align < ad.a.aligned) - align = ad.a.aligned; - } else if (ad.a.packed) { + if (ad1.a.aligned) { + if (align < ad1.a.aligned) + align = ad1.a.aligned; + } else if (ad1.a.packed) { align = 1; } else if (*tcc_state->pack_stack_ptr) { if (align > *tcc_state->pack_stack_ptr) @@ -3232,14 +3236,14 @@ static int parse_btype(CType *type, AttributeDef *ad) } break; case TOK_ENUM: - struct_decl(&type1, VT_ENUM); + struct_decl(&type1, ad, VT_ENUM); basic_type2: u = type1.t; type->ref = type1.ref; goto basic_type1; case TOK_STRUCT: case TOK_UNION: - struct_decl(&type1, VT_STRUCT); + struct_decl(&type1, ad, VT_STRUCT); goto basic_type2; /* type modifiers */ diff --git a/tests/tests2/82_attribs_position.c b/tests/tests2/82_attribs_position.c new file mode 100644 index 0000000..45039b3 --- /dev/null +++ b/tests/tests2/82_attribs_position.c @@ -0,0 +1,14 @@ +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +typedef union Unaligned16a { + uint16_t u; + uint8_t b[2]; +} __attribute__((packed)) Unaligned16a; + +typedef union __attribute__((packed)) Unaligned16b { + uint16_t u; + uint8_t b[2]; +} Unaligned16b; + +int main () { return 0; } diff --git a/tests/tests2/82_attribs_position.expect b/tests/tests2/82_attribs_position.expect new file mode 100644 index 0000000..e69de29