ref: ab74e508b10e6bdf39ae71e204bf91642257d689
parent: a0862978b0a1d5c876db7839cc6905b749291640
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Aug 7 16:28:12 EDT 2015
Fix fundcl() Fundcl() has to take the decision when it is needed the parameter context or not, and the only way is to check if the next token is a allowed one in a function definition. Ideally the context should be poped before calling expect(), but we know that after a parameter list cannot go a identifier, so it is not a problem.
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -91,34 +91,43 @@
Type type = {.n = {.elem = -1}, .pars = NULL};
Symbol *syms[NR_FUNPARAM], **sp;
size_t size;
+ void *p;
pushctx();
expect('(');
- if (accept(')'))
- goto nopars;
+ if (accept(')')) {
+ dp = queue(dp, FTN, type.n.elem, type.pars);
+ } else {
+ type.n.elem = 0;
+ sp = syms;
+ do
+ *sp++ = dodcl(0, parameter, NS_IDEN, &type);
+ while (accept(','));
- type.n.elem = 0;
- sp = syms;
- do
- *sp++ = dodcl(0, parameter, NS_IDEN, &type);
- while (accept(','));
+ expect(')');
- if (ahead() != '{')
- goto nopars;
+ dp = queue(dp, FTN, type.n.elem, type.pars);
+ if (type.n.elem != -1) {
+ size = type.n.elem * sizeof(Symbol *);
+ p = memcpy(xmalloc(size), syms, size);
+ dp = queue(dp, PARS, 0, p);
+ }
+ }
- expect(')');
-
- dp = queue(dp, FTN, type.n.elem, type.pars);
- if (type.n.elem != -1) {
- size = type.n.elem * sizeof(Symbol *);
- dp = queue(dp, PARS, 0, memcpy(xmalloc(size), syms, size));
+ switch (yytoken) {
+ default:
+ /* This is not a function */
+ popctx();
+ case '{':
+ case TYPEIDEN:
+ case TYPE:
+ case TQUALIFIER:
+ case SCLASS:
+ /* This can be a function (K&R included) */
+ break;
}
return dp;
-
-nopars:
- expect(')');
- return queue(dp, FTN, type.n.elem, type.pars);
}
static struct dcldata *declarator0(struct dcldata *dp, unsigned ns);
@@ -457,9 +466,7 @@
warn("empty declaration");
return;
}
- if (sym->type->op == FTN) {
- popctx();
- } else {
+ if (sym->type->op != FTN) {
if (!sclass)
sym->flags |= ISAUTO;
if (accept('='))