type_t *get_qualified_type(type_t *orig_type, type_qualifiers_t const qual) { type_t *type = skip_typeref(orig_type); type_t *copy; if (is_type_array(type)) { /* For array types the element type has to be adjusted */ type_t *element_type = type->array.element_type; type_t *qual_element_type = get_qualified_type(element_type, qual); if (qual_element_type == element_type) return orig_type; copy = duplicate_type(type); copy->array.element_type = qual_element_type; } else if (is_type_valid(type)) { if ((type->base.qualifiers & qual) == (int)qual) return orig_type; copy = duplicate_type(type); copy->base.qualifiers |= qual; } else { return type; } return identify_new_type(copy); }
ReturnOop Array::shrink(int new_length) { GUARANTEE(new_length >= 0, "Negative array size prohibited"); int scale; if (is_type_array()) { TypeArrayClass::Raw array_class = blueprint(); scale = array_class().scale(); } else { GUARANTEE(is_obj_array(), "sanity"); scale = sizeof(OopDesc*); } Universe::shrink_object(this, ArrayDesc::allocation_size(new_length, scale)); set_length(new_length); return obj(); }
/** * Skip all typerefs and return the underlying type. */ type_t *skip_typeref(type_t *type) { type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE; while (true) { switch (type->kind) { case TYPE_ERROR: return type; case TYPE_TYPEDEF: { qualifiers |= type->base.qualifiers; const typedef_type_t *typedef_type = &type->typedeft; if (typedef_type->resolved_type != NULL) { type = typedef_type->resolved_type; break; } type = typedef_type->typedefe->type; continue; } case TYPE_TYPEOF: qualifiers |= type->base.qualifiers; type = type->typeoft.typeof_type; continue; default: break; } break; } if (qualifiers != TYPE_QUALIFIER_NONE) { type_t *const copy = duplicate_type(type); /* for const with typedefed array type the element type has to be * adjusted */ if (is_type_array(copy)) { type_t *element_type = copy->array.element_type; element_type = duplicate_type(element_type); element_type->base.qualifiers |= qualifiers; copy->array.element_type = element_type; } else { copy->base.qualifiers |= qualifiers; } type = identify_new_type(copy); } return type; }
static long get_offsetof_offset(const offsetof_expression_t *expression) { type_t *orig_type = expression->type; long offset = 0; designator_t *designator = expression->designator; for ( ; designator != NULL; designator = designator->next) { type_t *type = skip_typeref(orig_type); if (designator->symbol != NULL) { assert(is_type_compound(type)); symbol_t *symbol = designator->symbol; compound_t *compound = type->compound.compound; entity_t *iter = compound->members.first_entity; for (; iter->base.symbol != symbol; iter = iter->base.next) {} assert(iter->kind == ENTITY_COMPOUND_MEMBER); offset += iter->compound_member.offset; orig_type = iter->declaration.type; } else { expression_t *array_index = designator->array_index; assert(designator->array_index != NULL); assert(is_type_array(type)); long index_long = fold_expression_to_int(array_index); type_t *element_type = type->array.element_type; long element_size = get_type_size(element_type); /* TODO: check for overflow */ offset += index_long * element_size; orig_type = type->array.element_type; } } return offset; }
ciTypeArray* as_type_array() { assert(is_type_array(), "bad cast"); return (ciTypeArray*)this; }