scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 8c00d7841c469a78680766b398ea4766b1ac0a09
parent 90c4f9ccb0adff2fd1a188567d4553abdc13094a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 19 Jan 2016 10:08:22 +0100

Add emitdesign()

This function is needed because emitconst() cannot handle the case
where the designator is missed. After this function, we can remove
some of the code in emitconst()

Diffstat:
cc1/code.c | 48+++++++++++++++++++++++++++++++++++++++++++++++-
cc1/init.c | 23+++++++++++------------
2 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/cc1/code.c b/cc1/code.c @@ -201,6 +201,7 @@ emitconst(Node *np) (long long) sym->u.i & ones(tp->size)); break; case ARY: + /* TODO: All this code must go out */ if (sym->flags & ISSTRING) { putchar('"'); for (bp = sym->u.s; c = *bp; ++bp) @@ -306,10 +307,55 @@ emittype(Type *tp) } static void +emitdesig(Node *np, Type *tp) +{ + Symbol *sym; + size_t n; + Node *aux; + + if (!np) { + sym = NULL; + } else { + if (!np->symbol) + goto emit_expression; + sym = np->sym; + if ((sym->flags & ISINITLST) == 0) + goto emit_expression; + } + + switch (tp->op) { + case PTR: + case INT: + case ENUM: + aux = (sym) ? *sym->u.init : constnode(zero); + emitexp(OEXPR, aux); + break; + case STRUCT: + case ARY: + for (n = 0; n < tp->n.elem; ++n) { + aux = (sym) ? sym->u.init[n] : NULL; + emitdesig(aux, tp->type); + } + break; + default: + /* TODO: Handle other kind of constants */ + abort(); + } + + freetree(np); + return; + +emit_expression: + emitexp(OEXPR, np); +} + +static void emitinit(unsigned op, void *arg) { + Node *np = arg; + puts("("); - emitexp(OEXPR, arg); + emitdesig(np, np->type); puts(")"); } diff --git a/cc1/init.c b/cc1/init.c @@ -108,23 +108,22 @@ mkcompound(Init *ip) struct designator *dp, *next; Symbol *sym; - n = ip->max; - if (n >= n * sizeof(*v)) { + if ((n = ip->max) == 0) { + v = NULL; + } else if (n >= n * sizeof(*v)) { errorp("compound literal too big"); return constnode(zero); - } - n *= sizeof(*v); - v = memset(xmalloc(n), 0, n); + } else { + n *= sizeof(*v); + v = memset(xmalloc(n), 0, n); - for (dp = ip->head; dp; dp = next) { - p = &v[dp->pos]; - if (*p) { - warn("double initialization in compound literal"); + for (dp = ip->head; dp; dp = next) { + p = &v[dp->pos]; freetree(*p); + *p = dp->expr; + next = dp->next; + free(dp); } - *p = dp->expr; - next = dp->next; - free(dp); } sym = newsym(NS_IDEN);