while (x) {
p = x->next;
switch (x->type) {
+ case CDECL_DECL_NULL:
+ break;
case CDECL_DECL_IDENT:
free(x->u.ident);
break;
case CDECL_DECL_POINTER:
free_declspec(x->u.pointer.qualifiers);
- free_declarator(x->u.pointer.declarator);
break;
case CDECL_DECL_ARRAY:
free(x->u.array.vla);
- free_declarator(x->u.array.declarator);
break;
default:
assert(0);
}
+
+ free_declarator(x->child);
free(x);
x = p;
}
%type <strval> vla_ident
%type <uintval> declspec_simple typespec_simple qualifier_simple
%type <declspec> declspec_notype declspec_noid typespec_noid typespec
-%type <declspec> qualifier qualifiers pointer
+%type <declspec> qualifier qualifiers
%type <declspec> declspecs declspecs_noid
-%type <declarator> direct_declarator declarator declarators array
+%type <declarator> direct_declarator declarator declarators pointer array
%type <decl> declaration
%%
declspec_noid: declspec_notype | typespec_noid
-pointer: T_ASTERISK qualifiers { $$ = $2; }
-
vla_ident: T_IDENT | T_ASTERISK {
ALLOC($$, sizeof "");
strcpy($$, "");
.type = CDECL_DECL_ARRAY);
}
-declarator: direct_declarator | pointer direct_declarator {
+pointer: T_ASTERISK qualifiers direct_declarator {
ALLOC_STRUCT($$, struct cdecl_declarator,
.type = CDECL_DECL_POINTER,
- .u.pointer.qualifiers = $1,
- .u.pointer.declarator = $2);
+ .u.pointer.qualifiers = $2,
+ .child = $3);
+} | T_ASTERISK qualifiers pointer {
+ ALLOC_STRUCT($$, struct cdecl_declarator,
+ .type = CDECL_DECL_POINTER,
+ .u.pointer.qualifiers = $2,
+ .child = $3);
}
+declarator: direct_declarator | pointer
+
direct_declarator: {
ALLOC_STRUCT($$, struct cdecl_declarator,
- .type = CDECL_DECL_IDENT,
- .u.ident = NULL);
+ .type = CDECL_DECL_NULL);
} | T_IDENT {
ALLOC_STRUCT($$, struct cdecl_declarator,
.type = CDECL_DECL_IDENT,
.u.ident = $1);
} | direct_declarator array {
$$ = $2;
- $$->u.array.declarator = $1;
+ $$->child = $1;
} | T_LPAREN declarator T_RPAREN {
$$ = $2;
};