commit 43a3b37a514e390199668bab42c3451901de5917
parent 8f5f61842eec2f1553ddbc90bf454600168f0718
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 18 Jan 2016 15:20:50 +0100
Emit compound initializers
At this point we are not emiting anything, but we have the full process
working. We have to create a function which could emit this kind of
constants.
Diffstat:
5 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -384,7 +384,7 @@ extern Node *castcode(Node *np, Type *newtp);
extern TUINT ones(int nbytes);
/* expr.c */
-extern Node *decay(Node *), *negate(Node *np), *assign(Node *np);;
+extern Node *decay(Node *), *negate(Node *np), *assign(void);;
extern Node *convert(Node *np, Type *tp1, char iscast);
extern Node *iconstexpr(void), *condexpr(void), *expr(void);
extern bool isnodecmp(int op);
diff --git a/cc1/code.c b/cc1/code.c
@@ -207,6 +207,8 @@ emitconst(Node *np)
for (bp = sym->u.s; c = *bp; ++bp)
printf("%02X", c & 0xFF);
break;
+ case STRUCT:
+ return;
default:
/* TODO: Handle other kind of constants */
abort();
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -788,7 +788,7 @@ identifier(struct decl *dcl)
if (sym->token == IDEN && sym->type->op != FTN)
emit(ODECL, sym);
- if (yytoken == '=')
+ if (accept('='))
initializer(sym, sym->type, -1);
if (!(sym->flags & (ISGLOBAL|ISEXTERN)) && tp->op != FTN)
sym->flags |= ISDEFINED;
diff --git a/cc1/expr.c b/cc1/expr.c
@@ -512,9 +512,7 @@ static Node *
assignop(char op, Node *lp, Node *rp)
{
if ((rp = convert(decay(rp), lp->type, 0)) == NULL) {
- errorp((op == OINIT) ?
- "incorrect initiliazer" :
- "incompatible types when assigning");
+ errorp("incompatible types when assigning");
return lp;
}
@@ -657,7 +655,7 @@ arguments(Node *np)
toomany = 0;
do {
- arg = decay(assign(NULL));
+ arg = decay(assign());
argtype = *targs;
if (argtype == ellipsistype) {
n = 0;
@@ -1006,21 +1004,15 @@ ternary(void)
}
Node *
-assign(Node *np)
+assign(void)
{
- Node *(*fun)(char , Node *, Node *);
+ Node *np, *(*fun)(char , Node *, Node *);
char op;
- if (np) {
- op = OINIT;
- } else {
- op = OASSIGN;
- np = ternary();
- }
-
+ np = ternary();
for (;;) {
switch (yytoken) {
- case '=': /* op = op; */; fun = assignop; break;
+ case '=': op = OASSIGN; fun = assignop; break;
case MUL_EQ: op = OA_MUL; fun = arithmetic; break;
case DIV_EQ: op = OA_DIV; fun = arithmetic; break;
case MOD_EQ: op = OA_MOD; fun = integerop; break;
@@ -1035,7 +1027,7 @@ assign(Node *np)
}
chklvalue(np);
next();
- np = (fun)(op, np, assign(NULL));
+ np = (fun)(op, np, assign());
}
}
@@ -1073,9 +1065,9 @@ expr(void)
{
Node *lp, *rp;
- lp = assign(NULL);
+ lp = assign();
while (accept(',')) {
- rp = assign(NULL);
+ rp = assign();
lp = node(OCOMMA, rp->type, lp, rp);
}
diff --git a/cc1/init.c b/cc1/init.c
@@ -78,11 +78,24 @@ designation(Init *ip)
return ip;
}
+static Node *initlist(Type *tp);
+
static Node *
-initlist(Symbol *sym, Type *tp)
+initialize(Type *tp)
+{
+ Node *np;
+
+ np = (accept('{')) ? initlist(tp) : assign();
+ if ((np = convert(decay(np), tp, 0)) == NULL)
+ errorp("incorrect initializer");
+ return np;
+}
+
+static Node *
+initlist(Type *tp)
{
Init *ip;
- Symbol *nsym;
+ Symbol *sym;
struct designator *dp;
int toomany = 0;
Type *newtp;
@@ -99,19 +112,20 @@ initlist(Symbol *sym, Type *tp)
designation(ip);
switch (tp->op) {
case ARY:
- newtp = tp->type;
- if (!tp->defined || ip->pos < tp->n.elem)
+ newtp = sym->type;
+ if (!tp->defined || ip->pos <= tp->n.elem)
break;
if (!toomany)
warn("excess elements in array initializer");
toomany = 1;
break;
case STRUCT:
- if (ip->pos < tp->n.elem) {
- sym = tp->p.fields[ip->pos];
+ if (ip->pos <= tp->n.elem) {
+ sym = tp->p.fields[ip->pos-1];
newtp = sym->type;
break;
}
+ newtp = inttype;
if (!toomany)
warn("excess elements in struct initializer");
toomany = 1;
@@ -119,7 +133,7 @@ initlist(Symbol *sym, Type *tp)
default:
newtp = tp;
warn("braces around scalar initializer");
- if (ip->pos <= 0)
+ if (ip->pos == 1)
break;
if (!toomany)
warn("excess elements in scalar initializer");
@@ -128,8 +142,7 @@ initlist(Symbol *sym, Type *tp)
}
dp = ip->head;
dp->pos = ip->pos;
- /* TODO: pass the correct parameters to initlist */
- dp->expr = (accept('{')) ? initlist(sym, tp) : assign(NULL);
+ dp->expr = initialize(newtp);
if (!accept(','))
break;
@@ -141,9 +154,10 @@ end_of_initializer:
tp->n.elem = ip->pos;
tp->defined = 1;
}
- nsym = newsym(NS_IDEN);
- nsym->u.init = ip;
- return constnode(nsym);
+ sym = newsym(NS_IDEN);
+ sym->u.init = ip;
+ sym->type = tp;
+ return constnode(sym);
}
void
@@ -155,14 +169,7 @@ initializer(Symbol *sym, Type *tp, int nelem)
if (tp->op == FTN)
errorp("function '%s' is initialized like a variable", sym->name);
- switch (yytoken) {
- case '{':
- initlist(sym, tp);
- return;
- case '=':
- np = assign(varnode(sym));
- break;
- }
+ np = node(OINIT, tp, varnode(sym), initialize(tp));
if (flags & ISDEFINED) {
errorp("redeclaration of '%s'", sym->name);