{
switch (expression->kind) {
case EXPR_REFERENCE: return expression->reference.declaration->type;
- case EXPR_SELECT: return expression->select.compound_entry->type;
+
+ case EXPR_SELECT:
+ return get_qualified_type(expression->select.compound_entry->type,
+ expression->base.type->base.qualifiers);
case EXPR_UNARY_DEREFERENCE: {
const expression_t *const value = expression->unary.value;
select->select.compound_entry = entry;
- type_t *res_type = entry->type;
- type_qualifiers_t qual = type_left->base.qualifiers;
- if (qual != 0) {
- type_t *const copy = duplicate_type(res_type);
- copy->base.qualifiers |= qual;
-
- res_type = typehash_insert(copy);
- if (type != copy)
- free_type(copy);
- }
+ type_t *const res_type =
+ get_qualified_type(entry->type, type_left->base.qualifiers);
/* we always do the auto-type conversions; the & and sizeof parser contains
* code to revert this! */
to = type_void;
}
- type_t *const copy = duplicate_type(to);
- copy->base.qualifiers = to1->base.qualifiers | to2->base.qualifiers;
-
- type_t *const type = typehash_insert(copy);
- if (type != copy)
- free_type(copy);
-
+ type_t *const type =
+ get_qualified_type(to, to1->base.qualifiers | to2->base.qualifiers);
result_type = make_pointer_type(type, TYPE_QUALIFIER_NONE);
} else if (is_type_integer(other_type)) {
warningf(&conditional->base.source_position,
return result;
}
+type_t *get_qualified_type(type_t *type, type_qualifiers_t const qual)
+{
+ assert(!is_typeref(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 type;
+
+ copy = duplicate_type(type);
+ copy->array.element_type = qual_element_type;
+ } else {
+ if ((type->base.qualifiers & qual) == qual)
+ return type;
+
+ copy = duplicate_type(type);
+ copy->base.qualifiers |= qual;
+ }
+
+ type = typehash_insert(copy);
+ if (type != copy)
+ obstack_free(type_obst, copy);
+
+ return type;
+}
+
/**
* Check if a type is valid.
*
bool types_compatible(const type_t *type1, const type_t *type2);
type_t *get_unqualified_type(type_t *type);
+type_t *get_qualified_type(type_t*, type_qualifiers_t);
type_t *skip_typeref(type_t *type);
/**