aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/expr.c133
-rw-r--r--gcc/expr.h9
-rw-r--r--gcc/tree.c137
-rw-r--r--gcc/tree.h39
5 files changed, 182 insertions, 155 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b014528..6920846 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2015-05-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expr.h (array_at_struct_end_p): Move to...
+ (array_ref_element_size): Likewise.
+ (component_ref_field_offset): Likewise.
+ * tree.h (array_ref_element_size): ...here.
+ (array_at_struct_end_p): Likewise.
+ (component_ref_field_offset): Likewise.
+ * expr.c (array_ref_element_size): Move to...
+ (array_ref_low_bound): Likewise.
+ (array_at_struct_end_p): Likewise.
+ (array_ref_up_bound): Likewise.
+ (component_ref_field_offset): Likewise.
+ * tree.c (array_ref_element_size): ...here.
+ (array_ref_low_bound): Likewise.
+ (array_ref_up_bound): Likewise.
+ (array_at_struct_end_p): Likewise.
+ (component_ref_field_offset): Likewise.
+
2015-05-27 Gregor Richards <gregor.richards@uwaterloo.ca>
Szabolcs Nagy <szabolcs.nagy@arm.com>
diff --git a/gcc/expr.c b/gcc/expr.c
index 1dd1cf3..5a931dc 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7025,139 +7025,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
return exp;
}
-/* Return a tree of sizetype representing the size, in bytes, of the element
- of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-
-tree
-array_ref_element_size (tree exp)
-{
- tree aligned_size = TREE_OPERAND (exp, 3);
- tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- location_t loc = EXPR_LOCATION (exp);
-
- /* If a size was specified in the ARRAY_REF, it's the size measured
- in alignment units of the element type. So multiply by that value. */
- if (aligned_size)
- {
- /* ??? tree_ssa_useless_type_conversion will eliminate casts to
- sizetype from another type of the same width and signedness. */
- if (TREE_TYPE (aligned_size) != sizetype)
- aligned_size = fold_convert_loc (loc, sizetype, aligned_size);
- return size_binop_loc (loc, MULT_EXPR, aligned_size,
- size_int (TYPE_ALIGN_UNIT (elmt_type)));
- }
-
- /* Otherwise, take the size from that of the element type. Substitute
- any PLACEHOLDER_EXPR that we have. */
- else
- return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
-}
-
-/* Return a tree representing the lower bound of the array mentioned in
- EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-
-tree
-array_ref_low_bound (tree exp)
-{
- tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
- /* If a lower bound is specified in EXP, use it. */
- if (TREE_OPERAND (exp, 2))
- return TREE_OPERAND (exp, 2);
-
- /* Otherwise, if there is a domain type and it has a lower bound, use it,
- substituting for a PLACEHOLDER_EXPR as needed. */
- if (domain_type && TYPE_MIN_VALUE (domain_type))
- return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
-
- /* Otherwise, return a zero of the appropriate type. */
- return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
-}
-
-/* Returns true if REF is an array reference to an array at the end of
- a structure. If this is the case, the array may be allocated larger
- than its upper bound implies. */
-
-bool
-array_at_struct_end_p (tree ref)
-{
- if (TREE_CODE (ref) != ARRAY_REF
- && TREE_CODE (ref) != ARRAY_RANGE_REF)
- return false;
-
- while (handled_component_p (ref))
- {
- /* If the reference chain contains a component reference to a
- non-union type and there follows another field the reference
- is not at the end of a structure. */
- if (TREE_CODE (ref) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
- {
- tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
- while (nextf && TREE_CODE (nextf) != FIELD_DECL)
- nextf = DECL_CHAIN (nextf);
- if (nextf)
- return false;
- }
-
- ref = TREE_OPERAND (ref, 0);
- }
-
- /* If the reference is based on a declared entity, the size of the array
- is constrained by its given domain. */
- if (DECL_P (ref))
- return false;
-
- return true;
-}
-
-/* Return a tree representing the upper bound of the array mentioned in
- EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-
-tree
-array_ref_up_bound (tree exp)
-{
- tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
- /* If there is a domain type and it has an upper bound, use it, substituting
- for a PLACEHOLDER_EXPR as needed. */
- if (domain_type && TYPE_MAX_VALUE (domain_type))
- return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
-
- /* Otherwise fail. */
- return NULL_TREE;
-}
-
-/* Return a tree representing the offset, in bytes, of the field referenced
- by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
-
-tree
-component_ref_field_offset (tree exp)
-{
- tree aligned_offset = TREE_OPERAND (exp, 2);
- tree field = TREE_OPERAND (exp, 1);
- location_t loc = EXPR_LOCATION (exp);
-
- /* If an offset was specified in the COMPONENT_REF, it's the offset measured
- in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that
- value. */
- if (aligned_offset)
- {
- /* ??? tree_ssa_useless_type_conversion will eliminate casts to
- sizetype from another type of the same width and signedness. */
- if (TREE_TYPE (aligned_offset) != sizetype)
- aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset);
- return size_binop_loc (loc, MULT_EXPR, aligned_offset,
- size_int (DECL_OFFSET_ALIGN (field)
- / BITS_PER_UNIT));
- }
-
- /* Otherwise, take the offset from that of the field. Substitute
- any PLACEHOLDER_EXPR that we have. */
- else
- return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
-}
-
/* Alignment in bits the TARGET of an assignment may be assumed to have. */
static unsigned HOST_WIDE_INT
diff --git a/gcc/expr.h b/gcc/expr.h
index 7b28ffd..8cf9720 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -281,19 +281,10 @@ rtx get_personality_function (tree);
extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
-bool array_at_struct_end_p (tree);
-
-/* Return a tree of sizetype representing the size, in bytes, of the element
- of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-extern tree array_ref_element_size (tree);
extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, bool *);
-/* Return a tree representing the offset, in bytes, of the field referenced
- by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
-extern tree component_ref_field_offset (tree);
-
extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
enum expand_modifier);
diff --git a/gcc/tree.c b/gcc/tree.c
index 60d4509..c22fa76 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -24,8 +24,8 @@ along with GCC; see the file COPYING3. If not see
tables index by tree code that describe how to take apart
nodes of that code.
- It is intended to be language-independent, but occasionally
- calls language-dependent routines defined (for C) in typecheck.c. */
+ It is intended to be language-independent but can occasionally
+ calls language-dependent routines. */
#include "config.h"
#include "system.h"
@@ -12453,6 +12453,139 @@ get_base_address (tree t)
return t;
}
+/* Return a tree of sizetype representing the size, in bytes, of the element
+ of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+
+tree
+array_ref_element_size (tree exp)
+{
+ tree aligned_size = TREE_OPERAND (exp, 3);
+ tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ location_t loc = EXPR_LOCATION (exp);
+
+ /* If a size was specified in the ARRAY_REF, it's the size measured
+ in alignment units of the element type. So multiply by that value. */
+ if (aligned_size)
+ {
+ /* ??? tree_ssa_useless_type_conversion will eliminate casts to
+ sizetype from another type of the same width and signedness. */
+ if (TREE_TYPE (aligned_size) != sizetype)
+ aligned_size = fold_convert_loc (loc, sizetype, aligned_size);
+ return size_binop_loc (loc, MULT_EXPR, aligned_size,
+ size_int (TYPE_ALIGN_UNIT (elmt_type)));
+ }
+
+ /* Otherwise, take the size from that of the element type. Substitute
+ any PLACEHOLDER_EXPR that we have. */
+ else
+ return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
+}
+
+/* Return a tree representing the lower bound of the array mentioned in
+ EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+
+tree
+array_ref_low_bound (tree exp)
+{
+ tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+ /* If a lower bound is specified in EXP, use it. */
+ if (TREE_OPERAND (exp, 2))
+ return TREE_OPERAND (exp, 2);
+
+ /* Otherwise, if there is a domain type and it has a lower bound, use it,
+ substituting for a PLACEHOLDER_EXPR as needed. */
+ if (domain_type && TYPE_MIN_VALUE (domain_type))
+ return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
+
+ /* Otherwise, return a zero of the appropriate type. */
+ return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
+}
+
+/* Return a tree representing the upper bound of the array mentioned in
+ EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+
+tree
+array_ref_up_bound (tree exp)
+{
+ tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+ /* If there is a domain type and it has an upper bound, use it, substituting
+ for a PLACEHOLDER_EXPR as needed. */
+ if (domain_type && TYPE_MAX_VALUE (domain_type))
+ return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
+
+ /* Otherwise fail. */
+ return NULL_TREE;
+}
+
+/* Returns true if REF is an array reference to an array at the end of
+ a structure. If this is the case, the array may be allocated larger
+ than its upper bound implies. */
+
+bool
+array_at_struct_end_p (tree ref)
+{
+ if (TREE_CODE (ref) != ARRAY_REF
+ && TREE_CODE (ref) != ARRAY_RANGE_REF)
+ return false;
+
+ while (handled_component_p (ref))
+ {
+ /* If the reference chain contains a component reference to a
+ non-union type and there follows another field the reference
+ is not at the end of a structure. */
+ if (TREE_CODE (ref) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+ {
+ tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
+ while (nextf && TREE_CODE (nextf) != FIELD_DECL)
+ nextf = DECL_CHAIN (nextf);
+ if (nextf)
+ return false;
+ }
+
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ /* If the reference is based on a declared entity, the size of the array
+ is constrained by its given domain. */
+ if (DECL_P (ref))
+ return false;
+
+ return true;
+}
+
+/* Return a tree representing the offset, in bytes, of the field referenced
+ by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
+
+tree
+component_ref_field_offset (tree exp)
+{
+ tree aligned_offset = TREE_OPERAND (exp, 2);
+ tree field = TREE_OPERAND (exp, 1);
+ location_t loc = EXPR_LOCATION (exp);
+
+ /* If an offset was specified in the COMPONENT_REF, it's the offset measured
+ in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that
+ value. */
+ if (aligned_offset)
+ {
+ /* ??? tree_ssa_useless_type_conversion will eliminate casts to
+ sizetype from another type of the same width and signedness. */
+ if (TREE_TYPE (aligned_offset) != sizetype)
+ aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset);
+ return size_binop_loc (loc, MULT_EXPR, aligned_offset,
+ size_int (DECL_OFFSET_ALIGN (field)
+ / BITS_PER_UNIT));
+ }
+
+ /* Otherwise, take the offset from that of the field. Substitute
+ any PLACEHOLDER_EXPR that we have. */
+ else
+ return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
+}
+
/* Return the machine mode of T. For vectors, returns the mode of the
inner type. The main use case is to feed the result to HONOR_NANS,
avoiding the BLKmode that a direct TYPE_MODE (T) might return. */
diff --git a/gcc/tree.h b/gcc/tree.h
index 58d2e9b..732a61c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4564,8 +4564,34 @@ extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*,
#define walk_tree_without_duplicates(a,b,c) \
walk_tree_without_duplicates_1 (a, b, c, NULL)
-extern tree get_base_address (tree t);
extern tree drop_tree_overflow (tree);
+
+/* Given a memory reference expression T, return its base address.
+ The base address of a memory reference expression is the main
+ object being referenced. */
+extern tree get_base_address (tree t);
+
+/* Return a tree of sizetype representing the size, in bytes, of the element
+ of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+extern tree array_ref_element_size (tree);
+
+/* Return a tree representing the upper bound of the array mentioned in
+ EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+extern tree array_ref_up_bound (tree);
+
+/* Return a tree representing the lower bound of the array mentioned in
+ EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+extern tree array_ref_low_bound (tree);
+
+/* Returns true if REF is an array reference to an array at the end of
+ a structure. If this is the case, the array may be allocated larger
+ than its upper bound implies. */
+extern bool array_at_struct_end_p (tree);
+
+/* Return a tree representing the offset, in bytes, of the field referenced
+ by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
+extern tree component_ref_field_offset (tree);
+
extern int tree_map_base_eq (const void *, const void *);
extern unsigned int tree_map_base_hash (const void *);
extern int tree_map_base_marked_p (const void *);
@@ -5052,12 +5078,6 @@ tree_int_cst_compare (const_tree t1, const_tree t2)
extern void set_decl_rtl (tree, rtx);
extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
-/* Return a tree representing the upper bound of the array mentioned in
- EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-extern tree array_ref_up_bound (tree);
-
-extern tree build_personality_function (const char *);
-
/* Given an expression EXP that is a handled_component_p,
look for the ultimate containing object, which is returned and specify
the access position and size. */
@@ -5065,10 +5085,7 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
tree *, machine_mode *, int *, int *,
bool);
-/* Return a tree representing the lower bound of the array mentioned in
- EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-extern tree array_ref_low_bound (tree);
-
+extern tree build_personality_function (const char *);
struct GTY(()) int_n_trees_t {
/* These parts are initialized at runtime */