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

📄 decl.c

📁 lcc,一个可变目标c语言编译器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		default: assert(0);		}	return ty;}static Symbol *parameters(Type fty) {	List list = NULL;	Symbol *params;	if (kind[t] == STATIC || istypename(t, tsym)) {		int n = 0;		Type ty1 = NULL;		for (;;) {			Type ty;			int sclass = 0;			char *id = NULL;			if (ty1 && t == ELLIPSIS) {				static struct symbol sentinel;				if (sentinel.type == NULL) {					sentinel.type = voidtype;					sentinel.defined = 1;				}				if (ty1 == voidtype)					error("illegal formal parameter types\n");				list = append(&sentinel, list);				t = gettok();				break;			}			if (!istypename(t, tsym) && t != REGISTER)				error("missing parameter type\n");			n++;			ty = dclr(specifier(&sclass), &id, NULL, 1);			if ( ty == voidtype && (ty1 || id)			||  ty1 == voidtype)				error("illegal formal parameter types\n");			if (id == NULL)				id = stringd(n);			if (ty != voidtype)				list = append(dclparam(sclass, id, ty, &src), list);			if (Aflag >= 1 && !hasproto(ty))				warning("missing prototype\n");			if (ty1 == NULL)				ty1 = ty;			if (t != ',')				break;			t = gettok();		}		fty->u.f.proto = newarray(length(list) + 1,			sizeof (Type *), PERM);		params = ltov(&list, FUNC);		for (n = 0; params[n]; n++)			fty->u.f.proto[n] = params[n]->type;		fty->u.f.proto[n] = NULL;		fty->u.f.oldstyle = 0;	} else {		if (t == ID)			for (;;) {				Symbol p;				if (t != ID) {					error("expecting an identifier\n");					break;				}				p = dclparam(0, token, inttype, &src);				p->defined = 0;				list = append(p, list);				t = gettok();				if (t != ',')					break;				t = gettok();			}		params = ltov(&list, FUNC);		fty->u.f.proto = NULL;		fty->u.f.oldstyle = 1;	}	if (t != ')') {		static char stop[] = { CHAR, STATIC, IF, ')', 0 };		expect(')');		skipto('{', stop);	}	if (t == ')')		t = gettok();	return params;}static void exitparams(Symbol params[]) {	assert(params);	if (params[0] && !params[0]->defined)		error("extraneous old-style parameter list\n");	if (level > PARAM)		exitscope();	exitscope();}static Symbol dclparam(int sclass, char *id, Type ty, Coordinate *pos) {	Symbol p;	if (isfunc(ty))		ty = ptr(ty);	else if (isarray(ty))		ty = atop(ty);	if (sclass == 0)		sclass = AUTO;	else if (sclass != REGISTER) {		error("invalid storage class `%k' for `%t%s\n",			sclass, ty, stringf(id ? " %s'" : "' parameter", id));		sclass = AUTO;	} else if (isvolatile(ty) || isstruct(ty)) {		warning("register declaration ignored for `%t%s\n",			ty, stringf(id ? " %s'" : "' parameter", id));		sclass = AUTO;	}	p = lookup(id, identifiers);	if (p && p->scope == level)		error("duplicate declaration for `%s' previously declared at %w\n", id, &p->src);	else		p = install(id, &identifiers, level, FUNC);	p->sclass = sclass;	p->src = *pos;	p->type = ty;	p->defined = 1;	if (t == '=') {		error("illegal initialization for parameter `%s'\n", id);		t = gettok();		(void)expr1(0);	}	return p;}static Type structdcl(int op) {	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 stop[] = { IF, ',', 0 };		ty = newstruct(op, tag);		ty->u.sym->src = pos;		ty->u.sym->defined = 1;		t = gettok();		if (istypename(t, tsym))			fields(ty);		else			error("invalid %k field declarations\n", op);		test('}', stop);	}	else if (*tag && (p = lookup(tag, types)) != NULL	&& p->type->op == op) {		ty = p->type;		if (t == ';' && p->scope < level)			ty = newstruct(op, tag);	}	else {		if (*tag == 0)			error("missing %k tag\n", op);		ty = newstruct(op, tag);	}	if (*tag && xref)		use(ty->u.sym, pos);	return ty;}static void fields(Type ty) {	{ int n = 0;	  while (istypename(t, tsym)) {	  	static char stop[] = { IF, CHAR, '}', 0 };	  	Type ty1 = specifier(NULL);	  	for (;;) {	  		Field p;	  		char *id = NULL;	  		Type fty = dclr(ty1, &id, NULL, 0);			p = newfield(id, ty, fty);			if (Aflag >= 1 && !hasproto(p->type))				warning("missing prototype\n");			if (t == ':') {				if (unqual(p->type) != inttype				&&  unqual(p->type) != unsignedtype) {					error("`%t' is an illegal bit-field type\n",						p->type);					p->type = inttype;				}				t = gettok();				p->bitsize = intexpr(0, 0);				if (p->bitsize > 8*inttype->size || p->bitsize < 0) {					error("`%d' is an illegal bit-field size\n",						p->bitsize);					p->bitsize = 8*inttype->size;				} else if (p->bitsize == 0 && id) {					warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id);					p->name = stringd(genlabel(1));				}				p->lsb = 1;			}			else {				if (id == NULL)					error("field name missing\n");				else if (isfunc(p->type))					error("`%t' is an illegal field type\n", p->type);				else if (p->type->size == 0)					error("undefined size for field `%t %s'\n",						p->type, id);			}			if (isconst(p->type))				ty->u.sym->u.s.cfields = 1;			if (isvolatile(p->type))				ty->u.sym->u.s.vfields = 1;	  		n++;	  		if (Aflag >= 2 && n == 128)	  			warning("more than 127 fields in `%t'\n", ty);	  		if (t != ',')	  			break;	  		t = gettok();	  	}	  	test(';', stop);	  } }	{ int bits = 0, off = 0, overflow = 0;	  Field p, *q = &ty->u.sym->u.s.flist;	  ty->align = IR->structmetric.align;	  for (p = *q; p; p = p->link) {	  	int a = p->type->align ? p->type->align : 1;		if (p->lsb)			a = unsignedtype->align;		if (ty->op == UNION)			off = bits = 0;		else if (p->bitsize == 0 || bits == 0		|| bits - 1 + p->bitsize > 8*unsignedtype->size) {			off = add(off, bits2bytes(bits-1));			bits = 0;			chkoverflow(off, a - 1);			off = roundup(off, a);		}		if (a > ty->align)			ty->align = a;		p->offset = off;		if (p->lsb) {			if (bits == 0)				bits = 1;			if (IR->little_endian)				p->lsb = bits;			else				p->lsb = 8*unsignedtype->size - bits + 1					- p->bitsize + 1;			bits += p->bitsize;		} else			off = add(off, p->type->size);		if (off + bits2bytes(bits-1) > ty->size)			ty->size = off + bits2bytes(bits-1);	  	if (p->name == NULL	  	|| !('1' <= *p->name && *p->name <= '9')) {	  		*q = p;	  		q = &p->link;	  	}	  }	  *q = NULL;	  chkoverflow(ty->size, ty->align - 1);	  ty->size = roundup(ty->size, ty->align);	  if (overflow) {	  	error("size of `%t' exceeds %d bytes\n", ty, inttype->u.sym->u.limits.max.i);	  	ty->size = inttype->u.sym->u.limits.max.i&(~(ty->align - 1));	  } }}static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt) {	int i, n;	Symbol *callee, *caller, p;	Type rty = freturn(ty);	if (isstruct(rty) && rty->size == 0)		error("illegal use of incomplete type `%t'\n", rty);	for (n = 0; params[n]; n++)		;	if (n > 0 && params[n-1]->name == NULL)		params[--n] = NULL;	if (Aflag >= 2 && n > 31)		warning("more than 31 parameters in function `%s'\n", id);	if (ty->u.f.oldstyle) {		if (Aflag >= 1)			warning("old-style function definition for `%s'\n", id);		caller = params;		callee = newarray(n + 1, sizeof *callee, FUNC);		memcpy(callee, caller, (n+1)*sizeof *callee);		enterscope();		assert(level == PARAM);		while (kind[t] == STATIC || istypename(t, tsym))			decl(dclparam);		foreach(identifiers, PARAM, oldparam, callee);		for (i = 0; (p = callee[i]) != NULL; i++) {			if (!p->defined)				callee[i] = dclparam(0, p->name, inttype, &p->src);			*caller[i] = *p;			caller[i]->sclass = AUTO;			caller[i]->type = promote(p->type);		}		p = lookup(id, identifiers);		if (p && p->scope == GLOBAL && isfunc(p->type)		&& p->type->u.f.proto) {			Type *proto = p->type->u.f.proto;			for (i = 0; caller[i] && proto[i]; i++) {				Type ty = unqual(proto[i]);				if (eqtype(isenum(ty) ? ty->type : ty,					unqual(caller[i]->type), 1) == 0)					break;				else if (isenum(ty) && !isenum(unqual(caller[i]->type)))					warning("compatibility of `%t' and `%t' is compiler dependent\n",						proto[i], caller[i]->type);			}			if (proto[i] || caller[i])				error("conflicting argument declarations for function `%s'\n", id);		}		else {			Type *proto = newarray(n + 1, sizeof *proto, PERM);			if (Aflag >= 1)				warning("missing prototype for `%s'\n", id);			for (i = 0; i < n; i++)				proto[i] = caller[i]->type;			proto[i] = NULL;			ty = func(rty, proto, 1);		}	} else {		callee = params;		caller = newarray(n + 1, sizeof *caller, FUNC);		for (i = 0; (p = callee[i]) != NULL && p->name; i++) {			NEW(caller[i], FUNC);			*caller[i] = *p;			if (isint(p->type))				caller[i]->type = promote(p->type);			caller[i]->sclass = AUTO;			if ('1' <= *p->name && *p->name <= '9')				error("missing name for parameter %d to function `%s'\n", i + 1, id);		}		caller[i] = NULL;	}	for (i = 0; (p = callee[i]) != NULL; i++)		if (p->type->size == 0) {			error("undefined size for parameter `%t %s'\n",				p->type, p->name);			caller[i]->type = p->type = inttype;		}	if (Aflag >= 2 && sclass != STATIC && strcmp(id, "main") == 0) {		if (ty->u.f.oldstyle)			warning("`%t %s()' is a non-ANSI definition\n", rty, id);		else if (!(rty == inttype			&& (n == 0 && callee[0] == NULL			||  n == 2 && callee[0]->type == inttype			&& isptr(callee[1]->type) && callee[1]->type->type == charptype			&& !variadic(ty))))			warning("`%s' is a non-ANSI definition\n", typestring(ty, id));	}	p = lookup(id, identifiers);	if (p && isfunc(p->type) && p->defined)		error("redefinition of `%s' previously defined at %w\n",			p->name, &p->src);	cfunc = dclglobal(sclass, id, ty, &pt);	cfunc->u.f.label = genlabel(1);	cfunc->u.f.callee = callee;	cfunc->u.f.pt = src;	cfunc->defined = 1;	if (xref)		use(cfunc, cfunc->src);	if (Pflag)		printproto(cfunc, cfunc->u.f.callee);	if (ncalled >= 0)		ncalled = findfunc(cfunc->name, pt.file);	labels   = table(NULL, LABELS);	stmtlabs = table(NULL, LABELS);	refinc = 1.0;	regcount = 0;	codelist = &codehead;	codelist->next = NULL;	if (!IR->wants_callb && isstruct(rty))		retv = genident(AUTO, ptr(unqual(rty)), PARAM);	compound(0, NULL, 0);	definelab(cfunc->u.f.label);	if (events.exit)		apply(events.exit, cfunc, NULL);	walk(NULL, 0, 0);	exitscope();	assert(level == PARAM);

⌨️ 快捷键说明

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