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

📄 decl.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 3 页
字号:
		t = '*';
		goto restart;
	case STDCALL:
		t = gettok();
		*attributes = STDCALLATTRIBUTE;
		goto restart;
	case '(':
		t = gettok();
		if (t == STDCALL) {
			t = gettok();
			*attributes = STDCALLATTRIBUTE;
		}
		else if (t == DLLIMPORT) {
			t = '*';
			*attributes = DLLIMPORTATTRIBUTE;
		}
		if (abstract
				&& (t == REGISTER || istypename(t, tsym) || t == ')')) {
			Symbol *args;
			ty = tnode(FUNCTION, ty);
			enterscope();
			if (level > PARAM)
				enterscope();
			args = parameters(ty);
			exitparams(args);
		}
		else {
			ty = dclr1(id, params, abstract, attributes);
			expect(')');
			if (abstract && ty == NULL
					&& (id == NULL || *id == NULL))
				return tnode(FUNCTION, NULL);
		} break;
	case '[':
		break;
	default:
		return ty;
	}
	while (t == '(' || t == '[')
		switch (t) {
		case '(':
			t = gettok(); {
				Symbol *args;
				ty = tnode(FUNCTION, ty);
				enterscope();
				if (level > PARAM)
					enterscope();
				args = parameters(ty);
				if (params && *params == NULL)
					*params = args;
				else
					exitparams(args);
			}
			break;
		case '[':
			t = gettok(); {
				int n = 0;
				if (kind[t] == ID) {
					n = intexpr(']', 1);
					if (n <= 0) {
						error(StrTab[323], n);// <`%d' is an illegal array size\n>
						n = 1;
					}
				}
				else
					expect(']');
				ty = tnode(ARRAY, ty);
				ty->size = n;
			} break;
		default:
			assert(0);
		}
	return ty;
}
static Symbol *parameters(Type fty)
{
	List list = NULL;
	Symbol *params;
	int callAttributes, dummy;
	Type tmpType;

	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(StrTab[324]);// <illegal formal parameter types\n>
				list = append(&sentinel, list);
				t = gettok();
				break;
			}
			if (!istypename(t, tsym) && t != REGISTER)
				error(StrTab[325]);// <missing parameter type\n>
			n++;
			tmpType = specifier(&sclass, NULL, &dummy,&dummy);
			ty = dclr(tmpType, &id, NULL, 1, &callAttributes);
			if (ty == voidtype && (ty1 || id)
					|| ty1 == voidtype)
				error(StrTab[326]);// <illegal formal parameter types\n>
			if (id == NULL)
				id = stringd(n);
			if (ty != voidtype)
				list = append(dclparam(sclass, id, ty, &src,callAttributes), list);
			if (Aflag >= 1 && !hasproto(ty))
				warning(StrTab[327]);// <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(StrTab[328]);// <expecting an identifier\n>
					break;
				}
				p = dclparam(0, token, inttype, &src,callAttributes);
				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(StrTab[329]);// <extraneous old-style parameter list\n>
	if (level > PARAM)
		exitscope();
	exitscope();
}

