2 * Parse and validate C declarations.
3 * Copyright © 2011 Nick Bowler
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 * Verify the declaration specifiers of a declaration.
30 static bool valid_declspecs(struct cdecl *decl)
32 struct cdecl_declspec *specs = decl->specifiers;
33 struct cdecl_declarator *d = decl->declarators;
34 unsigned num_storage = 0;
35 unsigned long typemap;
37 typemap = cdecl__build_typemap(specs);
41 for (struct cdecl_declspec *c = specs; c; c = c->next) {
42 switch (cdecl_spec_kind(c)) {
44 if (c->type == CDECL_TYPE_VOID &&
45 (d->type == CDECL_DECL_IDENT
46 || d->type == CDECL_DECL_ARRAY)) {
47 fprintf(stderr, "invalid declaration of type void\n");
52 if (++num_storage > 1) {
53 fprintf(stderr, "too many storage-class specifiers\n");
59 * Restrict qualifiers are only valid in the
60 * pointer qualifier list, which isn't checked here.
62 if (c->type == CDECL_QUAL_RESTRICT) {
63 fprintf(stderr, "only pointer types can be restrict-qualified.\n");
69 * We don't support functions yet.
71 fprintf(stderr, "only function declarations may have function specifiers.\n");
82 * The C grammar leaves ambiguous some cases where parentheses represent a
83 * function declarator or just parentheses. The language uses additional
84 * context (whether or not a typedef is in scope, etc.) to resolve these
85 * ambiguities, but we don't have access to that kind of information.
87 * The cdecl99 parser uses an unambiguous grammar which treats almost
88 * everything as a function, and thus considers things like 'int (x)' to
89 * be a function type with a single parameter of type 'x' (a typedef name),
90 * returning int. This can result in very complicated types for simple
91 * declarations. Ideally, cdecl99 should try and find the "simplest"
92 * explanation for a given declaration.
94 * Whether or not it achieves the simplest explanation, we apply a simple rule:
95 * if a declarator could be interpreted as something other than a function,
98 * - The function declarator has a null child declarator.
99 * - The function declarator has exactly one parameter, and is not variadic.
100 * - The function parameter has a type specifier, and it is a typedef name.
101 * - The function parameter has no other declaration specifiers.
102 * - The function parameter does not declare an identifier.
104 * Since cdecl99 supports things like [*] in any context (in C, such constructs
105 * are only valid in function parameter lists), we don't treat them specially
109 static struct cdecl_declarator *reduce_function(struct cdecl *param)
111 struct cdecl_declspec *spec = param->specifiers;
112 struct cdecl_declarator *decl = param->declarators;
113 struct cdecl_declarator *last;
115 for (last = decl; last && last->type != CDECL_DECL_NULL;)
121 last->type = CDECL_DECL_IDENT;
122 last->u.ident = spec->ident;
129 static bool function_is_reducible(struct cdecl_declarator *d)
131 if (d->type != CDECL_DECL_FUNCTION)
133 if (d->child->type != CDECL_DECL_NULL)
134 return false; /* e.g., int (*)(x) */
136 if (!d->u.function.parameters)
137 return false; /* e.g., int f() */
138 if (d->u.function.parameters->next)
139 return false; /* e.g., int (x, y) */
140 if (d->u.function.variadic)
141 return false; /* e.g., int (x, ...) */
143 if (d->u.function.parameters->specifiers->type != CDECL_TYPE_IDENT)
144 return false; /* e.g. int (int) */
145 if (d->u.function.parameters->specifiers->next)
146 return false; /* e.g. int (size_t const) */
152 simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d)
154 struct cdecl_declarator *new;
156 if (!function_is_reducible(d))
159 new = reduce_function(d->u.function.parameters);
161 return 0; /* e.g. int (foo bar) */
170 * The parser's bias towards considering things as functions whenever possible
171 * makes nested parentheses tricky. (x) is considered to be part of a function
172 * declarator until simplify_functions converts it. The problem is that
173 * (((x))) is not valid as part of a function declarator, but it *is* valid
174 * as an identifier enclosed 3 times in parentheses. This is complicated by
175 * the fact that things like (((int))) are not valid anywhere.
177 * To avoid ambiguities, the parser actually emits a "function" declarator for
178 * every pair of parentheses. The ones that can't reasonably be functions
179 * consist of a single "parameter" with no declaration specifiers (note that
180 * every valid function parameter will have at least one type specifier).
182 * This pass is to remove these fake functions from the parse tree. We take
183 * care to avoid turning invalid things like ((int)) into valid things like
184 * (int) by observing that the only valid function declarators that appear
185 * in these "fake" parentheses are those that have a non-null child declarator
186 * (for instance, int ((*)(int)) *or* those that will be eliminated by the
187 * simplify_functions pass.
191 reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d)
195 if (d->type != CDECL_DECL_FUNCTION)
198 param = d->u.function.parameters;
199 if (param && param->specifiers == NULL) {
200 struct cdecl_declarator *decl;
202 assert(!param->next);
204 decl = param->declarators;
205 if (decl->type == CDECL_DECL_NULL) {
208 d->u.function.parameters = NULL;
212 if (d->child->type != CDECL_DECL_NULL) {
213 fprintf(stderr, "invalid function parameter\n");
223 * We may have replaced d with another fake function which
224 * also needs to be eliminated.
226 if (reduce_parentheses(p, decl) < 0)
230 * If the remaining declarator is a function, make sure it's
231 * valid by checking its reducibility.
234 if (decl->type == CDECL_DECL_FUNCTION
235 && decl->child->type == CDECL_DECL_NULL
236 && !function_is_reducible(decl)) {
237 fprintf(stderr, "too many parentheses in function\n");
248 * Traverse the parse tree, calling a function on every declarator in a
249 * depth-first preorder traversal. The function is given a pointer to the
250 * declarator as well as to the pointer which was used to reach that
251 * declarator: this can be used to rewrite entire subtrees.
253 static bool forall_declarators(struct cdecl *decl,
254 int f(struct cdecl_declarator **, struct cdecl_declarator *))
256 struct cdecl_declarator *d, **p;
258 for (p = &decl->declarators, d = *p; d; p = &d->child, d = *p) {
271 if (d->type == CDECL_DECL_FUNCTION) {
274 for (i = d->u.function.parameters; i; i = i->next) {
275 if (!forall_declarators(i, f))
284 struct cdecl *cdecl_parse_decl(const char *declstr)
286 YY_BUFFER_STATE state;
290 state = yy_scan_string(declstr);
292 yy_delete_buffer(state);
297 for (struct cdecl *i = decl; i; i = i->next) {
298 if (!forall_declarators(i, reduce_parentheses))
300 if (!forall_declarators(i, simplify_functions))
303 if (!valid_declspecs(i))