]> git.draconx.ca Git - cdecl99.git/blobdiff - src/parse-decl.c
Make fix-gnulib only need a single output file.
[cdecl99.git] / src / parse-decl.c
index 42931a3c866ada6229ce3212efb03421119a238e..45cf67fcc5f7a8323a5624bd59a83a28d5cb94bb 100644 (file)
 #include "i18n.h"
 #include "normalize.h"
 
-/*
- * Determine if a declarator declares an identifier (other than a function
- * parameter).
- */
-static bool is_abstract(struct cdecl_declarator *d)
-{
-       while (d->child)
-               d = d->child;
-
-       return d->type != CDECL_DECL_IDENT;
-}
-
 /*
  * Verify the declaration specifiers of a declaration.  If top is true, treat
  * this as a top-level declaration.  Otherwise, treat this as a function
@@ -48,7 +36,7 @@ static bool valid_declspecs(struct cdecl *decl, bool top)
 {
        struct cdecl_declspec *specs = decl->specifiers;
        struct cdecl_declarator *d   = decl->declarators;
-       bool abstract = is_abstract(d);
+       bool abstract = cdecl_is_abstract(d);
        unsigned num_storage = 0;
        unsigned long typemap;
 
@@ -295,21 +283,26 @@ check_parameters(struct cdecl_declarator **p, struct cdecl_declarator *d)
                if (!valid_declspecs(param, false))
                        return -1;
 
+               /* Check for "void" function parameters as a special case. */
                for (spec = param->specifiers; spec; spec = spec->next) {
-                       if (spec->type == CDECL_TYPE_VOID
-                           && param->declarators->type == CDECL_DECL_NULL)
-                               has_void = true;
+                       if (param->declarators->type != CDECL_DECL_NULL)
+                               continue;
+                       if (spec->type != CDECL_TYPE_VOID)
+                               continue;
+
+                       if (spec != param->specifiers || spec->next != NULL) {
+                               fprintf(stderr, "void parameter must not have extra specifiers\n");
+                               return -1;
+                       } else if (d->u.function.parameters->next) {
+                               fprintf(stderr, "a void parameter must stand alone\n");
+                               return -1;
+                       } else if (d->u.function.variadic) {
+                               fprintf(stderr, "variadic functions cannot have a void parameter\n");
+                               return -1;
+                       }
                }
        }
 
-       if (has_void && d->u.function.parameters->next) {
-               fprintf(stderr, "a void parameter must stand alone\n");
-               return -1;
-       } else if (has_void && d->u.function.variadic) {
-               fprintf(stderr, "variadic functions cannot have a void parameter\n");
-               return -1;
-       }
-
        return 0;
 }
 
@@ -456,7 +449,8 @@ struct cdecl *cdecl_parse_decl(const char *declstr)
                if (!valid_declspecs(i, true))
                        goto err;
 
-               if (is_abstract(i->declarators) && (i != decl || i->next)) {
+               if (cdecl_is_abstract(i->declarators)
+                   && (i != decl || i->next)) {
                        fprintf(stderr, "mixing type names and declarations is not allowed\n");
                        goto err;
                }