ref: f08eafe178160c3dea617d0dd28c50b04b998c8d
parent: dcbb7393e11a24768718b157462f5ab97ae6ed8e
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Jul 6 16:27:44 EDT 2017
[cc1] Emit constant auto initalizers In the case of automatic variables of type struct or array is better to instace a hidden element and memcpy it instead of copying field by field. In the case of unions the best option depends of the field initialized.
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -289,6 +289,42 @@
return mkcompound(&in);
}
+static void
+autoinit(Symbol *sym, Node *np)
+{
+ Symbol *hidden;
+ Type *tp = sym->type;
+ size_t n; /* FIXME: It should be SIZET */
+
+ if (!(np->flags & NCONST))
+ abort(); /* TODO: Implement not constant initializers */
+
+repeat:
+ switch (tp->op) {
+ case UNION:
+ n = tp->n.elem-1;
+ tp = tp->p.fields[n]->type;
+ np = np->sym->u.init[n];
+ goto repeat;
+ case ARY:
+ case STRUCT:
+ hidden = newsym(NS_IDEN, NULL);
+ hidden->type = sym->type;
+ hidden->flags |= SLOCAL | SHASINIT;
+ emit(ODECL, hidden);
+ emit(OINIT, np);
+ emit(ODECL, sym);
+ emit(OEXPR,
+ node(OASSIGN, tp, varnode(sym), varnode(hidden)));
+ break;
+ default:
+ emit(ODECL, sym);
+ np = node(OASSIGN, tp, varnode(sym), np);
+ emit(OEXPR, np);
+ break;
+ }
+}
+
void
initializer(Symbol *sym, Type *tp)
{
@@ -318,8 +354,6 @@
errorp("'%s' has both '%s' and initializer",
sym->name, (flags&SEXTERN) ? "extern" : "typedef");
} else {
- emit(ODECL, sym);
- np = node(OASSIGN, tp, varnode(sym), np);
- emit(OEXPR, np);
+ autoinit(sym, np);
}
}