X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/c733aff6d0b2b107c88e37a1491f270db0634819..bcde46a8503359755ca72fe581a18f7a3bcaaf37:/src/parse-decl.c diff --git a/src/parse-decl.c b/src/parse-decl.c index c3ba32d..a6204a1 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -230,7 +230,7 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d) free(d->child); free(d); - return 0; + return 1; } /* @@ -260,6 +260,9 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d) * example, "(((x)))" into "(x)", an abstract function declarator. The result * is then subject to the function simplification step, which will turn "(x)" * into x (declaring an identifier). + * + * The whole process is repeated until no more changes are made to the parse + * tree, or a syntax error is detected. */ static struct cdecl *fake_function_param(struct cdecl_declarator *d) { @@ -281,26 +284,28 @@ reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d) { struct cdecl *param; - 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; + do { + d = *p; + 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) { + /* Fake parameter on real function. */ + d->u.function.parameters = param; + cdecl__errmsg(CDECL__EBADPARAM); + return -1; + } + + param->declarators = d; + *p = d = decl; } - param->declarators = d; - *p = d = decl; + cdecl__free(param); } + } while (simplify_functions(p, d)); - cdecl__free(param); - } - - simplify_functions(p, d); return 0; }