decl.c (gnat_to_gnu_entity): In type annotation mode...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 30 Apr 2012 08:31:29 +0000 (08:31 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 30 Apr 2012 08:31:29 +0000 (08:31 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode,
do not adjust the size of a tagged type if there is a representation
clause on it.  Otherwise, round the adjustment up to the alignment
of the first field and use the appropriate helper routine.
(maybe_pad_type): Do not warn in type annotation mode on a tagged type.
(gnat_to_gnu_field): Do not error out under the same circumstances.
(annotate_rep): In type annotation mode, do not adjust the offset of
components of a tagged type with representation clause.  Otherwise,
round the adjustment up to the alignment of the first field.

From-SVN: r186961

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

index 838e4d0f6a8acc54accf32c20f624dd7abba6eb7..31d5ac418746367b856b17a8c9b3fc4ebf9beccc 100644 (file)
@@ -1,3 +1,15 @@
+2012-04-30  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode,
+       do not adjust the size of a tagged type if there is a representation
+       clause on it.  Otherwise, round the adjustment up to the alignment
+       of the first field and use the appropriate helper routine.
+       (maybe_pad_type): Do not warn in type annotation mode on a tagged type.
+       (gnat_to_gnu_field): Do not error out under the same circumstances.
+       (annotate_rep): In type annotation mode, do not adjust the offset of
+       components of a tagged type with representation clause.  Otherwise,
+       round the adjustment up to the alignment of the first field.
+
 2012-04-30  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/utils.c (finish_record_type): Force the traditional GCC
@@ -14,7 +26,7 @@
        (destroy_dummy_type): Likewise.
        * gcc-interface/trans.c (gnat_validate_uc_list): New variable.
        (gigi): Call validate_unchecked_conversion on gnat_validate_uc_list
-       after the translation is completed.  Call destroy_gnat_to_gnu and
+       after the translation is completed.  Call destroy_gnat_to_gnu and
        destroy_dummy_type at the end.
        (Subprogram_Body_to_gnu): Do not call mark_out_of_scope.
        (gnat_to_gnu) <N_Block_Statement>: Likewise.
index 6f351d3db2e3cbedac73e60c880cd7e23c8a6f8b..333d33b307e66f71cbcc60b6fb99fcc3ab4ae615 100644 (file)
@@ -5027,28 +5027,33 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
          if (CONTAINS_PLACEHOLDER_P (gnu_size))
            gnu_size = max_size (gnu_size, true);
 
-         if (type_annotate_only && Is_Tagged_Type (gnat_entity))
+         /* 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.  */
+         if (type_annotate_only
+             && Is_Tagged_Type (gnat_entity)
+             && !VOID_TYPE_P (gnu_type)
+             && (!TYPE_FIELDS (gnu_type)
+                 || integer_zerop (bit_position (TYPE_FIELDS (gnu_type)))))
            {
-             /* In this mode, the tag and the parent components are not
-                generated by the front-end so the sizes must be adjusted.  */
              tree pointer_size = bitsize_int (POINTER_SIZE), offset;
              Uint uint_size;
 
              if (Is_Derived_Type (gnat_entity))
                {
-                 offset = UI_To_gnu (Esize (Etype (Base_Type (gnat_entity))),
-                                     bitsizetype);
-                 Set_Alignment (gnat_entity,
-                                Alignment (Etype (Base_Type (gnat_entity))));
+                 Entity_Id gnat_parent = Etype (Base_Type (gnat_entity));
+                 offset = UI_To_gnu (Esize (gnat_parent), bitsizetype);
+                 Set_Alignment (gnat_entity, Alignment (gnat_parent));
                }
              else
                offset = pointer_size;
 
+             if (TYPE_FIELDS (gnu_type))
+               offset
+                 = round_up (offset, DECL_ALIGN (TYPE_FIELDS (gnu_type)));
+
              gnu_size = size_binop (PLUS_EXPR, gnu_size, offset);
-             gnu_size = size_binop (MULT_EXPR, pointer_size,
-                                               size_binop (CEIL_DIV_EXPR,
-                                                           gnu_size,
-                                                           pointer_size));
+             gnu_size = round_up (gnu_size, POINTER_SIZE);
              uint_size = annotate_value (gnu_size);
              Set_Esize (gnat_entity, uint_size);
              Set_RM_Size (gnat_entity, uint_size);
@@ -6619,7 +6624,9 @@ maybe_pad_type (tree type, tree size, unsigned int align,
   /* If the size was widened explicitly, maybe give a warning.  Take the
      original size as the maximum size of the input if there was an
      unconstrained record involved and round it up to the specified alignment,
-     if one was specified.  */
+     if one was specified.  But don't do it if we are just annotating types
+     and the type is tagged, since tagged types aren't fully laid out in this
+     mode.  */
   if (CONTAINS_PLACEHOLDER_P (orig_size))
     orig_size = max_size (orig_size, true);
 
@@ -6635,7 +6642,8 @@ maybe_pad_type (tree type, tree size, unsigned int align,
           && TREE_CODE (orig_size) == INTEGER_CST
           && (TREE_OVERFLOW (size)
               || TREE_OVERFLOW (orig_size)
-              || tree_int_cst_lt (size, orig_size))))
+              || tree_int_cst_lt (size, orig_size)))
+      && !(type_annotate_only && Is_Tagged_Type (Etype (gnat_entity))))
     {
       Node_Id gnat_error_node = Empty;
 
@@ -6901,10 +6909,13 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
            }
        }
 
-      /* If this field needs strict alignment, ensure the record is
-        sufficiently aligned and that that position and size are
-        consistent with the alignment.  */
-      if (needs_strict_alignment)
+      /* If this field needs strict alignment, check that the record is
+        sufficiently aligned and that position and size are consistent
+        with the alignment.  But don't do it if we are just annotating
+        types and the field's type is tagged, since tagged types aren't
+        fully laid out in this mode.  */
+      if (needs_strict_alignment
+         && !(type_annotate_only && Is_Tagged_Type (gnat_field_type)))
        {
          TYPE_ALIGN (gnu_record_type)
            = MAX (TYPE_ALIGN (gnu_record_type), TYPE_ALIGN (gnu_field_type));
@@ -7839,12 +7850,16 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
          {
            tree parent_offset;
 
-           if (type_annotate_only && Is_Tagged_Type (gnat_entity))
+           /* 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
+              we need to add the appropriate offset to each component without
+              representation clause.  */
+           if (type_annotate_only
+               && Is_Tagged_Type (gnat_entity)
+               && No (Component_Clause (gnat_field)))
              {
-               /* In this mode the tag and parent components are not
-                  generated, so we add the appropriate offset to each
-                  component.  For a component appearing in the current
-                  extension, the offset is the size of the parent.  */
+               /* 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
@@ -7852,6 +7867,11 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
                                 bitsizetype);
                else
                  parent_offset = bitsize_int (POINTER_SIZE);
+
+               if (TYPE_FIELDS (gnu_type))
+                 parent_offset
+                   = round_up (parent_offset,
+                               DECL_ALIGN (TYPE_FIELDS (gnu_type)));
              }
            else
              parent_offset = bitsize_zero_node;