Handle struct designator for anonymous struct member

This commit is contained in:
Rui Ueyama 2020-07-19 17:19:50 +09:00
parent 31dc1dfa21
commit 95eb5b01b3
2 changed files with 16 additions and 0 deletions

12
parse.c
View File

@ -149,6 +149,7 @@ static Node *new_add(Node *lhs, Node *rhs, Token *tok);
static Node *new_sub(Node *lhs, Node *rhs, Token *tok);
static Node *mul(Token **rest, Token *tok);
static Node *cast(Token **rest, Token *tok);
static Member *get_struct_member(Type *ty, Token *tok);
static Type *struct_decl(Token **rest, Token *tok);
static Type *union_decl(Token **rest, Token *tok);
static Node *postfix(Token **rest, Token *tok);
@ -888,11 +889,22 @@ static int array_designator(Token **rest, Token *tok, Type *ty) {
// struct-designator = "." ident
static Member *struct_designator(Token **rest, Token *tok, Type *ty) {
Token *start = tok;
tok = skip(tok, ".");
if (tok->kind != TK_IDENT)
error_tok(tok, "expected a field designator");
for (Member *mem = ty->members; mem; mem = mem->next) {
// Anonymous struct member
if (mem->ty->kind == TY_STRUCT && !mem->name) {
if (get_struct_member(mem->ty, tok)) {
*rest = start;
return mem;
}
continue;
}
// Regular struct member
if (mem->name->len == tok->len && !strncmp(mem->name->loc, tok->loc, tok->len)) {
*rest = tok->next;
return mem;

View File

@ -255,6 +255,10 @@ int main() {
ASSERT(0, g51[0].a);
ASSERT(0, g51[1].a);
ASSERT(1, ({ struct { struct { int a; struct { int b; }; }; int c; } x={1,2,3,.b=4,5}; x.a; }));
ASSERT(4, ({ struct { struct { int a; struct { int b; }; }; int c; } x={1,2,3,.b=4,5}; x.b; }));
ASSERT(5, ({ struct { struct { int a; struct { int b; }; }; int c; } x={1,2,3,.b=4,5}; x.c; }));
printf("OK\n");
return 0;
}