struct type *next;
int size, align;
void (*init)(struct type *type, struct value *val);
+ void (*prepare_type)(struct type *type);
void (*print)(struct type *type, struct value *val);
void (*print_type)(struct type *type, FILE *f);
int (*cmp_order)(struct type *t1, struct type *t2,
{
struct value *ret;
- if (!t->size)
- val_init(t, NULL);
ret = calloc(1, t->size);
if (init)
memcpy(ret, init, t->size);
###### value functions
- static void array_init(struct type *type, struct value *val)
+ static void array_prepare_type(struct type *type)
{
- int i;
+ mpz_t q;
+ if (!type->array.vsize)
+ return;
+
+ mpz_init(q);
+ mpz_tdiv_q(q, mpq_numref(type->array.vsize->val->num),
+ mpq_denref(type->array.vsize->val->num));
+ type->array.size = mpz_get_si(q);
+ mpz_clear(q);
- if (type->array.vsize) {
- mpz_t q;
- mpz_init(q);
- mpz_tdiv_q(q, mpq_numref(type->array.vsize->val->num),
- mpq_denref(type->array.vsize->val->num));
- type->array.size = mpz_get_si(q);
- mpz_clear(q);
- }
type->size = type->array.size * type->array.member->size;
type->align = type->array.member->align;
+ }
+
+ static void array_init(struct type *type, struct value *val)
+ {
+ int i;
if (!val)
return;
static struct type array_prototype = {
.init = array_init,
+ .prepare_type = array_prepare_type,
.print_type = array_print_type,
.compat = array_compat,
.free = array_free,
char tail[3];
mpq_t num;
struct text noname = { "", 0 };
+ struct type *t;
- $0 = add_type(c, noname, &array_prototype);
- $0->array.member = $<4;
- $0->array.vsize = NULL;
+ $0 = t = add_type(c, noname, &array_prototype);
+ t->array.member = $<4;
+ t->array.vsize = NULL;
if (number_parse(num, tail, $2.txt) == 0)
tok_err(c, "error: unrecognised number", &$2);
else if (tail[0])
tok_err(c, "error: unsupported number suffix", &$2);
else {
- $0->array.size = mpz_get_ui(mpq_numref(num));
+ t->array.size = mpz_get_ui(mpq_numref(num));
if (mpz_cmp_ui(mpq_denref(num), 1) != 0) {
tok_err(c, "error: array size must be an integer",
&$2);
&$2);
mpq_clear(num);
}
+ t->size = t->array.size * t->array.member->size;
+ t->align = t->array.member->align;
} }$
| [ IDENTIFIER ] Type ${ {
struct variable *v = cast(var, b->left)->var;
if (v->merged)
v = v->merged;
+ free_value(v->type, v->val);
+ free(v->val);
+ if (v->type->prepare_type)
+ // FIXME is this the first usage of the type?
+ v->type->prepare_type(v->type);
if (b->right) {
right = interp_exec(b->right, &rtype);
- free_value(v->type, v->val);
- free(v->val);
v->val = val_alloc(v->type, &right);
rtype = Tnone;
} else {
- free_value(v->type, v->val);
- free(v->val);
v->val = val_alloc(v->type, NULL);
}
break;