decl.c (gnat_to_gnu_entity): When discriminants affect the shape of the subtype...
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 20 May 2009 08:29:05 +0000 (08:29 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 20 May 2009 08:29:05 +0000 (08:29 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: When
discriminants affect the shape of the subtype, retrieve the GCC type
directly from the original field if the GNAT types for the field and
the original field are the same.

From-SVN: r147732

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c

index 0548b21cbcf761aa794551a67f028181efbb30af..d7396f142623e5e5afdd68047e476c5536aeb9b2 100644 (file)
@@ -1,3 +1,10 @@
+2009-05-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: When
+       discriminants affect the shape of the subtype, retrieve the GCC type
+       directly from the original field if the GNAT types for the field and
+       the original field are the same.
+
 2009-05-15  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/ada-tree.h (TYPE_GCC_MIN_VALUE, TYPE_GCC_MAX_VALUE):
index 46215daf4c97a5dbbaa3a2d95c4943ec38e06b2a..649b9ef41d269c1566be6be70c18c3e84327c406 100644 (file)
@@ -3124,21 +3124,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                        || !Is_Tagged_Type (gnat_base_type)))
                  {
                    tree gnu_old_field
-                     = gnat_to_gnu_field_decl (Original_Record_Component
-                                               (gnat_field));
+                     = gnat_to_gnu_field_decl
+                       (Original_Record_Component (gnat_field));
                    tree gnu_offset
-                     = TREE_VALUE (purpose_member (gnu_old_field,
-                                                   gnu_pos_list));
+                     = TREE_VALUE
+                       (purpose_member (gnu_old_field, gnu_pos_list));
                    tree gnu_pos = TREE_PURPOSE (gnu_offset);
                    tree gnu_bitpos = TREE_VALUE (TREE_VALUE (gnu_offset));
-                   tree gnu_field_type
-                     = gnat_to_gnu_type (Etype (gnat_field));
-                   tree gnu_size = TYPE_SIZE (gnu_field_type);
-                   tree gnu_new_pos = NULL_TREE;
+                   tree gnu_field, gnu_field_type, gnu_size, gnu_new_pos;
                    unsigned int offset_align
-                     = tree_low_cst (TREE_PURPOSE (TREE_VALUE (gnu_offset)),
-                                     1);
-                   tree gnu_field;
+                     = tree_low_cst
+                       (TREE_PURPOSE (TREE_VALUE (gnu_offset)), 1);
+
+                   /* If the type is the same, retrieve the GCC type from the
+                      old field to take into account possible adjustments.  */
+                   if (Etype (gnat_field)
+                       == Etype (Original_Record_Component (gnat_field)))
+                     gnu_field_type = TREE_TYPE (gnu_old_field);
+                   else
+                     gnu_field_type = gnat_to_gnu_type (Etype (gnat_field));
+
+                   gnu_size = TYPE_SIZE (gnu_field_type);
 
                    /* If there was a component clause, the field types must be
                       the same for the type and subtype, so copy the data from
@@ -3197,6 +3203,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                                                 TYPE_SIZE (gnu_type)))
                          continue;
                      }
+                   else
+                     gnu_new_pos = NULL_TREE;
 
                    gnu_field
                      = create_field_decl