- for (struct cdecl *i = decl; i; i = i->next) {
- if (!forall_declarators(i, reduce_parentheses))
- goto err;
- if (!forall_declarators(i, simplify_functions))
- goto err;
+static int do_postprocess(struct cdecl *decl, int english_mode)
+{
+ struct cdecl_declspec *norm_specs;
+ struct cdecl *i;
+
+ /*
+ * For a C declaration with more than one full declarator, the
+ * specifier list is common to all of them. Normalize it once,
+ * then propagate that to all the linked cdecl structures.
+ *
+ * In english mode, the cdecl structure list always has exactly
+ * one entry so we don't need to do anything differently.
+ */
+ norm_specs = cdecl__normalize_specs(decl->specifiers);
+ for (i = decl; i; i = i->next)
+ i->specifiers = norm_specs;
+
+ for (i = decl; i; i = i->next) {
+ if (!english_mode) {
+ if (forall_declarators(i, reduce_parentheses) < 0)
+ return 0;
+ }
+
+ if (forall_declarators(i, postproc_common) < 0)
+ return 0;
+
+ if (!valid_declspecs(i, true))
+ return 0;
+
+ if (cdecl_is_abstract(i->declarators)
+ && (i != decl || i->next)) {
+ cdecl__errmsg(CDECL__EDECLTYPE);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static struct cdecl *parse_common(const char *str, int english_mode)
+{
+ struct cdecl *decl;
+
+ if (!(decl = do_parse(str, english_mode)))
+ return NULL;
+
+ if (!do_postprocess(decl, english_mode)) {
+ cdecl__free(decl);
+ return NULL;