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

📄 types.c

📁 非常好的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	case C: return chartype;
	case S: return shorttype;
	case I: return inttype;
	case U: return unsignedtype;
	case P: return voidptype;
	case L: return longlongtype;
	}
	assert(0); return 0;
}
int hasproto(Type ty)
{
	if (ty == 0)
		return 1;
	switch (ty->op) {
	case CONST: case VOLATILE: case CONST+VOLATILE: case POINTER:
	case STDCALL:
	case ARRAY:
		return hasproto(ty->type);
	case FUNCTION:
		return hasproto(ty->type) && ty->u.f.proto;
	case STRUCT: case UNION:
	case CHAR:   case SHORT: case INT:  case DOUBLE:
	case VOID:   case FLOAT: case ENUM: case UNSIGNED: case LONGLONG:
		return 1;
	}
	assert(0); return 0;
}
/* check - check ty for ambiguous inherited fields, return augmented field set */
static Field check(Type ty,Type top,Field inherited,int off)
{
	Field p;

	for (p = ty->u.sym->u.s.flist; p; p = p->link)
		if (p->name && isfield(p->name, inherited))
			error(StrTab[29], p->name, top, ty);// <ambiguous field `%s' of `%t' from `%t'\n>
		else if (p->name && !isfield(p->name, top->u.sym->u.s.flist)) {
			Field new;
			NEW(new, FUNC);
			*new = *p;
			new->offset = off + p->offset;
			new->link = inherited;
			inherited = new;
		}
	for (p = ty->u.sym->u.s.flist; p; p = p->link)
		if (p->name == 0)
			inherited = check(p->type, top, inherited,
				off + p->offset);
	return inherited;
}

/* checkfields - check for ambiguous inherited fields in struct/union ty */
void checkfields(Type ty)
{
	Field p, inherited = 0;

	for (p = ty->u.sym->u.s.flist; p; p = p->link)
		if (p->name == 0)
			inherited = check(p->type, ty, inherited, p->offset);
}

/* extends - if ty extends fty, return a pointer to field structure */
Field extends(Type ty,Type fty)
{
	Field p, q;

	for (p = unqual(ty)->u.sym->u.s.flist; p; p = p->link)
		if (p->name == 0 && unqual(p->type) == unqual(fty))
			return p;
		else if (p->name == 0 && (q = extends(p->type, fty)) != NULL) {
			static struct field f;
			f = *q;
			f.offset = p->offset + q->offset;
			return &f;
		}
	return 0;
}

/* fieldlist - construct a flat list of fields in type ty */
Field fieldlist(Type ty)
{
	Field p, q, t, inherited = 0, *r;

	ty = unqual(ty);
	for (p = ty->u.sym->u.s.flist; p; p = p->link)
		if (p->name == 0)
			inherited = check(p->type, ty, inherited, p->offset);
	if (inherited == 0)
		return ty->u.sym->u.s.flist;
	for (q = 0, p = inherited; p; q = p, p = t) {
		t = p->link;
		p->link = q;
	}
	for (r = &inherited, p = ty->u.sym->u.s.flist; p && q; )
		if (p->name == 0)
			p = p->link;
		else if (p->offset <= q->offset) {
			NEW(*r, FUNC);
			**r = *p;
			r = &(*r)->link;
			p = p->link;
		} else {
			*r = q;
			r = &q->link;
			q = q->link;
		}
	for ( ; p; p = p->link)
		if (p->name) {
			NEW(*r, FUNC);
			**r = *p;
			r = &(*r)->link;
		}
	*r = q;
	return inherited;
}

/* fieldref - find field name of type ty, return entry */
Field fieldref(char *name, Type ty)
{
	Field p;

	if ((p = isfield(name, unqual(ty)->u.sym->u.s.flist)) != NULL) {
		if (xref) {
			Symbol q;
			assert(unqual(ty)->u.sym->u.s.ftab);
			q = lookup(name, unqual(ty)->u.sym->u.s.ftab);
			assert(q);
			use(q, src);
		}
		return p;
	}
	if (Xflag)
		for (p = unqual(ty)->u.sym->u.s.flist; p; p = p->link) {
			Field q;
			if (p->name == NULL && isstruct(p->type)
			&& (q = fieldref(name, p->type)) != NULL) {
				static struct field f;
				f = *q;
				f.offset = p->offset + q->offset;
				return &f;
			}
		}
	return 0;
}

