static int group_net_to_field(type_t type, netid_t nid) { int count = 0; if (type_is_record(type)) { const int nfields = type_fields(type); netid_t first = 0; for (int i = 0; i < nfields; i++) { tree_t field = type_field(type, i); type_t ftype = tree_type(field); const netid_t next = first + type_width(tree_type(field)); if (nid >= first && nid < next) { if (type_is_array(ftype) || type_is_record(ftype)) return count + group_net_to_field(ftype, nid - first); else return count; } first = next; count += type_width(ftype); } fatal_trace("group_net_to_field failed to find field for nid=%d type=%s", nid, type_pp(type)); } else if (type_is_array(type)) { type_t elem = type_elem(type); const int width = type_width(elem); if (type_is_record(elem)) return (nid / width) * width + group_net_to_field(elem, nid % width); else return group_net_to_field(elem, nid % width); } else return 0; }
bool type_is_record(type_t t) { assert(t != NULL); if (t->kind == T_SUBTYPE) return type_is_record(type_base(t)); else return (t->kind == T_RECORD); }
static bool group_contains_record(type_t type) { if (type_is_record(type)) return true; else if (type_is_array(type)) return group_contains_record(type_elem(type)); else return false; }
unsigned type_width(type_t type) { if (type_is_array(type)) { const unsigned elem_w = type_width(type_elem(type)); unsigned w = 1; const int ndims = type_dims(type); for (int i = 0; i < ndims; i++) { int64_t low, high; range_bounds(type_dim(type, i), &low, &high); w *= MAX(high - low + 1, 0) * elem_w; } return w; } else if (type_is_record(type)) { type_t base = type_base_recur(type); unsigned w = 0; const int nfields = type_fields(base); for (int i = 0; i < nfields; i++) w += type_width(tree_type(type_field(base, i))); return w; } else return 1; }