ada-tree.h (TYPE_VAX_FLOATING_POINT_P): Move around.

* gcc-interface/ada-tree.h (TYPE_VAX_FLOATING_POINT_P): Move around.
	(TYPE_UNCONSTRAINED_ARRAY): Adjust comment.
	* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Tidy
	up.  Add comment and use canonical predicate for thin pointers.
	(gnat_to_gnu) <N_Free_Statement>: Tidy up and reorder.  Add comment
	and use canonical predicate for thin pointers.
	* gcc-interface/utils.c (convert_to_fat_pointer): Remove superfluous
	'else' and use standard name.
	(convert_to_thin_pointer): Delete.
	(convert) <POINTER_TYPE>: Do the difference in sizetype directly and
	change obsolete idioms.  Do not call above function.
	(unchecked_convert): Fix formatting.
	* gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: In the thin
	pointer case, use byte_position to get the field position.

From-SVN: r185132
This commit is contained in:
Eric Botcazou 2012-03-09 09:28:02 +00:00 committed by Eric Botcazou
parent 210ac0b75b
commit 0d7de0e10b
5 changed files with 77 additions and 92 deletions

View File

@ -1,3 +1,20 @@
2012-03-09 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/ada-tree.h (TYPE_VAX_FLOATING_POINT_P): Move around.
(TYPE_UNCONSTRAINED_ARRAY): Adjust comment.
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Tidy
up. Add comment and use canonical predicate for thin pointers.
(gnat_to_gnu) <N_Free_Statement>: Tidy up and reorder. Add comment
and use canonical predicate for thin pointers.
* gcc-interface/utils.c (convert_to_fat_pointer): Remove superfluous
'else' and use standard name.
(convert_to_thin_pointer): Delete.
(convert) <POINTER_TYPE>: Do the difference in sizetype directly and
change obsolete idioms. Do not call above function.
(unchecked_convert): Fix formatting.
* gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: In the thin
pointer case, use byte_position to get the field position.
2012-03-07 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity): Do not set flags on the

View File

