[hackers] [scc] [cc1] Support nested parameter declarations || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 27 Mar 2017 09:25:15 +0200 (CEST)

commit c6dd2dacda6c093f1a7d3c9786f64f4294e390a1
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon Mar 27 09:22:21 2017 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon Mar 27 09:25:06 2017 +0200

    [cc1] Support nested parameter declarations
    
    The code was written in a way that there was possible only one
    list of parameters, which was totally wrong, since it is
    possible to have pointers to functions that return pointers
    to other functions.

diff --git a/cc1/decl.c b/cc1/decl.c
index b4dccde..0e19c6b 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -17,6 +17,7 @@ static char sccsid[] = "@(#) ./cc1/decl.c";
 #define NOQUIET 0
 
 #define NR_DCL_TYP (NR_DECLARATORS+NR_FUNPARAM)
+#define NR_DCL_SYM (NR_DECLARATORS+NR_FUNPARAM+1)
 
 struct declarators {
         unsigned nr;
_AT_@ -30,6 +31,7 @@ struct declarators {
                 TINT nelem;
                 Symbol *sym;
                 Type **tpars;
+ Symbol **pars;
         } d [NR_DECLARATORS];
 };
 
_AT_@ -40,9 +42,12 @@ struct decl {
         Symbol *sym;
         Type *type;
         Type *parent;
+ Symbol **pars;
+ Symbol *bufpars[NR_DCL_SYM];
         Type *buftpars[NR_DCL_TYP];
 };
 
+
 static void
 endfundcl(Type *tp, Symbol **pars)
 {
_AT_@ -79,6 +84,7 @@ push(struct declarators *dp, int op, ...)
         case FTN:
                 p->nelem = va_arg(va, unsigned);
                 p->tpars = va_arg(va, Type **);
+ p->pars = va_arg(va, Symbol **);
                 break;
         case IDEN:
                 p->sym = va_arg(va, Symbol *);
_AT_@ -102,7 +108,8 @@ pop(struct declarators *dp, struct decl *dcl)
         }
 
         if (dcl->type->op == FTN)
- endfundcl(dcl->type, dp->pars);
+ endfundcl(dcl->type, dcl->pars);
+ dcl->pars = p->pars;
 
         dcl->type = mktype(dcl->type, p->op, p->nelem, p->tpars);
         return 1;
_AT_@ -351,7 +358,7 @@ static Symbol *dodcl(int rep,
                      Type *type);
 
 static int
-krpars(Symbol *pars[], unsigned *nparsp)
+krpars(struct declarators *dp)
 {
         Symbol *sym;
         int toomany = 0;
_AT_@ -368,30 +375,25 @@ krpars(Symbol *pars[], unsigned *nparsp)
                 }
                 if (npars < NR_FUNPARAM) {
                         ++npars;
- *pars++ = sym;
+ *dp->pars++ = sym;
                         continue;
                 }
                 if (!toomany)
                 toomany = 1;
         } while (accept(','));
 
- *nparsp = npars;
         return toomany;
 }
 
