diff options
Diffstat (limited to 'lcc/src/init.c')
-rw-r--r-- | lcc/src/init.c | 318 |
1 files changed, 0 insertions, 318 deletions
diff --git a/lcc/src/init.c b/lcc/src/init.c deleted file mode 100644 index 172d7c0..0000000 --- a/lcc/src/init.c +++ /dev/null @@ -1,318 +0,0 @@ -#include "c.h" - - -static int curseg; /* current segment */ - -/* defpointer - initialize a pointer to p or to 0 if p==0 */ -void defpointer(Symbol p) { - if (p) { - (*IR->defaddress)(p); - p->ref++; - } else { - static Value v; - (*IR->defconst)(P, voidptype->size, v); - } -} - -/* genconst - generate/check constant expression e; return size */ -static int genconst(Tree e, int def) { - for (;;) - switch (generic(e->op)) { - case ADDRG: - if (def) - (*IR->defaddress)(e->u.sym); - return e->type->size; - case CNST: - if (e->op == CNST+P && isarray(e->type)) { - e = cvtconst(e); - continue; - } - if (def) - (*IR->defconst)(e->type->op, e->type->size, e->u.v); - return e->type->size; - case RIGHT: - assert(e->kids[0] || e->kids[1]); - if (e->kids[1] && e->kids[0]) - error("initializer must be constant\n"); - e = e->kids[1] ? e->kids[1] : e->kids[0]; - continue; - case CVP: - if (isarith(e->type)) - error("cast from `%t' to `%t' is illegal in constant expressions\n", - e->kids[0]->type, e->type); - /* fall thru */ - case CVI: case CVU: case CVF: - e = e->kids[0]; - continue; - default: - error("initializer must be constant\n"); - if (def) - genconst(consttree(0, inttype), def); - return inttype->size; - } -} - -/* initvalue - evaluate a constant expression for a value of integer type ty */ -static Tree initvalue(Type ty) { - Type aty; - Tree e; - - needconst++; - e = expr1(0); - if ((aty = assign(ty, e)) != NULL) - e = cast(e, aty); - else { - error("invalid initialization type; found `%t' expected `%t'\n", - e->type, ty); - e = retype(consttree(0, inttype), ty); - } - needconst--; - if (generic(e->op) != CNST) { - error("initializer must be constant\n"); - e = retype(consttree(0, inttype), ty); - } - return e; -} - -/* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */ -static int initarray(int len, Type ty, int lev) { - int n = 0; - - do { - initializer(ty, lev); - n += ty->size; - if ((len > 0 && n >= len) || t != ',') - break; - t = gettok(); - } while (t != '}'); - return n; -} - -/* initchar - initialize array of <= len ty characters; if len == 0, go to } */ -static int initchar(int len, Type ty) { - int n = 0; - char buf[16], *s = buf; - - do { - *s++ = initvalue(ty)->u.v.i; - if (++n%inttype->size == 0) { - (*IR->defstring)(inttype->size, buf); - s = buf; - } - if ((len > 0 && n >= len) || t != ',') - break; - t = gettok(); - } while (t != '}'); - if (s > buf) - (*IR->defstring)(s - buf, buf); - return n; -} - -/* initend - finish off an initialization at level lev; accepts trailing comma */ -static void initend(int lev, char follow[]) { - if (lev == 0 && t == ',') - t = gettok(); - test('}', follow); -} - -/* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */ -static int initfields(Field p, Field q) { - unsigned int bits = 0; - int i, n = 0; - - do { - i = initvalue(inttype)->u.v.i; - if (fieldsize(p) < 8*p->type->size) { - if ((p->type == inttype && - (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))) - || (p->type == unsignedtype && (i&~fieldmask(p)) != 0)) - warning("initializer exceeds bit-field width\n"); - i &= fieldmask(p); - } - bits |= i<<fieldright(p); - if (IR->little_endian) { - if (fieldsize(p) + fieldright(p) > n) - n = fieldsize(p) + fieldright(p); - } else { - if (fieldsize(p) + fieldleft(p) > n) - n = fieldsize(p) + fieldleft(p); - } - if (p->link == q) - break; - p = p->link; - } while (t == ',' && (t = gettok()) != 0); - n = (n + 7)/8; - for (i = 0; i < n; i++) { - Value v; - if (IR->little_endian) { - v.u = (unsigned char)bits; - bits >>= 8; - } else { /* a big endian */ - v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1))); - bits <<= 8; - } - (*IR->defconst)(U, unsignedchar->size, v); - } - return n; -} - -/* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */ -static int initstruct(int len, Type ty, int lev) { - int a, n = 0; - Field p = ty->u.sym->u.s.flist; - - do { - if (p->offset > n) { - (*IR->space)(p->offset - n); - n += p->offset - n; - } - if (p->lsb) { - Field q = p; - while (q->link && q->link->offset == p->offset) - q = q->link; - n += initfields(p, q->link); - p = q; - } else { - initializer(p->type, lev); - n += p->type->size; - } - if (p->link) { - p = p->link; - a = p->type->align; - } else - a = ty->align; - if (a && n%a) { - (*IR->space)(a - n%a); - n = roundup(n, a); - } - if ((len > 0 && n >= len) || t != ',') - break; - t = gettok(); - } while (t != '}'); - return n; -} - -/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */ -Type initializer(Type ty, int lev) { - int n = 0; - Tree e; - Type aty = NULL; - static char follow[] = { IF, CHAR, STATIC, 0 }; - - ty = unqual(ty); - if (isscalar(ty)) { - needconst++; - if (t == '{') { - t = gettok(); - e = expr1(0); - initend(lev, follow); - } else - e = expr1(0); - e = pointer(e); - if ((aty = assign(ty, e)) != NULL) - e = cast(e, aty); - else - error("invalid initialization type; found `%t' expected `%t'\n", - e->type, ty); - n = genconst(e, 1); - deallocate(STMT); - needconst--; - } - if ((isunion(ty) || isstruct(ty)) && ty->size == 0) { - static char follow[] = { CHAR, STATIC, 0 }; - error("cannot initialize undefined `%t'\n", ty); - skipto(';', follow); - return ty; - } else if (isunion(ty)) { - if (t == '{') { - t = gettok(); - n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1); - initend(lev, follow); - } else { - if (lev == 0) - error("missing { in initialization of `%t'\n", ty); - n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1); - } - } else if (isstruct(ty)) { - if (t == '{') { - t = gettok(); - n = initstruct(0, ty, lev + 1); - test('}', follow); - } else if (lev > 0) - n = initstruct(ty->size, ty, lev + 1); - else { - error("missing { in initialization of `%t'\n", ty); - n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1); - } - } - if (isarray(ty)) - aty = unqual(ty->type); - if (isarray(ty) && ischar(aty)) { - if (t == SCON) { - if (ty->size > 0 && ty->size == tsym->type->size - 1) - tsym->type = array(chartype, ty->size, 0); - n = tsym->type->size; - (*IR->defstring)(tsym->type->size, tsym->u.c.v.p); - t = gettok(); - } else if (t == '{') { - t = gettok(); - if (t == SCON) { - ty = initializer(ty, lev + 1); - initend(lev, follow); - return ty; - } - n = initchar(0, aty); - test('}', follow); - } else if (lev > 0 && ty->size > 0) - n = initchar(ty->size, aty); - else { /* eg, char c[] = 0; */ - error("missing { in initialization of `%t'\n", ty); - n = initchar(1, aty); - } - } else if (isarray(ty)) { - if (t == SCON && aty == widechar) { - int i; - unsigned int *s = tsym->u.c.v.p; - if (ty->size > 0 && ty->size == tsym->type->size - widechar->size) - tsym->type = array(widechar, ty->size/widechar->size, 0); - n = tsym->type->size; - for (i = 0; i < n; i += widechar->size) { - Value v; - v.u = *s++; - (*IR->defconst)(widechar->op, widechar->size, v); - } - t = gettok(); - } else if (t == '{') { - t = gettok(); - if (t == SCON && aty == widechar) { - ty = initializer(ty, lev + 1); - initend(lev, follow); - return ty; - } - n = initarray(0, aty, lev + 1); - test('}', follow); - } else if (lev > 0 && ty->size > 0) - n = initarray(ty->size, aty, lev + 1); - else { - error("missing { in initialization of `%t'\n", ty); - n = initarray(aty->size, aty, lev + 1); - } - } - if (ty->size) { - if (n > ty->size) - error("too many initializers\n"); - else if (n < ty->size) - (*IR->space)(ty->size - n); - } else if (isarray(ty) && ty->type->size > 0) - ty = array(ty->type, n/ty->type->size, 0); - else - ty->size = n; - return ty; -} - -/* swtoseg - switch to segment seg, if necessary */ -void swtoseg(int seg) { - if (curseg != seg) - (*IR->segment)(seg); - curseg = seg; -} |