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));
 	  }
       }
 }

Reply via email to