} *specifiers;
struct cdecl_declarator {
- struct cdecl_declarator *next;
+ struct cdecl_declarator *next, *child;
unsigned type;
union {
char *ident;
struct cdecl_pointer {
- struct cdecl_declspec *qualifiers;
- struct cdecl_declarator *declarator;
+ struct cdecl_declspec *qualifiers;
} pointer;
struct cdecl_array {
char *vla;
uintmax_t length;
- struct cdecl_declarator *declarator;
} array;
} u;
} *declarators;
return ret;
}
-static struct cdecl_declarator *next_declarator(struct cdecl_declarator *d)
-{
- switch (d->type) {
- case CDECL_DECL_IDENT:
- return NULL;
- case CDECL_DECL_POINTER:
- return d->u.pointer.declarator;
- case CDECL_DECL_ARRAY:
- return d->u.array.declarator;
- default:
- assert(0);
- }
-}
-
/* Renders the name of the thing being declared. */
static size_t
explain_prologue(char *buf, size_t n, struct cdecl_declarator *d)
return snprintf(buf, n, "type");
return snprintf(buf, n, "declare %s as", d->u.ident);
}
- d = next_declarator(d);
+ d = d->child;
}
}
if (d->type == CDECL_DECL_IDENT)
return 0;
- rc = explain_declarators(buf, n, next_declarator(d));
+ rc = explain_declarators(buf, n, d->child);
ret += advance(&buf, &n, rc);
switch (d->type) {
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;
}
ALLOC_STRUCT($$, struct cdecl_declarator,
.type = CDECL_DECL_POINTER,
.u.pointer.qualifiers = $2,
- .u.pointer.declarator = $3);
+ .child = $3);
} | T_ASTERISK qualifiers pointer {
ALLOC_STRUCT($$, struct cdecl_declarator,
.type = CDECL_DECL_POINTER,
.u.pointer.qualifiers = $2,
- .u.pointer.declarator = $3);
+ .child = $3);
}
declarator: direct_declarator | pointer;
.u.ident = $1);
} | direct_declarator array {
$$ = $2;
- $$->u.array.declarator = $1;
+ $$->child = $1;
} | T_LPAREN declarator T_RPAREN {
$$ = $2;
};