]> git.draconx.ca Git - cdecl99.git/blobdiff - src/parse-decl.c
libcdecl: Fix regression in function parsing.
[cdecl99.git] / src / parse-decl.c
index c3ba32db8b3ed177dccf4873b98f61d16d4494da..a6204a18a00c32b524d9bc5dc89cff67cc5b7905 100644 (file)
@@ -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;
 }