X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/df4db3927748d77c1192c0b103f3ffdfbc5d7fd8..31ac11cc668bb8ecc1317fd2e8bd79b7925bceeb:/src/parse-decl.c diff --git a/src/parse-decl.c b/src/parse-decl.c index e5395b4..42931a3 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -25,6 +25,7 @@ #include "parse.h" #include "scan.h" #include "i18n.h" +#include "normalize.h" /* * Determine if a declarator declares an identifier (other than a function @@ -349,6 +350,27 @@ check_arrays(struct cdecl_declarator **p, struct cdecl_declarator *d) return 0; } +static int +normalize_specs(struct cdecl_declarator **p, struct cdecl_declarator *d) +{ + struct cdecl_function *func; + struct cdecl_pointer *ptr; + + switch (d->type) { + case CDECL_DECL_POINTER: + ptr = &d->u.pointer; + ptr->qualifiers = cdecl__normalize_specs(ptr->qualifiers); + break; + case CDECL_DECL_FUNCTION: + func = &d->u.function; + for (struct cdecl *i = func->parameters; i; i = i->next) + i->specifiers = cdecl__normalize_specs(i->specifiers); + break; + } + + return 0; +} + /* * Traverse the parse tree, calling a function on every declarator in a * depth-first preorder traversal. The function is given a pointer to the @@ -388,6 +410,7 @@ static bool forall_declarators(struct cdecl *decl, struct cdecl *cdecl_parse_decl(const char *declstr) { + struct cdecl_declspec *norm_specs; YY_BUFFER_STATE state; yyscan_t scanner; struct cdecl *decl; @@ -407,7 +430,16 @@ struct cdecl *cdecl_parse_decl(const char *declstr) if (rc != 0) return NULL; + /* + * Since the top-level specifiers are shared between each top-level + * declarator, we need to normalize them once and then propagate the + * new specifier list. + */ + norm_specs = cdecl__normalize_specs(decl->specifiers); + for (struct cdecl *i = decl; i; i = i->next) { + i->specifiers = norm_specs; + if (!forall_declarators(i, reduce_parentheses)) goto err; if (!forall_declarators(i, simplify_functions)) @@ -418,6 +450,8 @@ struct cdecl *cdecl_parse_decl(const char *declstr) goto err; if (!forall_declarators(i, check_arrays)) goto err; + if (!forall_declarators(i, normalize_specs)) + goto err; if (!valid_declspecs(i, true)) goto err; @@ -456,12 +490,16 @@ struct cdecl *cdecl_parse_english(const char *english) return NULL; for (struct cdecl *i = decl; i; i = i->next) { + i->specifiers = cdecl__normalize_specs(i->specifiers); + if (!forall_declarators(i, check_parameters)) goto err; if (!forall_declarators(i, check_rettypes)) goto err; if (!forall_declarators(i, check_arrays)) goto err; + if (!forall_declarators(i, normalize_specs)) + goto err; if (!valid_declspecs(i, true)) goto err;