Tested on x86_64-suse-linux, applied on the mainline.
2015-12-20 Eric Botcazou <ebotca...@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: During
layout in type_annotate_only mode, skip discriminants of derived
tagged types renaming those of the parent type.
In type_annotate_only mode, if the type is tagged, do not override a
size clause but take into account the alignment of the tag.
(annotate_rep): In type_annotate_only mode, deal with discriminants
of derived tagged types renaming those of the parent type.
--
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 231856)
+++ gcc-interface/decl.c (working copy)
@@ -3181,6 +3181,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
&& Present (Corresponding_Discriminant (gnat_field)))
continue;
+ /* However, if we are just annotating types, the Parent_Subtype
+ doesn't exist so we need skip the discriminant altogether. */
+ if (type_annotate_only
+ && Is_Tagged_Type (gnat_entity)
+ && Is_Derived_Type (gnat_entity)
+ && Present (Corresponding_Discriminant (gnat_field)))
+ continue;
+
gnu_field
= gnat_to_gnu_field (gnat_field, gnu_type, packed, definition,
debug_info_p);
@@ -5321,15 +5329,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
/* If we are just annotating types and the type is tagged, the tag
and the parent components are not generated by the front-end so
- sizes must be adjusted if there is no representation clause. */
+ alignment and sizes must be adjusted if there is no rep clause. */
if (type_annotate_only
&& Is_Tagged_Type (gnat_entity)
+ && Unknown_RM_Size (gnat_entity)
&& !VOID_TYPE_P (gnu_type)
&& (!TYPE_FIELDS (gnu_type)
|| integer_zerop (bit_position (TYPE_FIELDS (gnu_type)))))
{
- tree pointer_size = bitsize_int (POINTER_SIZE), offset;
- Uint uint_size;
+ tree offset;
if (Is_Derived_Type (gnat_entity))
{
@@ -5338,7 +5346,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
Set_Alignment (gnat_entity, Alignment (gnat_parent));
}
else
- offset = pointer_size;
+ {
+ unsigned int align
+ = MAX (TYPE_ALIGN (gnu_type), POINTER_SIZE) / BITS_PER_UNIT;
+ offset = bitsize_int (POINTER_SIZE);
+ Set_Alignment (gnat_entity, UI_From_Int (align));
+ }
if (TYPE_FIELDS (gnu_type))
offset
@@ -5346,10 +5359,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
gnu_size = size_binop (PLUS_EXPR, gnu_size, offset);
gnu_size = round_up (gnu_size, POINTER_SIZE);
- uint_size = annotate_value (gnu_size);
- Set_Esize (gnat_entity, uint_size);
+ Uint uint_size = annotate_value (gnu_size);
Set_RM_Size (gnat_entity, uint_size);
+ Set_Esize (gnat_entity, uint_size);
+ }
+
+ /* If there is a rep clause, only adjust alignment and Esize. */
+ else if (type_annotate_only && Is_Tagged_Type (gnat_entity))
+ {
+ unsigned int align
+ = MAX (TYPE_ALIGN (gnu_type), POINTER_SIZE) / BITS_PER_UNIT;
+ Set_Alignment (gnat_entity, UI_From_Int (align));
+ gnu_size = round_up (gnu_size, POINTER_SIZE);
+ Set_Esize (gnat_entity, annotate_value (gnu_size));
}
+
+ /* Otherwise no adjustment is needed. */
else
Set_Esize (gnat_entity, annotate_value (gnu_size));
}
@@ -7933,12 +7958,19 @@ annotate_rep (Entity_Id gnat_entity, tre
{
/* If there is no entry, this is an inherited component whose
position is the same as in the parent type. */
- Set_Component_Bit_Offset
- (gnat_field,
- Component_Bit_Offset (Original_Record_Component (gnat_field)));
+ Entity_Id gnat_orig_field = Original_Record_Component (gnat_field);
- Set_Esize (gnat_field,
- Esize (Original_Record_Component (gnat_field)));
+ /* If we are just annotating types, discriminants renaming those of
+ the parent have no entry so deal with them specifically. */
+ if (type_annotate_only
+ && gnat_orig_field == gnat_field
+ && Ekind (gnat_field) == E_Discriminant)
+ gnat_orig_field = Corresponding_Discriminant (gnat_field);
+
+ Set_Component_Bit_Offset (gnat_field,
+ Component_Bit_Offset (gnat_orig_field));
+
+ Set_Esize (gnat_field, Esize (gnat_orig_field));
}
}
}