/* ftype - return a function type for rty function (ty,...)' */
Type ftype(Type rty,Type ty)
{
	List list = append(ty, NULL);

	list = append(voidtype, list);
	return func(rty, ltov(&list, PERM), 0);
}

/* isfield - if name is a field in flist, return pointer to the field structure */
static Field isfield(char *name,Field flist)
{
	for ( ; flist; flist = flist->link)
		if (flist->name == name)
			break;
	return flist;
}

/* outtype - output type ty */
void outtype(Type ty)
{
	switch (ty->op) {
	case CONST+VOLATILE:
		print("%k %k %t", CONST, VOLATILE, ty->type);
		break;
	case CONST: case VOLATILE:
		print("%k %t", ty->op, ty->type);
		break;
	case STRUCT: case UNION: case ENUM:
		assert(ty->u.sym);
		if (ty->size == 0)
			print(StrTab[30]);// <incomplete >
		assert(ty->u.sym->name);
		if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') {
			Symbol p = findtype(ty);
			if (p == 0)
				print(StrTab[31], ty->op, &ty->u.sym->src);// <%k defined at %w>
			else
				print(p->name);
		} else {
			print("%k %s", ty->op, ty->u.sym->name);
			if (ty->size == 0)
				print(StrTab[32], &ty->u.sym->src);// < defined at %w>
		}
		break;
	case VOID: case FLOAT: case DOUBLE:
	case CHAR: case SHORT: case INT: case UNSIGNED:
		print(ty->u.sym->name);
		break;
	case POINTER:
		print(StrTab[33], ty->type);// <pointer to %t>
		break;
	case FUNCTION:
		print(StrTab[34], ty->type);// <%t function>
		if (ty->u.f.proto && ty->u.f.proto[0]) {
			int i;
			print("(%t", ty->u.f.proto[0]);
			for (i = 1; ty->u.f.proto[i]; i++)
				if (ty->u.f.proto[i] == voidtype)
					print(",...");
				else
					print(",%t", ty->u.f.proto[i]);
			print(")");
		} else if (ty->u.f.proto && ty->u.f.proto[0] == 0)
			print("(void)");

		break;
	case ARRAY:
		if (ty->size > 0 && ty->type && ty->type->size > 0) {
			print("array %d", ty->size/ty->type->size);
			while (ty->type && isarray(ty->type) && ty->type->type->size > 0) {
				ty = ty->type;
				print(",%d", ty->size/ty->type->size);
			}
		} else
			print(StrTab[35]);// <incomplete array>
		if (ty->type)
			print(StrTab[36], ty->type);// < of %t>
		break;
	case STDCALL:
		print(StrTab[37],ty->type);// <%t _stdcall >
		break;
	case LONGLONG:
		print(StrTab[38]);// <long long >
		break;
	default: assert(0);
	}
}

/* printdecl - output a C declaration for symbol p of type ty */
void printdecl(Symbol p, Type ty)
{
	switch (p->sclass) {
	case AUTO:
		fprint(2, StrTab[39], typestring(ty, p->name));// <%s;\n>
		break;
	case STATIC: case EXTERN:
		fprint(2, StrTab[40], p->sclass, typestring(ty, p->name));// <%k %s;\n>
		break;
	case TYPEDEF: case ENUM:
		break;
	default: assert(0);
	}
}

/* printproto - output a prototype declaration for function p */
void printproto(Symbol p,Symbol callee[])
{
	if (p->type->u.f.proto)
		printdecl(p, p->type);
	else {
		int i;
		List list = 0;
		if (callee[0] == 0)
			list = append(voidtype, list);
		else
			for (i = 0; callee[i]; i++)
				list = append(callee[i]->type, list);
		printdecl(p, func(freturn(p->type), ltov(&list, PERM), 0));
	}
}

