commit ab74e508b10e6bdf39ae71e204bf91642257d689
parent a0862978b0a1d5c876db7839cc6905b749291640
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 7 Aug 2015 20:28:12 +0200
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.
Diffstat:
M | cc1/decl.c | | | 51 | +++++++++++++++++++++++++++++---------------------- |
1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -91,34 +91,43 @@ fundcl(struct dcldata *dp)
Type type = {.n = {.elem = -1}, .pars = NULL};
Symbol *syms[NR_FUNPARAM], **sp;
size_t size;
+ void *p;
pushctx();
expect('(');
- if (accept(')'))
- goto nopars;
-
- type.n.elem = 0;
- sp = syms;
- do
- *sp++ = dodcl(0, parameter, NS_IDEN, &type);
- while (accept(','));
+ 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(','));
- if (ahead() != '{')
- goto nopars;
+ expect(')');
- expect(')');
+ 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);
+ }
+ }
- 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 @@ internal(Symbol *sym, int sclass, Type *data)
warn("empty declaration");
return;
}
- if (sym->type->op == FTN) {
- popctx();
- } else {
+ if (sym->type->op != FTN) {
if (!sclass)
sym->flags |= ISAUTO;
if (accept('='))