]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Don't dynamically allocate null declarators.
authorNick Bowler <nbowler@draconx.ca>
Sun, 23 Jul 2023 19:37:32 +0000 (15:37 -0400)
committerNick Bowler <nbowler@draconx.ca>
Sun, 23 Jul 2023 19:37:32 +0000 (15:37 -0400)
Since identifiers now come with their own declarator allocations,
nothing actually modifies any part of an allocated null declarator.

And since null declarators are always the same (with all members zero),
we don't even need to allocate them at all.  Just use a single static
allocation and make every reference to a null declarator point to that.

Then we just need to not free null declarators in the various places
where that currently happens.

src/parse-decl.c
src/parse.y

index 8516a3acab732e26388cb6e40c1ff8fadab4dc69..a31a37756427a7f096a26ab3c5718f90535eaef4 100644 (file)
@@ -220,7 +220,6 @@ static struct cdecl_declarator *reduce_function(struct cdecl *param)
        spec->u.declarator.type = CDECL_DECL_IDENT;
        *p = &spec->u.declarator;
 
-       free(d);
        d = param->declarators;
        free(param);
        return d;
@@ -262,7 +261,6 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d)
        if (!new)
                return 0; /* e.g. int (foo bar) */
        *p = new;
-       free(d->child);
        free(d);
 
        return 1;
index 8631f3b4613fd028b720865f4b85ed03237c3384..ba9bf220f95513df509afca3610ccd4f8adedf92 100644 (file)
@@ -105,6 +105,7 @@ static void free_declarator(struct cdecl_declarator *x)
 
                switch (x->type) {
                case CDECL_DECL_NULL:
+                       x = NULL;
                case CDECL_DECL_IDENT:
                case CDECL_DECL_ARRAY:
                        break;
@@ -168,11 +169,18 @@ static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *id
 
        while ((d = *p)->child)
                p = &d->child;
-       free(d);
 
-       *p = d = &ident->u.declarator;
+       *p = &ident->u.declarator;
        return decl;
 }
+
+static struct cdecl_declarator *nulldecl(void)
+{
+       static const struct cdecl_declarator nulldecl = {0};
+       return (void *)&nulldecl;
+}
+#define NULLDECL (nulldecl())
+
 %}
 
 %destructor { free($$); }            <item>
@@ -431,16 +439,14 @@ declarator_ish: direct_declarator_ish | pointer
 postfix: array | parens
 
 direct_declarator_ish: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 } | direct_declarator_ish postfix {
        $$ = $2;
        $$->child = $1;
 }
 
 direct_declarator: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 } | T_IDENT {
        $$ = &$1->u.declarator;
 } | direct_declarator postfix {
@@ -491,8 +497,7 @@ english_declaration: storage_func_specs english_declarator post_specs {
 }
 
 english_declarator: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 } | english_declarator qualifiers T_POINTER T_TO {
        ALLOC_STRUCT($$, struct cdecl_declarator,
                .type = CDECL_DECL_POINTER,
@@ -535,8 +540,7 @@ typedef_name_qual: T_IDENT qualifiers {
 }
 
 null_decl: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 }
 
 /*