dbxout.c (dbxout_range_type): Add LOW and HIGH parameters.
* dbxout.c (dbxout_range_type): Add LOW and HIGH parameters. Use them for bounds. (print_int_cst_bounds_in_octal_p): Likewise. (dbxout_type): Adjust calls to above functions. Be prepared to deal with subtypes. * dwarf2out.c (base_type_die): Likewise. (is_subrange_type): Delete. (subrange_type_die): Add LOW and HIGH parameters. Use them for bounds. (modified_type_die): Call subrange_type_for_debug_p on subtypes. * fold-const.c (fold_truth_not_expr) <CONVERT_EXPR>: Do not strip it if the destination type is boolean. (build_range_check): Do not special-case subtypes. (fold_sign_changed_comparison): Likewise. (fold_unary): Likewise. * langhooks-def.h (LANG_HOOKS_GET_SUBRANGE_BOUNDS): Define. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add LANG_HOOKS_GET_SUBRANGE_BOUNDS. * langhooks.h (lang_hooks_for_types): Add get_subrange_bounds. * tree.c (subrange_type_for_debug_p): New predicate based on the former is_subrange_type. * tree.h (subrange_type_for_debug_p): Declare. * tree-chrec.c (avoid_arithmetics_in_type_p): Delete. (convert_affine_scev): Remove call to above function. (chrec_convert_aggressive): Likewise. * tree-ssa.c (useless_type_conversion_p_1): Do not specifically return false for conversions involving subtypes. * tree-vrp.c (vrp_val_max): Do not special-case subtypes. (vrp_val_min): Likewise. (needs_overflow_infinity): Likewise. (extract_range_from_unary_expr): Likewise. ada/ * gcc-interface/ada-tree.h (TYPE_GCC_MIN_VALUE, TYPE_GCC_MAX_VALUE): New macros. (TYPE_RM_VALUES): Likewise. (TYPE_RM_SIZE): Rewrite in terms of TYPE_RM_VALUES. (SET_TYPE_RM_SIZE): New macro. (TYPE_RM_MIN_VALUE, TYPE_RM_MAX_VALUE): Likewise. (SET_TYPE_RM_SIZE, SET_TYPE_RM_MAX_VALUE): Likewise. (TYPE_MIN_VALUE, TYPE_MAX_VALUE): Redefine. * gcc-interface/gigi.h (create_range_type): Declare. * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Modular_Integer_Type> Use SET_TYPE_RM_MAX_VALUE to set the upper bound on the UMT type. <E_Signed_Integer_Subtype>: Build a regular integer type first and then set the RM bounds. Use SET_TYPE_RM_SIZE to set the RM size. <E_Floating_Point_Subtype>: Build a regular floating-point type first and then set the RM bounds. <E_Array_Type>: Use create_range_type instead of build_range_type. <E_Array_Subtype>: Build a regular integer type first and then set the RM bounds for the extra subtype. <E_String_Literal_Subtype>: Use create_range_type instead of build_range_type. <all>: Set the RM bounds for enumeration types and the GCC bounds for floating-point types. (set_rm_size): Use SET_TYPE_RM_SIZE to set the RM size. (make_type_from_size) <INTEGER_TYPE>: Use SET_TYPE_RM_{MIN,MAX}_VALUE to set the bounds. Use SET_TYPE_RM_SIZE to set the RM size. (substitute_in_type) <INTEGER_TYPE>: Deal with GCC bounds for domain types and with RM bounds for subtypes. * gcc-interface/misc.c (LANG_HOOKS_GET_SUBRANGE_BOUNDS): Define. (gnat_print_type) <REAL_TYPE>: New case. <ENUMERAL_TYPE>: Fall through to above case. (gnat_get_subrange_bounds): New function. * gcc-interface/trans.c (add_decl_expr): Mark the trees rooted as TYPE_RM_MIN_VALUE and TYPE_RM_MAX_VALUE, if any. * gcc-interface/utils.c (gnat_init_decl_processing): Use precision 8 for booleans. Adjust and use SET_TYPE_RM_SIZE to set the RM size. (create_range_type): New function. (create_param_decl): Build a regular integer type first and then set the RM bounds for the extra subtype. (unchecked_convert): Remove kludge for 'Valid. * gcc-interface/utils2.c (build_binary_op) <ARRAY_RANGE_REF>: Convert the index to sizetype instead of TYPE_DOMAIN. From-SVN: r147563
This commit is contained in:
parent
331d918689
commit
84fb43a1a4
|
@ -1,3 +1,35 @@
|
|||
2009-05-15 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* dbxout.c (dbxout_range_type): Add LOW and HIGH parameters. Use them
|
||||
for bounds.
|
||||
(print_int_cst_bounds_in_octal_p): Likewise.
|
||||
(dbxout_type): Adjust calls to above functions. Be prepared to deal
|
||||
with subtypes.
|
||||
* dwarf2out.c (base_type_die): Likewise.
|
||||
(is_subrange_type): Delete.
|
||||
(subrange_type_die): Add LOW and HIGH parameters. Use them for bounds.
|
||||
(modified_type_die): Call subrange_type_for_debug_p on subtypes.
|
||||
* fold-const.c (fold_truth_not_expr) <CONVERT_EXPR>: Do not strip it if
|
||||
the destination type is boolean.
|
||||
(build_range_check): Do not special-case subtypes.
|
||||
(fold_sign_changed_comparison): Likewise.
|
||||
(fold_unary): Likewise.
|
||||
* langhooks-def.h (LANG_HOOKS_GET_SUBRANGE_BOUNDS): Define.
|
||||
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add LANG_HOOKS_GET_SUBRANGE_BOUNDS.
|
||||
* langhooks.h (lang_hooks_for_types): Add get_subrange_bounds.
|
||||
* tree.c (subrange_type_for_debug_p): New predicate based on the former
|
||||
is_subrange_type.
|
||||
* tree.h (subrange_type_for_debug_p): Declare.
|
||||
* tree-chrec.c (avoid_arithmetics_in_type_p): Delete.
|
||||
(convert_affine_scev): Remove call to above function.
|
||||
(chrec_convert_aggressive): Likewise.
|
||||
* tree-ssa.c (useless_type_conversion_p_1): Do not specifically return
|
||||
false for conversions involving subtypes.
|
||||
* tree-vrp.c (vrp_val_max): Do not special-case subtypes.
|
||||
(vrp_val_min): Likewise.
|
||||
(needs_overflow_infinity): Likewise.
|
||||
(extract_range_from_unary_expr): Likewise.
|
||||
|
||||
2009-05-15 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* config/frv/frv.h: Clean up references to GO_IF_LEGITIMATE_ADDRESS.
|
||||
|
|
|
@ -1,3 +1,47 @@
|
|||
2009-05-15 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/ada-tree.h (TYPE_GCC_MIN_VALUE, TYPE_GCC_MAX_VALUE):
|
||||
New macros.
|
||||
(TYPE_RM_VALUES): Likewise.
|
||||
(TYPE_RM_SIZE): Rewrite in terms of TYPE_RM_VALUES.
|
||||
(SET_TYPE_RM_SIZE): New macro.
|
||||
(TYPE_RM_MIN_VALUE, TYPE_RM_MAX_VALUE): Likewise.
|
||||
(SET_TYPE_RM_SIZE, SET_TYPE_RM_MAX_VALUE): Likewise.
|
||||
(TYPE_MIN_VALUE, TYPE_MAX_VALUE): Redefine.
|
||||
* gcc-interface/gigi.h (create_range_type): Declare.
|
||||
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Modular_Integer_Type>
|
||||
Use SET_TYPE_RM_MAX_VALUE to set the upper bound on the UMT type.
|
||||
<E_Signed_Integer_Subtype>: Build a regular integer type first and
|
||||
then set the RM bounds. Use SET_TYPE_RM_SIZE to set the RM size.
|
||||
<E_Floating_Point_Subtype>: Build a regular floating-point type first
|
||||
and then set the RM bounds.
|
||||
<E_Array_Type>: Use create_range_type instead of build_range_type.
|
||||
<E_Array_Subtype>: Build a regular integer type first and then set
|
||||
the RM bounds for the extra subtype.
|
||||
<E_String_Literal_Subtype>: Use create_range_type instead of
|
||||
build_range_type.
|
||||
<all>: Set the RM bounds for enumeration types and the GCC bounds for
|
||||
floating-point types.
|
||||
(set_rm_size): Use SET_TYPE_RM_SIZE to set the RM size.
|
||||
(make_type_from_size) <INTEGER_TYPE>: Use SET_TYPE_RM_{MIN,MAX}_VALUE
|
||||
to set the bounds. Use SET_TYPE_RM_SIZE to set the RM size.
|
||||
(substitute_in_type) <INTEGER_TYPE>: Deal with GCC bounds for domain
|
||||
types and with RM bounds for subtypes.
|
||||
* gcc-interface/misc.c (LANG_HOOKS_GET_SUBRANGE_BOUNDS): Define.
|
||||
(gnat_print_type) <REAL_TYPE>: New case.
|
||||
<ENUMERAL_TYPE>: Fall through to above case.
|
||||
(gnat_get_subrange_bounds): New function.
|
||||
* gcc-interface/trans.c (add_decl_expr): Mark the trees rooted as
|
||||
TYPE_RM_MIN_VALUE and TYPE_RM_MAX_VALUE, if any.
|
||||
* gcc-interface/utils.c (gnat_init_decl_processing): Use precision 8
|
||||
for booleans. Adjust and use SET_TYPE_RM_SIZE to set the RM size.
|
||||
(create_range_type): New function.
|
||||
(create_param_decl): Build a regular integer type first and then set
|
||||
the RM bounds for the extra subtype.
|
||||
(unchecked_convert): Remove kludge for 'Valid.
|
||||
* gcc-interface/utils2.c (build_binary_op) <ARRAY_RANGE_REF>: Convert
|
||||
the index to sizetype instead of TYPE_DOMAIN.
|
||||
|
||||
2009-05-14 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/decl.c (elaborate_expression_1): Remove GNAT_EXPR
|
||||
|
|
|
@ -167,9 +167,87 @@ struct GTY(()) lang_decl { tree t; };
|
|||
mechanism refer to the routine gnat_to_gnu_entity. */
|
||||
#define TYPE_CI_CO_LIST(NODE) TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE))
|
||||
|
||||
/* For integral types, this is the RM size of the type. */
|
||||
/* For numerical types, this is the GCC lower bound of the type. The GCC
|
||||
type system is based on the invariant that an object X of a given type
|
||||
cannot hold at run time a value smaller than its lower bound; otherwise
|
||||
the behavior is undefined. The optimizer takes advantage of this and
|
||||
considers that the assertion X >= LB is always true. */
|
||||
#define TYPE_GCC_MIN_VALUE(NODE) (NUMERICAL_TYPE_CHECK (NODE)->type.minval)
|
||||
|
||||
/* For numerical types, this is the GCC upper bound of the type. The GCC
|
||||
type system is based on the invariant that an object X of a given type
|
||||
cannot hold at run time a value larger than its upper bound; otherwise
|
||||
the behavior is undefined. The optimizer takes advantage of this and
|
||||
considers that the assertion X <= UB is always true. */
|
||||
#define TYPE_GCC_MAX_VALUE(NODE) (NUMERICAL_TYPE_CHECK (NODE)->type.maxval)
|
||||
|
||||
/* For numerical types, this holds various RM-defined values. */
|
||||
#define TYPE_RM_VALUES(NODE) TYPE_LANG_SLOT_1 (NUMERICAL_TYPE_CHECK (NODE))
|
||||
|
||||
/* For numerical types, this is the RM size of the type, aka its precision.
|
||||
There is a discrepancy between what is called precision here (and more
|
||||
generally throughout gigi) and what is called precision in the GCC type
|
||||
system: in the former case it's TYPE_RM_SIZE whereas it's TYPE_PRECISION
|
||||
in the latter case. They are not identical because of the need to support
|
||||
invalid values.
|
||||
|
||||
These values can be outside the range of values allowed by the RM size
|
||||
but they must nevertheless be valid in the GCC type system, otherwise
|
||||
the optimizer can pretend that they simply don't exist. Therefore they
|
||||
must be within the range of values allowed by the precision in the GCC
|
||||
sense, hence TYPE_PRECISION be set to the Esize, not the RM size. */
|
||||
#define TYPE_RM_SIZE(NODE) \
|
||||
TYPE_LANG_SLOT_1 (TREE_CHECK3 (NODE, ENUMERAL_TYPE, BOOLEAN_TYPE, INTEGER_TYPE))
|
||||
(TYPE_RM_VALUES (NODE) ? TREE_VEC_ELT (TYPE_RM_VALUES (NODE), 0) : NULL_TREE)
|
||||
#define SET_TYPE_RM_SIZE(NODE, X) \
|
||||
TREE_VEC_ELT ((TYPE_RM_VALUES (NODE) \
|
||||
= (TYPE_RM_VALUES (NODE) \
|
||||
? TYPE_RM_VALUES (NODE) : make_tree_vec (3))), 0) = (X)
|
||||
|
||||
/* For numerical types, this is the RM lower bound of the type. There is
|
||||
again a discrepancy between this lower bound and the GCC lower bound,
|
||||
again because of the need to support invalid values.
|
||||
|
||||
These values can be outside the range of values allowed by the RM lower
|
||||
bound but they must nevertheless be valid in the GCC type system, otherwise
|
||||
the optimizer can pretend that they simply don't exist. Therefore they
|
||||
must be within the range of values allowed by the lower bound in the GCC
|
||||
sense, hence the GCC lower bound be set to that of the base type. */
|
||||
#define TYPE_RM_MIN_VALUE(NODE) \
|
||||
(TYPE_RM_VALUES (NODE) ? TREE_VEC_ELT (TYPE_RM_VALUES (NODE), 1) : NULL_TREE)
|
||||
#define SET_TYPE_RM_MIN_VALUE(NODE, X) \
|
||||
TREE_VEC_ELT ((TYPE_RM_VALUES (NODE) \
|
||||
= (TYPE_RM_VALUES (NODE) \
|
||||
? TYPE_RM_VALUES (NODE) : make_tree_vec (3))), 1) = (X)
|
||||
|
||||
/* For numerical types, this is the RM upper bound of the type. There is
|
||||
again a discrepancy between this upper bound and the GCC upper bound,
|
||||
again because of the need to support invalid values.
|
||||
|
||||
These values can be outside the range of values allowed by the RM upper
|
||||
bound but they must nevertheless be valid in the GCC type system, otherwise
|
||||
the optimizer can pretend that they simply don't exist. Therefore they
|
||||
must be within the range of values allowed by the upper bound in the GCC
|
||||
sense, hence the GCC upper bound be set to that of the base type. */
|
||||
#define TYPE_RM_MAX_VALUE(NODE) \
|
||||
(TYPE_RM_VALUES (NODE) ? TREE_VEC_ELT (TYPE_RM_VALUES (NODE), 2) : NULL_TREE)
|
||||
#define SET_TYPE_RM_MAX_VALUE(NODE, X) \
|
||||
TREE_VEC_ELT ((TYPE_RM_VALUES (NODE) \
|
||||
= (TYPE_RM_VALUES (NODE) \
|
||||
? TYPE_RM_VALUES (NODE) : make_tree_vec (3))), 2) = (X)
|
||||
|
||||
/* For numerical types, this is the lower bound of the type, i.e. the RM lower
|
||||
bound for language-defined types and the GCC lower bound for others. */
|
||||
#undef TYPE_MIN_VALUE
|
||||
#define TYPE_MIN_VALUE(NODE) \
|
||||
(TYPE_RM_MIN_VALUE (NODE) \
|
||||
? TYPE_RM_MIN_VALUE (NODE) : TYPE_GCC_MIN_VALUE (NODE))
|
||||
|
||||
/* For numerical types, this is the upper bound of the type, i.e. the RM upper
|
||||
bound for language-defined types and the GCC upper bound for others. */
|
||||
#undef TYPE_MAX_VALUE
|
||||
#define TYPE_MAX_VALUE(NODE) \
|
||||
(TYPE_RM_MAX_VALUE (NODE) \
|
||||
? TYPE_RM_MAX_VALUE (NODE) : TYPE_GCC_MAX_VALUE (NODE))
|
||||
|
||||
/* In an UNCONSTRAINED_ARRAY_TYPE, points to the record containing both
|
||||
the template and object.
|
||||
|
|
|
@ -1503,7 +1503,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
&& !tree_int_cst_equal (gnu_high, TYPE_MAX_VALUE (gnu_type)))
|
||||
{
|
||||
tree gnu_subtype = make_unsigned_type (esize);
|
||||
TYPE_MAX_VALUE (gnu_subtype) = gnu_high;
|
||||
SET_TYPE_RM_MAX_VALUE (gnu_subtype, gnu_high);
|
||||
TREE_TYPE (gnu_subtype) = gnu_type;
|
||||
TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
|
||||
TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "UMT");
|
||||
|
@ -1519,7 +1519,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
case E_Decimal_Fixed_Point_Subtype:
|
||||
|
||||
/* For integral subtypes, we make a new INTEGER_TYPE. Note that we do
|
||||
not want to call build_range_type since we would like each subtype
|
||||
not want to call create_range_type since we would like each subtype
|
||||
node to be distinct. ??? Historically this was in preparation for
|
||||
when memory aliasing is implemented, but that's obsolete now given
|
||||
the call to relate_alias_sets below.
|
||||
|
@ -1539,39 +1539,37 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
|| !Compile_Time_Known_Value (Type_High_Bound (gnat_entity))))
|
||||
gnat_to_gnu_entity (Ancestor_Subtype (gnat_entity), gnu_expr, 0);
|
||||
|
||||
gnu_type = make_node (INTEGER_TYPE);
|
||||
TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
|
||||
/* Set the precision to the Esize except for bit-packed arrays. */
|
||||
if (Is_Packed_Array_Type (gnat_entity)
|
||||
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
|
||||
esize = UI_To_Int (RM_Size (gnat_entity));
|
||||
|
||||
/* This should be an unsigned type if the base type is unsigned or
|
||||
if the lower bound is constant and non-negative or if the type
|
||||
is biased. */
|
||||
TYPE_UNSIGNED (gnu_type) = (Is_Unsigned_Type (Etype (gnat_entity))
|
||||
|| Is_Unsigned_Type (gnat_entity)
|
||||
|| Has_Biased_Representation (gnat_entity));
|
||||
if (Is_Unsigned_Type (Etype (gnat_entity))
|
||||
|| Is_Unsigned_Type (gnat_entity)
|
||||
|| Has_Biased_Representation (gnat_entity))
|
||||
gnu_type = make_unsigned_type (esize);
|
||||
else
|
||||
gnu_type = make_signed_type (esize);
|
||||
TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
|
||||
|
||||
/* Set the precision to the Esize except for bit-packed arrays and
|
||||
subtypes of Standard.Boolean. */
|
||||
if (Is_Packed_Array_Type (gnat_entity)
|
||||
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
|
||||
esize = UI_To_Int (RM_Size (gnat_entity));
|
||||
else if (Is_Boolean_Type (gnat_entity))
|
||||
esize = 1;
|
||||
SET_TYPE_RM_MIN_VALUE
|
||||
(gnu_type,
|
||||
convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_Low_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("L"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity))));
|
||||
|
||||
TYPE_PRECISION (gnu_type) = esize;
|
||||
|
||||
TYPE_MIN_VALUE (gnu_type)
|
||||
= convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_Low_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("L"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity)));
|
||||
|
||||
TYPE_MAX_VALUE (gnu_type)
|
||||
= convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_High_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("U"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity)));
|
||||
SET_TYPE_RM_MAX_VALUE
|
||||
(gnu_type,
|
||||
convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_High_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("U"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity))));
|
||||
|
||||
/* One of the above calls might have caused us to be elaborated,
|
||||
so don't blow up if so. */
|
||||
|
@ -1584,8 +1582,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
TYPE_BIASED_REPRESENTATION_P (gnu_type)
|
||||
= Has_Biased_Representation (gnat_entity);
|
||||
|
||||
layout_type (gnu_type);
|
||||
|
||||
/* Attach the TYPE_STUB_DECL in case we have a parallel type. */
|
||||
TYPE_STUB_DECL (gnu_type)
|
||||
= create_type_stub_decl (gnu_entity_name, gnu_type);
|
||||
|
@ -1616,8 +1612,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
tree gnu_field_type, gnu_field;
|
||||
|
||||
/* Set the RM size before wrapping up the type. */
|
||||
TYPE_RM_SIZE (gnu_type)
|
||||
= UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
|
||||
SET_TYPE_RM_SIZE (gnu_type,
|
||||
UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
|
||||
TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
|
||||
gnu_field_type = gnu_type;
|
||||
|
||||
|
@ -1669,8 +1665,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
tree gnu_field_type, gnu_field;
|
||||
|
||||
/* Set the RM size before wrapping up the type. */
|
||||
TYPE_RM_SIZE (gnu_type)
|
||||
= UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
|
||||
SET_TYPE_RM_SIZE (gnu_type,
|
||||
UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
|
||||
gnu_field_type = gnu_type;
|
||||
|
||||
gnu_type = make_node (RECORD_TYPE);
|
||||
|
@ -1741,20 +1737,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
gnu_type = make_node (REAL_TYPE);
|
||||
TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
|
||||
TYPE_PRECISION (gnu_type) = fp_size_to_prec (esize);
|
||||
TYPE_GCC_MIN_VALUE (gnu_type)
|
||||
= TYPE_GCC_MIN_VALUE (TREE_TYPE (gnu_type));
|
||||
TYPE_GCC_MAX_VALUE (gnu_type)
|
||||
= TYPE_GCC_MAX_VALUE (TREE_TYPE (gnu_type));
|
||||
layout_type (gnu_type);
|
||||
|
||||
TYPE_MIN_VALUE (gnu_type)
|
||||
= convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_Low_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("L"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity)));
|
||||
SET_TYPE_RM_MIN_VALUE
|
||||
(gnu_type,
|
||||
convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_Low_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("L"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity))));
|
||||
|
||||
TYPE_MAX_VALUE (gnu_type)
|
||||
= convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_High_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("U"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity)));
|
||||
SET_TYPE_RM_MAX_VALUE
|
||||
(gnu_type,
|
||||
convert (TREE_TYPE (gnu_type),
|
||||
elaborate_expression (Type_High_Bound (gnat_entity),
|
||||
gnat_entity, get_identifier ("U"),
|
||||
definition, true,
|
||||
Needs_Debug_Info (gnat_entity))));
|
||||
|
||||
/* One of the above calls might have caused us to be elaborated,
|
||||
so don't blow up if so. */
|
||||
|
@ -1764,8 +1767,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
break;
|
||||
}
|
||||
|
||||
layout_type (gnu_type);
|
||||
|
||||
/* Inherit our alias set from what we're a subtype of, as for
|
||||
integer subtypes. */
|
||||
relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY);
|
||||
|
@ -1899,8 +1900,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
gnu_index_types[index]
|
||||
= create_index_type (convert (sizetype, gnu_min),
|
||||
convert (sizetype, gnu_max),
|
||||
build_range_type (gnu_ind_subtype,
|
||||
gnu_min, gnu_max),
|
||||
create_range_type (gnu_ind_subtype,
|
||||
gnu_min, gnu_max),
|
||||
gnat_entity);
|
||||
/* Update the maximum size of the array, in elements. */
|
||||
gnu_max_size
|
||||
|
@ -2585,19 +2586,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
subtype if necessary. */
|
||||
if (TYPE_MODULAR_P (gnu_inner_type))
|
||||
{
|
||||
tree gnu_subtype = make_node (INTEGER_TYPE);
|
||||
tree gnu_subtype
|
||||
= make_unsigned_type (TYPE_PRECISION (gnu_inner_type));
|
||||
TREE_TYPE (gnu_subtype) = gnu_inner_type;
|
||||
TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
|
||||
|
||||
TYPE_UNSIGNED (gnu_subtype) = 1;
|
||||
TYPE_PRECISION (gnu_subtype)
|
||||
= TYPE_PRECISION (gnu_inner_type);
|
||||
TYPE_MIN_VALUE (gnu_subtype)
|
||||
= TYPE_MIN_VALUE (gnu_inner_type);
|
||||
TYPE_MAX_VALUE (gnu_subtype)
|
||||
= TYPE_MAX_VALUE (gnu_inner_type);
|
||||
layout_type (gnu_subtype);
|
||||
|
||||
SET_TYPE_RM_MIN_VALUE (gnu_subtype,
|
||||
TYPE_MIN_VALUE (gnu_inner_type));
|
||||
SET_TYPE_RM_MAX_VALUE (gnu_subtype,
|
||||
TYPE_MAX_VALUE (gnu_inner_type));
|
||||
gnu_inner_type = gnu_subtype;
|
||||
}
|
||||
|
||||
|
@ -2665,9 +2661,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
tree gnu_index_type
|
||||
= create_index_type (convert (sizetype, gnu_lower_bound),
|
||||
convert (sizetype, gnu_upper_bound),
|
||||
build_range_type (gnu_string_index_type,
|
||||
gnu_lower_bound,
|
||||
gnu_upper_bound),
|
||||
create_range_type (gnu_string_index_type,
|
||||
gnu_lower_bound,
|
||||
gnu_upper_bound),
|
||||
gnat_entity);
|
||||
|
||||
gnu_type
|
||||
|
@ -4743,6 +4739,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
|| (kind == E_Floating_Point_Type && !Vax_Float (gnat_entity)))
|
||||
{
|
||||
tree gnu_scalar_type = gnu_type;
|
||||
tree gnu_low_bound, gnu_high_bound;
|
||||
|
||||
/* If this is a padded type, we need to use the underlying type. */
|
||||
if (TREE_CODE (gnu_scalar_type) == RECORD_TYPE
|
||||
|
@ -4754,19 +4751,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
|||
if (!longest_float_type_node && kind == E_Floating_Point_Type)
|
||||
longest_float_type_node = gnu_scalar_type;
|
||||
|
||||
TYPE_MIN_VALUE (gnu_scalar_type)
|
||||
= gnat_to_gnu (Type_Low_Bound (gnat_entity));
|
||||
TYPE_MAX_VALUE (gnu_scalar_type)
|
||||
= gnat_to_gnu (Type_High_Bound (gnat_entity));
|
||||
gnu_low_bound = gnat_to_gnu (Type_Low_Bound (gnat_entity));
|
||||
gnu_high_bound = gnat_to_gnu (Type_High_Bound (gnat_entity));
|
||||
|
||||
/* For enumeration types, write full debugging information. */
|
||||
if (kind == E_Enumeration_Type)
|
||||
{
|
||||
/* Since this has both a typedef and a tag, avoid outputting
|
||||
the name twice. */
|
||||
/* Enumeration types have specific RM bounds. */
|
||||
SET_TYPE_RM_MIN_VALUE (gnu_scalar_type, gnu_low_bound);
|
||||
SET_TYPE_RM_MAX_VALUE (gnu_scalar_type, gnu_high_bound);
|
||||
|
||||
/* Write full debugging information. Since this has both a
|
||||
typedef and a tag, avoid outputting the name twice. */
|
||||
DECL_ARTIFICIAL (gnu_decl) = 1;
|
||||
rest_of_type_decl_compilation (gnu_decl);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Floating-point types don't have specific RM bounds. */
|
||||
TYPE_GCC_MIN_VALUE (gnu_scalar_type) = gnu_low_bound;
|
||||
TYPE_GCC_MAX_VALUE (gnu_scalar_type) = gnu_high_bound;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we deferred processing of incomplete types, re-enable it. If there
|
||||
|
@ -7391,7 +7396,7 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
|
|||
&& Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
|
||||
|| (TREE_CODE (gnu_type) == ENUMERAL_TYPE
|
||||
|| TREE_CODE (gnu_type) == BOOLEAN_TYPE))
|
||||
TYPE_RM_SIZE (gnu_type) = size;
|
||||
SET_TYPE_RM_SIZE (gnu_type, size);
|
||||
|
||||
/* ...or the Ada size for record and union types. */
|
||||
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
|
||||
|
@ -7443,10 +7448,12 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
|
|||
else
|
||||
new_type = make_signed_type (size);
|
||||
TREE_TYPE (new_type) = TREE_TYPE (type) ? TREE_TYPE (type) : type;
|
||||
TYPE_MIN_VALUE (new_type)
|
||||
= convert (TREE_TYPE (new_type), TYPE_MIN_VALUE (type));
|
||||
TYPE_MAX_VALUE (new_type)
|
||||
= convert (TREE_TYPE (new_type), TYPE_MAX_VALUE (type));
|
||||
SET_TYPE_RM_MIN_VALUE (new_type,
|
||||
convert (TREE_TYPE (new_type),
|
||||
TYPE_MIN_VALUE (type)));
|
||||
SET_TYPE_RM_MAX_VALUE (new_type,
|
||||
convert (TREE_TYPE (new_type),
|
||||
TYPE_MAX_VALUE (type)));
|
||||
/* Propagate the name to avoid creating a fake subrange type. */
|
||||
if (TYPE_NAME (type))
|
||||
{
|
||||
|
@ -7456,7 +7463,7 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
|
|||
TYPE_NAME (new_type) = TYPE_NAME (type);
|
||||
}
|
||||
TYPE_BIASED_REPRESENTATION_P (new_type) = biased_p;
|
||||
TYPE_RM_SIZE (new_type) = bitsize_int (size);
|
||||
SET_TYPE_RM_SIZE (new_type, bitsize_int (size));
|
||||
return new_type;
|
||||
|
||||
case RECORD_TYPE:
|
||||
|
@ -7703,18 +7710,20 @@ substitute_in_type (tree t, tree f, tree r)
|
|||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
case REAL_TYPE:
|
||||
if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t))
|
||||
|| CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t)))
|
||||
{
|
||||
tree low = SUBSTITUTE_IN_EXPR (TYPE_MIN_VALUE (t), f, r);
|
||||
tree high = SUBSTITUTE_IN_EXPR (TYPE_MAX_VALUE (t), f, r);
|
||||
|
||||
if (low == TYPE_MIN_VALUE (t) && high == TYPE_MAX_VALUE (t))
|
||||
/* First the domain types of arrays. */
|
||||
if (CONTAINS_PLACEHOLDER_P (TYPE_GCC_MIN_VALUE (t))
|
||||
|| CONTAINS_PLACEHOLDER_P (TYPE_GCC_MAX_VALUE (t)))
|
||||
{
|
||||
tree low = SUBSTITUTE_IN_EXPR (TYPE_GCC_MIN_VALUE (t), f, r);
|
||||
tree high = SUBSTITUTE_IN_EXPR (TYPE_GCC_MAX_VALUE (t), f, r);
|
||||
|
||||
if (low == TYPE_GCC_MIN_VALUE (t) && high == TYPE_GCC_MAX_VALUE (t))
|
||||
return t;
|
||||
|
||||
new = copy_type (t);
|
||||
TYPE_MIN_VALUE (new) = low;
|
||||
TYPE_MAX_VALUE (new) = high;
|
||||
TYPE_GCC_MIN_VALUE (new) = low;
|
||||
TYPE_GCC_MAX_VALUE (new) = high;
|
||||
|
||||
if (TREE_CODE (t) == INTEGER_TYPE && TYPE_INDEX_TYPE (t))
|
||||
SET_TYPE_INDEX_TYPE
|
||||
|
@ -7723,6 +7732,23 @@ substitute_in_type (tree t, tree f, tree r)
|
|||
return new;
|
||||
}
|
||||
|
||||
/* Then the subtypes. */
|
||||
if (CONTAINS_PLACEHOLDER_P (TYPE_RM_MIN_VALUE (t))
|
||||
|| CONTAINS_PLACEHOLDER_P (TYPE_RM_MAX_VALUE (t)))
|
||||
{
|
||||
tree low = SUBSTITUTE_IN_EXPR (TYPE_RM_MIN_VALUE (t), f, r);
|
||||
tree high = SUBSTITUTE_IN_EXPR (TYPE_RM_MAX_VALUE (t), f, r);
|
||||
|
||||
if (low == TYPE_RM_MIN_VALUE (t) && high == TYPE_RM_MAX_VALUE (t))
|
||||
return t;
|
||||
|
||||
new = copy_type (t);
|
||||
SET_TYPE_RM_MIN_VALUE (new, low);
|
||||
SET_TYPE_RM_MAX_VALUE (new, high);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
|
|
|
@ -558,6 +558,10 @@ extern tree copy_type (tree type);
|
|||
extern tree create_index_type (tree min, tree max, tree index,
|
||||
Node_Id gnat_node);
|
||||
|
||||
/* Return a subtype of TYPE with range MIN to MAX. If TYPE is NULL,
|
||||
sizetype is used. */
|
||||
extern tree create_range_type (tree type, tree min, tree max);
|
||||
|
||||
/* Return a TYPE_DECL node suitable for the TYPE_STUB_DECL field of a type.
|
||||
TYPE_NAME gives the name of the type and TYPE is a ..._TYPE node giving
|
||||
its data type. */
|
||||
|
|
|
@ -78,6 +78,7 @@ static int gnat_eh_type_covers (tree, tree);
|
|||
static void gnat_parse_file (int);
|
||||
static void internal_error_function (const char *, va_list *);
|
||||
static tree gnat_type_max_size (const_tree);
|
||||
static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
|
||||
|
||||
/* Definitions for our language-specific hooks. */
|
||||
|
||||
|
@ -125,6 +126,8 @@ static tree gnat_type_max_size (const_tree);
|
|||
#define LANG_HOOKS_TYPE_FOR_SIZE gnat_type_for_size
|
||||
#undef LANG_HOOKS_TYPES_COMPATIBLE_P
|
||||
#define LANG_HOOKS_TYPES_COMPATIBLE_P gnat_types_compatible_p
|
||||
#undef LANG_HOOKS_GET_SUBRANGE_BOUNDS
|
||||
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS gnat_get_subrange_bounds
|
||||
#undef LANG_HOOKS_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table
|
||||
#undef LANG_HOOKS_BUILTIN_FUNCTION
|
||||
|
@ -513,6 +516,12 @@ gnat_print_type (FILE *file, tree node, int indent)
|
|||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
print_node_brief (file, "RM size", TYPE_RM_SIZE (node), indent + 4);
|
||||
|
||||
/* ... fall through ... */
|
||||
|
||||
case REAL_TYPE:
|
||||
print_node_brief (file, "RM min", TYPE_RM_MIN_VALUE (node), indent + 4);
|
||||
print_node_brief (file, "RM max", TYPE_RM_MAX_VALUE (node), indent + 4);
|
||||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
|
@ -644,6 +653,18 @@ gnat_type_max_size (const_tree gnu_type)
|
|||
return max_unitsize;
|
||||
}
|
||||
|
||||
/* GNU_TYPE is a subtype of an integral type. Set LOWVAL to the low bound
|
||||
and HIGHVAL to the high bound, respectively. */
|
||||
|
||||
static void
|
||||
gnat_get_subrange_bounds (const_tree gnu_type, tree *lowval, tree *highval)
|
||||
{
|
||||
tree min = TYPE_MIN_VALUE (gnu_type);
|
||||
tree max = TYPE_MAX_VALUE (gnu_type);
|
||||
*lowval = TREE_CONSTANT (min) ? min : TYPE_GCC_MIN_VALUE (gnu_type);
|
||||
*highval = TREE_CONSTANT (max) ? max : TYPE_GCC_MAX_VALUE (gnu_type);
|
||||
}
|
||||
|
||||
/* GNU_TYPE is a type. Determine if it should be passed by reference by
|
||||
default. */
|
||||
|
||||
|
|
|
@ -5562,6 +5562,7 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
|
|||
Note that walk_tree knows how to deal with TYPE_DECL, but neither
|
||||
VAR_DECL nor CONST_DECL. This appears to be somewhat arbitrary. */
|
||||
mark_visited (&gnu_stmt);
|
||||
|
||||
if (TREE_CODE (gnu_decl) == VAR_DECL
|
||||
|| TREE_CODE (gnu_decl) == CONST_DECL)
|
||||
{
|
||||
|
@ -5569,13 +5570,31 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
|
|||
mark_visited (&DECL_SIZE_UNIT (gnu_decl));
|
||||
mark_visited (&DECL_INITIAL (gnu_decl));
|
||||
}
|
||||
/* In any case, we have to deal with our own TYPE_ADA_SIZE field. */
|
||||
if (TREE_CODE (gnu_decl) == TYPE_DECL
|
||||
&& (TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == UNION_TYPE
|
||||
|| TREE_CODE (type) == QUAL_UNION_TYPE)
|
||||
&& (t = TYPE_ADA_SIZE (type)))
|
||||
mark_visited (&t);
|
||||
|
||||
/* In any case, we have to deal with our own fields. */
|
||||
else if (TREE_CODE (gnu_decl) == TYPE_DECL)
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case QUAL_UNION_TYPE:
|
||||
if ((t = TYPE_ADA_SIZE (type)))
|
||||
mark_visited (&t);
|
||||
break;
|
||||
|
||||
case INTEGER_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
case REAL_TYPE:
|
||||
if ((t = TYPE_RM_MIN_VALUE (type)))
|
||||
mark_visited (&t);
|
||||
if ((t = TYPE_RM_MAX_VALUE (type)))
|
||||
mark_visited (&t);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
add_stmt_with_node (gnu_stmt, gnat_entity);
|
||||
|
|
|
@ -530,12 +530,14 @@ gnat_init_decl_processing (void)
|
|||
set_sizetype (size_type_node);
|
||||
|
||||
/* In Ada, we use an unsigned 8-bit type for the default boolean type. */
|
||||
boolean_type_node = make_node (BOOLEAN_TYPE);
|
||||
TYPE_PRECISION (boolean_type_node) = 1;
|
||||
fixup_unsigned_type (boolean_type_node);
|
||||
TYPE_RM_SIZE (boolean_type_node) = bitsize_int (1);
|
||||
boolean_type_node = make_unsigned_type (8);
|
||||
TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
|
||||
SET_TYPE_RM_MAX_VALUE (boolean_type_node,
|
||||
build_int_cst (boolean_type_node, 1));
|
||||
SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
|
||||
|
||||
build_common_tree_nodes_2 (0);
|
||||
boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
|
||||
|
||||
ptr_void_type_node = build_pointer_type (void_type_node);
|
||||
}
|
||||
|
@ -1195,6 +1197,42 @@ create_index_type (tree min, tree max, tree index, Node_Id gnat_node)
|
|||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Return a subtype of TYPE with range MIN to MAX. If TYPE is NULL,
|
||||
sizetype is used. */
|
||||
|
||||
tree
|
||||
create_range_type (tree type, tree min, tree max)
|
||||
{
|
||||
tree range_type;
|
||||
|
||||
if (type == NULL_TREE)
|
||||
type = sizetype;
|
||||
|
||||
/* First build a type with the base range. */
|
||||
range_type
|
||||
= build_range_type (type, TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
|
||||
|
||||
min = convert (type, min);
|
||||
max = convert (type, max);
|
||||
|
||||
/* If this type has the TYPE_RM_{MIN,MAX}_VALUE we want, return it. */
|
||||
if (TYPE_RM_MIN_VALUE (range_type)
|
||||
&& TYPE_RM_MAX_VALUE (range_type)
|
||||
&& operand_equal_p (TYPE_RM_MIN_VALUE (range_type), min, 0)
|
||||
&& operand_equal_p (TYPE_RM_MAX_VALUE (range_type), max, 0))
|
||||
return range_type;
|
||||
|
||||
/* Otherwise, if TYPE_RM_{MIN,MAX}_VALUE is set, make a copy. */
|
||||
if (TYPE_RM_MIN_VALUE (range_type) || TYPE_RM_MAX_VALUE (range_type))
|
||||
range_type = copy_type (range_type);
|
||||
|
||||
/* Then set the actual range. */
|
||||
SET_TYPE_RM_MIN_VALUE (range_type, min);
|
||||
SET_TYPE_RM_MAX_VALUE (range_type, max);
|
||||
|
||||
return range_type;
|
||||
}
|
||||
|
||||
/* Return a TYPE_DECL node suitable for the TYPE_STUB_DECL field of a type.
|
||||
TYPE_NAME gives the name of the type and TYPE is a ..._TYPE node giving
|
||||
|
@ -1581,16 +1619,12 @@ create_param_decl (tree param_name, tree param_type, bool readonly)
|
|||
if (TREE_CODE (param_type) == INTEGER_TYPE
|
||||
&& TYPE_BIASED_REPRESENTATION_P (param_type))
|
||||
{
|
||||
tree subtype = make_node (INTEGER_TYPE);
|
||||
tree subtype
|
||||
= make_unsigned_type (TYPE_PRECISION (integer_type_node));
|
||||
TREE_TYPE (subtype) = integer_type_node;
|
||||
TYPE_BIASED_REPRESENTATION_P (subtype) = 1;
|
||||
|
||||
TYPE_UNSIGNED (subtype) = 1;
|
||||
TYPE_PRECISION (subtype) = TYPE_PRECISION (integer_type_node);
|
||||
TYPE_MIN_VALUE (subtype) = TYPE_MIN_VALUE (param_type);
|
||||
TYPE_MAX_VALUE (subtype) = TYPE_MAX_VALUE (param_type);
|
||||
layout_type (subtype);
|
||||
|
||||
SET_TYPE_RM_MIN_VALUE (subtype, TYPE_MIN_VALUE (param_type));
|
||||
SET_TYPE_RM_MAX_VALUE (subtype, TYPE_MAX_VALUE (param_type));
|
||||
param_type = subtype;
|
||||
}
|
||||
else
|
||||
|
@ -4288,8 +4322,7 @@ maybe_unconstrained_array (tree exp)
|
|||
}
|
||||
|
||||
/* Return true if EXPR is an expression that can be folded as an operand
|
||||
of a VIEW_CONVERT_EXPR. See the head comment of unchecked_convert for
|
||||
the rationale. */
|
||||
of a VIEW_CONVERT_EXPR. See ada-tree.h for a complete rationale. */
|
||||
|
||||
static bool
|
||||
can_fold_for_view_convert_p (tree expr)
|
||||
|
@ -4337,22 +4370,7 @@ can_fold_for_view_convert_p (tree expr)
|
|||
|
||||
we expect the 8 bits at Vbits'Address to always contain Value, while
|
||||
their original location depends on the endianness, at Value'Address
|
||||
on a little-endian architecture but not on a big-endian one.
|
||||
|
||||
??? There is a problematic discrepancy between what is called precision
|
||||
here (and more generally throughout gigi) for integral types and what is
|
||||
called precision in the middle-end. In the former case it's the RM size
|
||||
as given by TYPE_RM_SIZE (or rm_size) whereas it's TYPE_PRECISION in the
|
||||
latter case, the hitch being that they are not equal when they matter,
|
||||
that is when the number of value bits is not equal to the type's size:
|
||||
TYPE_RM_SIZE does give the number of value bits but TYPE_PRECISION is set
|
||||
to the size. The sole exception are BOOLEAN_TYPEs for which both are 1.
|
||||
|
||||
The consequence is that gigi must duplicate code bridging the gap between
|
||||
the type's size and its precision that exists for TYPE_PRECISION in the
|
||||
middle-end, because the latter knows nothing about TYPE_RM_SIZE, and be
|
||||
wary of transformations applied in the middle-end based on TYPE_PRECISION
|
||||
because this value doesn't reflect the actual precision for Ada. */
|
||||
on a little-endian architecture but not on a big-endian one. */
|
||||
|
||||
tree
|
||||
unchecked_convert (tree type, tree expr, bool notrunc_p)
|
||||
|
@ -4397,43 +4415,6 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
|
|||
expr = convert (rtype, expr);
|
||||
expr = build1 (NOP_EXPR, type, expr);
|
||||
}
|
||||
|
||||
/* We have another special case: if we are unchecked converting either
|
||||
a subtype or a type with limited range into a base type, we need to
|
||||
ensure that VRP doesn't propagate range information because this
|
||||
conversion may be done precisely to validate that the object is
|
||||
within the range it is supposed to have. */
|
||||
else if (TREE_CODE (expr) != INTEGER_CST
|
||||
&& TREE_CODE (type) == INTEGER_TYPE && !TREE_TYPE (type)
|
||||
&& ((TREE_CODE (etype) == INTEGER_TYPE && TREE_TYPE (etype))
|
||||
|| TREE_CODE (etype) == ENUMERAL_TYPE
|
||||
|| TREE_CODE (etype) == BOOLEAN_TYPE))
|
||||
{
|
||||
/* The optimization barrier is a VIEW_CONVERT_EXPR node; moreover,
|
||||
in order not to be deemed an useless type conversion, it must
|
||||
be from subtype to base type.
|
||||
|
||||
Therefore we first do the bulk of the conversion to a subtype of
|
||||
the final type. And this conversion must itself not be deemed
|
||||
useless if the source type is not a subtype because, otherwise,
|
||||
the final VIEW_CONVERT_EXPR will be deemed so as well. That's
|
||||
why we toggle the unsigned flag in this conversion, which is
|
||||
harmless since the final conversion is only a reinterpretation
|
||||
of the bit pattern.
|
||||
|
||||
??? This may raise addressability and/or aliasing issues because
|
||||
VIEW_CONVERT_EXPR gets gimplified as an lvalue, thus causing the
|
||||
address of its operand to be taken if it is deemed addressable
|
||||
and not already in GIMPLE form. */
|
||||
tree rtype
|
||||
= gnat_type_for_mode (TYPE_MODE (type), !TYPE_UNSIGNED (etype));
|
||||
rtype = copy_type (rtype);
|
||||
TYPE_MAIN_VARIANT (rtype) = rtype;
|
||||
TREE_TYPE (rtype) = type;
|
||||
expr = convert (rtype, expr);
|
||||
expr = build1 (VIEW_CONVERT_EXPR, type, expr);
|
||||
}
|
||||
|
||||
else
|
||||
expr = convert (type, expr);
|
||||
}
|
||||
|
|
|
@ -802,11 +802,10 @@ build_binary_op (enum tree_code op_code, tree result_type,
|
|||
left_type = TREE_TYPE (left_operand);
|
||||
}
|
||||
|
||||
/* Then convert the right operand to its base type. This will
|
||||
prevent unneeded signedness conversions when sizetype is wider than
|
||||
integer. */
|
||||
/* Then convert the right operand to its base type. This will prevent
|
||||
unneeded sign conversions when sizetype is wider than integer. */
|
||||
right_operand = convert (right_base_type, right_operand);
|
||||
right_operand = convert (TYPE_DOMAIN (left_type), right_operand);
|
||||
right_operand = convert (sizetype, right_operand);
|
||||
|
||||
if (!TREE_CONSTANT (right_operand)
|
||||
|| !TREE_CONSTANT (TYPE_MIN_VALUE (right_type)))
|
||||
|
|
70
gcc/dbxout.c
70
gcc/dbxout.c
|
@ -318,9 +318,9 @@ static void dbxout_args (tree);
|
|||
static void dbxout_type_fields (tree);
|
||||
static void dbxout_type_method_1 (tree);
|
||||
static void dbxout_type_methods (tree);
|
||||
static void dbxout_range_type (tree);
|
||||
static void dbxout_range_type (tree, tree, tree);
|
||||
static void dbxout_type (tree, int);
|
||||
static bool print_int_cst_bounds_in_octal_p (tree);
|
||||
static bool print_int_cst_bounds_in_octal_p (tree, tree, tree);
|
||||
static bool is_fortran (void);
|
||||
static void dbxout_type_name (tree);
|
||||
static void dbxout_class_name_qualifiers (tree);
|
||||
|
@ -1593,10 +1593,10 @@ dbxout_type_methods (tree type)
|
|||
|
||||
/* Emit a "range" type specification, which has the form:
|
||||
"r<index type>;<lower bound>;<upper bound>;".
|
||||
TYPE is an INTEGER_TYPE. */
|
||||
TYPE is an INTEGER_TYPE, LOW and HIGH are the bounds. */
|
||||
|
||||
static void
|
||||
dbxout_range_type (tree type)
|
||||
dbxout_range_type (tree type, tree low, tree high)
|
||||
{
|
||||
stabstr_C ('r');
|
||||
if (TREE_TYPE (type))
|
||||
|
@ -1624,25 +1624,23 @@ dbxout_range_type (tree type)
|
|||
}
|
||||
|
||||
stabstr_C (';');
|
||||
if (TYPE_MIN_VALUE (type) != 0
|
||||
&& host_integerp (TYPE_MIN_VALUE (type), 0))
|
||||
if (low && host_integerp (low, 0))
|
||||
{
|
||||
if (print_int_cst_bounds_in_octal_p (type))
|
||||
stabstr_O (TYPE_MIN_VALUE (type));
|
||||
if (print_int_cst_bounds_in_octal_p (type, low, high))
|
||||
stabstr_O (low);
|
||||
else
|
||||
stabstr_D (tree_low_cst (TYPE_MIN_VALUE (type), 0));
|
||||
stabstr_D (tree_low_cst (low, 0));
|
||||
}
|
||||
else
|
||||
stabstr_C ('0');
|
||||
|
||||
stabstr_C (';');
|
||||
if (TYPE_MAX_VALUE (type) != 0
|
||||
&& host_integerp (TYPE_MAX_VALUE (type), 0))
|
||||
if (high && host_integerp (high, 0))
|
||||
{
|
||||
if (print_int_cst_bounds_in_octal_p (type))
|
||||
stabstr_O (TYPE_MAX_VALUE (type));
|
||||
if (print_int_cst_bounds_in_octal_p (type, low, high))
|
||||
stabstr_O (high);
|
||||
else
|
||||
stabstr_D (tree_low_cst (TYPE_MAX_VALUE (type), 0));
|
||||
stabstr_D (tree_low_cst (high, 0));
|
||||
stabstr_C (';');
|
||||
}
|
||||
else
|
||||
|
@ -1663,10 +1661,9 @@ dbxout_range_type (tree type)
|
|||
static void
|
||||
dbxout_type (tree type, int full)
|
||||
{
|
||||
tree tem;
|
||||
tree main_variant;
|
||||
static int anonymous_type_number = 0;
|
||||
bool vector_type = false;
|
||||
tree tem, main_variant, low, high;
|
||||
|
||||
if (TREE_CODE (type) == VECTOR_TYPE)
|
||||
{
|
||||
|
@ -1676,6 +1673,27 @@ dbxout_type (tree type, int full)
|
|||
vector_type = true;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == INTEGER_TYPE)
|
||||
{
|
||||
if (TREE_TYPE (type) == 0)
|
||||
{
|
||||
low = TYPE_MIN_VALUE (type);
|
||||
high = TYPE_MAX_VALUE (type);
|
||||
}
|
||||
|
||||
else if (subrange_type_for_debug_p (type, &low, &high))
|
||||
;
|
||||
|
||||
/* If this is a subtype that should not be emitted as a subrange type,
|
||||
use the base type. */
|
||||
else
|
||||
{
|
||||
type = TREE_TYPE (type);
|
||||
low = TYPE_MIN_VALUE (type);
|
||||
high = TYPE_MAX_VALUE (type);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there was an input error and we don't really have a type,
|
||||
avoid crashing and write something that is at least valid
|
||||
by assuming `int'. */
|
||||
|
@ -1877,7 +1895,7 @@ dbxout_type (tree type, int full)
|
|||
stabstr_C (';');
|
||||
}
|
||||
|
||||
dbxout_range_type (type);
|
||||
dbxout_range_type (type, low, high);
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -1893,7 +1911,7 @@ dbxout_type (tree type, int full)
|
|||
stabstr_C (';');
|
||||
}
|
||||
|
||||
if (print_int_cst_bounds_in_octal_p (type))
|
||||
if (print_int_cst_bounds_in_octal_p (type, low, high))
|
||||
{
|
||||
stabstr_C ('r');
|
||||
|
||||
|
@ -1908,15 +1926,15 @@ dbxout_type (tree type, int full)
|
|||
dbxout_type_index (type);
|
||||
|
||||
stabstr_C (';');
|
||||
stabstr_O (TYPE_MIN_VALUE (type));
|
||||
stabstr_O (low);
|
||||
stabstr_C (';');
|
||||
stabstr_O (TYPE_MAX_VALUE (type));
|
||||
stabstr_O (high);
|
||||
stabstr_C (';');
|
||||
}
|
||||
|
||||
else
|
||||
/* Output other integer types as subranges of `int'. */
|
||||
dbxout_range_type (type);
|
||||
dbxout_range_type (type, low, high);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -2010,7 +2028,7 @@ dbxout_type (tree type, int full)
|
|||
else
|
||||
{
|
||||
stabstr_C ('a');
|
||||
dbxout_range_type (tem);
|
||||
dbxout_range_type (tem, TYPE_MIN_VALUE (tem), TYPE_MAX_VALUE (tem));
|
||||
}
|
||||
|
||||
dbxout_type (TREE_TYPE (type), 0);
|
||||
|
@ -2258,7 +2276,7 @@ dbxout_type (tree type, int full)
|
|||
should be printed in octal format. */
|
||||
|
||||
static bool
|
||||
print_int_cst_bounds_in_octal_p (tree type)
|
||||
print_int_cst_bounds_in_octal_p (tree type, tree low, tree high)
|
||||
{
|
||||
/* If we can use GDB extensions and the size is wider than a long
|
||||
(the size used by GDB to read them) or we may have trouble writing
|
||||
|
@ -2272,10 +2290,8 @@ print_int_cst_bounds_in_octal_p (tree type)
|
|||
can't span same size unsigned types. */
|
||||
|
||||
if (use_gnu_debug_info_extensions
|
||||
&& TYPE_MIN_VALUE (type) != 0
|
||||
&& TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
|
||||
&& TYPE_MAX_VALUE (type) != 0
|
||||
&& TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
|
||||
&& low && TREE_CODE (low) == INTEGER_CST
|
||||
&& high && TREE_CODE (high) == INTEGER_CST
|
||||
&& (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
|
||||
|| ((TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
|
||||
&& TYPE_UNSIGNED (type))
|
||||
|
|
|
@ -5095,8 +5095,7 @@ static void output_line_info (void);
|
|||
static void output_file_names (void);
|
||||
static dw_die_ref base_type_die (tree);
|
||||
static int is_base_type (tree);
|
||||
static bool is_subrange_type (const_tree);
|
||||
static dw_die_ref subrange_type_die (tree, dw_die_ref);
|
||||
static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref);
|
||||
static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
|
||||
static int type_is_enum (const_tree);
|
||||
static unsigned int dbx_reg_number (const_rtx);
|
||||
|
@ -9273,6 +9272,11 @@ base_type_die (tree type)
|
|||
if (TREE_CODE (type) == ERROR_MARK || TREE_CODE (type) == VOID_TYPE)
|
||||
return 0;
|
||||
|
||||
/* If this is a subtype that should not be emitted as a subrange type,
|
||||
use the base type. See subrange_type_for_debug_p. */
|
||||
if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case INTEGER_TYPE:
|
||||
|
@ -9392,67 +9396,11 @@ simple_type_size_in_bits (const_tree type)
|
|||
return TYPE_ALIGN (type);
|
||||
}
|
||||
|
||||
/* Return true if the debug information for the given type should be
|
||||
emitted as a subrange type. */
|
||||
|
||||
static inline bool
|
||||
is_subrange_type (const_tree type)
|
||||
{
|
||||
tree subtype = TREE_TYPE (type);
|
||||
|
||||
/* Subrange types are identified by the fact that they are integer
|
||||
types, and that they have a subtype which is either an integer type
|
||||
or an enumeral type. */
|
||||
|
||||
if (TREE_CODE (type) != INTEGER_TYPE
|
||||
|| subtype == NULL_TREE)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (subtype) != INTEGER_TYPE
|
||||
&& TREE_CODE (subtype) != ENUMERAL_TYPE
|
||||
&& TREE_CODE (subtype) != BOOLEAN_TYPE)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (type) == TREE_CODE (subtype)
|
||||
&& int_size_in_bytes (type) == int_size_in_bytes (subtype)
|
||||
&& TYPE_MIN_VALUE (type) != NULL
|
||||
&& TYPE_MIN_VALUE (subtype) != NULL
|
||||
&& tree_int_cst_equal (TYPE_MIN_VALUE (type), TYPE_MIN_VALUE (subtype))
|
||||
&& TYPE_MAX_VALUE (type) != NULL
|
||||
&& TYPE_MAX_VALUE (subtype) != NULL
|
||||
&& tree_int_cst_equal (TYPE_MAX_VALUE (type), TYPE_MAX_VALUE (subtype)))
|
||||
{
|
||||
/* The type and its subtype have the same representation. If in
|
||||
addition the two types also have the same name, then the given
|
||||
type is not a subrange type, but rather a plain base type. */
|
||||
/* FIXME: brobecker/2004-03-22:
|
||||
Sizetype INTEGER_CSTs nodes are canonicalized. It should
|
||||
therefore be sufficient to check the TYPE_SIZE node pointers
|
||||
rather than checking the actual size. Unfortunately, we have
|
||||
found some cases, such as in the Ada "integer" type, where
|
||||
this is not the case. Until this problem is solved, we need to
|
||||
keep checking the actual size. */
|
||||
tree type_name = TYPE_NAME (type);
|
||||
tree subtype_name = TYPE_NAME (subtype);
|
||||
|
||||
if (type_name != NULL && TREE_CODE (type_name) == TYPE_DECL)
|
||||
type_name = DECL_NAME (type_name);
|
||||
|
||||
if (subtype_name != NULL && TREE_CODE (subtype_name) == TYPE_DECL)
|
||||
subtype_name = DECL_NAME (subtype_name);
|
||||
|
||||
if (type_name == subtype_name)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Given a pointer to a tree node for a subrange type, return a pointer
|
||||
to a DIE that describes the given type. */
|
||||
|
||||
static dw_die_ref
|
||||
subrange_type_die (tree type, dw_die_ref context_die)
|
||||
subrange_type_die (tree type, tree low, tree high, dw_die_ref context_die)
|
||||
{
|
||||
dw_die_ref subrange_die;
|
||||
const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type);
|
||||
|
@ -9469,12 +9417,10 @@ subrange_type_die (tree type, dw_die_ref context_die)
|
|||
add_AT_unsigned (subrange_die, DW_AT_byte_size, size_in_bytes);
|
||||
}
|
||||
|
||||
if (TYPE_MIN_VALUE (type) != NULL)
|
||||
add_bound_info (subrange_die, DW_AT_lower_bound,
|
||||
TYPE_MIN_VALUE (type));
|
||||
if (TYPE_MAX_VALUE (type) != NULL)
|
||||
add_bound_info (subrange_die, DW_AT_upper_bound,
|
||||
TYPE_MAX_VALUE (type));
|
||||
if (low)
|
||||
add_bound_info (subrange_die, DW_AT_lower_bound, low);
|
||||
if (high)
|
||||
add_bound_info (subrange_die, DW_AT_upper_bound, high);
|
||||
|
||||
return subrange_die;
|
||||
}
|
||||
|
@ -9491,7 +9437,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
|
|||
dw_die_ref sub_die = NULL;
|
||||
tree item_type = NULL;
|
||||
tree qualified_type;
|
||||
tree name;
|
||||
tree name, low, high;
|
||||
|
||||
if (code == ERROR_MARK)
|
||||
return NULL;
|
||||
|
@ -9561,9 +9507,11 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
|
|||
simple_type_size_in_bits (type) / BITS_PER_UNIT);
|
||||
item_type = TREE_TYPE (type);
|
||||
}
|
||||
else if (is_subrange_type (type))
|
||||
else if (code == INTEGER_TYPE
|
||||
&& TREE_TYPE (type) != NULL_TREE
|
||||
&& subrange_type_for_debug_p (type, &low, &high))
|
||||
{
|
||||
mod_type_die = subrange_type_die (type, context_die);
|
||||
mod_type_die = subrange_type_die (type, low, high, context_die);
|
||||
item_type = TREE_TYPE (type);
|
||||
}
|
||||
else if (is_base_type (type))
|
||||
|
|
|
@ -3741,7 +3741,7 @@ fold_truth_not_expr (tree arg)
|
|||
case NON_LVALUE_EXPR:
|
||||
return invert_truthvalue (TREE_OPERAND (arg, 0));
|
||||
|
||||
case NOP_EXPR:
|
||||
CASE_CONVERT:
|
||||
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
|
||||
{
|
||||
t = build1 (TRUTH_NOT_EXPR, type, arg);
|
||||
|
@ -3750,7 +3750,6 @@ fold_truth_not_expr (tree arg)
|
|||
|
||||
/* ... fall through ... */
|
||||
|
||||
case CONVERT_EXPR:
|
||||
case FLOAT_EXPR:
|
||||
t = build1 (TREE_CODE (arg), type,
|
||||
invert_truthvalue (TREE_OPERAND (arg, 0)));
|
||||
|
@ -4694,7 +4693,6 @@ static tree
|
|||
build_range_check (tree type, tree exp, int in_p, tree low, tree high)
|
||||
{
|
||||
tree etype = TREE_TYPE (exp), value;
|
||||
enum tree_code code;
|
||||
|
||||
#ifdef HAVE_canonicalize_funcptr_for_compare
|
||||
/* Disable this optimization for function pointer expressions
|
||||
|
@ -4777,35 +4775,14 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
|
|||
}
|
||||
|
||||
/* Optimize (c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low).
|
||||
This requires wrap-around arithmetics for the type of the expression. */
|
||||
code = TREE_CODE (etype);
|
||||
switch (code)
|
||||
{
|
||||
case INTEGER_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
/* There is no requirement that LOW be within the range of ETYPE
|
||||
if the latter is a subtype. It must, however, be within the base
|
||||
type of ETYPE. So be sure we do the subtraction in that type. */
|
||||
if (code == INTEGER_TYPE && TREE_TYPE (etype))
|
||||
{
|
||||
etype = TREE_TYPE (etype);
|
||||
/* But not in an enumeral or boolean type though. */
|
||||
code = TREE_CODE (etype);
|
||||
}
|
||||
This requires wrap-around arithmetics for the type of the expression.
|
||||
First make sure that arithmetics in this type is valid, then make sure
|
||||
that it wraps around. */
|
||||
if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE)
|
||||
etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
|
||||
TYPE_UNSIGNED (etype));
|
||||
|
||||
if (code != INTEGER_TYPE)
|
||||
etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
|
||||
TYPE_UNSIGNED (etype));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we don't have wrap-around arithmetics upfront, try to force it. */
|
||||
if (TREE_CODE (etype) == INTEGER_TYPE
|
||||
&& !TYPE_OVERFLOW_WRAPS (etype))
|
||||
if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS (etype))
|
||||
{
|
||||
tree utype, minv, maxv;
|
||||
|
||||
|
@ -7229,11 +7206,6 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
|
|||
if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
|
||||
return NULL_TREE;
|
||||
|
||||
/* If the conversion is from an integral subtype to its basetype
|
||||
leave it alone. */
|
||||
if (TREE_TYPE (inner_type) == outer_type)
|
||||
return NULL_TREE;
|
||||
|
||||
if (TREE_CODE (arg1) != INTEGER_CST
|
||||
&& !(CONVERT_EXPR_P (arg1)
|
||||
&& TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
|
||||
|
@ -8291,9 +8263,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
|||
transformation effectively doesn't preserve non-maximal ranges. */
|
||||
if (TREE_CODE (type) == INTEGER_TYPE
|
||||
&& TREE_CODE (op0) == BIT_AND_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST
|
||||
/* Not if the conversion is to the sub-type. */
|
||||
&& TREE_TYPE (type) != TREE_TYPE (op0))
|
||||
&& TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
|
||||
{
|
||||
tree and = op0;
|
||||
tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
|
||||
|
@ -8410,11 +8380,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
|||
|| POINTER_TYPE_P (type))
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (op0))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (op0)))
|
||||
&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0))
|
||||
/* Do not muck with VIEW_CONVERT_EXPRs that convert from
|
||||
a sub-type to its base type as generated by the Ada FE. */
|
||||
&& !(INTEGRAL_TYPE_P (TREE_TYPE (op0))
|
||||
&& TREE_TYPE (TREE_TYPE (op0))))
|
||||
&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
|
||||
return fold_convert (type, op0);
|
||||
|
||||
/* Strip inner integral conversions that do not change the precision. */
|
||||
|
|
|
@ -161,6 +161,7 @@ extern tree lhd_make_node (enum tree_code);
|
|||
lhd_omp_firstprivatize_type_sizes
|
||||
#define LANG_HOOKS_TYPE_HASH_EQ NULL
|
||||
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL
|
||||
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
|
||||
#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
|
||||
#define LANG_HOOKS_HASH_TYPES true
|
||||
|
||||
|
@ -177,6 +178,7 @@ extern tree lhd_make_node (enum tree_code);
|
|||
LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
|
||||
LANG_HOOKS_TYPE_HASH_EQ, \
|
||||
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
|
||||
LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
|
||||
LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
|
||||
LANG_HOOKS_HASH_TYPES \
|
||||
}
|
||||
|
|
|
@ -130,6 +130,9 @@ struct lang_hooks_for_types
|
|||
for the debugger about the array bounds, strides, etc. */
|
||||
bool (*get_array_descr_info) (const_tree, struct array_descr_info *);
|
||||
|
||||
/* Fill in information for the debugger about the bounds of TYPE. */
|
||||
void (*get_subrange_bounds) (const_tree, tree *, tree *);
|
||||
|
||||
/* If we requested a pointer to a vector, build up the pointers that
|
||||
we stripped off while looking for the inner type. Similarly for
|
||||
return values from functions. The argument TYPE is the top of the
|
||||
|
|
|
@ -1100,21 +1100,6 @@ nb_vars_in_chrec (tree chrec)
|
|||
}
|
||||
}
|
||||
|
||||
/* Returns true if TYPE is a type in that we cannot directly perform
|
||||
arithmetics, even though it is a scalar type. */
|
||||
|
||||
static bool
|
||||
avoid_arithmetics_in_type_p (const_tree type)
|
||||
{
|
||||
/* Ada frontend uses subtypes -- an arithmetic cannot be directly performed
|
||||
in the subtype, but a base type must be used, and the result then can
|
||||
be casted to the subtype. */
|
||||
if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static tree chrec_convert_1 (tree, tree, gimple, bool);
|
||||
|
||||
/* Converts BASE and STEP of affine scev to TYPE. LOOP is the loop whose iv
|
||||
|
@ -1136,10 +1121,6 @@ convert_affine_scev (struct loop *loop, tree type,
|
|||
tree new_base, new_step;
|
||||
tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
|
||||
|
||||
/* If we cannot perform arithmetic in TYPE, avoid creating an scev. */
|
||||
if (avoid_arithmetics_in_type_p (type))
|
||||
return false;
|
||||
|
||||
/* In general,
|
||||
(TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
|
||||
but we must check some assumptions.
|
||||
|
@ -1342,10 +1323,6 @@ chrec_convert_aggressive (tree type, tree chrec)
|
|||
if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
|
||||
return NULL_TREE;
|
||||
|
||||
/* If we cannot perform arithmetic in TYPE, avoid creating an scev. */
|
||||
if (avoid_arithmetics_in_type_p (type))
|
||||
return NULL_TREE;
|
||||
|
||||
rtype = POINTER_TYPE_P (type) ? sizetype : type;
|
||||
|
||||
left = CHREC_LEFT (chrec);
|
||||
|
|
|
@ -923,19 +923,9 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
|
|||
|| TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
|
||||
return false;
|
||||
|
||||
/* Conversions from a non-base to a base type are not useless.
|
||||
This way we preserve the invariant to do arithmetic in
|
||||
base types only. */
|
||||
if (TREE_TYPE (inner_type)
|
||||
&& TREE_TYPE (inner_type) != inner_type
|
||||
&& (TREE_TYPE (outer_type) == outer_type
|
||||
|| TREE_TYPE (outer_type) == NULL_TREE))
|
||||
return false;
|
||||
|
||||
/* We don't need to preserve changes in the types minimum or
|
||||
maximum value in general as these do not generate code
|
||||
unless the types precisions are different. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ DEF_VEC_ALLOC_O(switch_update, heap);
|
|||
static VEC (switch_update, heap) *to_update_switch_stmts;
|
||||
|
||||
|
||||
/* Return the maximum value for TYPEs base type. */
|
||||
/* Return the maximum value for TYPE. */
|
||||
|
||||
static inline tree
|
||||
vrp_val_max (const_tree type)
|
||||
|
@ -129,14 +129,10 @@ vrp_val_max (const_tree type)
|
|||
if (!INTEGRAL_TYPE_P (type))
|
||||
return NULL_TREE;
|
||||
|
||||
/* For integer sub-types the values for the base type are relevant. */
|
||||
if (TREE_TYPE (type))
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
return TYPE_MAX_VALUE (type);
|
||||
}
|
||||
|
||||
/* Return the minimum value for TYPEs base type. */
|
||||
/* Return the minimum value for TYPE. */
|
||||
|
||||
static inline tree
|
||||
vrp_val_min (const_tree type)
|
||||
|
@ -144,10 +140,6 @@ vrp_val_min (const_tree type)
|
|||
if (!INTEGRAL_TYPE_P (type))
|
||||
return NULL_TREE;
|
||||
|
||||
/* For integer sub-types the values for the base type are relevant. */
|
||||
if (TREE_TYPE (type))
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
return TYPE_MIN_VALUE (type);
|
||||
}
|
||||
|
||||
|
@ -188,11 +180,7 @@ vrp_val_is_min (const_tree val)
|
|||
static inline bool
|
||||
needs_overflow_infinity (const_tree type)
|
||||
{
|
||||
return (INTEGRAL_TYPE_P (type)
|
||||
&& !TYPE_OVERFLOW_WRAPS (type)
|
||||
/* Integer sub-types never overflow as they are never
|
||||
operands of arithmetic operators. */
|
||||
&& !(TREE_TYPE (type) && TREE_TYPE (type) != type));
|
||||
return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
|
||||
}
|
||||
|
||||
/* Return whether TYPE can support our overflow infinity
|
||||
|
@ -2702,13 +2690,6 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
|
|||
tree inner_type = TREE_TYPE (op0);
|
||||
tree outer_type = type;
|
||||
|
||||
/* Always use base-types here. This is important for the
|
||||
correct signedness. */
|
||||
if (TREE_TYPE (inner_type))
|
||||
inner_type = TREE_TYPE (inner_type);
|
||||
if (TREE_TYPE (outer_type))
|
||||
outer_type = TREE_TYPE (outer_type);
|
||||
|
||||
/* If VR0 is varying and we increase the type precision, assume
|
||||
a full range for the following transformation. */
|
||||
if (vr0.type == VR_VARYING
|
||||
|
|
51
gcc/tree.c
51
gcc/tree.c
|
@ -5696,6 +5696,57 @@ build_range_type (tree type, tree lowval, tree highval)
|
|||
return itype;
|
||||
}
|
||||
|
||||
/* Return true if the debug information for TYPE, a subtype, should be emitted
|
||||
as a subrange type. If so, set LOWVAL to the low bound and HIGHVAL to the
|
||||
high bound, respectively. Sometimes doing so unnecessarily obfuscates the
|
||||
debug info and doesn't reflect the source code. */
|
||||
|
||||
bool
|
||||
subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval)
|
||||
{
|
||||
tree base_type = TREE_TYPE (type), low, high;
|
||||
|
||||
/* Subrange types have a base type which is an integral type. */
|
||||
if (!INTEGRAL_TYPE_P (base_type))
|
||||
return false;
|
||||
|
||||
/* Get the real bounds of the subtype. */
|
||||
if (lang_hooks.types.get_subrange_bounds)
|
||||
lang_hooks.types.get_subrange_bounds (type, &low, &high);
|
||||
else
|
||||
{
|
||||
low = TYPE_MIN_VALUE (type);
|
||||
high = TYPE_MAX_VALUE (type);
|
||||
}
|
||||
|
||||
/* If the type and its base type have the same representation and the same
|
||||
name, then the type is not a subrange but a copy of the base type. */
|
||||
if ((TREE_CODE (base_type) == INTEGER_TYPE
|
||||
|| TREE_CODE (base_type) == BOOLEAN_TYPE)
|
||||
&& int_size_in_bytes (type) == int_size_in_bytes (base_type)
|
||||
&& tree_int_cst_equal (low, TYPE_MIN_VALUE (base_type))
|
||||
&& tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type)))
|
||||
{
|
||||
tree type_name = TYPE_NAME (type);
|
||||
tree base_type_name = TYPE_NAME (base_type);
|
||||
|
||||
if (type_name && TREE_CODE (type_name) == TYPE_DECL)
|
||||
type_name = DECL_NAME (type_name);
|
||||
|
||||
if (base_type_name && TREE_CODE (base_type_name) == TYPE_DECL)
|
||||
base_type_name = DECL_NAME (base_type_name);
|
||||
|
||||
if (type_name == base_type_name)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lowval)
|
||||
*lowval = low;
|
||||
if (highval)
|
||||
*highval = high;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Just like build_index_type, but takes lowval and highval instead
|
||||
of just highval (maxval). */
|
||||
|
||||
|
|
|
@ -4860,6 +4860,7 @@ extern void build_common_tree_nodes_2 (int);
|
|||
extern void build_common_builtin_nodes (void);
|
||||
extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
|
||||
extern tree build_range_type (tree, tree, tree);
|
||||
extern bool subrange_type_for_debug_p (const_tree, tree *, tree *);
|
||||
extern HOST_WIDE_INT int_cst_value (const_tree);
|
||||
|
||||
extern bool fields_compatible_p (const_tree, const_tree);
|
||||
|
|
Loading…
Reference in New Issue