[Ada] Fix irregular output with -gnatR3
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 24 May 2018 13:07:06 +0000 (13:07 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Thu, 24 May 2018 13:07:06 +0000 (13:07 +0000)
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

gcc/ada/ChangeLog
gcc/ada/fe.h
gcc/ada/gcc-interface/decl.c
gcc/ada/repinfo.adb

index 0ea491e1ffcaebe49b679ececdaa961e559097b7..5ebe69e4de6f7cca188f6aa1a91e64a88a66f1a1 100644 (file)
@@ -1,3 +1,13 @@
+2018-05-24  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * 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.
+
 2018-05-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/trans.c (Handled_Sequence_Of_Statements_to_gnu):
index 77faac9777a3995a16b6e06bb6a1210e0b71cd4d..1928609ba05394031b788358e8a1ee73e37bd943 100644 (file)
@@ -68,6 +68,8 @@ extern Boolean Debug_Flag_NN;
 #define Set_Component_Size             einfo__set_component_size
 #define Set_Esize                      einfo__set_esize
 #define Set_Mechanism                  einfo__set_mechanism
+#define Set_Normalized_First_Bit       einfo__set_normalized_first_bit
+#define Set_Normalized_Position                einfo__set_normalized_position
 #define Set_RM_Size                    einfo__set_rm_size
 
 extern void Set_Alignment              (Entity_Id, Uint);
@@ -75,6 +77,8 @@ extern void Set_Component_Bit_Offset  (Entity_Id, Uint);
 extern void Set_Component_Size         (Entity_Id, Uint);
 extern void Set_Esize                  (Entity_Id, Uint);
 extern void Set_Mechanism              (Entity_Id, Mechanism_Type);
+extern void Set_Normalized_First_Bit   (Entity_Id, Uint);
+extern void Set_Normalized_Position    (Entity_Id, Uint);
 extern void Set_RM_Size                        (Entity_Id, Uint);
 
 #define Is_Entity_Name einfo__is_entity_name
index 7a827b742d89476250360fe8b7242b37f70b3094..a63cc1887bf78ab11b6f5f2943a707ed4f41da03 100644 (file)
@@ -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));
          }
       }
 }
index 7f7152d7b12ff791bcccb0efee5e59391a0b04bf..fd7a9319038c8635a5e1613a03faf93f5bf36e69 100644 (file)
@@ -992,7 +992,6 @@ package body Repinfo is
             declare
                Ctyp : constant Entity_Id := Underlying_Type (Etype (Comp));
                Esiz : constant Uint      := Esize (Comp);
-               Bofs : constant Uint      := Component_Bit_Offset (Comp);
                Npos : constant Uint      := Normalized_Position (Comp);
                Fbit : constant Uint      := Normalized_First_Bit (Comp);
                Spos : Uint;
@@ -1047,35 +1046,14 @@ package body Repinfo is
                   Spaces (Max_Spos_Length - UI_Image_Length);
                   Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
 
-               elsif Known_Component_Bit_Offset (Comp)
-                 and then List_Representation_Info = 3
-               then
-                  Spaces (Max_Spos_Length - 2);
-                  Write_Str ("bit offset ");
-
-                  if Starting_Position /= Uint_0
-                    or else Starting_First_Bit /= Uint_0
-                  then
-                     UI_Write (Starting_Position * SSU + Starting_First_Bit);
-                     Write_Str (" + ");
-                  end if;
-
-                  Write_Val (Bofs, Paren => True);
-                  Write_Str (" size in bits = ");
-                  Write_Val (Esiz, Paren => True);
-                  Write_Eol;
-
-                  goto Continue;
-
                elsif Known_Normalized_Position (Comp)
                  and then List_Representation_Info = 3
                then
                   Spaces (Max_Spos_Length - 2);
 
                   if Starting_Position /= Uint_0 then
-                     Write_Char (' ');
                      UI_Write (Starting_Position);
-                     Write_Str (" +");
+                     Write_Str (" + ");
                   end if;
 
                   Write_Val (Npos);