/* printtype - print details of type ty on fd */
void printtype(Type ty,int fd)
{
	switch (ty->op) {
	case STRUCT: case UNION: {
		Field p;
		fprint(fd, StrTab[41], ty->op, ty->u.sym->name, ty->size);// <%k %s size=%d {\n>
		for (p = ty->u.sym->u.s.flist; p; p = p->link) {
			fprint(fd, StrTab[42], p->name, p->offset);// <field %s: offset=%d>
			if (p->lsb)
				fprint(fd, StrTab[43],// < bits=%d..%d>
					fieldsize(p) + fieldright(p), fieldright(p));
			fprint(fd, StrTab[44], p->type);// < type=%t>
		}
		fprint(fd, StrTab[45]);// <}\n>
		break;
		}
	case ENUM: {
		int i;
		Symbol p;
		fprint(fd, StrTab[46], ty->u.sym->name);// <enum %s {>
		for (i = 0; (p = ty->u.sym->u.idlist[i]) != NULL; i++) {
			if (i > 0)
				fprint(fd, StrTab[47]);// <,>
			fprint(fd, StrTab[48], p->name, p->u.value);// <%s=%d>
		}
		fprint(fd, StrTab[49]);// <}\n>
		break;
		}
	default:
		fprint(fd, StrTab[50], ty);// <%t\n>
	}
}

/* typestring - return ty as C declaration for str, which may be "" */
char *typestring(Type ty,char *str)
{
	for ( ; ty; ty = ty->type) {
		Symbol p;
		switch (ty->op) {
		case CONST+VOLATILE:
			if (isptr(ty->type))
				str = stringf("%k %k %s", CONST, VOLATILE, str);
			else
				return stringf("%k %k %s", CONST, VOLATILE, typestring(ty->type, str));
			break;
		case CONST: case VOLATILE:
			if (isptr(ty->type))
				str = stringf("%k %s", ty->op, str);
			else
				return stringf("%k %s", ty->op, typestring(ty->type, str));
			break;
		case STRUCT: case UNION: case ENUM:
			assert(ty->u.sym);
			if ((p = findtype(ty)) != NULL)
				return *str ? stringf("%s %s", p->name, str) : p->name;
			if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9')
				warning(StrTab[51], ty->op);// <unnamed %k in prototype\n>
			if (*str)
				return stringf("%k %s %s", ty->op, ty->u.sym->name, str);
			else
				return stringf("%k %s", ty->op, ty->u.sym->name);
		case VOID: case FLOAT: case DOUBLE:
		case CHAR: case SHORT: case INT: case UNSIGNED:
			return *str ? stringf("%s %s", ty->u.sym->name, str) : ty->u.sym->name;
		case POINTER:
			if (unqual(ty->type)->op != CHAR && (p = findtype(ty)) != NULL)
				return *str ? stringf("%s %s", p->name, str) : p->name;
			str = stringf(isarray(ty->type) || isfunc(ty->type) ? "(*%s)" : "*%s", str);
			break;
		case FUNCTION:
			if ((p = findtype(ty)) != NULL)
				return *str ? stringf("%s %s", p->name, str) : p->name;
			if (ty->u.f.proto == 0)
				str = stringf("%s()", str);
			else if (ty->u.f.proto[0]) {
				int i;
				str = stringf("%s(%s", str, typestring(ty->u.f.proto[0], ""));
				for (i = 1; ty->u.f.proto[i]; i++)
					if (ty->u.f.proto[i] == voidtype)
						str = stringf("%s, ...", str);
					else
						str = stringf("%s, %s", str, typestring(ty->u.f.proto[i], ""));
				str = stringf("%s)", str);
			} else
				str = stringf("%s(void)", str);
			break;
		case ARRAY:
			if ((p = findtype(ty)) != NULL)
				return *str ? stringf("%s %s", p->name, str) : p->name;
			if (ty->type && ty->type->size > 0)
				str = stringf("%s[%d]", str, ty->size/ty->type->size);
			else
				str = stringf("%s[]", str);
			break;
		default: assert(0);
		}
	}
	assert(0); return 0;
}

⌨️ 快捷键说明

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