ref: 8c00d7841c469a78680766b398ea4766b1ac0a09
parent: 90c4f9ccb0adff2fd1a188567d4553abdc13094a
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jan 19 05:08:22 EST 2016
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()
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -201,6 +201,7 @@
(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 @@
}
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(")");
}
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -108,23 +108,22 @@
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);