⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 lcc,一个可变目标c语言编译器的源码
💻 C
字号:
#include "c.h"static char rcsid[] = "$Id: init.c,v 1.1 2002/08/28 23:12:43 drh Exp $";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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -