* simplify_functions pass.
*/
-static int
-reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d)
+static struct cdecl *fake_function_param(struct cdecl_declarator *d)
{
struct cdecl *param;
if (d->type != CDECL_DECL_FUNCTION)
- return 0;
+ return NULL;
param = d->u.function.parameters;
- if (param && param->specifiers == NULL) {
- struct cdecl_declarator *decl;
+ if (!param || param->specifiers)
+ return NULL;
- assert(!param->next);
+ assert(!param->next);
+ return param;
+}
- decl = param->declarators;
- if (decl->type == CDECL_DECL_NULL) {
- free(decl);
- free(param);
- d->u.function.parameters = NULL;
- return 0;
- }
+static int
+reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d)
+{
+ struct cdecl *param;
+ int fake = 0;
+
+ while ((param = fake_function_param(d))) {
+ struct cdecl_declarator *decl = param->declarators;
+ d->u.function.parameters = NULL;
+
+ if (decl->type != CDECL_DECL_NULL) {
+ if (d->child->type != CDECL_DECL_NULL) {
+ /* Found fake parameter on real function. */
+ d->u.function.parameters = param;
+ cdecl__errmsg(CDECL__EBADPARAM);
+ return -1;
+ }
- if (d->child->type != CDECL_DECL_NULL) {
- cdecl__errmsg(CDECL__EBADPARAM);
- return -1;
+ param->declarators = d;
+ *p = d = decl;
+ fake = 1;
}
- free(d->child);
- free(param);
- free(d);
- *p = decl;
-
- /*
- * We may have replaced d with another fake function which
- * also needs to be eliminated.
- */
- if (reduce_parentheses(p, decl) < 0)
- return -1;
-
- /*
- * If the remaining declarator is a function, make sure it's
- * valid by checking its reducibility.
- */
- decl = *p;
- if (decl->type == CDECL_DECL_FUNCTION
- && decl->child->type == CDECL_DECL_NULL
- && !function_is_reducible(decl)) {
- cdecl__errmsg(CDECL__EMANYPAREN);
- return -1;
- }
+ cdecl__free(param);
+ }
- return 0;
+ simplify_functions(p, d);
+ if (fake && (*p)->type == CDECL_DECL_FUNCTION) {
+ /* Started with a fake function but ended with a real one. */
+ cdecl__errmsg(CDECL__EMANYPAREN);
+ return -1;
}
return 0;
if (!english_mode) {
if (forall_declarators(i, reduce_parentheses) < 0)
return 0;
- if (forall_declarators(i, simplify_functions) < 0)
- return 0;
}
if (forall_declarators(i, postproc_common) < 0)