true if both types have no names. */
static bool
-compare_type_names_p (tree t1, tree t2, bool for_completion_p)
+compare_type_names_p (tree t1, tree t2)
{
tree name1 = TYPE_NAME (t1);
tree name2 = TYPE_NAME (t2);
- /* Consider anonymous types all unique for completion. */
- if (for_completion_p
- && (!name1 || !name2))
- return false;
-
if (name1 && TREE_CODE (name1) == TYPE_DECL)
- {
- name1 = DECL_NAME (name1);
- if (for_completion_p
- && !name1)
- return false;
- }
- gcc_assert (!name1 || TREE_CODE (name1) == IDENTIFIER_NODE);
+ name1 = DECL_NAME (name1);
+ gcc_checking_assert (!name1 || TREE_CODE (name1) == IDENTIFIER_NODE);
if (name2 && TREE_CODE (name2) == TYPE_DECL)
- {
- name2 = DECL_NAME (name2);
- if (for_completion_p
- && !name2)
- return false;
- }
- gcc_assert (!name2 || TREE_CODE (name2) == IDENTIFIER_NODE);
+ name2 = DECL_NAME (name2);
+ gcc_checking_assert (!name2 || TREE_CODE (name2) == IDENTIFIER_NODE);
/* Identifiers can be compared with pointer equality rather
than a string comparison. */
return false;
}
-/* If the type T1 and the type T2 are a complete and an incomplete
- variant of the same type return true. */
-
-static bool
-gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
-{
- /* If one pointer points to an incomplete type variant of
- the other pointed-to type they are the same. */
- if (TREE_CODE (t1) == TREE_CODE (t2)
- && RECORD_OR_UNION_TYPE_P (t1)
- && (!COMPLETE_TYPE_P (t1)
- || !COMPLETE_TYPE_P (t2))
- && TYPE_QUALS (t1) == TYPE_QUALS (t2)
- && compare_type_names_p (TYPE_MAIN_VARIANT (t1),
- TYPE_MAIN_VARIANT (t2), true))
- return true;
- return false;
-}
-
static bool
gimple_types_compatible_p_1 (tree, tree, type_pair_t,
VEC(type_pair_t, heap) **,
state->u.same_p = 1;
/* The struct tags shall compare equal. */
- if (!compare_type_names_p (t1, t2, false))
+ if (!compare_type_names_p (t1, t2))
goto different_types;
/* If their attributes are not the same they can't be the same type. */
if (TREE_CODE (type) == METHOD_TYPE)
v = iterative_hash_canonical_type (TYPE_METHOD_BASETYPE (type), v);
- /* For result types allow mismatch in completeness. */
- if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
- {
- v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
- v = iterative_hash_name
- (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v);
- }
- else
- v = iterative_hash_canonical_type (TREE_TYPE (type), v);
+ v = iterative_hash_canonical_type (TREE_TYPE (type), v);
for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
{
- /* For argument types allow mismatch in completeness. */
- if (RECORD_OR_UNION_TYPE_P (TREE_VALUE (p)))
- {
- v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v);
- v = iterative_hash_name
- (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v);
- }
- else
- v = iterative_hash_canonical_type (TREE_VALUE (p), v);
+ v = iterative_hash_canonical_type (TREE_VALUE (p), v);
na++;
}
tree f;
for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
- {
- v = iterative_hash_canonical_type (TREE_TYPE (f), v);
- nf++;
- }
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ v = iterative_hash_canonical_type (TREE_TYPE (f), v);
+ nf++;
+ }
v = iterative_hash_hashval_t (nf, v);
}
case FUNCTION_TYPE:
/* Function types are the same if the return type and arguments types
are the same. */
- if (!gimple_compatible_complete_and_incomplete_subtype_p
- (TREE_TYPE (t1), TREE_TYPE (t2))
- && !gimple_canonical_types_compatible_p
- (TREE_TYPE (t1), TREE_TYPE (t2)))
+ if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return false;
if (!comp_type_attributes (t1, t2))
parms1 && parms2;
parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
{
- if (!gimple_compatible_complete_and_incomplete_subtype_p
- (TREE_VALUE (parms1), TREE_VALUE (parms2))
- && !gimple_canonical_types_compatible_p
- (TREE_VALUE (parms1), TREE_VALUE (parms2)))
+ if (!gimple_canonical_types_compatible_p
+ (TREE_VALUE (parms1), TREE_VALUE (parms2)))
return false;
}
f1 && f2;
f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
{
+ /* Skip non-fields. */
+ while (f1 && TREE_CODE (f1) != FIELD_DECL)
+ f1 = TREE_CHAIN (f1);
+ while (f2 && TREE_CODE (f2) != FIELD_DECL)
+ f2 = TREE_CHAIN (f2);
+ if (!f1 || !f2)
+ break;
/* The fields must have the same name, offset and type. */
if (DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
|| !gimple_compare_field_offset (f1, f2)
/* Register type T in the global type table gimple_types.
If another type T', compatible with T, already existed in
gimple_types then return T', otherwise return T. This is used by
- LTO to merge identical types read from different TUs. */
+ LTO to merge identical types read from different TUs.
+
+ ??? This merging does not exactly match how the tree.c middle-end
+ functions will assign TYPE_CANONICAL when new types are created
+ during optimization (which at least happens for pointer and array
+ types). */
tree
gimple_register_canonical_type (tree t)
if (TYPE_CANONICAL (t))
return TYPE_CANONICAL (t);
- /* For pointer and reference types do as the middle-end does - the
- canonical type is a pointer to the canonical pointed-to type. */
- if (TREE_CODE (t) == POINTER_TYPE)
- {
- TYPE_CANONICAL (t)
- = build_pointer_type_for_mode
- (gimple_register_canonical_type (TREE_TYPE (t)),
- TYPE_MODE (t), TYPE_REF_CAN_ALIAS_ALL (t));
- return TYPE_CANONICAL (t);
- }
- else if (TREE_CODE (t) == REFERENCE_TYPE)
- {
- TYPE_CANONICAL (t)
- = build_reference_type_for_mode
- (gimple_register_canonical_type (TREE_TYPE (t)),
- TYPE_MODE (t), TYPE_REF_CAN_ALIAS_ALL (t));
- return TYPE_CANONICAL (t);
- }
-
if (gimple_canonical_types == NULL)
gimple_canonical_types = htab_create_ggc (16381, gimple_canonical_type_hash,
gimple_canonical_type_eq, 0);