aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc.h3
-rw-r--r--decl.c10
-rw-r--r--doc/software.md4
-rw-r--r--eval.c8
-rw-r--r--expr.c18
-rw-r--r--init.c4
-rw-r--r--qbe.c57
-rw-r--r--stmt.c2
-rw-r--r--type.c119
9 files changed, 98 insertions, 127 deletions
diff --git a/cc.h b/cc.h
index 9de12b3..fbf6075 100644
--- a/cc.h
+++ b/cc.h
@@ -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);
diff --git a/decl.c b/decl.c
index 38a4256..361c0d9 100644
--- a/decl.c
+++ b/decl.c
@@ -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:
diff --git a/eval.c b/eval.c
index 79bccd2..20eda9b 100644
--- a/eval.c
+++ b/eval.c
@@ -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;
diff --git a/expr.c b/expr.c
index 657e211..5e712d3 100644
--- a/expr.c
+++ b/expr.c
@@ -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");
diff --git a/init.c b/init.c
index beba85f..2eee141 100644
--- a/init.c
+++ b/init.c
@@ -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;
}
diff --git a/qbe.c b/qbe.c
index d974bed..06d6615 100644
--- a/qbe.c
+++ b/qbe.c
@@ -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)
diff --git a/stmt.c b/stmt.c
index 34795e2..4033a69 100644
--- a/stmt.c
+++ b/stmt.c
@@ -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));
diff --git a/type.c b/type.c
index cac5061..30ca520 100644
--- a/type.c
+++ b/type.c
@@ -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)