scc

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

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:
Mcc1/cc1.h | 3++-
Mcc1/code.c | 6++++--
Mcc1/decl.c | 31++++++++++++++++++++++---------
Mcc1/types.c | 9++++++++-
Minc/cc.h | 1+
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'