[hackers] [scc] Emit parameters in functions || Roberto E. Vargas Caballero
commit 7d056d042a60919bb854929e776e138e0ee2817d
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Aug 5 20:01:45 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Aug 5 20:01:45 2015 +0200
Emit parameters in functions
Parameters are marked with a P, and in this case are
emited before of the body of the function, but this is
something we should change because we are loosing the
storage specifier.
diff --git a/cc1/decl.c b/cc1/decl.c
index 6957c38..3376a60 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -59,8 +59,8 @@ fundcl(struct dcldata *dp)
{
Type dummy = {.n = {.elem = 0}, .pars = NULL};
- pushctx();
parlist(&dummy);
+
return queue(dp, FTN, dummy.n.elem, dummy.pars);
}
_AT_@ -409,6 +409,7 @@ parameter(Symbol *sym, int sclass, Type *data)
error("bad storage class in function parameter");
if (n++ == NR_FUNPARAM)
error("too much parameters in function definition");
+ sym->flags |= ISPARAM;
funtp->pars = xrealloc(funtp->pars, n);
funtp->pars[n-1] = tp;
funtp->n.elem = n;
_AT_@ -462,27 +463,23 @@ prototype(Symbol *sym)
if (sym->token == TYPEIDEN)
error("function definition declared 'typedef'");
- /* TODO: emit parameters emit(ODECL, *sp++); */
sym->flags |= ISDEFINED;
curfun = sym;
emit(OFUN, sym);
compound(NULL, NULL, NULL);
emit(OEFUN, NULL);
+ popctx();
r = 0;
}
- /*
- * fundcl() creates a new context for the parameters
- * and in this point we have to destroy the context
- */
- popctx();
return r;
}
-static bool
+static Symbol *
dodcl(int rep, void (*fun)(Symbol *, int, Type *), uint8_t ns, Type *type)
{
- Type *base;
+ Symbol *sym;
+ Type *base, *tp;
int sclass;
/* FIXME: curctx == PARCTX is incorrect. Structs also
_AT_@ -496,8 +493,8 @@ dodcl(int rep, void (*fun)(Symbol *, int, Type *), uint8_t ns, Type *type)
}
do {
- Symbol *sym = declarator(base, ns);
- Type *tp = sym->type;
+ sym = declarator(base, ns);
+ tp = sym->type;
switch (sclass) {
case REGISTER:
_AT_@ -516,13 +513,13 @@ dodcl(int rep, void (*fun)(Symbol *, int, Type *), uint8_t ns, Type *type)
sym->token = TYPEIDEN;
break;
}
-
if (tp->op == FTN && !prototype(sym))
- return 0;
+ return NULL;
(*fun)(sym, sclass, type);
+
} while (rep && accept(','));
- return 1;
+ return sym;
}
void
_AT_@ -535,20 +532,46 @@ decl(void)
expect(';');
}
+/*
+ * parlist() is called every time there is a argument list.
+ * It means that is called for prototypes and for functions.
+ * In both cases a new context is needed for the arguments,
+ * but in the case of prototypes we need pop the context
+ * before parsing anything else or we can have name conflicts.
+ * The heuristic used here to detect a function is check if
+ * next token will be '{', but it implies that K&R alike
+ * functions are not allowed.
+ */
static void
parlist(Type *tp)
{
+ Symbol *pars[NR_FUNPARAM], **sp = pars, *sym;
+ bool isfun;
+ int n;
+
+ pushctx();
expect('(');
if (accept(')')) {
- /* TODO: implement k&r functions */
+ tp->n.elem = -1;
return;
}
+
do
- dodcl(0, parameter, NS_IDEN, tp);
+ *sp++ = dodcl(0, parameter, NS_IDEN, tp);
while (accept(','));
+ isfun = ahead() == '{';
+ if (!isfun)
+ popctx();
expect(')');
+
+ if (!isfun)
+ return;
+
+ n = tp->n.elem;
+ for (sp = pars; n-- > 0; ++sp)
+ emit(ODECL, *sp);
}
static void
Received on Wed Aug 05 2015 - 20:09:42 CEST
This archive was generated by hypermail 2.3.0
: Wed Aug 05 2015 - 20:12:12 CEST