commit bab40c3565755c5caadec881f259947dd0dbafa2
parent 0ba1212867ef18e71a4f05ed19b6d0c89208e954
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 25 Sep 2015 22:01:18 +0200
Add support for vararg function definition
Diffstat:
5 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -416,4 +416,5 @@ extern Type *voidtype, *pvoidtype, *booltype,
*ushortype, *shortype,
*longtype, *ulongtype,
*ullongtype, *llongtype,
- *floattype, *doubletype, *ldoubletype;
+ *floattype, *doubletype, *ldoubletype,
+ *ellipsistype;
diff --git a/cc1/code.c b/cc1/code.c
@@ -357,9 +357,11 @@ emitfun(unsigned op, void *arg)
n = sym->type->n.elem;
for (sp = sym->u.pars; n-- > 0; ++sp) {
+ if ((sym = *sp) == NULL)
+ continue;
/* enable non used warnings in parameters */
- (*sp)->flags &= ~ISUSED;
- emit(ODECL, *sp);
+ sym->flags &= ~ISUSED;
+ emit(ODECL, sym);
}
puts("\\");
}
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -116,6 +116,18 @@ arydcl(struct declarators *dp)
push(dp, ARY, n);
}
+static void
+newpar(Type *fun, Type *par)
+{
+ TINT n = fun->n.elem;
+
+ if (n == NR_FUNPARAM)
+ error("too much parameters in function definition");
+ fun->p.pars = xrealloc(fun->p.pars, ++n * sizeof(Type *));
+ fun->p.pars[n-1] = par;
+ fun->n.elem = n;
+}
+
static Symbol *
parameter(struct decl *dcl)
{
@@ -164,12 +176,7 @@ parameter(struct decl *dcl)
}
sym->type = tp;
sym->flags |= ISUSED; /* avoid non used warnings in prototypes */
-
- if (n == NR_FUNPARAM)
- error("too much parameters in function definition");
- funtp->p.pars = xrealloc(funtp->p.pars, ++n * sizeof(Type *));
- funtp->p.pars[n-1] = tp;
- funtp->n.elem = n;
+ newpar(funtp, tp);
return sym;
}
@@ -193,9 +200,15 @@ fundcl(struct declarators *dp)
if (!accept(')')) {
type.n.elem = 0;
sp = syms;
- do
- *sp++ = dodcl(0, parameter, NS_IDEN, &type);
- while (accept(','));
+ do {
+ if (!accept(ELLIPSIS)) {
+ *sp++ = dodcl(0, parameter, NS_IDEN, &type);
+ } else {
+ newpar(&type, ellipsistype);
+ *sp++ = NULL;
+ break;
+ }
+ } while (accept(','));
expect(')');
diff --git a/cc1/types.c b/cc1/types.c
@@ -241,6 +241,12 @@ static Type types[] = {
.align = 1,
.n.rank = RANK_UINT,
.printed = 1
+ },
+ { /* 18 = ellipsis */
+ .op = ELLIPSIS,
+ .letter = L_ELLIPSIS,
+ .defined = 1,
+ .printed = 1
}
};
@@ -252,7 +258,8 @@ Type *voidtype = &types[0], *pvoidtype = &types[1],
*longtype = &types[10], *ulongtype = &types[11],
*ullongtype = &types[12], *llongtype = &types[13],
*floattype = &types[14], *doubletype = &types[15],
- *ldoubletype = &types[16], *sizettype = &types[17];
+ *ldoubletype = &types[16], *sizettype = &types[17],
+ *ellipsistype = &types[18];
static Symbol dummy0 = {.u.i = 0, .type = &types[9]},
dummy1 = {.u.i = 1, .type = &types[9]};
diff --git a/inc/cc.h b/inc/cc.h
@@ -21,6 +21,7 @@ typedef unsigned bool;
#define L_UINT16 'N'
#define L_UINT32 'Z'
#define L_UINT64 'O'
+#define L_ELLIPSIS 'E'
#define L_VOID '0'
#define L_POINTER 'P'