Since identifiers now come with their own declarator allocations,
nothing actually modifies any part of an allocated null declarator.
And since null declarators are always the same (with all members zero),
we don't even need to allocate them at all. Just use a single static
allocation and make every reference to a null declarator point to that.
Then we just need to not free null declarators in the various places
where that currently happens.
spec->u.declarator.type = CDECL_DECL_IDENT;
*p = &spec->u.declarator;
spec->u.declarator.type = CDECL_DECL_IDENT;
*p = &spec->u.declarator;
d = param->declarators;
free(param);
return d;
d = param->declarators;
free(param);
return d;
if (!new)
return 0; /* e.g. int (foo bar) */
*p = new;
if (!new)
return 0; /* e.g. int (foo bar) */
*p = new;
switch (x->type) {
case CDECL_DECL_NULL:
switch (x->type) {
case CDECL_DECL_NULL:
case CDECL_DECL_IDENT:
case CDECL_DECL_ARRAY:
break;
case CDECL_DECL_IDENT:
case CDECL_DECL_ARRAY:
break;
while ((d = *p)->child)
p = &d->child;
while ((d = *p)->child)
p = &d->child;
- *p = d = &ident->u.declarator;
+ *p = &ident->u.declarator;
+
+static struct cdecl_declarator *nulldecl(void)
+{
+ static const struct cdecl_declarator nulldecl = {0};
+ return (void *)&nulldecl;
+}
+#define NULLDECL (nulldecl())
+
%}
%destructor { free($$); } <item>
%}
%destructor { free($$); } <item>
postfix: array | parens
direct_declarator_ish: {
postfix: array | parens
direct_declarator_ish: {
- ALLOC_STRUCT($$, struct cdecl_declarator,
- .type = CDECL_DECL_NULL);
} | direct_declarator_ish postfix {
$$ = $2;
$$->child = $1;
}
direct_declarator: {
} | direct_declarator_ish postfix {
$$ = $2;
$$->child = $1;
}
direct_declarator: {
- ALLOC_STRUCT($$, struct cdecl_declarator,
- .type = CDECL_DECL_NULL);
} | T_IDENT {
$$ = &$1->u.declarator;
} | direct_declarator postfix {
} | T_IDENT {
$$ = &$1->u.declarator;
} | direct_declarator postfix {
- ALLOC_STRUCT($$, struct cdecl_declarator,
- .type = CDECL_DECL_NULL);
} | english_declarator qualifiers T_POINTER T_TO {
ALLOC_STRUCT($$, struct cdecl_declarator,
.type = CDECL_DECL_POINTER,
} | english_declarator qualifiers T_POINTER T_TO {
ALLOC_STRUCT($$, struct cdecl_declarator,
.type = CDECL_DECL_POINTER,
- ALLOC_STRUCT($$, struct cdecl_declarator,
- .type = CDECL_DECL_NULL);