]> git.draconx.ca Git - cdecl99.git/commitdiff
Kill the "horizontal" declarator chain.
authorNick Bowler <nbowler@draconx.ca>
Wed, 6 Jul 2011 02:43:42 +0000 (22:43 -0400)
committerNick Bowler <nbowler@draconx.ca>
Wed, 6 Jul 2011 02:43:42 +0000 (22:43 -0400)
The "next" pointer in declarators is used in exactly one place: the list
of declarators of a declaration.  Move this chain to the toplevel so
that we get a list of declarations instead: now every struct cdecl has
exatly one declarator.

This helps eliminate the nasty hack in "explain" to print multiple
declarators.

src/cdecl.h
src/cdecl99.c
src/parse.y

index 883a4e40138fafbe01959b280eeae681266e905a..95d763424b9b88372efd071fa5380237d360d680 100644 (file)
@@ -48,6 +48,8 @@ enum {
 };
 
 struct cdecl {
+       struct cdecl *next;
+
        struct cdecl_declspec {
                struct cdecl_declspec *next;
                unsigned type;
@@ -55,7 +57,7 @@ struct cdecl {
        } *specifiers;
 
        struct cdecl_declarator {
-               struct cdecl_declarator *next, *child;
+               struct cdecl_declarator *child;
                unsigned type;
                union {
                        char *ident;
index d966805d323b79bd7cb7c710c188b14d2428c985..639edea68ac3de89665bfc67e24af40391ee7cff 100644 (file)
@@ -40,21 +40,15 @@ static int cmd_explain(char *cmd, char *arg)
        static char *buf;
 
        struct cdecl *decl;
-       struct cdecl_declarator *d;
        size_t rc;
 
        decl = cdecl_parse_decl(arg);
        if (!decl)
                goto out;
 
-       for (d = decl->declarators; d; d = d->next) {
-               struct cdecl decl_tmp = {
-                       .specifiers  = decl->specifiers,
-                       .declarators = d,
-               };
-
+       for (struct cdecl *i = decl; i; i = i->next) {
 retry:
-               rc = cdecl_explain(buf, bufsz, &decl_tmp);
+               rc = cdecl_explain(buf, bufsz, i);
                if (rc >= bufsz) {
                        char *tmp;
 
index 7d4c3dc0c889f88469c4905f9f8cf36fa685b33d..86091f9c33e71b609e8141fcf5be4e13d51f3651 100644 (file)
@@ -76,8 +76,10 @@ static void free_declspec(struct cdecl_declspec *x)
 static void free_declarator(struct cdecl_declarator *x)
 {
        struct cdecl_declarator *p;
+
        while (x) {
-               p = x->next;
+               p = x->child;
+
                switch (x->type) {
                case CDECL_DECL_NULL:
                        break;
@@ -94,23 +96,31 @@ static void free_declarator(struct cdecl_declarator *x)
                        assert(0);
                }
 
-               free_declarator(x->child);
                free(x);
                x = p;
        }
 }
 
-static void free_decl(struct cdecl *decl)
+static void free_decl(struct cdecl *x)
 {
-       free_declspec(decl->specifiers);
-       free_declarator(decl->declarators);
-       free(decl);
+       struct cdecl *p;
+
+       while (x) {
+               p = x->next;
+
+               /* The specifiers may be shared by an entire chain. */
+               if (!p || p->specifiers != x->specifiers)
+                       free_declspec(x->specifiers);
+
+               free_declarator(x->declarators);
+               free(x);
+               x = p;
+       }
 }
 
 void cdecl_free(struct cdecl *decl)
 {
-       if (decl)
-               free_decl(decl);
+       free_decl(decl);
 }
 %}
 
@@ -165,8 +175,8 @@ void cdecl_free(struct cdecl *decl)
 %type <declspec>   declspec_notype declspec_noid typespec_noid typespec
 %type <declspec>   qualifier qualifiers
 %type <declspec>   declspecs declspecs_noid
-%type <declarator> direct_declarator declarator declarators pointer array
-%type <decl>       declaration
+%type <declarator> direct_declarator declarator pointer array
+%type <decl>       declaration declarators declarator_wrap
 
 %%
 
@@ -175,9 +185,10 @@ input: declaration {
 };
 
 declaration: declspecs declarators T_SEMICOLON {
-       ALLOC_STRUCT($$, struct cdecl,
-               .specifiers = $1,
-               .declarators = $2);
+       $$ = $2;
+
+       for (struct cdecl *i = $$; i; i = i->next)
+               i->specifiers = $1;
 };
 
 declspecs: declspec_notype declspecs {
@@ -198,10 +209,14 @@ qualifiers: { $$ = NULL; } | qualifiers qualifier {
        $$->next = $1;
 }
 
-declarators: declarator | declarator T_COMMA declarators {
+declarators: declarator_wrap | declarator_wrap T_COMMA declarators {
        $$ = $1;
        $$->next = $3;
-};
+}
+
+declarator_wrap: declarator {
+       ALLOC_STRUCT($$, struct cdecl, .declarators = $1);
+}
 
 declspec_simple: T_AUTO { $$ = CDECL_STOR_AUTO;     }
        | T_TYPEDEF     { $$ = CDECL_STOR_TYPEDEF;  }