ref: 38c240c4f09858a4ce71d70ee7fe16e7df7c9bff
parent: ba98fe9738f78620b50c8351d46c95f923052dd7
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Jan 17 06:59:04 EST 2016
Move initializer code to a new file This code is going to be too long, and it is not totally related to expressions, so it is better to create a new file.
--- a/cc1/Makefile
+++ b/cc1/Makefile
@@ -3,7 +3,7 @@
include ../config.mk
OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
- code.o stmt.o cpp.o fold.o
+ code.o stmt.o cpp.o fold.o init.o
all: cc1
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -374,13 +374,14 @@
extern TUINT ones(int nbytes);
/* expr.c */
-extern Node *expr(void), *negate(Node *np), *constexpr(void);
+extern Node *decay(Node *), *negate(Node *np), *assign(Node *np);;
extern Node *convert(Node *np, Type *tp1, char iscast);
-extern Node *iconstexpr(void), *condexpr(void);
+extern Node *iconstexpr(void), *condexpr(void), *expr(void);
extern bool isnodecmp(int op);
extern int negop(int op);
extern bool cmpnode(Node *np, TUINT val);
-extern Node *decay(Node *np);
+
+/* init.c */
extern void initializer(Symbol *sym, Type *tp, int nelem);
/* cpp.c */
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -779,7 +779,7 @@
if (sym->token == IDEN && sym->type->op != FTN)
emit(ODECL, sym);
- if (accept('='))+ if (yytoken == '=')
initializer(sym, sym->type, -1);
if (!(sym->flags & (ISGLOBAL|ISEXTERN)) && tp->op != FTN)
sym->flags |= ISDEFINED;
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -629,8 +629,6 @@
return np;
}
-static Node *assign(void);
-
static Node *
arguments(Node *np)
{@@ -659,7 +657,7 @@
toomany = 0;
do {- arg = decay(assign());
+ arg = decay(assign(NULL));
argtype = *targs;
if (argtype == ellipsistype) {n = 0;
@@ -1007,16 +1005,22 @@
return cond;
}
-static Node *
-assign(void)
+Node *
+assign(Node *np)
{- Node *np, *(*fun)(char , Node *, Node *);
+ Node *(*fun)(char , Node *, Node *);
char op;
- np = ternary();
+ if (np) {+ op = OINIT;
+ } else {+ op = OASSIGN;
+ np = ternary();
+ }
+
for (;;) { switch (yytoken) {- case '=': op = OASSIGN; fun = assignop; break;
+ case '=': /* op = op; */; 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;
@@ -1031,7 +1035,7 @@
}
chklvalue(np);
next();
- np = (fun)(op, np, assign());
+ np = (fun)(op, np, assign(NULL));
}
}
@@ -1069,9 +1073,9 @@
{Node *lp, *rp;
- lp = assign();
+ lp = assign(NULL);
while (accept(',')) {- rp = assign();
+ rp = assign(NULL);
lp = node(OCOMMA, rp->type, lp, rp);
}
@@ -1087,177 +1091,4 @@
if (np->constant)
warn("conditional expression is constant");return np;
-}
-
-struct designator {- TINT pos;
- struct designator *next;
-};
-
-static TINT
-arydesig(Type *tp)
-{- TINT npos;
- Node *np;
-
- if (tp->op != ARY)
- errorp("array index in non-array initializer");- next();
- np = iconstexpr();
- npos = np->sym->u.i;
- freetree(np);
- expect(']');- return npos;
-}
-
-static TINT
-fielddesig(Type *tp)
-{- TINT npos;
- int ons;
- Symbol *sym, **p;
-
- if (!tp->aggreg)
- errorp("field name not in record or union initializer");- ons = namespace;
- namespace = tp->ns;
- next();
- namespace = ons;
- if (yytoken != IDEN)
- unexpected();
- sym = yylval.sym;
- if ((sym->flags & ISDECLARED) == 0) {- errorp(" unknown field '%s' specified in initializer",- sym->name);
- return 0;
- }
- for (p = tp->p.fields; *p != sym; ++p)
- /* nothing */;
- return p - tp->p.fields;
-}
-
-static struct designator *
-designation(Type *tp)
-{- struct designator *des = NULL, *d;
- TINT (*fun)(Type *);
-
- for (;;) {- switch (yytoken) {- case '[': fun = arydesig; break;
- case '.': fun = fielddesig; break;
- default:
- if (des)
- expect('=');- return des;
- }
- d = xmalloc(sizeof(*d));
- d->next = NULL;
-
- if (!des) {- des = d;
- } else {- des->next = d;
- des = d;
- }
- des->pos = (*fun)(tp);
- }
-}
-
-static void
-initlist(Symbol *sym, Type *tp)
-{- struct designator *des;
- int toomany = 0;
- TINT n;
- Type *newtp;
-
- for (n = 0; ; ++n) {- if ((des = designation(tp)) == NULL) {- des = xmalloc(sizeof(*des));
- des->pos = n;
- } else {- n = des->pos;
- }
- switch (tp->op) {- case ARY:
- if (tp->defined && n >= tp->n.elem) {- if (!toomany)
- warn("excess elements in array initializer");- toomany = 1;
- sym = NULL;
- }
- newtp = tp->type;
- break;
- case STRUCT:
- if (n >= tp->n.elem) {- if (!toomany)
- warn("excess elements in struct initializer");- toomany = 1;
- sym = NULL;
- } else {- sym = tp->p.fields[n];
- newtp = sym->type;
- }
- break;
- default:
- newtp = tp;
- warn("braces around scalar initializer");- if (n > 0) {- if (!toomany)
- warn("excess elements in scalar initializer");- toomany = 1;
- sym = NULL;
- }
- break;
- }
- initializer(sym, newtp, n);
- if (!accept(','))- break;
- }
- expect('}');-
- if (tp->op == ARY && !tp->defined) {- tp->n.elem = n + 1;
- tp->defined = 1;
- }
-}
-
-void
-initializer(Symbol *sym, Type *tp, int nelem)
-{- Node *np;
- int flags = sym->flags;
-
- if (tp->op == FTN)
- error("function '%s' is initialized like a variable", sym->name);-
- if (accept('{')) {- initlist(sym, tp);
- return;
- }
- np = assign();
-
- /* if !sym it means there are too much initializers */
- if (!sym)
- return;
- if (nelem >= 0)
- return;
-
- np = assignop(OINIT, varnode(sym), np);
-
- if (flags & ISDEFINED) {- errorp("redeclaration of '%s'", sym->name);- } else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {- if (!np->right->constant)
- errorp("initializer element is not constant");- emit(OINIT, np);
- sym->flags |= ISDEFINED;
- } else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {- errorp("'%s' has both '%s' and initializer",- sym->name, (flags&ISEXTERN) ? "extern" : "typedef");
- } else {- np->op = OASSIGN;
- emit(OEXPR, np);
- }
}
--- /dev/null
+++ b/cc1/init.c
@@ -1,0 +1,184 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../inc/cc.h"
+#include "../inc/sizes.h"
+#include "cc1.h"
+
+struct designator {+ TINT pos;
+ struct designator *next;
+};
+
+static TINT
+arydesig(Type *tp)
+{+ TINT npos;
+ Node *np;
+
+ if (tp->op != ARY)
+ errorp("array index in non-array initializer");+ next();
+ np = iconstexpr();
+ npos = np->sym->u.i;
+ freetree(np);
+ expect(']');+ return npos;
+}
+
+static TINT
+fielddesig(Type *tp)
+{+ TINT npos;
+ int ons;
+ Symbol *sym, **p;
+
+ if (!tp->aggreg)
+ errorp("field name not in record or union initializer");+ ons = namespace;
+ namespace = tp->ns;
+ next();
+ namespace = ons;
+ if (yytoken != IDEN)
+ unexpected();
+ sym = yylval.sym;
+ if ((sym->flags & ISDECLARED) == 0) {+ errorp(" unknown field '%s' specified in initializer",+ sym->name);
+ return 0;
+ }
+ for (p = tp->p.fields; *p != sym; ++p)
+ /* nothing */;
+ return p - tp->p.fields;
+}
+
+static struct designator *
+designation(Type *tp)
+{+ struct designator *des = NULL, *d;
+ TINT (*fun)(Type *);
+
+ for (;;) {+ switch (yytoken) {+ case '[': fun = arydesig; break;
+ case '.': fun = fielddesig; break;
+ default:
+ if (des)
+ expect('=');+ return des;
+ }
+ d = xmalloc(sizeof(*d));
+ d->next = NULL;
+
+ if (!des) {+ des = d;
+ } else {+ des->next = d;
+ des = d;
+ }
+ des->pos = (*fun)(tp);
+ }
+}
+
+static void
+initlist(Symbol *sym, Type *tp)
+{+ struct designator *des;
+ int toomany = 0;
+ TINT n;
+ Type *newtp;
+
+ for (n = 0; ; ++n) {+ if ((des = designation(tp)) == NULL) {+ des = xmalloc(sizeof(*des));
+ des->pos = n;
+ } else {+ n = des->pos;
+ }
+ switch (tp->op) {+ case ARY:
+ if (tp->defined && n >= tp->n.elem) {+ if (!toomany)
+ warn("excess elements in array initializer");+ toomany = 1;
+ sym = NULL;
+ }
+ newtp = tp->type;
+ break;
+ case STRUCT:
+ if (n >= tp->n.elem) {+ if (!toomany)
+ warn("excess elements in struct initializer");+ toomany = 1;
+ sym = NULL;
+ } else {+ sym = tp->p.fields[n];
+ newtp = sym->type;
+ }
+ break;
+ default:
+ newtp = tp;
+ warn("braces around scalar initializer");+ if (n > 0) {+ if (!toomany)
+ warn("excess elements in scalar initializer");+ toomany = 1;
+ sym = NULL;
+ }
+ break;
+ }
+ initializer(sym, newtp, n);
+ if (!accept(','))+ break;
+ }
+ expect('}');+
+ if (tp->op == ARY && !tp->defined) {+ tp->n.elem = n + 1;
+ tp->defined = 1;
+ }
+}
+
+extern Node *assign(Node *np);
+
+void
+initializer(Symbol *sym, Type *tp, int nelem)
+{+ Node *np;
+ int flags = sym->flags;
+
+ if (tp->op == FTN)
+ errorp("function '%s' is initialized like a variable", sym->name);+
+ switch (yytoken) {+ case '{':+ initlist(sym, tp); /* FIXME: This code is not complete */
+ return;
+ case '=':
+ np = assign(varnode(sym));
+ break;
+ }
+
+ /* FIXME: old code used in the recursive call
+ * if (!sym)
+ * return;
+ * if (nelem >= 0)
+ * return;
+ */
+
+ if (flags & ISDEFINED) {+ errorp("redeclaration of '%s'", sym->name);+ } else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {+ if (!np->right->constant)
+ errorp("initializer element is not constant");+ emit(OINIT, np);
+ sym->flags |= ISDEFINED;
+ } else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {+ errorp("'%s' has both '%s' and initializer",+ sym->name, (flags&ISEXTERN) ? "extern" : "typedef");
+ } else {+ np->op = OASSIGN;
+ emit(OEXPR, np);
+ }
+}
--
⑨