/* Chain the variant part at the end of the field list. */
if (gnu_variant_part)
- {
- /* We make an exception if the variant part is at offset 0, has a fixed
- size, and there is a single rep'ed field placed after it because, in
- this case, there is an obvious order of increasing position. */
- if (variants_have_rep
- && TREE_CODE (DECL_SIZE_UNIT (gnu_variant_part)) == INTEGER_CST
- && gnu_rep_list
- && gnu_field_list == gnu_rep_list
- && !tree_int_cst_lt (DECL_FIELD_OFFSET (gnu_rep_list),
- DECL_SIZE_UNIT (gnu_variant_part)))
- {
- DECL_CHAIN (gnu_variant_part) = gnu_field_list;
- gnu_field_list = gnu_variant_part;
- }
- else
- gnu_field_list = chainon (gnu_field_list, gnu_variant_part);
- }
+ gnu_field_list = chainon (gnu_field_list, gnu_variant_part);
if (cancel_alignment)
SET_TYPE_ALIGN (gnu_record_type, 0);
Note that we rely on the pointer equality created here for
TYPE_NAME to look through conversions in various places. */
TYPE_NAME (new_type) = TYPE_NAME (type);
+ TYPE_PACKED (new_type) = 1;
TYPE_JUSTIFIED_MODULAR_P (new_type) = TYPE_JUSTIFIED_MODULAR_P (type);
TYPE_CONTAINS_TEMPLATE_P (new_type) = TYPE_CONTAINS_TEMPLATE_P (type);
TYPE_REVERSE_STORAGE_ORDER (new_type) = TYPE_REVERSE_STORAGE_ORDER (type);
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
{
tree new_field_type = TREE_TYPE (field);
- tree new_field, new_size;
+ tree new_field, new_field_size;
if (RECORD_OR_UNION_TYPE_P (new_field_type)
&& !TYPE_FAT_POINTER_P (new_field_type)
&& !TYPE_FAT_POINTER_P (new_field_type)
&& !TYPE_CONTAINS_TEMPLATE_P (new_field_type)
&& TYPE_ADA_SIZE (new_field_type))
- new_size = TYPE_ADA_SIZE (new_field_type);
+ new_field_size = TYPE_ADA_SIZE (new_field_type);
else
- new_size = DECL_SIZE (field);
+ new_field_size = DECL_SIZE (field);
+ /* This is a layout with full representation, alignment and size clauses
+ so we simply pass 0 as PACKED like gnat_to_gnu_field in this case. */
new_field
= create_field_decl (DECL_NAME (field), new_field_type, new_type,
- new_size, bit_position (field),
- TYPE_PACKED (type),
+ new_field_size, bit_position (field), 0,
!DECL_NONADDRESSABLE_P (field));
DECL_INTERNAL_P (new_field) = DECL_INTERNAL_P (field);
DECL_BIT_FIELD (field) = 0;
}
+ /* Clear DECL_BIT_FIELD_TYPE for a variant part at offset 0, it's simply
+ not supported by the DECL_BIT_FIELD_REPRESENTATIVE machinery because
+ the variant part is always the last field in the list. */
+ if (DECL_INTERNAL_P (field)
+ && TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
+ && integer_zerop (pos))
+ DECL_BIT_FIELD_TYPE (field) = NULL_TREE;
+
/* If we still have DECL_BIT_FIELD set at this point, we know that the
field is technically not addressable. Except that it can actually
be addressed if it is BLKmode and happens to be properly aligned. */
size = round_up (size, BITS_PER_UNIT);
}
- /* If we may, according to ADDRESSABLE, make a bitfield if a size is
+ /* If we may, according to ADDRESSABLE, make a bitfield when the size is
specified for two reasons: first if the size differs from the natural
- size. Second, if the alignment is insufficient. There are a number of
+ size; second, if the alignment is insufficient. There are a number of
ways the latter can be true.
We never make a bitfield if the type of the field has a nonconstant size,
We do *preventively* make a bitfield when there might be the need for it
but we don't have all the necessary information to decide, as is the case
- of a field with no specified position in a packed record.
+ of a field in a packed record.
We also don't look at STRICT_ALIGNMENT here, and rely on later processing
in layout_decl or finish_record_type to clear the bit_field indication if