-static void
-krfun(struct declarators *dp,
- Symbol *pars[], unsigned *ntypep, unsigned *nparsp)
+static unsigned
+krfun(struct declarators *dp)
 {
         int toomany = 0;
 
 
         if (yytoken != ')')
- toomany = krpars(pars, nparsp);
- else
- *nparsp = 0;
+ toomany = krpars(dp);
 
- *ntypep = 1;
         if (dp->nr_types == NR_DCL_TYP) {
                 toomany = 1;
         } else {
_AT_@ -401,11 +403,11 @@ krfun(struct declarators *dp,
 
         if (toomany)
                 errorp("too many parameters in function definition");
+ return 1;
 }
 
-static void
-ansifun(struct declarators *dp,
- Symbol *pars[], unsigned *ntypep, unsigned *nparsp)
+static unsigned
+ansifun(struct declarators *dp)
 {
         Symbol *sym;
         unsigned npars, ntype, toomany, distoomany, voidpar;
_AT_@ -437,7 +439,7 @@ ansifun(struct declarators *dp,
                                 toomany = 1;
                         } else {
                                 npars++;
- *pars++ = sym;
+ *dp->pars++ = sym;
                         }
                 }
 
_AT_@ -457,8 +459,7 @@ ansifun(struct declarators *dp,
                 errorp("too many parameters in function definition");
         if (voidpar && ntype > 1)
                 errorp("'void' must be the only parameter");
- *ntypep = ntype;
- *nparsp = npars;
+ return ntype;
 }
 
 static int
_AT_@ -525,8 +526,9 @@ static void
 fundcl(struct declarators *dp)
 {
         Type **types = dp->tpars;
- unsigned npars, ntypes, typefun;
- void (*fun)(struct declarators *, Symbol **, unsigned *, unsigned *);
+ unsigned ntypes, typefun;
+ Symbol **pars = dp->pars;
+ unsigned (*fun)(struct declarators *);
 
         pushctx();
         expect('(');
_AT_@ -537,11 +539,11 @@ fundcl(struct declarators *dp)
                 typefun = FTN;
                 fun = ansifun;
         }
- (*fun)(dp, dp->pars, &ntypes, &npars);
- dp->pars[npars] = NULL;
+ ntypes = (*fun)(dp);
+ *dp->pars++= NULL;
         expect(')');
 
- push(dp, typefun, ntypes, types);
+ push(dp, typefun, ntypes, types, pars);
 }
 
 static void declarator(struct declarators *dp);
_AT_@ -908,7 +910,7 @@ field(struct decl *dcl)
 static Symbol *
 dodcl(int rep, Symbol *(*fun)(struct decl *), unsigned ns, Type *parent)
 {
- Symbol *sym, *pars[NR_FUNPARAM+1];
+ Symbol *sym;
         Type *base;
         struct decl dcl;
         struct declarators stack;
_AT_@ -921,16 +923,16 @@ dodcl(int rep, Symbol *(*fun)(struct decl *), unsigned ns, Type *parent)
                 dcl.type = base;
                 stack.nr_types = stack.nr = 0;
                 stack.tpars = dcl.buftpars;
+ stack.pars = dcl.bufpars;
                 stack.dcl = &dcl;
                 stack.ns = ns;
- stack.pars = pars;
 
                 declarator(&stack);
 
                 while (pop(&stack, &dcl))
                         /* nothing */;
                 sym = (*fun)(&dcl);
- if (funbody(sym, pars))
+ if (funbody(sym, dcl.pars))
                         return sym;
         } while (rep && accept(','));
 
diff --git a/tests/execute/0130-mulpars.c b/tests/execute/0130-mulpars.c
new file mode 100644
index 0000000..ce84f68
--- /dev/null
+++ b/tests/execute/0130-mulpars.c
_AT_@ -0,0 +1,23 @@
+
+int
+f2(int c, int b)
+{
+ return c - b;
+}
+
+int (*
+f1(int a, int b))(int c, int b)
+{
+ if (a != b)
+ return f2;
+ return 0;
+}
+
+int
+main()
+{
+ int (* (*p)(int a, int b))(int c, int d) = f1;
+
+
+ return (*(*p)(0, 2))(2, 2);
+}
diff --git a/tests/execute/scc-tests.lst b/tests/execute/scc-tests.lst
index afb11b6..60e147f 100644
--- a/tests/execute/scc-tests.lst
+++ b/tests/execute/scc-tests.lst
_AT_@ -120,3 +120,4 @@
 0127-doublecte.c [TODO]
 0128-kr_names.c
 0129-initi.c [TODO]
+0130-mulpars.c
Received on Mon Mar 27 2017 - 09:25:15 CEST

This archive was generated by hypermail 2.3.0 : Mon Mar 27 2017 - 09:36:18 CEST