static Symbol dclparam(int sclass, char *id, Type ty, Coordinate * pos,int callAttributes)
{
	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(StrTab[330],// <invalid storage class `%k' for `%t%s\n>
			sclass, ty, stringf(id ? " %s'" : StrTab[331], id));// <' parameter>
		sclass = AUTO;
	}
	else if (isvolatile(ty) || isstruct(ty)) {
		warning(StrTab[332],// <register declaration ignored for `%t%s\n>
				ty, stringf(id ? " %s'" : StrTab[333], id));// <' parameter>
		sclass = AUTO;
	}

	p = lookup(id, identifiers);
	if (p && p->scope == level)
		error(StrTab[334], id, &p->src);// <duplicate declaration for `%s' previously declared at %w\n>

	else
		p = install(id, &identifiers, level, FUNC);
	p->sclass = sclass;
	p->src = *pos;
	p->type = ty;
	p->defined = 1;
	if (t == '=') {
		error(StrTab[335], id);// <illegal initialization for parameter `%s'\n>
		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(StrTab[336], op);// <invalid %k field declarations\n>
		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(StrTab[337], op);// <missing %k tag\n>
		ty = newstruct(op, tag);
	}
	if (*tag && xref)
		use(ty->u.sym, pos);
	return ty;
}
static void fields(Type ty)
{
	{
		int n = 0;
		int callAttributes;
		int dummy;

		while (istypename(t, tsym)) {
			static char stop[] = {IF, CHAR, '}', 0};
			Type ty1 = specifier(NULL, NULL, &callAttributes,&dummy);
			for (;;) {
				Field p;
				char *id = NULL;

				Type fty = dclr(ty1, &id, NULL, 0, &dummy);
				p = newfield(id, ty, fty);
				if (Aflag >= 1 && !hasproto(p->type)) {
					if (id)
						warning(StrTab[338], id);// <missing prototype for %s\n>
					else
						warning(StrTab[339]);// <missing prototype\n>
				}
				if (t == ':') {
					if (unqual(p->type) != inttype
							&& unqual(p->type) != unsignedtype) {
						if (unqual(p->type) != unsignedshort
								&& unqual(p->type) != unsignedlong)
							error(StrTab[340],// <`%t' is an illegal bit-field type\n>
								p->type);
						else if (Aflag > 1)
							warning(StrTab[341], p->type);// <promoting %t to int\n>
						p->type = inttype;
					}
					t = gettok();
					p->bitsize = (short)intexpr(0, 0);
					if (p->bitsize > 8 * inttype->size || p->bitsize < 0) {
						error(StrTab[342],// <`%d' is an illegal bit-field size\n>
							p->bitsize);
						p->bitsize = (short)(8 * inttype->size);
					}
					else if (p->bitsize == 0 && id) {
						warning(StrTab[343], p->type, id);// <extraneous 0-width bit field `%t %s' ignored\n>

						p->name = stringd(genlabel(1));
					}
					p->lsb = 1;
				}
				else if (id == NULL && Xflag && isstruct(p->type)) {
					if (Aflag >= 2)
						warning(StrTab[344], ty);// <non-ANSI unnamed substructure in `%t'\n>
					if (p->type->size == 0)
						error(StrTab[345], p->type);// <undefined size for field `%t'\n>
					p->name = NULL;
					break;
				}
				else {
					if (id == 0 && isstruct(p->type)) {
						if (Aflag >= 2)
							warning(StrTab[346]);// <non-ANSI unnamed substructure\n>
						if (p->type->size == 0)
							error(StrTab[347],p->type);// <undefined size for field '%t'\n>
						p->name = 0;
						break;
					}
					else if (isfunc(p->type))
						error(StrTab[348], p->type);// <`%t' is an illegal field type\n>
					else if (p->type->size == 0) {

						warning(StrTab[349], p->type, id);// <undefined size for field `%t %s'\n>
						p->type->size = p->type->align;
					}
				}
				if (isconst(p->type))
					ty->u.sym->u.s.cfields = 1;
				if (isvolatile(p->type))
					ty->u.sym->u.s.vfields = 1;
				if (dummy) {
					if (fty->op == POINTER) {
						if (fty->type->op != FUNCTION)
							error(StrTab[350]);// <incorrect _stdcall usage>
						else
							fty->type->u.f.isStdCall = 1;
					}
					else
						fty->u.f.isStdCall = 1;
				}
				n++;
				if (Aflag >= 2 && n == 128)
					warning(StrTab[351], ty);// <more than 127 fields in `%t'\n>
				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 (a > DefaultAlignment) a = DefaultAlignment;
			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 = (short)bits;
				else
					p->lsb = (short)(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(StrTab[352], ty, INT_MAX);// <size of `%t' exceeds %d bytes\n>
			ty->size = INT_MAX & (~(ty->align - 1));
		}
		if (Xflag)
			checkfields(ty);
	}
}
static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt, int callAttributes)
{
	int i, n;
	Symbol *callee, *caller, p;
	Type rty = freturn(ty);
	Code cp;

	if (isstruct(rty) && rty->size == 0)
		error(StrTab[353], rty);// <illegal use of incomplete type `%t'\n>
	memset(&FunctionInfo,0,sizeof(FunctionInfo));
	StatementCount = 1;
	hasAllocA = 0;
	for (n = 0; params[n]; n++);
	if (n > 0 && params[n - 1]->name == NULL)
		params[--n] = NULL;
	if (Aflag >= 2 && n > 31)
		warning(StrTab[354], id);// <more than 31 parameters in function `%s'\n>
	for (i=0; i<n;i++) {
		params[i]->firstuse = StatementCount;
		params[i]->x.isArgument = 1;
	}
	StatementCount++;
	FunctionNodes = 0;
	if (ty->u.f.oldstyle) {
		if (Aflag >= 1)
			warning(StrTab[429],id); // <old style function definition for %s\n>
		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,0);
			*caller[i] = *p;
			caller[i]->sclass = AUTO;
			if (unqual(p->type) == floattype)
				caller[i]->type = doubletype;
			else
				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;
			}
			if (proto[i] || caller[i])
				error(StrTab[355], id);// <conflicting argument declarations for function `%s'\n>

		}
		else {
			Type *proto = newarray(n + 1, sizeof *proto, PERM);
			if (Aflag >= 1)
				warning(StrTab[356], id);// <missing prototype for `%s'\n>
			for (i = 0; i < n; i++)
				proto[i] = caller[i]->type;
			proto[i] = NULL;
			ty = func(rty, proto, 1);
		}
		for (i=0; i < n; i++) {
			callee[i]->x.isArgument = 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;
			caller[i]->type = promote(p->type);
			caller[i]->sclass = AUTO;
			if ('1' <= *p->name && *p->name <= '9')
				error(StrTab[357], i + 1, id);// <missing name for parameter %d to function `%s'\n>

		}
		caller[i] = NULL;
	}
	for (i = 0; (p = callee[i]) != NULL; i++)
		if (p->type->size == 0) {
			error(StrTab[358],// <undefined size for parameter `%t %s'\n>
				p->type, p->name);
			caller[i]->type = p->type = inttype;
		}
	if (Aflag >= 1 && sclass != STATIC && strcmp(id, "main") == 0) {
		if (ty->u.f.oldstyle)
                warning(StrTab[430], rty, id); // <`%t %s()' is a non-ANSI definition\n>
        else if (!(rty == inttype
                && (n == 0 && callee[0] == NULL
                ||  n == 2 && callee[0]->type == inttype
                && isptr(callee[1]->type) && callee[1]->type->type == ptr(chartype)
                && !variadic(ty))))
                warning(StrTab[431], typestring(ty, id)); // <`%s' is a non-ANSI definition\n>
	}
	p = lookup(id, identifiers);
	if (p && isfunc(p->type) && p->defined)
		error(StrTab[359],// <redefinition of `%s' previously defined at %w\n>
			p->name, &p->src);
	cfunc = dclglobal(sclass, id, ty, &pt, callAttributes);
	cfunc->u.f.label = genlabel(1);
	cfunc->u.f.callee = callee;
	cfunc->u.f.pt = src;
	cfunc->defined = 1;
	cfunc->Flags = (unsigned char)callAttributes;
	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 = (float) 1.0;
	regcount = 0;
	codelist = &codehead;
	codelist->next = NULL;
	definept(NULL,POINT_STARTFN);
	if (!IR->wants_callb && isstruct(rty))

⌨️ 快捷键说明

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