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

📄 decl.c

📁 lcc,一个可变目标c语言编译器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	foreach(identifiers, level, checkref, NULL);	if (!IR->wants_callb && isstruct(rty)) {		Symbol *a;		a = newarray(n + 2, sizeof *a, FUNC);		a[0] = retv;		memcpy(&a[1], callee, (n+1)*sizeof *callee);		callee = a;		a = newarray(n + 2, sizeof *a, FUNC);		NEW(a[0], FUNC);		*a[0] = *retv;		memcpy(&a[1], caller, (n+1)*sizeof *callee);		caller = a;	}	if (!IR->wants_argb)		for (i = 0; caller[i]; i++)			if (isstruct(caller[i]->type)) {				caller[i]->type = ptr(caller[i]->type);				callee[i]->type = ptr(callee[i]->type);				caller[i]->structarg = callee[i]->structarg = 1;			}	if (glevel > 1)	for (i = 0; callee[i]; i++) callee[i]->sclass = AUTO;	if (cfunc->sclass != STATIC)		(*IR->export)(cfunc);	if (glevel && IR->stabsym) {		swtoseg(CODE); (*IR->stabsym)(cfunc); }	swtoseg(CODE);	(*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);	if (glevel && IR->stabfend)		(*IR->stabfend)(cfunc, lineno);	foreach(stmtlabs, LABELS, checklab, NULL);	exitscope();	expect('}');	labels = stmtlabs = NULL;	retv  = NULL;	cfunc = NULL;}static void oldparam(Symbol p, void *cl) {	int i;	Symbol *callee = cl;	for (i = 0; callee[i]; i++)		if (p->name == callee[i]->name) {			callee[i] = p;			return;		}	error("declared parameter `%s' is missing\n", p->name);}void compound(int loop, struct swtch *swp, int lev) {	Code cp;	int nregs;	walk(NULL, 0, 0);	cp = code(Blockbeg);	enterscope();	assert(level >= LOCAL);	if (level == LOCAL && events.entry)		apply(events.entry, cfunc, NULL);	definept(NULL);	expect('{');	autos = registers = NULL;	if (level == LOCAL && IR->wants_callb	&& isstruct(freturn(cfunc->type))) {		retv = genident(AUTO, ptr(unqual(freturn(cfunc->type))), level);		retv->defined = 1;		retv->ref = 1;		registers = append(retv, registers);	}	while (kind[t] == CHAR || kind[t] == STATIC	|| istypename(t, tsym) && getchr() != ':')		decl(dcllocal);	{		int i;		Symbol *a = ltov(&autos, STMT);		nregs = length(registers);		for (i = 0; a[i]; i++)			registers = append(a[i], registers);		cp->u.block.locals = ltov(&registers, FUNC);	}	if (events.blockentry)		apply(events.blockentry, cp->u.block.locals, NULL);	while (kind[t] == IF || kind[t] == ID)		statement(loop, swp, lev);	walk(NULL, 0, 0);	foreach(identifiers, level, checkref, NULL);	{		int i = nregs, j;		Symbol p;		for ( ; (p = cp->u.block.locals[i]) != NULL; i++) {			for (j = i; j > nregs				&& cp->u.block.locals[j-1]->ref < p->ref; j--)				cp->u.block.locals[j] = cp->u.block.locals[j-1];			cp->u.block.locals[j] = p;		}	}	if (level == LOCAL) {		Code cp;		for (cp = codelist; cp->kind < Label; cp = cp->prev)			;		if (cp->kind != Jump) {			if (freturn(cfunc->type) != voidtype) {				warning("missing return value\n");				retcode(cnsttree(inttype, 0L));			} else				retcode(NULL);		}	}	if (events.blockexit)		apply(events.blockexit, cp->u.block.locals, NULL);	cp->u.block.level = level;	cp->u.block.identifiers = identifiers;	cp->u.block.types = types;	code(Blockend)->u.begin = cp;	if (reachable(Gen))		definept(NULL);	if (level > LOCAL) {		exitscope();		expect('}');	}}static void checkref(Symbol p, void *cl) {	if (p->scope >= PARAM	&& (isvolatile(p->type) || isfunc(p->type)))		p->addressed = 1;	if (Aflag >= 2 && p->defined && p->ref == 0) {		if (p->sclass == STATIC)			warning("static `%t %s' is not referenced\n",				p->type, p->name);		else if (p->scope == PARAM)			warning("parameter `%t %s' is not referenced\n",				p->type, p->name);		else if (p->scope >= LOCAL && p->sclass != EXTERN)			warning("local `%t %s' is not referenced\n",				p->type, p->name);	}	if (p->sclass == AUTO	&& (p->scope  == PARAM && regcount == 0	 || p->scope  >= LOCAL)	&& !p->addressed && isscalar(p->type) && p->ref >= 3.0)		p->sclass = REGISTER;	if (level == GLOBAL && p->sclass == STATIC && !p->defined	&& isfunc(p->type) && p->ref)		error("undefined static `%t %s'\n", p->type, p->name);	assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));}static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate *pos) {	Symbol p, q;	if (sclass == 0)		sclass = isfunc(ty) ? EXTERN : AUTO;	else if (isfunc(ty) && sclass != EXTERN) {		error("invalid storage class `%k' for `%t %s'\n",			sclass, ty, id);		sclass = EXTERN;	} else if (sclass == REGISTER	&& (isvolatile(ty) || isstruct(ty) || isarray(ty))) {		warning("register declaration ignored for `%t %s'\n",			ty, id);		sclass = AUTO;	}	q = lookup(id, identifiers);	if (q && q->scope >= level	||  q && q->scope == PARAM && level == LOCAL)		if (sclass == EXTERN && q->sclass == EXTERN		&& eqtype(q->type, ty, 1))			ty = compose(ty, q->type);		else			error("redeclaration of `%s' previously declared at %w\n", q->name, &q->src);	assert(level >= LOCAL);	p = install(id, &identifiers, level, sclass == STATIC || sclass == EXTERN ? PERM : FUNC);	p->type = ty;	p->sclass = sclass;	p->src = *pos;	switch (sclass) {	case EXTERN:   q = lookup(id, globals);		       if (q == NULL || q->sclass == TYPEDEF || q->sclass == ENUM) {		       	q = lookup(id, externals);		       	if (q == NULL) {		       		q = install(p->name, &externals, GLOBAL, PERM);		       		q->type = p->type;		       		q->sclass = EXTERN;		       		q->src = src;		       		(*IR->defsymbol)(q);		       	}		       }		       if (!eqtype(p->type, q->type, 1))		       	warning("declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);		       p->u.alias = q; break;	case STATIC:   (*IR->defsymbol)(p);		       initglobal(p, 0);		       if (!p->defined)		       	if (p->type->size > 0) {		       		defglobal(p, BSS);		       		(*IR->space)(p->type->size);		       	} else		       		error("undefined size for `%t %s'\n",		       			p->type, p->name);		       p->defined = 1; break;	case REGISTER: registers = append(p, registers);		       regcount++;		       p->defined = 1; break;	case AUTO:     autos = append(p, autos);		       p->defined = 1;		       if (isarray(ty))		       	p->addressed = 1; break;	default: assert(0);	}	if (t == '=') {		Tree e;		if (sclass == EXTERN)			error("illegal initialization of `extern %s'\n", id);		t = gettok();		definept(NULL);		if (isscalar(p->type)		||  isstruct(p->type) && t != '{') {			if (t == '{') {				t = gettok();				e = expr1(0);				expect('}');			} else				e = expr1(0);		} else {			Symbol t1;			Type ty = p->type, ty1 = ty;			while (isarray(ty1))				ty1 = ty1->type;			if (!isconst(ty) && (!isarray(ty) || !isconst(ty1)))				ty = qual(CONST, ty);			t1 = genident(STATIC, ty, GLOBAL);			initglobal(t1, 1);			if (isarray(p->type) && p->type->size == 0			&& t1->type->size > 0)				p->type = array(p->type->type,					t1->type->size/t1->type->type->size, 0);			e = idtree(t1);		}		walk(root(asgn(p, e)), 0, 0);		p->ref = 1;	}	if (!isfunc(p->type) && p->defined && p->type->size <= 0)		error("undefined size for `%t %s'\n", p->type, id);	return p;}void finalize(void) {	foreach(externals,   GLOBAL,    doextern, NULL);	foreach(identifiers, GLOBAL,    doglobal, NULL);	foreach(identifiers, GLOBAL,    checkref, NULL);	foreach(constants,   CONSTANTS, doconst,  NULL);}static void doextern(Symbol p, void *cl) {	(*IR->import)(p);}static void doglobal(Symbol p, void *cl) {	if (!p->defined && (p->sclass == EXTERN	|| isfunc(p->type) && p->sclass == AUTO))		(*IR->import)(p);	else if (!p->defined && !isfunc(p->type)	&& (p->sclass == AUTO || p->sclass == STATIC)) {		if (isarray(p->type)		&& p->type->size == 0 && p->type->type->size > 0)			p->type = array(p->type->type, 1, 0);		if (p->type->size > 0) {			defglobal(p, BSS);			(*IR->space)(p->type->size);			if (glevel > 0 && IR->stabsym)				(*IR->stabsym)(p);		} else			error("undefined size for `%t %s'\n",				p->type, p->name);		p->defined = 1;	}	if (Pflag	&& !isfunc(p->type)	&& !p->generated && p->sclass != EXTERN)		printdecl(p, p->type);}void doconst(Symbol p, void *cl) {	if (p->u.c.loc) {		assert(p->u.c.loc->u.seg == 0); 		defglobal(p->u.c.loc, LIT);		if (isarray(p->type) && p->type->type == widechar) {			unsigned int *s = p->u.c.v.p;			int n = p->type->size/widechar->size;			while (n-- > 0) {				Value v;				v.u = *s++;				(*IR->defconst)(widechar->op, widechar->size, v);			}		} else if (isarray(p->type))			(*IR->defstring)(p->type->size, p->u.c.v.p);		else			(*IR->defconst)(p->type->op, p->type->size, p->u.c.v);		p->u.c.loc = NULL;	}}void checklab(Symbol p, void *cl) {	if (!p->defined)		error("undefined label `%s'\n", p->name);	p->defined = 1;}Type enumdcl(void) {	char *tag;	Type ty;	Symbol p;	Coordinate pos;	t = gettok();	pos = src;	if (t == ID) {		tag = token;		t = gettok();	} else		tag = "";	if (t == '{') {		static char follow[] = { IF, 0 };		int n = 0;		long k = -1;		List idlist = 0;		ty = newstruct(ENUM, tag);		t = gettok();		if (t != ID)			error("expecting an enumerator identifier\n");		while (t == ID) {			char *id = token;			Coordinate s;			if (tsym && tsym->scope == level)				error("redeclaration of `%s' previously declared at %w\n",					token, &tsym->src);			s = src;			t = gettok();			if (t == '=') {				t = gettok();				k = intexpr(0, 0);			} else {				if (k == inttype->u.sym->u.limits.max.i)					error("overflow in value for enumeration constant `%s'\n", id);				k++;			}			p = install(id, &identifiers, level,  level < LOCAL ? PERM : FUNC);			p->src = s;			p->type = ty;			p->sclass = ENUM;			p->u.value = k;			idlist = append(p, idlist);			n++;			if (Aflag >= 2 && n == 128)				warning("more than 127 enumeration constants in `%t'\n", ty);			if (t != ',')				break;			t = gettok();			if (Aflag >= 2 && t == '}')				warning("non-ANSI trailing comma in enumerator list\n");		}		test('}', follow);		ty->type = inttype;		ty->size = ty->type->size;		ty->align = ty->type->align;		ty->u.sym->u.idlist = ltov(&idlist, PERM);		ty->u.sym->defined = 1;	} else if ((p = lookup(tag, types)) != NULL && p->type->op == ENUM) {		ty = p->type;		if (t == ';')			error("empty declaration\n");	} else {		error("unknown enumeration `%s'\n",  tag);		ty = newstruct(ENUM, tag);		ty->type = inttype;	}	if (*tag && xref)		use(p, pos);	return ty;}Type typename(void) {	Type ty = specifier(NULL);	if (t == '*' || t == '(' || t == '[') {		ty = dclr(ty, NULL, NULL, 1);		if (Aflag >= 1 && !hasproto(ty))			warning("missing prototype\n");	}	return ty;}

⌨️ 快捷键说明

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