Exemplo n.º 1
0
/* asgncode - assign type code to ty */
static void asgncode(Type ty, int lev) {
	if (ty->x.marked || ty->x.typeno)
		return;
	ty->x.marked = 1;
	switch (ty->op) {
	case VOLATILE: case CONST: case VOLATILE+CONST:
		asgncode(ty->type, lev);
		ty->x.typeno = ty->type->x.typeno;
		break;
	case POINTER: case FUNCTION: case ARRAY:
		asgncode(ty->type, lev + 1);
		/* fall thru */
	case VOID: case INT: case UNSIGNED: case FLOAT:
		break;
	case STRUCT: case UNION: {
		Field p;
		for (p = fieldlist(ty); p; p = p->link)
			asgncode(p->type, lev + 1);
		/* fall thru */
	case ENUM:
		if (ty->x.typeno == 0)
			ty->x.typeno = ++ntypes;
		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9'))
			dbxout(ty);
		break;
		}
	default:
		assert(0);
	}
}
Exemplo n.º 2
0
static int typeuid(Type ty) {
	rcc_type_ty type;

	assert(ty);
	if (ty->x.typeno != 0)
		return ty->x.typeno;
	ty->x.typeno = pickle->nuids++;
	switch (ty->op) {
#define xx(op) case op: type = rcc_##op(ty->size, ty->align); break
	xx(INT);
	xx(UNSIGNED);
	xx(FLOAT);
	xx(VOID);
#undef xx
#define xx(op) case op: type = rcc_##op(ty->size, ty->align, typeuid(ty->type)); break
	xx(POINTER);
	xx(ARRAY);
	xx(CONST);
	xx(VOLATILE);
#undef xx
	case CONST+VOLATILE:
		type = rcc_CONST(ty->size, ty->align, typeuid(ty->type));
		break;
	case ENUM: {
		list_ty ids = Seq_new(0);
		int i;
		for (i = 0; ty->u.sym->u.idlist[i] != NULL; i++)
			Seq_addhi(ids, rcc_enum_(ty->u.sym->u.idlist[i]->name,
				ty->u.sym->u.idlist[i]->u.value));
		assert(i > 0);
		type = rcc_ENUM(ty->size, ty->align, ty->u.sym->name, ids);
		break;
		}
	case STRUCT: case UNION: {
		list_ty fields = Seq_new(0);
		Field p = fieldlist(ty);
		for ( ; p != NULL; p = p->link)
			Seq_addhi(fields, rcc_field(p->name, typeuid(p->type), p->offset, p->bitsize, p->lsb));
		if (ty->op == STRUCT)
			type = rcc_STRUCT(ty->size, ty->align, ty->u.sym->name, fields);
		else
			type = rcc_UNION (ty->size, ty->align, ty->u.sym->name, fields);
		break;
		}
	case FUNCTION: {
		list_ty formals = Seq_new(0);
		if (ty->u.f.proto != NULL && ty->u.f.proto[0] != NULL) {
			int i;
			for (i = 0; ty->u.f.proto[i] != NULL; i++)
				Seq_addhi(formals, to_generic_int(typeuid(ty->u.f.proto[i])));
		} else if (ty->u.f.proto != NULL && ty->u.f.proto[0] == NULL)
			Seq_addhi(formals, to_generic_int(typeuid(voidtype)));
		type = rcc_FUNCTION(ty->size, ty->align, typeuid(ty->type), formals);
		break;
		}
	default: assert(0);
	}
	Seq_addhi(pickle->items, rcc_Type(ty->x.typeno, type));
	return ty->x.typeno;
}
Exemplo n.º 3
0
/*
 * emittype - emit ty's type number, emitting its definition if necessary.
 * Returns the output column number after emission; col is the approximate
 * output column before emission and is used to emit continuation lines for long
 * struct, union, and enum types. Continuations are not emitted for other types,
 * even if the definition is long. lev is the depth of calls to emittype.
 */
static int emittype(Type ty, int lev, int col) {
	int tc = ty->x.typeno;

	if (isconst(ty) || isvolatile(ty)) {
		col = emittype(ty->type, lev, col);
		ty->x.typeno = ty->type->x.typeno;
		ty->x.printed = 1;
		return col;
	}
	if (tc == 0) {
		ty->x.typeno = tc = ++ntypes;
/*              fprint(2,"`%t'=%d\n", ty, tc); */
	}
	print("%d", tc), col += 3;
	if (ty->x.printed)
		return col;
	ty->x.printed = 1;
	switch (ty->op) {
	case VOID:	/* void is defined as itself */
		print("=%d", tc), col += 1+3;
		break;
	case INT:
		if (ty == chartype)	/* plain char is a subrange of itself */
			print("=r%d;%d;%d;", tc, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
				col += 2+3+2*2.408*ty->size+2;
		else			/* other signed ints are subranges of int */
			print("=r1;%D;%D;", ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
				col += 4+2*2.408*ty->size+2;
		break;
	case UNSIGNED:
		if (ty == chartype)	/* plain char is a subrange of itself */
			print("=r%d;0;%u;", tc, ty->u.sym->u.limits.max.i),
				col += 2+3+2+2.408*ty->size+1;
		else			/* other signed ints are subranges of int */
			print("=r1;0;%U;", ty->u.sym->u.limits.max.i),
				col += 4+2.408*ty->size+1;
		break;
	case FLOAT:	/* float, double, long double get sizes, not ranges */
		print("=r1;%d;0;", ty->size), col += 4+1+3;
		break;
	case POINTER:
		print("=*"), col += 2;
		col = emittype(ty->type, lev + 1, col);
		break;
	case FUNCTION:
		print("=f"), col += 2;
		col = emittype(ty->type, lev + 1, col);
		break;
	case ARRAY:	/* array includes subscript as an int range */
		if (ty->size && ty->type->size)
			print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1;
		else
			print("=ar1;0;-1;"), col += 10;
		col = emittype(ty->type, lev + 1, col);
		break;
	case STRUCT: case UNION: {
		Field p;
		if (!ty->u.sym->defined) {
			print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name);
			col += 2+1+strlen(ty->u.sym->name)+1;
			break;
		}
		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
			ty->x.printed = 0;
			break;
		}
		print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3;
		for (p = fieldlist(ty); p; p = p->link) {
			if (p->name)
				print("%s:", p->name), col += strlen(p->name)+1;
			else
				print(":"), col += 1;
			col = emittype(p->type, lev + 1, col);
			if (p->lsb)
				print(",%d,%d;", 8*p->offset +
					(IR->little_endian ? fieldright(p) : fieldleft(p)),
					fieldsize(p));
			else
				print(",%d,%d;", 8*p->offset, 8*p->type->size);
			col += 1+3+1+3+1;	/* accounts for ,%d,%d; */
			if (col >= 80 && p->link) {
				print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
				col = 8;
			}
		}
		print(";"), col += 1;
		break;
		}
	case ENUM: {
		Symbol *p;
		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
			ty->x.printed = 0;
			break;
		}
		print("=e"), col += 2;
		for (p = ty->u.sym->u.idlist; *p; p++) {
			print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3;
			if (col >= 80 && p[1]) {
				print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
				col = 8;
			}
		}
		print(";"), col += 1;
		break;
		}
	default:
		assert(0);
	}
	return col;
}