Skip to content

Commit

Permalink
Add __attribute__((aligned(N)) for struct declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Dec 7, 2020
1 parent 44bea4c commit b35d148
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
45 changes: 32 additions & 13 deletions parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2595,25 +2595,44 @@ static void struct_members(Token **rest, Token *tok, Type *ty) {
ty->members = head.next;
}

// attribute = ("__attribute__" "(" "(" "packed" ")" ")")?
static Token *attribute(Token *tok, Type *ty) {
if (!equal(tok, "__attribute__"))
return tok;
// attribute = ("__attribute__" "(" "(" "packed" ")" ")")*
static Token *attribute_list(Token *tok, Type *ty) {
while (consume(&tok, tok, "__attribute__")) {
tok = skip(tok, "(");
tok = skip(tok, "(");

bool first = true;

while (!consume(&tok, tok, ")")) {
if (!first)
tok = skip(tok, ",");
first = false;

if (consume(&tok, tok, "packed")) {
ty->is_packed = true;
continue;
}

if (consume(&tok, tok, "aligned")) {
tok = skip(tok, "(");
ty->align = const_expr(&tok, tok);
tok = skip(tok, ")");
continue;
}

error_tok(tok, "unknown attribute");
}

tok = skip(tok, ")");
}

tok = tok->next;
tok = skip(tok, "(");
tok = skip(tok, "(");
tok = skip(tok, "packed");
tok = skip(tok, ")");
tok = skip(tok, ")");
ty->is_packed = true;
return tok;
}

// struct-union-decl = attribute? ident? ("{" struct-members)?
static Type *struct_union_decl(Token **rest, Token *tok) {
Type *ty = struct_type();
tok = attribute(tok, ty);
tok = attribute_list(tok, ty);

// Read a tag.
Token *tag = NULL;
Expand All @@ -2638,7 +2657,7 @@ static Type *struct_union_decl(Token **rest, Token *tok) {

// Construct a struct object.
struct_members(&tok, tok, ty);
*rest = attribute(tok, ty);
*rest = attribute_list(tok, ty);

if (tag) {
// If this is a redefinition, overwrite a previous type.
Expand Down
18 changes: 18 additions & 0 deletions test/attribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ int main() {
ASSERT(1, offsetof(struct __attribute__((packed)) T { char a; int b[2]; }, b));
ASSERT(1, _Alignof(struct __attribute__((packed)) { char a; int b[2]; }));

ASSERT(8, ({ struct __attribute__((aligned(8))) { int a; } x; _Alignof(x); }));
ASSERT(8, ({ struct { int a; } __attribute__((aligned(8))) x; _Alignof(x); }));

ASSERT(8, ({ struct __attribute__((aligned(8), packed)) { char a; int b; } x; _Alignof(x); }));
ASSERT(8, ({ struct { char a; int b; } __attribute__((aligned(8), packed)) x; _Alignof(x); }));
ASSERT(1, offsetof(struct __attribute__((aligned(8), packed)) { char a; int b; }, b));
ASSERT(1, offsetof(struct { char a; int b; } __attribute__((aligned(8), packed)), b));

ASSERT(8, ({ struct __attribute__((aligned(8))) __attribute__((packed)) { char a; int b; } x; _Alignof(x); }));
ASSERT(8, ({ struct { char a; int b; } __attribute__((aligned(8))) __attribute__((packed)) x; _Alignof(x); }));
ASSERT(1, offsetof(struct __attribute__((aligned(8))) __attribute__((packed)) { char a; int b; }, b));
ASSERT(1, offsetof(struct { char a; int b; } __attribute__((aligned(8))) __attribute__((packed)), b));

ASSERT(8, ({ struct __attribute__((aligned(8))) { char a; int b; } __attribute__((packed)) x; _Alignof(x); }));
ASSERT(1, offsetof(struct __attribute__((aligned(8))) { char a; int b; } __attribute__((packed)), b));

ASSERT(16, ({ struct __attribute__((aligned(8+8))) { char a; int b; } x; _Alignof(x); }));

printf("OK\n");
return 0;
}

0 comments on commit b35d148

Please sign in to comment.