aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2012-03-12 20:00:32 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-03-12 20:00:32 +0000
commit2b45154d2074a11baa2dfa18247848227fbfa1f0 (patch)
tree1b26a4183158628e3053e92f393f5fa662df3146 /gcc
parent0452b4d47fe1e13bbcb8578e7e348cef2ca17e42 (diff)
downloadgcc-2b45154d2074a11baa2dfa18247848227fbfa1f0.zip
gcc-2b45154d2074a11baa2dfa18247848227fbfa1f0.tar.gz
gcc-2b45154d2074a11baa2dfa18247848227fbfa1f0.tar.bz2
gigi.h (shift_unc_components_for_thin_pointers): Kill.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog14
-rw-r--r--gcc/ada/gcc-interface/decl.c9
-rw-r--r--gcc/ada/gcc-interface/gigi.h4
-rw-r--r--gcc/ada/gcc-interface/trans.c18
-rw-r--r--gcc/ada/gcc-interface/utils.c49
-rw-r--r--gcc/ada/gcc-interface/utils2.c5
6 files changed, 55 insertions, 44 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2593ef2..bd97c1b 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,17 @@
+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.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 120628e..a3320ed 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -2280,13 +2280,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
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;
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index f7d787b..5b95f9c 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -736,10 +736,6 @@ extern tree build_unc_object_type_from_ptr (tree thin_fat_ptr_type,
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. */
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index cd6626f..89f5438 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1439,7 +1439,10 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
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);
}
@@ -1950,12 +1953,10 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
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;
@@ -6622,7 +6623,10 @@ gnat_to_gnu (Node_Id gnat_node)
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. */
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 4f8ab20..7383358 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3411,27 +3411,6 @@ build_unc_object_type_from_ptr (tree thin_fat_ptr_type, tree object_type,
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;
-}
/* 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
@@ -3616,7 +3595,18 @@ convert_to_fat_pointer (tree type, tree expr)
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,
@@ -4103,12 +4093,19 @@ convert (tree type, tree expr)
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))
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index 79c5a1f..d0769f7 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -1396,9 +1396,8 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
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);