aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-05-24 13:07:06 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-05-24 13:07:06 +0000
commit63a329f81c83b58694571cebb39c3ab8cec935c4 (patch)
treec8c829990917f139bff567e4f480f1376d74a210 /gcc/ada/gcc-interface/decl.c
parent736e16efea25ff2bb1a0fe230b6a242b8cd5dd0d (diff)
downloadgcc-63a329f81c83b58694571cebb39c3ab8cec935c4.zip
gcc-63a329f81c83b58694571cebb39c3ab8cec935c4.tar.gz
gcc-63a329f81c83b58694571cebb39c3ab8cec935c4.tar.bz2
[Ada] Fix irregular output with -gnatR3
This fixes a long-standing quirk present in the layout information for record types displayed by the -gnatR3 switch: when a component has a variable (starting) position, its corresponding line in the output has an irregular and awkward format. After this change, the format is the same as in all the other cases. For the following record: type R (m : natural) is record s : string (1 .. m); r : natural; b : boolean; end record; for R'alignment use 4; pragma Pack (R); the output of -gnatR3 used to be: for R'Object_Size use 17179869248; for R'Value_Size use ((#1 + 8) * 8); for R'Alignment use 4; for R use record m at 0 range 0 .. 30; s at 4 range 0 .. ((#1 * 8)) - 1; r at bit offset (((#1 + 4) * 8)) size in bits = 31 b at bit offset ((((#1 + 7) * 8) + 7)) size in bits = 1 end record; and is changed into: for R'Object_Size use 17179869248; for R'Value_Size use ((#1 + 8) * 8); for R'Alignment use 4; for R use record m at 0 range 0 .. 30; s at 4 range 0 .. ((#1 * 8)) - 1; r at (#1 + 4) range 0 .. 30; b at (#1 + 7) range 7 .. 7; end record; 2018-05-24 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * fe.h (Set_Normalized_First_Bit): Declare. (Set_Normalized_Position): Likewise. * repinfo.adb (List_Record_Layout): Do not use irregular output for a variable position. Fix minor spacing issue. * gcc-interface/decl.c (annotate_rep): If a field has a variable offset, compute the normalized position and annotate it in addition to the bit offset. From-SVN: r260669
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 7a827b7..a63cc18 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -8291,7 +8291,8 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
gnu_list);
if (t)
{
- tree parent_offset;
+ tree offset = TREE_VEC_ELT (TREE_VALUE (t), 0);
+ tree bit_offset = TREE_VEC_ELT (TREE_VALUE (t), 2);
/* 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
@@ -8301,31 +8302,46 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
&& Is_Tagged_Type (gnat_entity)
&& No (Component_Clause (gnat_field)))
{
+ tree parent_bit_offset;
+
/* For a component appearing in the current extension, the
offset is the size of the parent. */
if (Is_Derived_Type (gnat_entity)
&& Original_Record_Component (gnat_field) == gnat_field)
- parent_offset
+ parent_bit_offset
= UI_To_gnu (Esize (Etype (Base_Type (gnat_entity))),
bitsizetype);
else
- parent_offset = bitsize_int (POINTER_SIZE);
+ parent_bit_offset = bitsize_int (POINTER_SIZE);
if (TYPE_FIELDS (gnu_type))
- parent_offset
- = round_up (parent_offset,
+ parent_bit_offset
+ = round_up (parent_bit_offset,
DECL_ALIGN (TYPE_FIELDS (gnu_type)));
+
+ offset
+ = size_binop (PLUS_EXPR, offset,
+ fold_convert (sizetype,
+ size_binop (TRUNC_DIV_EXPR,
+ parent_bit_offset,
+ bitsize_unit_node)));
+ }
+
+ /* If the field has a variable offset, also compute the normalized
+ position since it's easier to do on trees here than to deduce
+ it from the annotated expression of Component_Bit_Offset. */
+ if (TREE_CODE (offset) != INTEGER_CST)
+ {
+ normalize_offset (&offset, &bit_offset, BITS_PER_UNIT);
+ Set_Normalized_Position (gnat_field,
+ annotate_value (offset));
+ Set_Normalized_First_Bit (gnat_field,
+ annotate_value (bit_offset));
}
- else
- parent_offset = bitsize_zero_node;
Set_Component_Bit_Offset
(gnat_field,
- annotate_value
- (size_binop (PLUS_EXPR,
- bit_from_pos (TREE_VEC_ELT (TREE_VALUE (t), 0),
- TREE_VEC_ELT (TREE_VALUE (t), 2)),
- parent_offset)));
+ annotate_value (bit_from_pos (offset, bit_offset)));
Set_Esize (gnat_field,
annotate_value (DECL_SIZE (TREE_PURPOSE (t))));
@@ -8334,19 +8350,27 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
{
/* If there is no entry, this is an inherited component whose
position is the same as in the parent type. */
- Entity_Id gnat_orig_field = Original_Record_Component (gnat_field);
+ Entity_Id gnat_orig = 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
+ && gnat_orig == gnat_field
&& Ekind (gnat_field) == E_Discriminant)
- gnat_orig_field = Corresponding_Discriminant (gnat_field);
+ gnat_orig = Corresponding_Discriminant (gnat_field);
+
+ if (Known_Normalized_Position (gnat_orig))
+ {
+ Set_Normalized_Position (gnat_field,
+ Normalized_Position (gnat_orig));
+ Set_Normalized_First_Bit (gnat_field,
+ Normalized_First_Bit (gnat_orig));
+ }
Set_Component_Bit_Offset (gnat_field,
- Component_Bit_Offset (gnat_orig_field));
+ Component_Bit_Offset (gnat_orig));
- Set_Esize (gnat_field, Esize (gnat_orig_field));
+ Set_Esize (gnat_field, Esize (gnat_orig));
}
}
}