[hackers] [scc] [cc1] Rewrite function declaration code || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Sun, 26 Feb 2017 18:29:14 +0100 (CET)

commit 8a57ba149a24de43b6163d49f59aacd93b9c9c57
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Sun Feb 26 16:57:00 2017 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Sun Feb 26 16:57:00 2017 +0100

    [cc1] Rewrite function declaration code
    
    This code had the problem that it needed dynamic memory that
    was allocated in one palce but had to be deallocted in other
    totally unrelated place. This code removes the need of dynamic
    memory and simplify the code in several places.

diff --git a/cc1/decl.c b/cc1/decl.c
index 6de804b..f930d92 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -14,15 +14,20 @@ static char sccsid[] = "@(#) ./cc1/decl.c";
 #define NOREP 0
 #define REP 1
 
+#define NR_DCL_TYP (NR_DECLARATORS+NR_FUNPARAM)
+#define NR_DCL_ARG (NR_DECLARATORS+NR_FUNPARAM+1)
 
 struct declarators {
- unsigned char nr;
+ unsigned nr;
+ unsigned nr_types, nr_pars;
+ Symbol **pars;
+ Type **tpars;
         struct declarator {
                 unsigned char op;
                 TINT nelem;
                 Symbol *sym;
- Type **tpars;
                 Symbol **pars;
+ Type **tpars;
         } d [NR_DECLARATORS];
 };
 
_AT_@ -34,6 +39,8 @@ struct decl {
         Symbol **pars;
         Type *type;
         Type *parent;
+ Symbol *bufpars[NR_DCL_ARG];
+ Type *buftpars[NR_DCL_ARG];
 };
 
 static void
_AT_@ -57,7 +64,7 @@ push(struct declarators *dp, int op, ...)
                 break;
         case KRFTN:
         case FTN:
- p->nelem = va_arg(va, TINT);
+ p->nelem = va_arg(va, unsigned);
                 p->tpars = va_arg(va, Type **);
                 p->pars = va_arg(va, Symbol **);
                 break;
_AT_@ -87,7 +94,6 @@ pop(struct declarators *dp, struct decl *dcl)
                  * function. We don't need
                  * the parameter symbols anymore.
                  */
- free(dcl->pars);
                 popctx();
                 dcl->pars = NULL;
         }
_AT_@ -144,7 +150,6 @@ parameter(struct decl *dcl)
 {
         Symbol *sym = dcl->sym;
         Type *funtp = dcl->parent, *tp = dcl->type;
- TINT n = funtp->n.elem;
         char *name = sym->name;
         int flags;
 
_AT_@ -201,12 +206,11 @@ static Symbol *dodcl(int rep,
                      unsigned ns,
                      Type *type);
 
-static void
-krfun(Type *tp, Type *types[], Symbol *syms[], int *ntypes, int *nsyms)
+static unsigned
+krfun(struct declarators *dp)
 {
- int n = 0;
         Symbol *sym;
- int toomany = 0;
+ unsigned toomany = 0, npars = 0;
 
         if (yytoken != ')') {
                 do {
_AT_@ -219,85 +223,112 @@ krfun(Type *tp, Type *types[], Symbol *syms[], int *ntypes, int *nsyms)
                                        yylval.sym->name);
                                 continue;
                         }
- if (n < NR_FUNPARAM) {
- ++n;
- *syms++ = sym;
+ if (dp->nr_pars < NR_DCL_ARG-1) {
+ ++npars;
+ ++dp->nr_pars;
+ *dp->pars++ = sym;
                                 continue;
                         }
                         if (!toomany)
- errorp("too much parameters in function definition");
+ errorp("too many parameters in function definition");
                         toomany = 1;
                 } while (accept(','));
         }
 
- *nsyms = n;
- *ntypes = 1;
- types[0] = ellipsistype;
+ if (dp->nr_types < NR_DCL_TYP) {
+ ++dp->nr_types;
+ *dp->tpars++ = ellipsistype;
+ }
+
+ return 1;
 }
 
