type_t array_aggregate_type(type_t array, int from_dim) { if (type_is_unconstrained(array)) { const int nindex = type_index_constrs(array); assert(from_dim < nindex); type_t type = type_new(T_UARRAY); type_set_ident(type, type_ident(array)); type_set_elem(type, type_elem(array)); for (int i = from_dim; i < nindex; i++) type_add_index_constr(type, type_index_constr(array, i)); return type; } else { const int ndims = type_dims(array); assert(from_dim < ndims); type_t type = type_new(T_CARRAY); type_set_ident(type, type_ident(array)); type_set_elem(type, type_elem(array)); for (int i = from_dim; i < ndims; i++) type_add_dim(type, type_dim(array, i)); return type; } }
void type_replace(type_t t, type_t a) { assert(t != NULL); assert(IS(t, T_INCOMPLETE)); t->kind = a->kind; t->ident = a->ident; const imask_t has = has_map[t->kind]; if (has & I_DIMS) { const int ndims = type_dims(a); for (int i = 0; i < ndims; i++) type_add_dim(t, type_dim(a, i)); } switch (a->kind) { case T_UARRAY: for (unsigned i = 0; i < type_index_constrs(a); i++) type_add_index_constr(t, type_index_constr(a, i)); // Fall-through case T_CARRAY: type_set_elem(t, type_elem(a)); break; case T_SUBTYPE: type_set_base(t, type_base(a)); break; case T_FUNC: type_set_result(t, type_result(a)); break; case T_INTEGER: case T_REAL: break; case T_ENUM: for (unsigned i = 0; i < type_enum_literals(a); i++) type_enum_add_literal(t, type_enum_literal(a, i)); break; case T_RECORD: for (unsigned i = 0; i < type_fields(a); i++) type_add_field(t, type_field(a, i)); break; default: assert(false); } }
type_t index_type_of(type_t type, int dim) { if (type_is_unconstrained(type)) return type_index_constr(type_base_recur(type), dim); else if (type_kind(type) == T_ENUM) return type; else { tree_t left = type_dim(type, dim).left; // If the left bound has not been assigned a type then there is some // error with it so just return a dummy type here return tree_has_type(left) ? tree_type(left) : type; } }