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:
parent
210ac0b75b
commit
0d7de0e10b
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue