aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2009-05-15 09:11:40 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2009-05-15 09:11:40 +0000
commit84fb43a1a4480e7a0a106fbe38144d1af50b476a (patch)
treefaaa7bb6c0694f3f9cf8d8dbe54a58161ef0489f /gcc/ada/gcc-interface/utils.c
parent331d91868977fe50f5d937a9c195b6418bfda5c3 (diff)
downloadgcc-84fb43a1a4480e7a0a106fbe38144d1af50b476a.zip
gcc-84fb43a1a4480e7a0a106fbe38144d1af50b476a.tar.gz
gcc-84fb43a1a4480e7a0a106fbe38144d1af50b476a.tar.bz2
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
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c115
1 files changed, 48 insertions, 67 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index e3cf975..6dbd1e7 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -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);
}