-static void
-ansifun(Type *tp, Type *types[], Symbol *syms[], int *ntypes, int *nsyms)
+static unsigned
+ansifun(struct declarators *dp)
 {
- int npars = 0;
         Symbol *sym;
- int toomany = 0, voidparam = 0;
+ unsigned ntype, toomany, distoomany, voidpar;
+ Type type, *tp;
 
+ type.n.elem = 0;
+ type.prop = 0;
+ ntype = toomany = toomany = distoomany = voidpar = 0;
         do {
- ++npars;
                 if (accept(ELLIPSIS)) {
- if (npars < 2)
+ if (ntype < 1)
                                 errorp("a named argument is requiered before '...'");
- *syms = NULL;
- *types++ = ellipsistype;
- } else if ((sym = dodcl(NOREP, parameter, NS_IDEN, tp)) == NULL) {
- if (tp->n.elem == 1)
- voidparam = 1;
- } else if (npars < NR_FUNPARAM) {
- *syms++ = sym;
- *types++ = sym->type;
- } else if (!toomany) {
+ if (yytoken != ')')
+ errorp("... must be the last parameter");
+ sym = NULL;
+ tp = ellipsistype;
+ } else if ((sym = dodcl(NOREP, parameter, NS_IDEN, &type)) == NULL) {
+ if (type.n.elem == 1 && ntype > 1)
+ voidpar = 1;
+ sym = NULL;
+ tp = NULL;
+ } else {
+ tp = sym->type;
+ }
+
+ if (sym) {
+ if (dp->nr_pars == NR_DCL_ARG-1) {
+ toomany = 1;
+ } else {
+ dp->nr_pars++;
+ *dp->pars++ = sym;
+ }
+ }
+
+ if (tp) {
+ if (dp->nr_types == NR_DCL_TYP) {
+ toomany = 1;
+ } else {
+ ntype++;
+ dp->nr_types++;
+ *dp->tpars++ = tp;
+ }
+ }
+
+ if (toomany == 1 && !distoomany) {
                         errorp("too many parameters in function definition");
- toomany = 1;
+ distoomany = 1;
                 }
- if (npars == 2 && voidparam)
- errorp("'void' must be the only parameter");
         } while (accept(','));
 
- *nsyms = *ntypes = voidparam ? 0 : npars;
+ if (voidpar && ntype > 1)
+ errorp("'void' must be the only parameter");
+
+ return ntype;
 }
 
 static void
 fundcl(struct declarators *dp)
 {
- Type *types[NR_FUNPARAM], type;
- Symbol *syms[NR_FUNPARAM+1], **pars;
- int k_r, ntypes, nsyms;
- size_t size;
+ Symbol **pars = dp->pars;
+ Type **types = dp->tpars;
+ unsigned ntypes, typefun;
+ unsigned (*fun)(struct declarators *dp);
 
         pushctx();
         expect('(');
- type.n.elem = 0;
- type.prop = 0;
-
- k_r = (yytoken == ')' || yytoken == IDEN);
- (k_r ? krfun : ansifun)(&type, types, syms, &ntypes, &nsyms);
- expect(')');
 
- type.n.elem = ntypes;
- if (ntypes <= 0) {
- type.p.pars = NULL;
+ if (yytoken == ')' || yytoken == IDEN) {
+ typefun = KRFTN;
+ fun = krfun;
         } else {
- size = ntypes * sizeof(Type *);
- type.p.pars = memcpy(xmalloc(size), types, size);
+ typefun = FTN;
+ fun = ansifun;
         }
- if (nsyms <= 0) {
- pars = NULL;
- } else {
- size = (nsyms + 1) * sizeof(Symbol *);
- pars = memcpy(xmalloc(size), syms, size);
- pars[nsyms] = NULL;
+
+ ntypes = (*fun)(dp);
+ expect(')');
+
+ if (dp->nr_pars < NR_DCL_ARG) {
+ *dp->pars++ = NULL;
+ ++dp->nr_pars;
         }
- push(dp, (k_r) ? KRFTN : FTN, type.n.elem, type.p.pars, pars);
+
+ push(dp, typefun, ntypes, types, pars);
 }
 
 static void declarator(struct declarators *dp, unsigned ns);
_AT_@ -670,6 +701,21 @@ bad_storage(Type *tp, char *name)
                 errorp("invalid storage class for function '%s'", name);
 }
 
+static Symbol **
+parsdup(Symbol **pars)
+{
+ Symbol **bp;
+ size_t n;
+
+ if (!pars)
+ return NULL;
+
+ for (n = 1, bp = pars; *bp; ++n, ++bp)
+ /* nothing */;
+ n *= sizeof(Symbol *);
+ return memcpy(xmalloc(n), pars, n);
+}
+
 static Symbol *
 redcl(Symbol *sym, Type *tp, Symbol **pars, int sclass)
 {
_AT_@ -692,7 +738,7 @@ redcl(Symbol *sym, Type *tp, Symbol **pars, int sclass)
                 goto redeclaration;
         }
 
- sym->u.pars = pars;
+ sym->u.pars = parsdup(pars);
 
         flags = sym->flags;
         switch (sclass) {
_AT_@ -764,7 +810,7 @@ identifier(struct decl *dcl)
                 int flags = sym->flags | SDECLARED;
 
                 sym->type = tp;
- sym->u.pars = dcl->pars;
+ sym->u.pars = parsdup(dcl->pars);
 
                 switch (sclass) {
                 case REGISTER:
_AT_@ -816,9 +862,11 @@ dodcl(int rep, Symbol *(*fun)(struct decl *), unsigned ns, Type *parent)
         base = specifier(&dcl.sclass, &dcl.qualifier);
 
         do {
- stack.nr = 0;
- dcl.pars = NULL;
                 dcl.type = base;
+ dcl.pars = NULL;
+ stack.nr_pars = stack.nr_types = stack.nr = 0;
+ stack.pars = dcl.bufpars;
+ stack.tpars = dcl.buftpars;
 
                 declarator(&stack, ns);
 
diff --git a/cc1/types.c b/cc1/types.c
index 4ea5dea..50e1fcb 100644
--- a/cc1/types.c
+++ b/cc1/types.c
_AT_@ -260,11 +260,17 @@ static Type *
 newtype(Type *base)
 {
         Type *tp;
+ size_t siz;
 
         tp = xmalloc(sizeof(*tp));
         *tp = *base;
         tp->id = newid();
 
+ if (tp->op == FTN) {
+ siz = tp->n.elem * sizeof(Type *);
+ tp->p.pars = memcpy(xmalloc(siz), tp->p.pars, siz);
+ }
+
         if (curfun) {
                 /* it is a type defined in the body of a function */
                 tp->next = localtypes;
_AT_@ -331,15 +337,8 @@ mktype(Type *tp, int op, TINT nelem, Type *pars[])
 
         tbl = &typetab[HASH(&type)];
         for (bp = *tbl; bp; bp = bp->h_next) {
- if (eqtype(bp, &type, 0)) {
- /*
- * pars was allocated by the caller
- * but the type already exists, so
- * we have to deallocte it
- */
- free(pars);
+ if (eqtype(bp, &type, 0))
                         return bp;
- }
         }
 
         bp = newtype(&type);
Received on Sun Feb 26 2017 - 18:29:14 CET

This archive was generated by hypermail 2.3.0 : Sun Feb 26 2017 - 18:36:19 CET