===================================================================
@@ -8162,6 +8162,8 @@ components_to_record (Node_Id gnat_compo
gnu_field_list = gnu_rep_list;
else
{
+ TYPE_NAME (gnu_rep_type)
+ = create_concat_name (gnat_record_type, "REP");
TYPE_REVERSE_STORAGE_ORDER (gnu_rep_type)
= TYPE_REVERSE_STORAGE_ORDER (gnu_record_type);
finish_record_type (gnu_rep_type, gnu_rep_list, 1, debug_info);
===================================================================
@@ -1863,6 +1863,9 @@ finish_record_type (tree record_type, tr
else
this_ada_size = this_size;
+ const bool variant_part = (TREE_CODE (type) == QUAL_UNION_TYPE);
+ const bool variant_part_at_zero = variant_part && integer_zerop (pos);
+
/* Clear DECL_BIT_FIELD for the cases layout_decl does not handle. */
if (DECL_BIT_FIELD (field)
&& operand_equal_p (this_size, TYPE_SIZE (type), 0))
@@ -1904,9 +1907,7 @@ finish_record_type (tree record_type, tr
/* 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))
+ if (variant_part_at_zero)
DECL_BIT_FIELD_TYPE (field) = NULL_TREE;
/* If we still have DECL_BIT_FIELD set at this point, we know that the
@@ -1941,18 +1942,18 @@ finish_record_type (tree record_type, tr
case RECORD_TYPE:
/* Since we know here that all fields are sorted in order of
increasing bit position, the size of the record is one
- higher than the ending bit of the last field processed
- unless we have a rep clause, since in that case we might
- have a field outside a QUAL_UNION_TYPE that has a higher ending
- position. So use a MAX in that case. Also, if this field is a
- QUAL_UNION_TYPE, we need to take into account the previous size in
- the case of empty variants. */
+ higher than the ending bit of the last field processed,
+ unless we have a variant part at offset 0, since in this
+ case we might have a field outside the variant part that
+ has a higher ending position; so use a MAX in this case.
+ Also, if this field is a QUAL_UNION_TYPE, we need to take
+ into account the previous size in the case of empty variants. */
ada_size
- = merge_sizes (ada_size, pos, this_ada_size,
- TREE_CODE (type) == QUAL_UNION_TYPE, rep_level > 0);
+ = merge_sizes (ada_size, pos, this_ada_size, variant_part,
+ variant_part_at_zero);
size
- = merge_sizes (size, pos, this_size,
- TREE_CODE (type) == QUAL_UNION_TYPE, rep_level > 0);
+ = merge_sizes (size, pos, this_size, variant_part,
+ variant_part_at_zero);
break;
default:
@@ -2233,13 +2234,12 @@ rest_of_record_type_compilation (tree re
/* Utility function of above to merge LAST_SIZE, the previous size of a record
with FIRST_BIT and SIZE that describe a field. SPECIAL is true if this
represents a QUAL_UNION_TYPE in which case we must look for COND_EXPRs and
- replace a value of zero with the old size. If HAS_REP is true, we take the
+ replace a value of zero with the old size. If MAX is true, we take the
MAX of the end position of this field with LAST_SIZE. In all other cases,
we use FIRST_BIT plus SIZE. Return an expression for the size. */
static tree
-merge_sizes (tree last_size, tree first_bit, tree size, bool special,
- bool has_rep)
+merge_sizes (tree last_size, tree first_bit, tree size, bool special, bool max)
{
tree type = TREE_TYPE (last_size);
tree new_size;
@@ -2247,7 +2247,7 @@ merge_sizes (tree last_size, tree first_
if (!special || TREE_CODE (size) != COND_EXPR)
{
new_size = size_binop (PLUS_EXPR, first_bit, size);
- if (has_rep)
+ if (max)
new_size = size_binop (MAX_EXPR, last_size, new_size);
}
@@ -2256,11 +2256,11 @@ merge_sizes (tree last_size, tree first_
integer_zerop (TREE_OPERAND (size, 1))
? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 1),
- 1, has_rep),
+ 1, max),
integer_zerop (TREE_OPERAND (size, 2))
? last_size : merge_sizes (last_size, first_bit,
TREE_OPERAND (size, 2),
- 1, has_rep));
+ 1, max));
/* We don't need any NON_VALUE_EXPRs and they can confuse us (especially
when fed through SUBSTITUTE_IN_EXPR) into thinking that a constant