+ && aggregate_value_p (t, current_function_decl)));
+}
+
+/* There are situations in which a language considers record types
+ compatible which have different field lists. Decide if two fields
+ are compatible. It is assumed that the parent records are compatible. */
+
+bool
+fields_compatible_p (tree f1, tree f2)
+{
+ if (!operand_equal_p (DECL_FIELD_BIT_OFFSET (f1),
+ DECL_FIELD_BIT_OFFSET (f2), OEP_ONLY_CONST))
+ return false;
+
+ if (!operand_equal_p (DECL_FIELD_OFFSET (f1),
+ DECL_FIELD_OFFSET (f2), OEP_ONLY_CONST))
+ return false;
+
+ if (!lang_hooks.types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+ return false;
+
+ return true;
+}
+
+/* Locate within RECORD a field that is compatible with ORIG_FIELD. */
+
+tree
+find_compatible_field (tree record, tree orig_field)
+{
+ tree f;
+
+ for (f = TYPE_FIELDS (record); f ; f = TREE_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL
+ && fields_compatible_p (f, orig_field))
+ return f;
+
+ /* ??? Why isn't this on the main fields list? */
+ f = TYPE_VFIELD (record);
+ if (f && TREE_CODE (f) == FIELD_DECL
+ && fields_compatible_p (f, orig_field))
+ return f;
+
+ /* ??? We should abort here, but Java appears to do Bad Things
+ with inherited fields. */
+ return orig_field;
+}
+
+/* Return value of a constant X. */
+
+HOST_WIDE_INT
+int_cst_value (tree x)
+{
+ unsigned bits = TYPE_PRECISION (TREE_TYPE (x));
+ unsigned HOST_WIDE_INT val = TREE_INT_CST_LOW (x);
+ bool negative = ((val >> (bits - 1)) & 1) != 0;
+
+ gcc_assert (bits <= HOST_BITS_PER_WIDE_INT);
+
+ if (negative)
+ val |= (~(unsigned HOST_WIDE_INT) 0) << (bits - 1) << 1;
+ else
+ val &= ~((~(unsigned HOST_WIDE_INT) 0) << (bits - 1) << 1);
+
+ return val;
+}
+
+/* Returns the greatest common divisor of A and B, which must be
+ INTEGER_CSTs. */
+
+tree
+tree_fold_gcd (tree a, tree b)
+{
+ tree a_mod_b;
+ tree type = TREE_TYPE (a);
+
+ gcc_assert (TREE_CODE (a) == INTEGER_CST);
+ gcc_assert (TREE_CODE (b) == INTEGER_CST);
+
+ if (integer_zerop (a))
+ return b;
+
+ if (integer_zerop (b))
+ return a;
+
+ if (tree_int_cst_sgn (a) == -1)
+ a = fold (build2 (MULT_EXPR, type, a,
+ convert (type, integer_minus_one_node)));
+
+ if (tree_int_cst_sgn (b) == -1)
+ b = fold (build2 (MULT_EXPR, type, b,
+ convert (type, integer_minus_one_node)));
+
+ while (1)
+ {
+ a_mod_b = fold (build2 (FLOOR_MOD_EXPR, type, a, b));
+
+ if (!TREE_INT_CST_LOW (a_mod_b)
+ && !TREE_INT_CST_HIGH (a_mod_b))
+ return b;
+
+ a = b;
+ b = a_mod_b;
+ }
+}
+
+/* Returns unsigned variant of TYPE. */
+
+tree
+unsigned_type_for (tree type)
+{
+ return lang_hooks.types.unsigned_type (type);
+}
+
+/* Returns signed variant of TYPE. */
+
+tree
+signed_type_for (tree type)
+{
+ return lang_hooks.types.signed_type (type);
+}
+
+/* Returns the largest value obtainable by casting something in INNER type to
+ OUTER type. */
+
+tree
+upper_bound_in_type (tree outer, tree inner)
+{
+ unsigned HOST_WIDE_INT lo, hi;
+ unsigned bits = TYPE_PRECISION (inner);
+
+ if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner))
+ {
+ /* Zero extending in these cases. */
+ if (bits <= HOST_BITS_PER_WIDE_INT)
+ {
+ hi = 0;
+ lo = (~(unsigned HOST_WIDE_INT) 0)
+ >> (HOST_BITS_PER_WIDE_INT - bits);
+ }
+ else
+ {
+ hi = (~(unsigned HOST_WIDE_INT) 0)
+ >> (2 * HOST_BITS_PER_WIDE_INT - bits);
+ lo = ~(unsigned HOST_WIDE_INT) 0;
+ }
+ }
+ else
+ {
+ /* Sign extending in these cases. */
+ if (bits <= HOST_BITS_PER_WIDE_INT)
+ {
+ hi = 0;
+ lo = (~(unsigned HOST_WIDE_INT) 0)
+ >> (HOST_BITS_PER_WIDE_INT - bits) >> 1;
+ }
+ else
+ {
+ hi = (~(unsigned HOST_WIDE_INT) 0)
+ >> (2 * HOST_BITS_PER_WIDE_INT - bits) >> 1;
+ lo = ~(unsigned HOST_WIDE_INT) 0;
+ }
+ }
+
+ return fold_convert (outer,
+ build_int_cst_wide (inner, lo, hi));
+}
+
+/* Returns the smallest value obtainable by casting something in INNER type to
+ OUTER type. */
+
+tree
+lower_bound_in_type (tree outer, tree inner)
+{
+ unsigned HOST_WIDE_INT lo, hi;
+ unsigned bits = TYPE_PRECISION (inner);
+
+ if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner))
+ lo = hi = 0;
+ else if (bits <= HOST_BITS_PER_WIDE_INT)
+ {
+ hi = ~(unsigned HOST_WIDE_INT) 0;
+ lo = (~(unsigned HOST_WIDE_INT) 0) << (bits - 1);
+ }
+ else
+ {
+ hi = (~(unsigned HOST_WIDE_INT) 0) << (bits - HOST_BITS_PER_WIDE_INT - 1);
+ lo = 0;
+ }
+
+ return fold_convert (outer,
+ build_int_cst_wide (inner, lo, hi));
+}
+
+/* Return nonzero if two operands that are suitable for PHI nodes are
+ necessarily equal. Specifically, both ARG0 and ARG1 must be either
+ SSA_NAME or invariant. Note that this is strictly an optimization.
+ That is, callers of this function can directly call operand_equal_p
+ and get the same result, only slower. */
+
+int
+operand_equal_for_phi_arg_p (tree arg0, tree arg1)
+{
+ if (arg0 == arg1)
+ return 1;
+ if (TREE_CODE (arg0) == SSA_NAME || TREE_CODE (arg1) == SSA_NAME)
+ return 0;
+ return operand_equal_p (arg0, arg1, 0);
+}
+
+/* Returns number of zeros at the end of binary representation of X.
+
+ ??? Use ffs if available? */
+
+tree
+num_ending_zeros (tree x)
+{
+ unsigned HOST_WIDE_INT fr, nfr;
+ unsigned num, abits;
+ tree type = TREE_TYPE (x);
+
+ if (TREE_INT_CST_LOW (x) == 0)
+ {
+ num = HOST_BITS_PER_WIDE_INT;
+ fr = TREE_INT_CST_HIGH (x);
+ }
+ else
+ {
+ num = 0;
+ fr = TREE_INT_CST_LOW (x);
+ }
+
+ for (abits = HOST_BITS_PER_WIDE_INT / 2; abits; abits /= 2)
+ {
+ nfr = fr >> abits;
+ if (nfr << abits == fr)
+ {
+ num += abits;
+ fr = nfr;
+ }
+ }
+
+ if (num > TYPE_PRECISION (type))
+ num = TYPE_PRECISION (type);
+
+ return build_int_cst_type (type, num);
+}
+
+
+#define WALK_SUBTREE(NODE) \
+ do \
+ { \
+ result = walk_tree (&(NODE), func, data, pset); \
+ if (result) \
+ return result; \
+ } \
+ while (0)
+
+/* This is a subroutine of walk_tree that walks field of TYPE that are to
+ be walked whenever a type is seen in the tree. Rest of operands and return
+ value are as for walk_tree. */
+
+static tree
+walk_type_fields (tree type, walk_tree_fn func, void *data,
+ struct pointer_set_t *pset)
+{
+ tree result = NULL_TREE;
+
+ switch (TREE_CODE (type))
+ {
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ /* We have to worry about mutually recursive pointers. These can't
+ be written in C. They can in Ada. It's pathological, but
+ there's an ACATS test (c38102a) that checks it. Deal with this
+ by checking if we're pointing to another pointer, that one
+ points to another pointer, that one does too, and we have no htab.
+ If so, get a hash table. We check three levels deep to avoid
+ the cost of the hash table if we don't need one. */
+ if (POINTER_TYPE_P (TREE_TYPE (type))
+ && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
+ && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
+ && !pset)
+ {
+ result = walk_tree_without_duplicates (&TREE_TYPE (type),
+ func, data);
+ if (result)
+ return result;
+
+ break;
+ }
+
+ /* ... fall through ... */
+
+ case COMPLEX_TYPE:
+ WALK_SUBTREE (TREE_TYPE (type));
+ break;
+
+ case METHOD_TYPE:
+ WALK_SUBTREE (TYPE_METHOD_BASETYPE (type));
+
+ /* Fall through. */
+
+ case FUNCTION_TYPE:
+ WALK_SUBTREE (TREE_TYPE (type));
+ {
+ tree arg;
+
+ /* We never want to walk into default arguments. */
+ for (arg = TYPE_ARG_TYPES (type); arg; arg = TREE_CHAIN (arg))
+ WALK_SUBTREE (TREE_VALUE (arg));
+ }
+ break;
+
+ case ARRAY_TYPE:
+ /* Don't follow this nodes's type if a pointer for fear that we'll
+ have infinite recursion. Those types are uninteresting anyway. */
+ if (!POINTER_TYPE_P (TREE_TYPE (type))
+ && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE)
+ WALK_SUBTREE (TREE_TYPE (type));
+ WALK_SUBTREE (TYPE_DOMAIN (type));
+ break;
+
+ case BOOLEAN_TYPE:
+ case ENUMERAL_TYPE:
+ case INTEGER_TYPE:
+ case CHAR_TYPE:
+ case REAL_TYPE:
+ WALK_SUBTREE (TYPE_MIN_VALUE (type));
+ WALK_SUBTREE (TYPE_MAX_VALUE (type));
+ break;
+
+ case OFFSET_TYPE:
+ WALK_SUBTREE (TREE_TYPE (type));
+ WALK_SUBTREE (TYPE_OFFSET_BASETYPE (type));
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* Apply FUNC to all the sub-trees of TP in a pre-order traversal. FUNC is
+ called with the DATA and the address of each sub-tree. If FUNC returns a
+ non-NULL value, the traversal is stopped, and the value returned by FUNC
+ is returned. If PSET is non-NULL it is used to record the nodes visited,
+ and to avoid visiting a node more than once. */
+
+tree
+walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
+{
+ enum tree_code code;
+ int walk_subtrees;
+ tree result;
+
+#define WALK_SUBTREE_TAIL(NODE) \
+ do \
+ { \
+ tp = & (NODE); \
+ goto tail_recurse; \
+ } \
+ while (0)
+
+ tail_recurse:
+ /* Skip empty subtrees. */
+ if (!*tp)
+ return NULL_TREE;
+
+ /* Don't walk the same tree twice, if the user has requested
+ that we avoid doing so. */
+ if (pset && pointer_set_insert (pset, *tp))
+ return NULL_TREE;
+
+ /* Call the function. */
+ walk_subtrees = 1;
+ result = (*func) (tp, &walk_subtrees, data);
+
+ /* If we found something, return it. */
+ if (result)
+ return result;
+
+ code = TREE_CODE (*tp);
+
+ /* Even if we didn't, FUNC may have decided that there was nothing
+ interesting below this point in the tree. */
+ if (!walk_subtrees)
+ {
+ if (code == TREE_LIST)
+ /* But we still need to check our siblings. */
+ WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+ else
+ return NULL_TREE;
+ }
+
+ result = lang_hooks.tree_inlining.walk_subtrees (tp, &walk_subtrees, func,
+ data, pset);
+ if (result || ! walk_subtrees)
+ return result;
+
+ /* If this is a DECL_EXPR, walk into various fields of the type that it's
+ defining. We only want to walk into these fields of a type in this
+ case. Note that decls get walked as part of the processing of a
+ BIND_EXPR.
+
+ ??? Precisely which fields of types that we are supposed to walk in
+ this case vs. the normal case aren't well defined. */
+ if (code == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+ {
+ tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
+
+ /* Call the function for the type. See if it returns anything or
+ doesn't want us to continue. If we are to continue, walk both
+ the normal fields and those for the declaration case. */
+ result = (*func) (type_p, &walk_subtrees, data);
+ if (result || !walk_subtrees)
+ return NULL_TREE;
+
+ result = walk_type_fields (*type_p, func, data, pset);
+ if (result)
+ return result;
+
+ WALK_SUBTREE (TYPE_SIZE (*type_p));
+ WALK_SUBTREE (TYPE_SIZE_UNIT (*type_p));
+
+ /* If this is a record type, also walk the fields. */
+ if (TREE_CODE (*type_p) == RECORD_TYPE
+ || TREE_CODE (*type_p) == UNION_TYPE
+ || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+ {
+ tree field;
+
+ for (field = TYPE_FIELDS (*type_p); field;
+ field = TREE_CHAIN (field))
+ {
+ /* We'd like to look at the type of the field, but we can easily
+ get infinite recursion. So assume it's pointed to elsewhere
+ in the tree. Also, ignore things that aren't fields. */
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ WALK_SUBTREE (DECL_FIELD_OFFSET (field));
+ WALK_SUBTREE (DECL_SIZE (field));
+ WALK_SUBTREE (DECL_SIZE_UNIT (field));
+ if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+ WALK_SUBTREE (DECL_QUALIFIER (field));
+ }
+ }
+ }
+
+ else if (code != SAVE_EXPR
+ && code != BIND_EXPR
+ && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+ {
+ int i, len;
+
+ /* Walk over all the sub-trees of this operand. */
+ len = TREE_CODE_LENGTH (code);
+ /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
+ But, we only want to walk once. */
+ if (code == TARGET_EXPR
+ && TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1))
+ --len;
+
+ /* Go through the subtrees. We need to do this in forward order so
+ that the scope of a FOR_EXPR is handled properly. */
+#ifdef DEBUG_WALK_TREE
+ for (i = 0; i < len; ++i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+#else
+ for (i = 0; i < len - 1; ++i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+
+ if (len)
+ {
+ /* The common case is that we may tail recurse here. */
+ if (code != BIND_EXPR
+ && !TREE_CHAIN (*tp))
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+ else
+ WALK_SUBTREE (TREE_OPERAND (*tp, len - 1));
+ }
+#endif
+ }
+
+ /* If this is a type, walk the needed fields in the type. */
+ else if (TYPE_P (*tp))
+ {
+ result = walk_type_fields (*tp, func, data, pset);
+ if (result)
+ return result;
+ }
+ else
+ {
+ /* Not one of the easy cases. We must explicitly go through the
+ children. */
+ switch (code)
+ {
+ case ERROR_MARK:
+ case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case VECTOR_CST:
+ case STRING_CST:
+ case BLOCK:
+ case PLACEHOLDER_EXPR:
+ case SSA_NAME:
+ case FIELD_DECL:
+ case RESULT_DECL:
+ /* None of thse have subtrees other than those already walked
+ above. */
+ break;
+
+ case TREE_LIST:
+ WALK_SUBTREE (TREE_VALUE (*tp));
+ WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+ break;
+
+ case TREE_VEC:
+ {
+ int len = TREE_VEC_LENGTH (*tp);
+
+ if (len == 0)
+ break;
+
+ /* Walk all elements but the first. */
+ while (--len)
+ WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
+
+ /* Now walk the first one as a tail call. */
+ WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
+ }
+
+ case COMPLEX_CST:
+ WALK_SUBTREE (TREE_REALPART (*tp));
+ WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
+
+ case CONSTRUCTOR:
+ WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
+
+ case SAVE_EXPR:
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+
+ case BIND_EXPR:
+ {
+ tree decl;
+ for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
+ {
+ /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
+ into declarations that are just mentioned, rather than
+ declared; they don't really belong to this part of the tree.
+ And, we can see cycles: the initializer for a declaration
+ can refer to the declaration itself. */
+ WALK_SUBTREE (DECL_INITIAL (decl));
+ WALK_SUBTREE (DECL_SIZE (decl));
+ WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+ }
+ WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+ }
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+ WALK_SUBTREE (*tsi_stmt_ptr (i));
+ }
+ break;
+
+ default:
+ /* ??? This could be a language-defined node. We really should make
+ a hook for it, but right now just ignore it. */
+ break;
+ }
+ }
+
+ /* We didn't find what we were looking for. */
+ return NULL_TREE;
+
+#undef WALK_SUBTREE_TAIL
+}
+#undef WALK_SUBTREE
+
+/* Like walk_tree, but does not walk duplicate nodes more than once. */
+
+tree
+walk_tree_without_duplicates (tree *tp, walk_tree_fn func, void *data)
+{
+ tree result;
+ struct pointer_set_t *pset;
+
+ pset = pointer_set_create ();
+ result = walk_tree (tp, func, data, pset);
+ pointer_set_destroy (pset);
+ return result;