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

📄 decl.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 3 页
字号:
		retv = genident(AUTO, ptr(rty), PARAM);
	cp = compound(0, NULL, 0);
	FunctionInfo.cp = cp;
	for (cp = codelist; cp->kind < Label; cp = cp->prev);
	if (cp->kind != Jump) {
		if (rty != voidtype
				&& (rty != inttype || Aflag >= 1))
			warning(StrTab[360]);// <missing return value\n>
		retcode(NULL);
	}
	definelab(cfunc->u.f.label);
	definept(NULL,POINT_ENDFN);
	if (events.exit)
		apply(events.exit, cfunc, NULL);
	walk(NULL, 0, 0);
	exitscope();
	assert(level == PARAM);
	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 0
	if (cfunc->sclass != STATIC)
		(*IR->export) (cfunc);
#endif
	if (glevel) {
		swtoseg(CODE);
		(*IR->stabsym) (cfunc);
	}
	swtoseg(CODE);
	if (cfunc->u.f.ncalls)
		FunctionHasCalls = 1;
	else
		FunctionHasCalls = 0;
	FunctionInfo.FnNrOfLines = src.y - cfunc->src.y;

	(*IR->function) (cfunc, caller, callee, cfunc->u.f.ncalls);
	if (cfunc->sclass != STATIC)
		(*IR->export) (cfunc);
	if (glevel && IR->stabfend)
		(*IR->stabfend) (cfunc, lineno);
	outflush();
	foreach(stmtlabs, LABELS, checklab, NULL);
	exitscope();
	expect('}');
	AddToFunctionsList(cfunc);
	labels = stmtlabs = NULL;
	retv = NULL;
	cfunc = NULL;
	ResetExceptions();
}
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(StrTab[362], p->name);// <declared parameter `%s' is missing\n>
}
Code compound(int loop, struct swtch * swp, int lev)
{
	Code cp;
	int nregs;

	walk(NULL, 0, 0);
	cp = code(Blockbeg);
	enterscope();
	assert(level >= LOCAL);
	autos = registers = NULL;
	if (level == LOCAL && IR->wants_callb
			&& isstruct(freturn(cfunc->type))) {
		retv = genident(AUTO, ptr(freturn(cfunc->type)), level);
		retv->defined = 1;
		retv->ref = (float) 1.0;
		registers = append(retv, registers);
	}
	if (level == LOCAL && events.entry)
		apply(events.entry, cfunc, NULL);
	expect('{');
	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);
	}
	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;
		}
	}
	cp->u.block.level = level;
	cp->u.block.identifiers = identifiers;
	cp->u.block.types = types;
	code(Blockend)->u.begin = cp;
	if (level > LOCAL) {
		exitscope();
		expect('}');
	}
	return cp;
}
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(StrTab[363],// <static `%t %s' is not referenced\n>
					p->type, p->name);
		else if (p->scope == PARAM && Aflag > 1)
			warning(StrTab[364],// <parameter `%t %s' is not referenced\n>
					p->type, p->name);
		else if (p->scope >= LOCAL && p->sclass != EXTERN)
			warning(StrTab[365],// <local `%t %s' is not referenced\n>
					p->type, p->name);
	}
	if (p->scope >= LOCAL && p->sclass == EXTERN) {
		Symbol q = lookup(p->name, externals);
		assert(q);
		q->ref += p->ref;
	}
	if (p->scope >= LOCAL && p->sclass != EXTERN ) {

		if (Aflag &&
			p->assigned == 1 && p->references == 1 && p->addressed == 0) {
			warning(StrTab[366],p->name);// < %s is assigned a value that is never used\n>
		}
		else if (p->assigned == 0 && p->references > 0) {
			if (p->type && p->type->op != ARRAY && p->type->op != STRUCT)
			warning(StrTab[367],p->name);// < possible usage of %s before definition\n>
		}
	}
	if (level == GLOBAL && p->sclass == STATIC && !p->defined
			&& isfunc(p->type) && p->ref)
		error(StrTab[368], p->type, p->name);// <undefined static `%t %s'\n>
	assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));
}
static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate * pos,int callAttributes)
{
	Symbol p, q;

	if (sclass == 0)
		sclass = isfunc(ty) ? EXTERN : AUTO;
	else if (isfunc(ty) && sclass != EXTERN) {
		error(StrTab[369],// <invalid storage class `%k' for `%t %s'\n>
			sclass, ty, id);
		sclass = EXTERN;
	}
	else if (sclass == REGISTER
			&& (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
		warning(StrTab[370],// <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(StrTab[371], q->name, &q->src);// <redeclaration of `%s' previously declared at %w\n>

	assert(level >= LOCAL);
	p = install(id, &identifiers, level, FUNC);
	p->type = ty;
	p->sclass = sclass;
	p->src = *pos;
	p->Flags = callAttributes;
	switch (sclass) {
	case EXTERN:
		if (q && q->scope == GLOBAL && q->sclass == STATIC) {
			p->sclass = STATIC;
			p->scope = GLOBAL;
			(*IR->defsymbol) (p);
			p->sclass = EXTERN;
			p->scope = level;
		}
		else
			(*IR->defsymbol) (p);
		{
			Symbol r = lookup(id, externals);
			if (r == NULL) {
				r = install(p->name, &externals, GLOBAL, PERM);
				r->src = p->src;
				r->type = p->type;
				r->sclass = p->sclass;
				q = lookup(id, globals);
				if (q && q->sclass != TYPEDEF && q->sclass != ENUM)
					r = q;
			}
			if (r && !eqtype(r->type, p->type, 1))
				warning(StrTab[372], r->name, &r->src);// <declaration of `%s' does not match previous declaration at %w\n>

		} 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(StrTab[373],// <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;
		break;
	default:
		assert(0);
	}
	if (t == '=') {
		Tree e;
		if (sclass == EXTERN)
			error(StrTab[374], id);// <illegal initialization of `extern %s'\n>
		t = gettok();
		definept(NULL,0);
		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 = (float) 1.0;
		p->firstuse = p->lastuse = StatementCount;
	}
#if 0
	else if (glevel >= 2 && OptimizeFlag == 0 
		&& ty && ty->op == POINTER && sclass == AUTO) {
		/* Initialize all uninitialized pointers to a known value */
		Tree e = tree(CNSTP, inttype, NULL, NULL);
		int wasAssigned = p->assigned;
		e->u.v.i = 0xffbadbad;
		walk(root(asgn(p,e)),0,0);
		p->assigned = wasAssigned;
	}
#endif
	if (!isfunc(p->type) && p->defined && p->type->size <= 0)
		error(StrTab[375], p->type, id);// <undefined size for `%t %s'\n>
	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)
{
	Symbol q = lookup(p->name, identifiers);

	if (q)
		q->ref += p->ref;
	else {
		(*IR->defsymbol) (p);
		(*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(StrTab[376],// <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))
			(*IR->defstring) (p->type->size, p->u.c.v.p,p->type->type->size);
		else
			(*IR->defconst) (ttob(p->type), p->u.c.v);
		p->u.c.loc->defined = 1;
		p->u.c.loc = NULL;
	}
}
void checklab(Symbol p, void *cl)
{
	if (!p->defined)
		error(StrTab[377], p->name);// <undefined label `%s'\n>
	p->defined = 1;
}

Type enumdcl(void)
{
	char *tag;
	Type ty;
	Symbol p;
	Coordinate pos;

	t = gettok();
	pos = src;
	p = NULL;           /* Better be sure that p is initialized before use */
	if (t == ID) {
		tag = token;
		t = gettok();
	}
	else
		tag = "";
	if (t == '{') {
		static char follow[] = {IF, 0};
		int n = 0, k = -1;
		List idlist = 0;
		ty = newstruct(ENUM, tag);
		t = gettok();
		if (t != ID)
			error(StrTab[378]);// <expecting an enumerator identifier\n>
		while (t == ID) {
			char *id = token;
			Coordinate s;
			if (tsym && tsym->scope == level)
				error(StrTab[379],// <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 == INT_MAX)
					error(StrTab[380], id);// <overflow in value for enumeration constant `%s'\n>
				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(StrTab[381], ty);// <more than 127 enumeration constants in `%t'\n>
			if (t != ',')
				break;
			t = gettok();
			if (Aflag >= 2 && t == '}')
				warning(StrTab[382]);// <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(StrTab[383]);// <empty declaration\n>
	}
	else {
		error(StrTab[384], tag);// <unknown enumeration `%s'\n>
		ty = newstruct(ENUM, tag);
		ty->type = inttype;
	}
	if (*tag && xref)
		use(p, pos);
	return ty;
}

Type typename(void)
{
	int callAttributes = 0,dllExport=0;
	Type ty = specifier(NULL, NULL, &callAttributes,&dllExport);

	if (t == '*' || t == '(' || t == '[') {
		ty = dclr(ty, NULL, NULL, 1, &callAttributes);
		if (Aflag >= 1 && !hasproto(ty))
			warning(StrTab[385]);// <missing prototype\n>
	}
	return ty;
}

void DumpCalledFunctions(DefinedFunctionsList *rvp)
{
	int i = 0;
	Symbol s;

	Symbol *calledFnTab = rvp->FunctionInfo.CalledFunctions;
	while (calledFnTab[i]) {
		s = (Symbol)calledFnTab[i];
		fprintf(xrefFile,"%s ",s->name);
		i++;
	}
	fprintf(xrefFile,"\n");
}

void DumpDefinedFunctions(void)
{
	DefinedFunctionsList *rvp;

	rvp = DefinedFunctions;
	while (rvp) {
		if (rvp->func->scope == GLOBAL && rvp->func->sclass != STATIC) {
			fprintf(xrefFile,"e %s %d\n",rvp->func->name,rvp->func->src.y);
			DumpCalledFunctions(rvp);
		}
		rvp = rvp->Next;
	}
	rvp = DefinedFunctions;
	while (rvp) {
		if (rvp->func->sclass == STATIC) {
			fprintf(xrefFile,"s %s %d\n",rvp->func->name,rvp->func->src.y);
			DumpCalledFunctions(rvp);
		}
		rvp = rvp->Next;
	}
}

void CheckStaticUses(void)
{

	DefinedFunctionsList *rvp;

	rvp = DefinedFunctions;
	return;
	while (rvp) {
		if (rvp->func->sclass == STATIC) {
			if (rvp->func->x.callused == 0 && rvp->func->ref == 0.0) {
				warning(StrTab[386],rvp->func->name);// <static function %s is never used\n>
			}
		}
		rvp = rvp->Next;
	}
}

int GetLastFunctionLabel(void)
{
	return cfunc->u.f.label;
}

⌨️ 快捷键说明

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