scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
Mcc1/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('='))