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`
This commit is contained in:
Vlad Vissoultchev 2016-04-04 15:30:26 +03:00
parent effc7d9ed4
commit 0691b7630b
3 changed files with 28 additions and 10 deletions

View File

@ -2906,16 +2906,20 @@ static void parse_attribute(AttributeDef *ad)
} }
/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ /* 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 a, v, size, align, maxalign, c, offset, flexible;
int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
Sym *s, *ss, *ass, **ps; Sym *s, *ss, *ass, **ps;
AttributeDef ad; AttributeDef ad1;
CType type1, btype; CType type1, btype;
a = tok; /* save decl type */ a = tok; /* save decl type */
next(); next();
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
parse_attribute(ad);
next();
}
if (tok != '{') { if (tok != '{') {
v = tok; v = tok;
next(); next();
@ -2983,7 +2987,7 @@ static void struct_decl(CType *type, int u)
offset = 0; offset = 0;
flexible = 0; flexible = 0;
while (tok != '}') { while (tok != '}') {
parse_btype(&btype, &ad); parse_btype(&btype, &ad1);
while (1) { while (1) {
if (flexible) if (flexible)
tcc_error("flexible array member '%s' not at the end of struct", 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; v = 0;
type1 = btype; type1 = btype;
if (tok != ':') { if (tok != ':') {
type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT);
if (v == 0) { if (v == 0) {
if ((type1.t & VT_BTYPE) != VT_STRUCT) if ((type1.t & VT_BTYPE) != VT_STRUCT)
expect("identifier"); expect("identifier");
@ -3028,10 +3032,10 @@ static void struct_decl(CType *type, int u)
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
size = type_size(&type1, &align); size = type_size(&type1, &align);
if (ad.a.aligned) { if (ad1.a.aligned) {
if (align < ad.a.aligned) if (align < ad1.a.aligned)
align = ad.a.aligned; align = ad1.a.aligned;
} else if (ad.a.packed) { } else if (ad1.a.packed) {
align = 1; align = 1;
} else if (*tcc_state->pack_stack_ptr) { } else if (*tcc_state->pack_stack_ptr) {
if (align > *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; break;
case TOK_ENUM: case TOK_ENUM:
struct_decl(&type1, VT_ENUM); struct_decl(&type1, ad, VT_ENUM);
basic_type2: basic_type2:
u = type1.t; u = type1.t;
type->ref = type1.ref; type->ref = type1.ref;
goto basic_type1; goto basic_type1;
case TOK_STRUCT: case TOK_STRUCT:
case TOK_UNION: case TOK_UNION:
struct_decl(&type1, VT_STRUCT); struct_decl(&type1, ad, VT_STRUCT);
goto basic_type2; goto basic_type2;
/* type modifiers */ /* type modifiers */

View File

@ -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; }

View File