@ -124,17 +124,17 @@ do { \
|| TREE_CODE (NODE) == ENUMERAL_TYPE) \
&& TYPE_BY_REFERENCE_P (NODE))
/* For INTEGER_TYPE, nonzero if this really represents a VAX
floating-point type. */
#define TYPE_VAX_FLOATING_POINT_P(NODE) \
TYPE_LANG_FLAG_3 (INTEGER_TYPE_CHECK (NODE))
/* For RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE, nonzero if this is the
type for an object whose type includes its template in addition to
its value (only true for RECORD_TYPE). */
#define TYPE_CONTAINS_TEMPLATE_P(NODE) \
TYPE_LANG_FLAG_3 (RECORD_OR_UNION_CHECK (NODE))
/* For INTEGER_TYPE, nonzero if this really represents a VAX
floating-point type. */
#define TYPE_VAX_FLOATING_POINT_P(NODE) \
TYPE_LANG_FLAG_3 (INTEGER_TYPE_CHECK (NODE))
/* True if NODE is a thin pointer. */
#define TYPE_IS_THIN_POINTER_P(NODE) \
(POINTER_TYPE_P (NODE) \
@ -328,8 +328,10 @@ do { \
SET_TYPE_LANG_SPECIFIC (POINTER_TYPE_CHECK (NODE), X)
/* For a RECORD_TYPE that is a fat pointer, this is the type for the
unconstrained object. Likewise for a RECORD_TYPE that is pointed
to by a thin pointer. */
unconstrained array. Likewise for a RECORD_TYPE that is pointed
to by a thin pointer, if it is made for the unconstrained array
type itself; the field is NULL_TREE if the RECORD_TYPE is made
for a constrained subtype of the array type. */
#define TYPE_UNCONSTRAINED_ARRAY(NODE) \
GET_TYPE_LANG_SPECIFIC (RECORD_TYPE_CHECK (NODE))
#define SET_TYPE_UNCONSTRAINED_ARRAY(NODE, X) \

View File

@ -1415,14 +1415,14 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
case Attr_Pool_Address:
{
tree gnu_obj_type;
tree gnu_ptr = gnu_prefix;
tree gnu_obj_type;
gnu_result_type = get_unpadded_type (Etype (gnat_node));
/* If this is an unconstrained array, we know the object has been
allocated with the template in front of the object. So compute
the template address. */
/* If this is fat pointer, the object must have been allocated with the
template in front of the array. So compute the template address; do
it by converting to a thin pointer. */
if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
gnu_ptr
= convert (build_pointer_type
@ -1431,16 +1431,15 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
gnu_ptr);
gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));
if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
{
tree gnu_char_ptr_type
= build_pointer_type (unsigned_char_type_node);
tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
gnu_ptr, gnu_pos);
}
/* If this is a thin pointer, the object must have been allocated with
the template in front of the array. So compute the template address
and return it. */
if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
gnu_ptr
= build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
gnu_ptr,
byte_position (TYPE_FIELDS (gnu_obj_type)));
gnu_result = convert (gnu_result_type, gnu_ptr);
}
@ -6593,23 +6592,20 @@ gnat_to_gnu (Node_Id gnat_node)
{
tree gnu_ptr = gnat_to_gnu (Expression (gnat_node));
tree gnu_ptr_type = TREE_TYPE (gnu_ptr);
tree gnu_obj_type;
tree gnu_actual_obj_type = 0;
tree gnu_obj_size;
tree gnu_obj_type, gnu_actual_obj_type;
/* If this is a thin pointer, we must dereference it to create
a fat pointer, then go back below to a thin pointer. The
reason for this is that we need a fat pointer someplace in
order to properly compute the size. */
/* If this is a thin pointer, we must first dereference it to create
a fat pointer, then go back below to a thin pointer. The reason
for this is that we need to have a fat pointer someplace in order
to properly compute the size. */
if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
gnu_ptr = build_unary_op (ADDR_EXPR, NULL_TREE,
build_unary_op (INDIRECT_REF, NULL_TREE,
gnu_ptr));
/* If this is an unconstrained array, we know the object must
have been allocated with the template in front of the object.
So pass the template address, but get the total size. Do this
by converting to a thin pointer. */
/* If this is a fat pointer, the object must have been allocated with
the template in front of the array. So pass the template address,
and get the total size; do it by converting to a thin pointer. */
if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
gnu_ptr
= convert (build_pointer_type
@ -6619,6 +6615,17 @@ gnat_to_gnu (Node_Id gnat_node)
gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));
/* If this is a thin pointer, the object must have been allocated with
the template in front of the array. So pass the template address,
and get the total size. */
if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
gnu_ptr
= build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
gnu_ptr,
byte_position (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. */
if (Present (Actual_Designated_Subtype (gnat_node)))
{
gnu_actual_obj_type
@ -6634,21 +6641,10 @@ gnat_to_gnu (Node_Id gnat_node)
else
gnu_actual_obj_type = gnu_obj_type;
gnu_obj_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
{
tree gnu_char_ptr_type
= build_pointer_type (unsigned_char_type_node);
tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
gnu_ptr, gnu_pos);
}
gnu_result
= build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, gnu_obj_type,
= build_call_alloc_dealloc (gnu_ptr,
TYPE_SIZE_UNIT (gnu_actual_obj_type),
gnu_obj_type,
Procedure_To_Call (gnat_node),
Storage_Pool (gnat_node),
gnat_node);

View File

@ -220,7 +220,6 @@ static tree compute_related_constant (tree, tree);
static tree split_plus (tree, tree *);
static tree float_type_for_precision (int, enum machine_mode);
static tree convert_to_fat_pointer (tree, tree);
static tree convert_to_thin_pointer (tree, tree);
static bool potential_alignment_gap (tree, tree, tree);
static void process_attributes (tree, struct attrib *);
@ -3608,10 +3607,10 @@ convert_to_fat_pointer (tree type, tree expr)
return t;
}
/* If EXPR is a thin pointer, make template and data from the record.. */
else if (TYPE_IS_THIN_POINTER_P (etype))
/* If EXPR is a thin pointer, make template and data from the record. */
if (TYPE_IS_THIN_POINTER_P (etype))
{
tree fields = TYPE_FIELDS (TREE_TYPE (etype));
tree field = TYPE_FIELDS (TREE_TYPE (etype));
expr = gnat_protect_expr (expr);
if (TREE_CODE (expr) == ADDR_EXPR)
@ -3619,10 +3618,10 @@ convert_to_fat_pointer (tree type, tree expr)
else
expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);
template_tree = build_component_ref (expr, NULL_TREE, fields, false);
template_tree = build_component_ref (expr, NULL_TREE, field, false);
expr = build_unary_op (ADDR_EXPR, NULL_TREE,
build_component_ref (expr, NULL_TREE,
DECL_CHAIN (fields), false));
DECL_CHAIN (field), false));
}
/* Otherwise, build the constructor for the template. */
@ -3649,27 +3648,6 @@ convert_to_fat_pointer (tree type, tree expr)
return gnat_build_constructor (type, v);
}
/* Convert to a thin pointer type, TYPE. The only thing we know how to convert
is something that is a fat pointer, so convert to it first if it EXPR
is not already a fat pointer. */
static tree
convert_to_thin_pointer (tree type, tree expr)
{
if (!TYPE_IS_FAT_POINTER_P (TREE_TYPE (expr)))
expr
= convert_to_fat_pointer
(TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))), expr);
/* We get the pointer to the data and use a NOP_EXPR to make it the
proper GCC type. */
expr = build_component_ref (expr, NULL_TREE, TYPE_FIELDS (TREE_TYPE (expr)),
false);
expr = build1 (NOP_EXPR, type, expr);
return expr;
}
/* Create an expression whose value is that of EXPR,
converted to type TYPE. The TREE_TYPE of the value
is always TYPE. This function implements all reasonable
@ -4124,33 +4102,25 @@ convert (tree type, tree expr)
case POINTER_TYPE:
case REFERENCE_TYPE:
/* If converting between two pointers to records denoting
both a template and type, adjust if needed to account
for any differing offsets, since one might be negative. */
/* If converting between two thin pointers, adjust if needed to account
for any differing offsets, since one of them might be negative. */
if (TYPE_IS_THIN_POINTER_P (etype) && TYPE_IS_THIN_POINTER_P (type))
{
tree bit_diff
= size_diffop (bit_position (TYPE_FIELDS (TREE_TYPE (etype))),
bit_position (TYPE_FIELDS (TREE_TYPE (type))));
tree byte_diff
= size_binop (CEIL_DIV_EXPR, bit_diff, sbitsize_unit_node);
= size_diffop (byte_position (TYPE_FIELDS (TREE_TYPE (etype))),
byte_position (TYPE_FIELDS (TREE_TYPE (type))));
expr = build1 (NOP_EXPR, type, expr);
TREE_CONSTANT (expr) = TREE_CONSTANT (TREE_OPERAND (expr, 0));
if (integer_zerop (byte_diff))
return expr;
return build_binary_op (POINTER_PLUS_EXPR, type, expr,
fold (convert (sizetype, byte_diff)));
fold_convert (sizetype, byte_diff));
}
/* If converting to a thin pointer, handle specially. */
if (TYPE_IS_THIN_POINTER_P (type)
&& TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)))
return convert_to_thin_pointer (type, expr);
/* If converting fat pointer to normal pointer, get the pointer to the
array and then convert it. */
else if (TYPE_IS_FAT_POINTER_P (etype))
/* If converting fat pointer to normal or thin pointer, get the pointer
to the array and then convert it. */
if (TYPE_IS_FAT_POINTER_P (etype))
expr
= build_component_ref (expr, NULL_TREE, TYPE_FIELDS (etype), false);
@ -4521,7 +4491,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
Likewise for a conversion to an unconstrained array. */
if ((((INTEGRAL_TYPE_P (type)
&& !(code == INTEGER_TYPE && TYPE_VAX_FLOATING_POINT_P (type)))
|| (POINTER_TYPE_P (type) && ! TYPE_IS_THIN_POINTER_P (type))
|| (POINTER_TYPE_P (type) && !TYPE_IS_THIN_POINTER_P (type))
|| (code == RECORD_TYPE && TYPE_JUSTIFIED_MODULAR_P (type)))
&& ((INTEGRAL_TYPE_P (etype)
&& !(ecode == INTEGER_TYPE && TYPE_VAX_FLOATING_POINT_P (etype)))

View File

@ -1398,7 +1398,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
if (TREE_CODE (operand) == POINTER_PLUS_EXPR
&& integer_zerop
(size_binop (PLUS_EXPR, TREE_OPERAND (operand, 1),
DECL_FIELD_OFFSET (TYPE_FIELDS (rec_type))))
byte_position (TYPE_FIELDS (rec_type))))
&& TREE_CODE (TREE_OPERAND (operand, 0)) == NOP_EXPR)
{
operand = TREE_OPERAND (TREE_OPERAND (operand, 0), 0);