diff options
-rw-r--r-- | cc.h | 3 | ||||
-rw-r--r-- | decl.c | 10 | ||||
-rw-r--r-- | doc/software.md | 4 | ||||
-rw-r--r-- | eval.c | 8 | ||||
-rw-r--r-- | expr.c | 18 | ||||
-rw-r--r-- | init.c | 4 | ||||
-rw-r--r-- | qbe.c | 57 | ||||
-rw-r--r-- | stmt.c | 2 | ||||
-rw-r--r-- | type.c | 119 |
9 files changed, 98 insertions, 127 deletions
@@ -188,6 +188,7 @@ struct member { struct type { enum typekind kind; + enum typeprop prop; int align; uint64_t size; struct repr *repr; @@ -390,7 +391,7 @@ _Bool consume(int); /* type */ -struct type *mktype(enum typekind); +struct type *mktype(enum typekind, enum typeprop); struct type *mkpointertype(struct type *, enum typequal); struct type *mkarraytype(struct type *, enum typequal, uint64_t); @@ -185,7 +185,9 @@ tagspec(struct scope *s) *t = typeuint; t->kind = kind; } else { - t = mktype(kind); + t = mktype(kind, PROPOBJECT); + if (kind == TYPESTRUCT) + t->prop |= PROPAGGR; t->repr = &i64; // XXX t->size = 0; t->align = 0; @@ -220,7 +222,7 @@ tagspec(struct scope *s) next(); if (consume(TASSIGN)) { e = constexpr(s); - if (e->kind != EXPRCONST || !(typeprop(e->type) & PROPINT)) + if (e->kind != EXPRCONST || !(e->type->prop & PROPINT)) error(&tok.loc, "expected integer constant expression"); if (e->type->basic.issigned && e->constant.i >= 1ull << 63) t->basic.issigned = true; @@ -480,7 +482,7 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs case TLPAREN: /* function declarator */ next(); func: - t = mktype(TYPEFUNC); + t = mktype(TYPEFUNC, PROPDERIVED); t->qual = QUALNONE; t->func.isprototype = false; t->func.isvararg = false; @@ -676,7 +678,7 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, ui t->size = mt.type->size; } } else { /* bit-field */ - if (!(typeprop(mt.type) & PROPINT)) + if (!(mt.type->prop & PROPINT)) error(&tok.loc, "bit-field has invalid type"); if (align) error(&tok.loc, "alignment specified for bit-field"); diff --git a/doc/software.md b/doc/software.md index e863711..03e28b9 100644 --- a/doc/software.md +++ b/doc/software.md @@ -23,8 +23,8 @@ below) to avoid errors in unused `static inline` functions in musl's things will break if any functions with `long double` get called. ```diff --struct type typeldouble = {.kind = TYPELDOUBLE, .size = 16, .align = 16}; // XXX: not supported by qbe -+struct type typeldouble = {.kind = TYPELDOUBLE, .size = 8, .align = 8, .repr = &f64}; +-struct type typeldouble = FLTTYPE(TYPELDOUBLE, 16, NULL); // XXX: not supported by qbe ++struct type typeldouble = FLTTYPE(TYPELDOUBLE, 8, &f64); ``` Requires several patches available here: @@ -12,7 +12,7 @@ cast(struct expr *expr) unsigned size; size = expr->type->size; - if (typeprop(expr->type) & PROPFLOAT) + if (expr->type->prop & PROPFLOAT) size |= F; else if (expr->type->basic.issigned) size |= S; @@ -31,7 +31,7 @@ static void binary(struct expr *expr, enum tokenkind op, struct expr *l, struct expr *r) { expr->kind = EXPRCONST; - if (typeprop(l->type) & PROPFLOAT) + if (l->type->prop & PROPFLOAT) op |= F; else if (l->type->basic.issigned) op |= S; @@ -126,9 +126,9 @@ eval(struct expr *expr) l = eval(expr->cast.e); if (l->kind == EXPRCONST) { expr->kind = EXPRCONST; - if (typeprop(l->type) & PROPINT && typeprop(expr->type) & PROPFLOAT) + if (l->type->prop & PROPINT && expr->type->prop & PROPFLOAT) expr->constant.f = l->constant.i; - else if (typeprop(l->type) & PROPFLOAT && typeprop(expr->type) & PROPINT) + else if (l->type->prop & PROPFLOAT && expr->type->prop & PROPINT) expr->constant.i = l->constant.f; else expr->constant = l->constant; @@ -126,8 +126,8 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct exp struct type *t = NULL; enum typeprop lp, rp; - lp = typeprop(l->type); - rp = typeprop(r->type); + lp = l->type->prop; + rp = r->type->prop; switch (op) { case TLOR: case TLAND: @@ -167,7 +167,7 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct exp if (l->type->kind != TYPEPOINTER || !(rp & PROPINT)) error(loc, "invalid operands to '+' operator"); t = l->type; - if (t->base->incomplete || !(typeprop(t->base) & PROPOBJECT)) + if (t->base->incomplete || !(t->base->prop & PROPOBJECT)) error(loc, "pointer operand to '+' must be to complete object type"); r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size)); break; @@ -178,7 +178,7 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct exp } if (l->type->kind != TYPEPOINTER || !(rp & PROPINT) && r->type->kind != TYPEPOINTER) error(loc, "invalid operands to '-' operator"); - if (l->type->base->incomplete || !(typeprop(l->type->base) & PROPOBJECT)) + if (l->type->base->incomplete || !(l->type->base->prop & PROPOBJECT)) error(loc, "pointer operand to '-' must be to complete object type"); if (rp & PROPINT) { t = l->type; @@ -551,7 +551,7 @@ postfixexpr(struct scope *s, struct expr *r) } if (arr->type->base->incomplete) error(&tok.loc, "array is pointer to incomplete type"); - if (!(typeprop(idx->type) & PROPINT)) + if (!(idx->type->prop & PROPINT)) error(&tok.loc, "index is not an integer type"); e = mkunaryexpr(TMUL, mkbinaryexpr(&tok.loc, TADD, arr, idx)); expect(TRBRACK, "after array index"); @@ -693,7 +693,7 @@ unaryexpr(struct scope *s) case TLNOT: next(); e = castexpr(s); - if (!(typeprop(e->type) & PROPSCALAR)) + if (!(e->type->prop & PROPSCALAR)) error(&tok.loc, "operator '!' must have scalar operand"); e = mkbinaryexpr(&tok.loc, TEQL, e, mkconstexpr(&typeint, 0)); break; @@ -823,7 +823,7 @@ nullpointer(struct expr *e) { if (e->kind != EXPRCONST) return false; - if (!(typeprop(e->type) & PROPINT) && (e->type->kind != TYPEPOINTER || e->type->base != &typevoid)) + if (!(e->type->prop & PROPINT) && (e->type->kind != TYPEPOINTER || e->type->base != &typevoid)) return false; return e->constant.i == 0; } @@ -847,7 +847,7 @@ condexpr(struct scope *s) f = e->cond.f->type; if (t == f) { e->type = t; - } else if (typeprop(t) & PROPARITH && typeprop(f) & PROPARITH) { + } else if (t->prop & PROPARITH && f->prop & PROPARITH) { e->type = commonreal(&e->cond.t, &e->cond.f); } else if (t == &typevoid && f == &typevoid) { e->type = &typevoid; @@ -890,7 +890,7 @@ intconstexpr(struct scope *s, bool allowneg) struct expr *e; e = constexpr(s); - if (e->kind != EXPRCONST || !(typeprop(e->type) & PROPINT)) + if (e->kind != EXPRCONST || !(e->type->prop & PROPINT)) error(&tok.loc, "not an integer constant expression"); if (!allowneg && e->type->basic.issigned && e->constant.i > INT64_MAX) error(&tok.loc, "integer constant expression cannot be negative"); @@ -244,7 +244,7 @@ parseinit(struct scope *s, struct type *t) expr = expr->unary.base; base = t->base; /* XXX: wide string literals */ - if (!(typeprop(base) & PROPCHAR)) + if (!(base->prop & PROPCHAR)) error(&tok.loc, "array initializer is string literal with incompatible type"); if (t->incomplete) updatearray(t, expr->string.size); @@ -257,7 +257,7 @@ parseinit(struct scope *s, struct type *t) goto add; break; default: /* scalar type */ - assert(typeprop(t) & PROPSCALAR); + assert(t->prop & PROPSCALAR); expr = exprconvert(expr, t); goto add; } @@ -247,7 +247,7 @@ funcstore(struct func *f, struct type *t, enum typequal tq, struct lvalue lval, error(&tok.loc, "volatile store is not yet supported"); if (tq & QUALCONST) error(&tok.loc, "cannot store to 'const' object"); - tp = typeprop(t); + tp = t->prop; assert(!lval.bits.before && !lval.bits.after || tp & PROPINT); switch (t->kind) { case TYPESTRUCT: @@ -324,12 +324,12 @@ funcload(struct func *f, struct type *t, struct lvalue lval) v->repr = t->repr; return v; default: - assert(typeprop(t) & PROPREAL); + assert(t->prop & PROPREAL); switch (t->size) { case 1: op = t->basic.issigned ? ILOADSB : ILOADUB; break; case 2: op = t->basic.issigned ? ILOADSH : ILOADUH; break; - case 4: op = typeprop(t) & PROPFLOAT ? ILOADS : t->basic.issigned ? ILOADSW : ILOADUW; break; - case 8: op = typeprop(t) & PROPFLOAT ? ILOADD : ILOADL; break; + case 4: op = t->prop & PROPFLOAT ? ILOADS : t->basic.issigned ? ILOADSW : ILOADUW; break; + case 8: op = t->prop & PROPFLOAT ? ILOADD : ILOADL; break; default: fatal("internal error; unimplemented load"); } @@ -618,7 +618,7 @@ funcexpr(struct func *f, struct expr *e) } break; case EXPRCONST: - if (typeprop(e->type) & PROPINT || e->type->kind == TYPEPOINTER) + if (e->type->prop & PROPINT || e->type->kind == TYPEPOINTER) return mkintconst(e->type->repr, e->constant.i); return mkfltconst(e->type->repr, e->constant.f); case EXPRBITFIELD: @@ -630,9 +630,9 @@ funcexpr(struct func *f, struct expr *e) l = funcload(f, e->incdec.base->type, lval); if (e->type->kind == TYPEPOINTER) r = mkintconst(e->type->repr, e->type->base->size); - else if (typeprop(e->type) & PROPINT) + else if (e->type->prop & PROPINT) r = mkintconst(e->type->repr, 1); - else if (typeprop(e->type) & PROPFLOAT) + else if (e->type->prop & PROPFLOAT) r = mkfltconst(e->type->repr, 1); else fatal("not a scalar"); @@ -665,7 +665,6 @@ funcexpr(struct func *f, struct expr *e) break; case EXPRCAST: { struct type *src, *dst; - int srcprop, dstprop; l = funcexpr(f, e->cast.e); r = NULL; @@ -678,19 +677,17 @@ funcexpr(struct func *f, struct expr *e) dst = &typeulong; if (dst->kind == TYPEVOID) return NULL; - srcprop = typeprop(src); - dstprop = typeprop(dst); - if (!(srcprop & PROPREAL) || !(dstprop & PROPREAL)) + if (!(src->prop & PROPREAL) || !(dst->prop & PROPREAL)) fatal("internal error; unsupported conversion"); if (dst->kind == TYPEBOOL) { l = extend(f, src, l); r = mkintconst(src->repr, 0); - if (srcprop & PROPINT) + if (src->prop & PROPINT) op = src->size == 8 ? ICNEL : ICNEW; else op = src->size == 8 ? ICNED : ICNES; - } else if (dstprop & PROPINT) { - if (srcprop & PROPINT) { + } else if (dst->prop & PROPINT) { + if (src->prop & PROPINT) { if (dst->size <= src->size) { op = ICOPY; } else { @@ -707,7 +704,7 @@ funcexpr(struct func *f, struct expr *e) op = src->size == 8 ? IDTOSI : ISTOSI; } } else { - if (srcprop & PROPINT) { + if (src->prop & PROPINT) { if (!src->basic.issigned) return utof(f, dst->repr, l); op = src->size == 8 ? ISLTOF : ISWTOF; @@ -749,7 +746,7 @@ funcexpr(struct func *f, struct expr *e) op = IMUL; break; case TDIV: - op = !(typeprop(e->type) & PROPINT) || e->type->basic.issigned ? IDIV : IUDIV; + op = !(e->type->prop & PROPINT) || e->type->basic.issigned ? IDIV : IUDIV; break; case TMOD: op = e->type->basic.issigned ? IREM : IUREM; @@ -779,49 +776,49 @@ funcexpr(struct func *f, struct expr *e) l = extend(f, t, l); r = extend(f, t, r); if (t->size <= 4) - op = typeprop(t) & PROPFLOAT ? ICLTS : t->basic.issigned ? ICSLTW : ICULTW; + op = t->prop & PROPFLOAT ? ICLTS : t->basic.issigned ? ICSLTW : ICULTW; else - op = typeprop(t) & PROPFLOAT ? ICLTD : t->basic.issigned ? ICSLTL : ICULTL; + op = t->prop & PROPFLOAT ? ICLTD : t->basic.issigned ? ICSLTL : ICULTL; break; case TGREATER: l = extend(f, t, l); r = extend(f, t, r); if (t->size <= 4) - op = typeprop(t) & PROPFLOAT ? ICGTS : t->basic.issigned ? ICSGTW : ICUGTW; + op = t->prop & PROPFLOAT ? ICGTS : t->basic.issigned ? ICSGTW : ICUGTW; else - op = typeprop(t) & PROPFLOAT ? ICGTD : t->basic.issigned ? ICSGTL : ICUGTL; + op = t->prop & PROPFLOAT ? ICGTD : t->basic.issigned ? ICSGTL : ICUGTL; break; case TLEQ: l = extend(f, t, l); r = extend(f, t, r); if (t->size <= 4) - op = typeprop(t) & PROPFLOAT ? ICLES : t->basic.issigned ? ICSLEW : ICULEW; + op = t->prop & PROPFLOAT ? ICLES : t->basic.issigned ? ICSLEW : ICULEW; else - op = typeprop(t) & PROPFLOAT ? ICLED : t->basic.issigned ? ICSLEL : ICULEL; + op = t->prop & PROPFLOAT ? ICLED : t->basic.issigned ? ICSLEL : ICULEL; break; case TGEQ: l = extend(f, t, l); r = extend(f, t, r); if (t->size <= 4) - op = typeprop(t) & PROPFLOAT ? ICGES : t->basic.issigned ? ICSGEW : ICUGEW; + op = t->prop & PROPFLOAT ? ICGES : t->basic.issigned ? ICSGEW : ICUGEW; else - op = typeprop(t) & PROPFLOAT ? ICGED : t->basic.issigned ? ICSGEL : ICUGEL; + op = t->prop & PROPFLOAT ? ICGED : t->basic.issigned ? ICSGEL : ICUGEL; break; case TEQL: l = extend(f, t, l); r = extend(f, t, r); if (t->size <= 4) - op = typeprop(t) & PROPFLOAT ? ICEQS : ICEQW; + op = t->prop & PROPFLOAT ? ICEQS : ICEQW; else - op = typeprop(t) & PROPFLOAT ? ICEQD : ICEQL; + op = t->prop & PROPFLOAT ? ICEQD : ICEQL; break; case TNEQ: l = extend(f, t, l); r = extend(f, t, r); if (t->size <= 4) - op = typeprop(t) & PROPFLOAT ? ICNES : ICNEW; + op = t->prop & PROPFLOAT ? ICNES : ICNEW; else - op = typeprop(t) & PROPFLOAT ? ICNED : ICNEL; + op = t->prop & PROPFLOAT ? ICNED : ICNEL; break; } if (op == INONE) @@ -1194,7 +1191,7 @@ dataitem(struct expr *expr, uint64_t size) dataitem(expr->binary.r, 0); break; case EXPRCONST: - if (typeprop(expr->type) & PROPFLOAT) + if (expr->type->prop & PROPFLOAT) printf("%c_%a", expr->type->size == 4 ? 's' : 'd', expr->constant.f); else printf("%" PRIu64, expr->constant.i); @@ -1258,7 +1255,7 @@ emitdata(struct decl *d, struct init *init) printf("z %" PRIu64 ", ", start - offset); if (cur->bits.before || cur->bits.after) { /* XXX: little-endian specific */ - assert(typeprop(cur->expr->type) & PROPINT); + assert(cur->expr->type->prop & PROPINT); assert(cur->expr->kind == EXPRCONST); bits |= cur->expr->constant.i << cur->bits.before % 8; for (offset = start; offset < end; ++offset, bits >>= 8) @@ -125,7 +125,7 @@ stmt(struct func *f, struct scope *s) e = expr(s); expect(TRPAREN, "after expression"); - if (!(typeprop(e->type) & PROPINT)) + if (!(e->type->prop & PROPINT)) error(&tok.loc, "controlling expression of switch statement must have integer type"); e = exprconvert(e, typeintpromote(e->type)); @@ -6,40 +6,60 @@ #include "util.h" #include "cc.h" -struct type typevoid = {.kind = TYPEVOID, .incomplete = true}; +#define INTTYPE(k, n, r, s, p) { \ + .kind = k, .size = n, .align = n, .repr = r, .basic.issigned = s, \ + .prop = PROPOBJECT|PROPSCALAR|PROPARITH|PROPREAL|PROPINT|p, \ +} +#define FLTTYPE(k, n, r) { \ + .kind = k, .size = n, .align = n, .repr = r, \ + .prop = PROPOBJECT|PROPSCALAR|PROPARITH|PROPREAL|PROPFLOAT, \ +} + +struct type typevoid = {.kind = TYPEVOID, .prop = PROPOBJECT, .incomplete = true}; -struct type typechar = {.kind = TYPECHAR, .size = 1, .align = 1, .repr = &i8, .basic.issigned = 1}; -struct type typeschar = {.kind = TYPECHAR, .size = 1, .align = 1, .repr = &i8, .basic.issigned = 1}; -struct type typeuchar = {.kind = TYPECHAR, .size = 1, .align = 1, .repr = &i8}; +struct type typebool = INTTYPE(TYPEBOOL, 1, &i8, false, 0); -struct type typeshort = {.kind = TYPESHORT, .size = 2, .align = 2, .repr = &i16, .basic.issigned = 1}; -struct type typeushort = {.kind = TYPESHORT, .size = 2, .align = 2, .repr = &i16}; +struct type typechar = INTTYPE(TYPECHAR, 1, &i8, true, PROPCHAR); +struct type typeschar = INTTYPE(TYPECHAR, 1, &i8, true, PROPCHAR); +struct type typeuchar = INTTYPE(TYPECHAR, 1, &i8, false, PROPCHAR); -struct type typeint = {.kind = TYPEINT, .size = 4, .align = 4, .repr = &i32, .basic.issigned = 1}; -struct type typeuint = {.kind = TYPEINT, .size = 4, .align = 4, .repr = &i32}; +struct type typeshort = INTTYPE(TYPESHORT, 2, &i16, true, 0); +struct type typeushort = INTTYPE(TYPESHORT, 2, &i16, false, 0); -struct type typelong = {.kind = TYPELONG, .size = 8, .align = 8, .repr = &i64, .basic.issigned = 1}; -struct type typeulong = {.kind = TYPELONG, .size = 8, .align = 8, .repr = &i64}; +struct type typeint = INTTYPE(TYPEINT, 4, &i32, true, 0); +struct type typeuint = INTTYPE(TYPEINT, 4, &i32, false, 0); -struct type typellong = {.kind = TYPELLONG, .size = 8, .align = 8, .repr = &i64, .basic.issigned = 1}; -struct type typeullong = {.kind = TYPELLONG, .size = 8, .align = 8, .repr = &i64}; +struct type typelong = INTTYPE(TYPELONG, 8, &i64, true, 0); +struct type typeulong = INTTYPE(TYPELONG, 8, &i64, false, 0); -struct type typebool = {.kind = TYPEBOOL, .size = 1, .align = 1, .repr = &i8}; -struct type typefloat = {.kind = TYPEFLOAT, .size = 4, .align = 4, .repr = &f32}; -struct type typedouble = {.kind = TYPEDOUBLE, .size = 8, .align = 8, .repr = &f64}; -struct type typeldouble = {.kind = TYPELDOUBLE, .size = 16, .align = 16}; // XXX: not supported by qbe +struct type typellong = INTTYPE(TYPELLONG, 8, &i64, true, 0); +struct type typeullong = INTTYPE(TYPELLONG, 8, &i64, false, 0); -static struct type typevaliststruct = {.kind = TYPESTRUCT, .size = 24, .align = 8}; -struct type typevalist = {.kind = TYPEARRAY, .size = 24, .align = 8, .array = {1}, .base = &typevaliststruct}; -struct type typevalistptr = {.kind = TYPEPOINTER, .size = 8, .align = 8, .repr = &i64, .base = &typevaliststruct}; +struct type typefloat = FLTTYPE(TYPEFLOAT, 4, &f32); +struct type typedouble = FLTTYPE(TYPEDOUBLE, 8, &f64); +struct type typeldouble = FLTTYPE(TYPELDOUBLE, 16, NULL); // XXX: not supported by qbe + +static struct type typevaliststruct = { + .kind = TYPESTRUCT, .size = 24, .align = 8, + .prop = PROPOBJECT|PROPAGGR, +}; +struct type typevalist = { + .kind = TYPEARRAY, .size = 24, .align = 8, .array = {1}, .base = &typevaliststruct, + .prop = PROPOBJECT|PROPDERIVED|PROPAGGR, +}; +struct type typevalistptr = { + .kind = TYPEPOINTER, .size = 8, .align = 8, .repr = &i64, .base = &typevaliststruct, + .prop = PROPOBJECT|PROPDERIVED|PROPSCALAR, +}; struct type * -mktype(enum typekind kind) +mktype(enum typekind kind, enum typeprop prop) { struct type *t; t = xmalloc(sizeof(*t)); t->kind = kind; + t->prop = prop; t->incomplete = 0; return t; @@ -50,7 +70,7 @@ mkpointertype(struct type *base, enum typequal qual) { struct type *t; - t = mktype(TYPEPOINTER); + t = mktype(TYPEPOINTER, PROPOBJECT|PROPDERIVED|PROPSCALAR); t->base = base; t->qual = qual; t->size = 8; @@ -65,7 +85,7 @@ mkarraytype(struct type *base, enum typequal qual, uint64_t len) { struct type *t; - t = mktype(TYPEARRAY); + t = mktype(TYPEARRAY, PROPOBJECT|PROPDERIVED|PROPAGGR); t->base = base; t->qual = qual; t->array.length = len; @@ -78,59 +98,10 @@ mkarraytype(struct type *base, enum typequal qual, uint64_t len) return t; } -enum typeprop -typeprop(struct type *t) -{ - enum typeprop p; - - switch (t->kind) { - case TYPEVOID: - p = PROPOBJECT; - break; - case TYPECHAR: - p = PROPOBJECT|PROPARITH|PROPSCALAR|PROPREAL|PROPINT|PROPCHAR; - break; - case TYPEBOOL: - case TYPESHORT: - case TYPEINT: - case TYPEENUM: - case TYPELONG: - case TYPELLONG: - p = PROPOBJECT|PROPARITH|PROPSCALAR|PROPREAL|PROPINT; - break; - case TYPEFLOAT: - case TYPEDOUBLE: - case TYPELDOUBLE: - p = PROPOBJECT|PROPARITH|PROPSCALAR|PROPFLOAT; - if (!t->basic.iscomplex) - p |= PROPREAL; - break; - case TYPEPOINTER: - p = PROPOBJECT|PROPSCALAR|PROPDERIVED; - break; - case TYPEARRAY: - p = PROPOBJECT|PROPAGGR|PROPDERIVED; - break; - case TYPEFUNC: - p = PROPDERIVED; - break; - case TYPESTRUCT: - p = PROPOBJECT|PROPAGGR; - break; - case TYPEUNION: - p = PROPOBJECT; - break; - default: - fatal("unknown type"); - } - - return p; -} - static int typerank(struct type *t) { - assert(typeprop(t) & PROPINT); + assert(t->prop & PROPINT); switch (t->kind) { case TYPEBOOL: return 1; case TYPECHAR: return 2; @@ -217,7 +188,7 @@ typecomposite(struct type *t1, struct type *t2) struct type * typeintpromote(struct type *t) { - if (typeprop(t) & PROPINT && typerank(t) <= typerank(&typeint)) + if (t->prop & PROPINT && typerank(t) <= typerank(&typeint)) return t->size < typeint.size || t->basic.issigned ? &typeint : &typeuint; return t; } @@ -235,7 +206,7 @@ typecommonreal(struct type *t1, struct type *t2) { struct type *tmp; - assert(typeprop(t1) & PROPREAL && typeprop(t2) & PROPREAL); + assert(t1->prop & PROPREAL && t2->prop & PROPREAL); if (t1 == t2) return t1; if (t1 == &typeldouble || t2 == &typeldouble) |