make_packable_type (tree type)
{
tree new_type = make_node (TREE_CODE (type));
- tree name = TYPE_NAME (type);
tree field_list = NULL_TREE;
tree old_field;
- if (name && TREE_CODE (name) == TYPE_DECL)
- name = DECL_NAME (name);
-
- /* Copy the name and flags from the old type to that of the new and set
- the alignment to try for an integral type. For QUAL_UNION_TYPE,
- also copy the size. */
- TYPE_NAME (new_type) = name;
- TYPE_JUSTIFIED_MODULAR_P (new_type)
- = TYPE_JUSTIFIED_MODULAR_P (type);
+ /* Copy the name and flags from the old type to that of the new. Note
+ that we rely on the pointer equality created here for TYPE_NAME at
+ the end of gnat_to_gnu. For QUAL_UNION_TYPE, also copy the size. */
+ TYPE_NAME (new_type) = TYPE_NAME (type);
+ TYPE_JUSTIFIED_MODULAR_P (new_type) = TYPE_JUSTIFIED_MODULAR_P (type);
TYPE_CONTAINS_TEMPLATE_P (new_type) = TYPE_CONTAINS_TEMPLATE_P (type);
if (TREE_CODE (type) == RECORD_TYPE)
TYPE_SIZE_UNIT (new_type) = TYPE_SIZE_UNIT (type);
}
+ /* Set the alignment to try for an integral type. */
TYPE_ALIGN (new_type) = ceil_alignment (tree_low_cst (TYPE_SIZE (type), 1));
TYPE_USER_ALIGN (new_type) = 1;
{
tree gnu_field_id = get_entity_name (gnat_field);
tree gnu_field_type = gnat_to_gnu_type (Etype (gnat_field));
- tree gnu_pos = 0;
- tree gnu_size = 0;
- tree gnu_field;
+ tree gnu_field, gnu_size, gnu_pos;
bool needs_strict_alignment
= (Is_Aliased (gnat_field) || Strict_Alignment (Etype (gnat_field))
|| Treat_As_Volatile (gnat_field));
else
packed = adjust_packed (gnu_field_type, gnu_record_type, packed);
- /* For packed records, this is one of the few occasions on which we use
- the official RM size for discrete or fixed-point components, instead
- of the normal GNAT size stored in Esize. See description in Einfo:
- "Handling of Type'Size Values" for further details. */
-
- if (packed == 1)
- gnu_size = validate_size (RM_Size (Etype (gnat_field)), gnu_field_type,
- gnat_field, FIELD_DECL, false, true);
-
+ /* If a size is specified, use it. Otherwise, if the record type is packed,
+ use the official RM size. See "Handling of Type'Size Values" in Einfo
+ for further details. */
if (Known_Static_Esize (gnat_field))
gnu_size = validate_size (Esize (gnat_field), gnu_field_type,
gnat_field, FIELD_DECL, false, true);
+ else if (packed == 1)
+ gnu_size = validate_size (RM_Size (Etype (gnat_field)), gnu_field_type,
+ gnat_field, FIELD_DECL, false, true);
+ else
+ gnu_size = NULL_TREE;
/* If we have a specified size that's smaller than that of the field type,
or a position is specified, and the field type is also a record that's
&& compare_tree_int (TYPE_SIZE (gnu_field_type), BIGGEST_ALIGNMENT) <= 0
&& (packed == 1
|| (gnu_size
- && tree_int_cst_lt (gnu_size, TYPE_SIZE (gnu_field_type)))
- || (Present (Component_Clause (gnat_field)) && gnu_size != 0)))
+ && (tree_int_cst_lt (gnu_size, TYPE_SIZE (gnu_field_type))
+ || Present (Component_Clause (gnat_field))))))
{
/* See what the alternate type and size would be. */
tree gnu_packable_type = make_packable_type (gnu_field_type);
{
gnu_field_type = gnu_packable_type;
- if (gnu_size == 0)
+ if (!gnu_size)
gnu_size = rm_size (gnu_field_type);
}
}
gnu_size = TYPE_SIZE (gnu_field_type);
}
+ else
+ gnu_pos = NULL_TREE;
+
/* We need to make the size the maximum for the type if it is
self-referential and an unconstrained type. In that case, we can't
pack the field since we can't make a copy to align it. */
packed = 0;
}
- /* If no size is specified (or if there was an error), don't specify a
- position. */
- if (!gnu_size)
- gnu_pos = NULL_TREE;
- else
+ /* If a size is specified, adjust the field's type to it. */
+ if (gnu_size)
{
/* If the field's type is justified modular, we would need to remove
the wrapper to (better) meet the layout requirements. However we
"PAD", false, definition, true);
}
+ /* Otherwise (or if there was an error), don't specify a position. */
+ else
+ gnu_pos = NULL_TREE;
+
gcc_assert (TREE_CODE (gnu_field_type) != RECORD_TYPE
|| !TYPE_CONTAINS_TEMPLATE_P (gnu_field_type));