+ switch (TREE_CODE (exp))
+ {
+ case BIT_FIELD_REF:
+ bit_offset = size_binop (PLUS_EXPR, bit_offset,
+ TREE_OPERAND (exp, 2));
+ break;
+
+ case COMPONENT_REF:
+ {
+ tree field = TREE_OPERAND (exp, 1);
+ tree this_offset = component_ref_field_offset (exp);
+
+ if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
+ {
+ this_offset = size_binop (MULT_EXPR,
+ fold_convert (bitsizetype,
+ this_offset),
+ bitsize_unit_node);
+ bit_offset = size_binop (PLUS_EXPR,
+ bit_offset, this_offset);
+ bit_offset = size_binop (PLUS_EXPR, bit_offset,
+ DECL_FIELD_BIT_OFFSET (field));
+ }
+ else
+ {
+ tree csize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ /* We need to adjust maxsize to the whole structure bitsize.
+ But we can subtract any constant offset seen sofar,
+ because that would get us out of the structure otherwise. */
+ if (maxsize != -1
+ && csize && host_integerp (csize, 1))
+ {
+ maxsize = (TREE_INT_CST_LOW (csize)
+ - TREE_INT_CST_LOW (bit_offset));
+ }
+ else
+ maxsize = -1;
+ }
+ }
+ break;
+
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ {
+ tree index = TREE_OPERAND (exp, 1);
+ tree low_bound = array_ref_low_bound (exp);
+ tree unit_size = array_ref_element_size (exp);
+
+ if (! integer_zerop (low_bound))
+ index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
+ index, low_bound);
+ index = size_binop (MULT_EXPR,
+ fold_convert (sizetype, index), unit_size);
+ if (TREE_CODE (index) == INTEGER_CST)
+ {
+ index = size_binop (MULT_EXPR,
+ fold_convert (bitsizetype, index),
+ bitsize_unit_node);
+ bit_offset = size_binop (PLUS_EXPR, bit_offset, index);
+
+ /* An array ref with a constant index up in the structure
+ hierarchy will constrain the size of any variable array ref
+ lower in the access hierarchy. */
+ seen_variable_array_ref = false;
+ }
+ else
+ {
+ tree asize = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ /* We need to adjust maxsize to the whole array bitsize.
+ But we can subtract any constant offset seen sofar,
+ because that would get us outside of the array otherwise. */
+ if (maxsize != -1
+ && asize && host_integerp (asize, 1))
+ {
+ maxsize = (TREE_INT_CST_LOW (asize)
+ - TREE_INT_CST_LOW (bit_offset));
+ }
+ else
+ maxsize = -1;
+
+ /* Remember that we have seen an array ref with a variable
+ index. */
+ seen_variable_array_ref = true;
+ }
+ }
+ break;
+
+ case REALPART_EXPR:
+ break;
+
+ case IMAGPART_EXPR:
+ bit_offset = size_binop (PLUS_EXPR, bit_offset,
+ bitsize_int (bitsize));
+ break;
+
+ case VIEW_CONVERT_EXPR:
+ /* ??? We probably should give up here and bail out. */
+ break;
+
+ default:
+ goto done;
+ }
+
+ exp = TREE_OPERAND (exp, 0);