* gcc-interface/gigi.h (shift_unc_components_for_thin_pointers): Kill.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Remove call
to above function.
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Adjust
handling of thin pointers.
<Attr_Descriptor_Size>: Likewise.
(gnat_to_gnu) <N_Free_Statement>: Likewise.
* gcc-interface/utils.c (shift_unc_components_for_thin_pointers): Kill.
(convert_to_fat_pointer): Adjust handling of thin pointers.
(convert) <POINTER_TYPE>: Likewise.
* gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: Likewise.
From-SVN: r185268
+2012-03-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/gigi.h (shift_unc_components_for_thin_pointers): Kill.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Remove call
+ to above function.
+ * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Adjust
+ handling of thin pointers.
+ <Attr_Descriptor_Size>: Likewise.
+ (gnat_to_gnu) <N_Free_Statement>: Likewise.
+ * gcc-interface/utils.c (shift_unc_components_for_thin_pointers): Kill.
+ (convert_to_fat_pointer): Adjust handling of thin pointers.
+ (convert) <POINTER_TYPE>: Likewise.
+ * gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: Likewise.
+
2012-03-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc-interface/Makefile.in (alpha*-dec-osf*): Remove.
gnu_fat_type, NULL, !Comes_From_Source (gnat_entity),
debug_info_p, gnat_entity);
- /* Create the type to be used as what a thin pointer designates:
- a record type for the object and its template with the fields
- shifted to have the template at a negative offset. */
+ /* Create the type to be designated by thin pointers: a record type for
+ the array and its template. We used to shift the fields to have the
+ template at a negative offset, but this was somewhat of a kludge; we
+ now shift thin pointer values explicitly but only those which have a
+ TYPE_UNCONSTRAINED_ARRAY attached to the designated RECORD_TYPE. */
tem = build_unc_object_type (gnu_template_type, tem,
create_concat_name (gnat_name, "XUT"),
debug_info_p);
- shift_unc_components_for_thin_pointers (tem);
SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem;
tree object_type, tree name,
bool debug_info_p);
-/* Shift the component offsets within an unconstrained object TYPE to make it
- suitable for use as a designated type for thin pointers. */
-extern void shift_unc_components_for_thin_pointers (tree type);
-
/* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE. In
the normal case this is just two adjustments, but we have more to do
if NEW is an UNCONSTRAINED_ARRAY_TYPE. */
gnu_ptr
= build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
gnu_ptr,
- byte_position (TYPE_FIELDS (gnu_obj_type)));
+ fold_build1 (NEGATE_EXPR, sizetype,
+ byte_position
+ (DECL_CHAIN
+ TYPE_FIELDS ((gnu_obj_type)))));
gnu_result = convert (gnu_result_type, gnu_ptr);
}
gnu_type = TREE_TYPE (gnu_prefix);
gcc_assert (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE);
- /* What we want is the offset of the ARRAY field in the record that the
- thin pointer designates, but the components have been shifted so this
- is actually the opposite of the offset of the BOUNDS field. */
+ /* What we want is the offset of the ARRAY field in the record
+ that the thin pointer designates. */
gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
- gnu_result = size_binop (MINUS_EXPR, bitsize_zero_node,
- bit_position (TYPE_FIELDS (gnu_type)));
+ gnu_result = bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
gnu_result_type = get_unpadded_type (Etype (gnat_node));
prefix_unused = true;
break;
gnu_ptr
= build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
gnu_ptr,
- byte_position (TYPE_FIELDS (gnu_obj_type)));
+ fold_build1 (NEGATE_EXPR, sizetype,
+ byte_position
+ (DECL_CHAIN
+ TYPE_FIELDS ((gnu_obj_type)))));
/* If we have a special dynamic constrained subtype on the node, use
it to compute the size; otherwise, use the designated subtype. */
return
build_unc_object_type (template_type, object_type, name, debug_info_p);
}
-
-/* Shift the component offsets within an unconstrained object TYPE to make it
- suitable for use as a designated type for thin pointers. */
-
-void
-shift_unc_components_for_thin_pointers (tree type)
-{
- /* Thin pointer values designate the ARRAY data of an unconstrained object,
- allocated past the BOUNDS template. The designated type is adjusted to
- have ARRAY at position zero and the template at a negative offset, so
- that COMPONENT_REFs on (*thin_ptr) designate the proper location. */
-
- tree bounds_field = TYPE_FIELDS (type);
- tree array_field = DECL_CHAIN (TYPE_FIELDS (type));
-
- DECL_FIELD_OFFSET (bounds_field)
- = size_binop (MINUS_EXPR, size_zero_node, byte_position (array_field));
-
- DECL_FIELD_OFFSET (array_field) = size_zero_node;
- DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
-}
\f
/* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.
In the normal case this is just two adjustments, but we have more to
if (TREE_CODE (expr) == ADDR_EXPR)
expr = TREE_OPERAND (expr, 0);
else
- expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+ {
+ /* If we have a TYPE_UNCONSTRAINED_ARRAY attached to the RECORD_TYPE,
+ the thin pointer value has been shifted so we first need to shift
+ it back to get the template address. */
+ if (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)))
+ expr
+ = build_binary_op (POINTER_PLUS_EXPR, etype, expr,
+ fold_build1 (NEGATE_EXPR, sizetype,
+ byte_position
+ (DECL_CHAIN (field))));
+ expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
+ }
template_tree = build_component_ref (expr, NULL_TREE, field, false);
expr = build_unary_op (ADDR_EXPR, NULL_TREE,
case POINTER_TYPE:
case REFERENCE_TYPE:
/* If converting between two thin pointers, adjust if needed to account
- for any differing offsets, since one of them might be negative. */
+ for differing offsets from the base pointer, depending on whether
+ there is a TYPE_UNCONSTRAINED_ARRAY attached to the record type. */
if (TYPE_IS_THIN_POINTER_P (etype) && TYPE_IS_THIN_POINTER_P (type))
{
- tree byte_diff
- = size_diffop (byte_position (TYPE_FIELDS (TREE_TYPE (etype))),
- byte_position (TYPE_FIELDS (TREE_TYPE (type))));
+ tree etype_pos
+ = TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype)) != NULL_TREE
+ ? byte_position (DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (etype))))
+ : size_zero_node;
+ tree type_pos
+ = TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)) != NULL_TREE
+ ? byte_position (DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (type))))
+ : size_zero_node;
+ tree byte_diff = size_diffop (type_pos, etype_pos);
expr = build1 (NOP_EXPR, type, expr);
if (integer_zerop (byte_diff))
tree rec_type = TREE_TYPE (type);
if (TREE_CODE (operand) == POINTER_PLUS_EXPR
- && integer_zerop
- (size_binop (PLUS_EXPR, TREE_OPERAND (operand, 1),
- byte_position (TYPE_FIELDS (rec_type))))
+ && TREE_OPERAND (operand, 1)
+ == byte_position (DECL_CHAIN (TYPE_FIELDS (rec_type)))
&& TREE_CODE (TREE_OPERAND (operand, 0)) == NOP_EXPR)
{
operand = TREE_OPERAND (TREE_OPERAND (operand, 0), 0);