/* 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); } }
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; }
/* * 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; }