diff --git a/parse.c b/parse.c index 7f85b9b..6b19e11 100644 --- a/parse.c +++ b/parse.c @@ -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; diff --git a/test/initializer.c b/test/initializer.c index e952ab6..93aa7c7 100644 --- a/test/initializer.c +++ b/test/initializer.c @@ -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; }