decl.c (variant_desc): Add AUX field.
[gcc.git] / gcc / ada / gcc-interface / decl.c
index f626e6186d23f1a69be7cc98f749c0d3b024d79e..a79cb0070246599523806ed84f516ec6e5765502 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *          Copyright (C) 1992-2017, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2018, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -123,6 +123,9 @@ typedef struct variant_desc_d {
 
   /* The type of the variant after transformation.  */
   tree new_type;
+
+  /* The auxiliary data.  */
+  tree aux;
 } variant_desc;
 
 
@@ -282,6 +285,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
   /* True if this entity is to be considered as imported.  */
   const bool imported_p
     = (Is_Imported (gnat_entity) && No (Address_Clause (gnat_entity)));
+  /* True if this entity has a foreign convention.  */
+  const bool foreign = Has_Foreign_Convention (gnat_entity);
   /* For a type, contains the equivalent GNAT node to be used in gigi.  */
   Entity_Id gnat_equiv_type = Empty;
   /* Temporary used to walk the GNAT tree.  */
@@ -599,16 +604,16 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
         was defined to represent.  This is necessary to avoid generating dumb
         elaboration code in simple cases, but we may throw it away later if it
         is not a constant.  But do not retrieve it if it is an allocator since
-        the designated type might still be dummy at this point.  */
+        the designated type might still be dummy at this point.  Note that we
+        invoke gnat_to_gnu_external and not gnat_to_gnu because the expression
+        may contain N_Expression_With_Actions nodes and thus declarations of
+        objects from other units that we need to discard.  */
       if (!definition
          && !No_Initialization (Declaration_Node (gnat_entity))
-         && Present (Expression (Declaration_Node (gnat_entity)))
-         && Nkind (Expression (Declaration_Node (gnat_entity)))
-            != N_Allocator)
-         /* The expression may contain N_Expression_With_Actions nodes and
-            thus object declarations from other units.  Discard them.  */
-       gnu_expr
-         = gnat_to_gnu_external (Expression (Declaration_Node (gnat_entity)));
+         && Present (gnat_temp = Expression (Declaration_Node (gnat_entity)))
+         && Nkind (gnat_temp) != N_Allocator
+         && (!type_annotate_only || Compile_Time_Known_Value (gnat_temp)))
+       gnu_expr = gnat_to_gnu_external (gnat_temp);
 
       /* ... fall through ... */
 
@@ -658,8 +663,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          }
 
        /* Get the type after elaborating the renamed object.  */
-       if (Has_Foreign_Convention (gnat_entity)
-           && Is_Descendant_Of_Address (Underlying_Type (gnat_type)))
+       if (foreign && Is_Descendant_Of_Address (Underlying_Type (gnat_type)))
          gnu_type = ptr_type_node;
        else
          {
@@ -713,48 +717,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          }
 
        /* If an alignment is specified, use it if valid.  Note that exceptions
-          are objects but don't have an alignment.  We must do this before we
-          validate the size, since the alignment can affect the size.  */
-       if (kind != E_Exception && Known_Alignment (gnat_entity))
-         {
-           gcc_assert (Present (Alignment (gnat_entity)));
-
-           align = validate_alignment (Alignment (gnat_entity), gnat_entity,
-                                       TYPE_ALIGN (gnu_type));
-
-           /* No point in changing the type if there is an address clause
-              as the final type of the object will be a reference type.  */
-           if (Present (Address_Clause (gnat_entity)))
-             align = 0;
-           else
-             {
-               tree orig_type = gnu_type;
-
-               gnu_type
-                 = maybe_pad_type (gnu_type, NULL_TREE, align, gnat_entity,
-                                   false, false, definition, true);
-
-               /* If a padding record was made, declare it now since it will
-                  never be declared otherwise.  This is necessary to ensure
-                  that its subtrees are properly marked.  */
-               if (gnu_type != orig_type && !DECL_P (TYPE_NAME (gnu_type)))
-                 create_type_decl (TYPE_NAME (gnu_type), gnu_type, true,
-                                   debug_info_p, gnat_entity);
-             }
-         }
-
-       /* If we are defining the object, see if it has a Size and validate it
-          if so.  If we are not defining the object and a Size clause applies,
-          simply retrieve the value.  We don't want to ignore the clause and
-          it is expected to have been validated already.  Then get the new
-          type, if any.  */
-       if (definition)
-         gnu_size = validate_size (Esize (gnat_entity), gnu_type,
-                                   gnat_entity, VAR_DECL, false,
-                                   Has_Size_Clause (gnat_entity));
-       else if (Has_Size_Clause (gnat_entity))
-         gnu_size = UI_To_gnu (Esize (gnat_entity), bitsizetype);
+          are objects but don't have an alignment and there is also no point in
+          setting it for an address clause, since the final type of the object
+          will be a reference type.  */
+       if (Known_Alignment (gnat_entity)
+           && kind != E_Exception
+           && No (Address_Clause (gnat_entity)))
+         align = validate_alignment (Alignment (gnat_entity), gnat_entity,
+                                     TYPE_ALIGN (gnu_type));
 
+       /* Likewise, if a size is specified, use it if valid.  */
+       if (Known_Esize (gnat_entity))
+         gnu_size
+           = validate_size (Esize (gnat_entity), gnu_type, gnat_entity,
+                            VAR_DECL, false, Has_Size_Clause (gnat_entity));
        if (gnu_size)
          {
            gnu_type
@@ -1622,6 +1598,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          tree gnu_list = NULL_TREE;
          Entity_Id gnat_literal;
 
+         /* Boolean types with foreign convention have precision 1.  */
+         if (is_boolean && foreign)
+           esize = 1;
+
          gnu_type = make_node (is_boolean ? BOOLEAN_TYPE : ENUMERAL_TYPE);
          TYPE_PRECISION (gnu_type) = esize;
          TYPE_UNSIGNED (gnu_type) = is_unsigned;
@@ -1802,6 +1782,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
        esize = UI_To_Int (RM_Size (gnat_entity));
 
+      /* Boolean types with foreign convention have precision 1.  */
+      if (Is_Boolean_Type (gnat_entity) && foreign)
+       {
+         gnu_type = make_node (BOOLEAN_TYPE);
+         TYPE_PRECISION (gnu_type) = 1;
+         TYPE_UNSIGNED (gnu_type) = 1;
+         set_min_and_max_values_for_integral_type (gnu_type, 1, UNSIGNED);
+         layout_type (gnu_type);
+       }
       /* First subtypes of Character are treated as Character; otherwise
         this should be an unsigned type if the base type is unsigned or
         if the lower bound is constant and non-negative or if the type
@@ -1811,7 +1800,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
         conversions to it and gives more leeway to the optimizer; but
         this means that we will need to explicitly test for this case
         when we change the representation based on the RM size.  */
-      if (kind == E_Enumeration_Subtype
+      else if (kind == E_Enumeration_Subtype
          && No (First_Literal (Etype (gnat_entity)))
          && Esize (gnat_entity) == RM_Size (gnat_entity)
          && esize == CHAR_TYPE_SIZE
@@ -1836,8 +1825,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                                         gnat_entity, "U", definition, true,
                                         debug_info_p));
 
-      TYPE_BIASED_REPRESENTATION_P (gnu_type)
-       = Has_Biased_Representation (gnat_entity);
+      if (TREE_CODE (gnu_type) == INTEGER_TYPE)
+       TYPE_BIASED_REPRESENTATION_P (gnu_type)
+         = Has_Biased_Representation (gnat_entity);
 
       /* Do the same processing for Character subtypes as for types.  */
       if (TYPE_STRING_FLAG (TREE_TYPE (gnu_type)))
@@ -1901,10 +1891,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                            UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
          TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
 
-         /* Strip the ___XP suffix for standard DWARF.  */
-         if (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
-           gnu_entity_name = TYPE_NAME (gnu_type);
-
          /* Create a stripped-down declaration, mainly for debugging.  */
          create_type_decl (gnu_entity_name, gnu_type, true, debug_info_p,
                            gnat_entity);
@@ -1944,7 +1930,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 
          /* We will output additional debug info manually below.  */
          finish_record_type (gnu_type, gnu_field, 2, false);
-         compute_record_mode (gnu_type);
          TYPE_JUSTIFIED_MODULAR_P (gnu_type) = 1;
 
          if (debug_info_p)
@@ -2072,11 +2057,16 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          {
            gnu_fat_type = TYPE_MAIN_VARIANT (TYPE_POINTER_TO (gnu_type));
            TYPE_NAME (gnu_fat_type) = NULL_TREE;
-           /* Save the contents of the dummy type for update_pointer_to.  */
-           TYPE_POINTER_TO (gnu_type) = copy_type (gnu_fat_type);
            gnu_ptr_template =
-             TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_fat_type)));
+             TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_fat_type)));
            gnu_template_type = TREE_TYPE (gnu_ptr_template);
+
+           /* Save the contents of the dummy type for update_pointer_to.  */
+           TYPE_POINTER_TO (gnu_type) = copy_type (gnu_fat_type);
+           TYPE_FIELDS (TYPE_POINTER_TO (gnu_type))
+             = copy_node (TYPE_FIELDS (gnu_fat_type));
+           DECL_CHAIN (TYPE_FIELDS (TYPE_POINTER_TO (gnu_type)))
+             = copy_node (DECL_CHAIN (TYPE_FIELDS (gnu_fat_type)));
          }
        else
          {
@@ -2097,29 +2087,39 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 
        /* Build the fat pointer type.  Use a "void *" object instead of
           a pointer to the array type since we don't have the array type
-          yet (it will reference the fat pointer via the bounds).  */
-       tem
-         = create_field_decl (get_identifier ("P_ARRAY"), ptr_type_node,
-                              gnu_fat_type, NULL_TREE, NULL_TREE, 0, 0);
-       DECL_CHAIN (tem)
-         = create_field_decl (get_identifier ("P_BOUNDS"), gnu_ptr_template,
-                              gnu_fat_type, NULL_TREE, NULL_TREE, 0, 0);
-
+          yet (it will reference the fat pointer via the bounds).  Note
+          that we reuse the existing fields of a dummy type because for:
+
+            type Arr is array (Positive range <>) of Element_Type;
+            type Array_Ref is access Arr;
+            Var : Array_Ref := Null;
+
+          in a declarative part, Arr will be frozen only after Var, which
+          means that the fields used in the CONSTRUCTOR built for Null are
+          those of the dummy type, which in turn means that COMPONENT_REFs
+          of Var may be built with these fields.  Now if COMPONENT_REFs of
+          Var are also built later with the fields of the final type, the
+          aliasing machinery may consider that the accesses are distinct
+          if the FIELD_DECLs are distinct as objects.  */
        if (COMPLETE_TYPE_P (gnu_fat_type))
          {
-           /* We are going to lay it out again so reset the alias set.  */
-           alias_set_type alias_set = TYPE_ALIAS_SET (gnu_fat_type);
-           TYPE_ALIAS_SET (gnu_fat_type) = -1;
-           finish_fat_pointer_type (gnu_fat_type, tem);
-           TYPE_ALIAS_SET (gnu_fat_type) = alias_set;
+           tem = TYPE_FIELDS (gnu_fat_type);
+           TREE_TYPE (tem) = ptr_type_node;
+           TREE_TYPE (DECL_CHAIN (tem)) = gnu_ptr_template;
+           TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (gnu_fat_type)) = 0;
            for (t = gnu_fat_type; t; t = TYPE_NEXT_VARIANT (t))
-             {
-               TYPE_FIELDS (t) = tem;
-               SET_TYPE_UNCONSTRAINED_ARRAY (t, gnu_type);
-             }
+             SET_TYPE_UNCONSTRAINED_ARRAY (t, gnu_type);
          }
        else
          {
+           tem
+             = create_field_decl (get_identifier ("P_ARRAY"),
+                                  ptr_type_node, gnu_fat_type,
+                                  NULL_TREE, NULL_TREE, 0, 0);
+           DECL_CHAIN (tem)
+             = create_field_decl (get_identifier ("P_BOUNDS"),
+                                  gnu_ptr_template, gnu_fat_type,
+                                  NULL_TREE, NULL_TREE, 0, 0);
            finish_fat_pointer_type (gnu_fat_type, tem);
            SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_type);
          }
@@ -2139,7 +2139,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
           index to the template.  */
        for (index = (convention_fortran_p ? ndim - 1 : 0),
             gnat_index = First_Index (gnat_entity);
-            0 <= index && index < ndim;
+            IN_RANGE (index, 0, ndim - 1);
             index += (convention_fortran_p ? - 1 : 1),
             gnat_index = Next_Index (gnat_index))
          {
@@ -2390,7 +2390,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
               gnat_index = First_Index (gnat_entity),
               gnat_base_index
                 = First_Index (Implementation_Base_Type (gnat_entity));
-              0 <= index && index < ndim;
+              IN_RANGE (index, 0, ndim - 1);
               index += (convention_fortran_p ? - 1 : 1),
               gnat_index = Next_Index (gnat_index),
               gnat_base_index = Next_Index (gnat_base_index))
@@ -2651,17 +2651,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                set_nonaliased_component_on_array_type (gnu_type);
            }
 
-         /* Strip the ___XP suffix for standard DWARF.  */
-         if (Is_Packed_Array_Impl_Type (gnat_entity)
-             && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
-           {
-             Entity_Id gnat_original_array_type
-               = Underlying_Type (Original_Array_Type (gnat_entity));
-
-             gnu_entity_name
-               = get_entity_name (gnat_original_array_type);
-           }
-
          /* Attach the TYPE_STUB_DECL in case we have a parallel type.  */
          TYPE_STUB_DECL (gnu_type)
            = create_type_stub_decl (gnu_entity_name, gnu_type);
@@ -2787,13 +2776,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
             array subtypes the same alias set.  */
          relate_alias_sets (gnu_type, gnu_base_type, ALIAS_SET_COPY);
 
-         /* If this is a packed type, make this type the same as the packed
-            array type, but do some adjusting in the type first.  */
+         /* If this is a packed type implemented specially, then replace our
+            type with the implementation type.  */
          if (Present (Packed_Array_Impl_Type (gnat_entity)))
            {
-             Entity_Id gnat_index;
-             tree gnu_inner;
-
              /* First finish the type we had been making so that we output
                 debugging information for it.  */
              process_attributes (&gnu_type, &attr_list, false, gnat_entity);
@@ -2808,26 +2794,24 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                 That's sort of "morally" true and will make it possible for
                 the debugger to look it up by name in DWARF, which is needed
                 in order to decode the packed array type.  */
-             gnu_decl
+             tree gnu_tmp_decl
                = create_type_decl (gnu_entity_name, gnu_type,
                                    !Comes_From_Source (Etype (gnat_entity))
                                    && artificial_p, debug_info_p,
                                    gnat_entity);
-
              /* Save it as our equivalent in case the call below elaborates
                 this type again.  */
-             save_gnu_tree (gnat_entity, gnu_decl, false);
+             save_gnu_tree (gnat_entity, gnu_tmp_decl, false);
 
-             gnu_decl
-               = gnat_to_gnu_entity (Packed_Array_Impl_Type (gnat_entity),
-                                     NULL_TREE, false);
-             this_made_decl = true;
-             gnu_type = TREE_TYPE (gnu_decl);
+             gnu_type
+               = gnat_to_gnu_type (Packed_Array_Impl_Type (gnat_entity));
              save_gnu_tree (gnat_entity, NULL_TREE, false);
-             save_gnu_tree (gnat_entity, gnu_decl, false);
-             saved = true;
 
-             gnu_inner = gnu_type;
+             /* Set the ___XP suffix for GNAT encodings.  */
+             if (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL)
+               gnu_entity_name = DECL_NAME (TYPE_NAME (gnu_type));
+
+             tree gnu_inner = gnu_type;
              while (TREE_CODE (gnu_inner) == RECORD_TYPE
                     && (TYPE_JUSTIFIED_MODULAR_P (gnu_inner)
                         || TYPE_PADDING_P (gnu_inner)))
@@ -2864,7 +2848,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                      gcc_checking_assert (!TYPE_ACTUAL_BOUNDS (gnu_inner));
                    }
 
-                 for (gnat_index = First_Index (gnat_entity);
+                 for (Entity_Id gnat_index = First_Index (gnat_entity);
                       Present (gnat_index);
                       gnat_index = Next_Index (gnat_index))
                    SET_TYPE_ACTUAL_BOUNDS
@@ -3328,6 +3312,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                                  all_rep ? NULL_TREE : bitsize_zero_node,
                                  NULL);
 
+           /* Empty classes have the size of a storage unit in C++.  */
+           if (TYPE_SIZE (gnu_type) == bitsize_zero_node
+               && Convention (gnat_entity) == Convention_CPP)
+             {
+               TYPE_SIZE (gnu_type) = bitsize_unit_node;
+               TYPE_SIZE_UNIT (gnu_type) = size_one_node;
+               compute_record_mode (gnu_type);
+             }
+
            /* If there are entities in the chain corresponding to components
               that we did not elaborate, ensure we elaborate their types if
               they are Itypes.  */
@@ -3994,8 +3987,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
        /* If we should request stack realignment for a foreign convention
           subprogram, do so.  Note that this applies to task entry points
           in particular.  */
-       if (FOREIGN_FORCE_REALIGN_STACK
-           && Has_Foreign_Convention (gnat_entity))
+       if (FOREIGN_FORCE_REALIGN_STACK && foreign)
          prepend_one_attribute
            (&attr_list, ATTR_MACHINE_ATTRIBUTE,
             get_identifier ("force_align_arg_pointer"), NULL_TREE,
@@ -4580,15 +4572,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
          gnu_type = change_qualified_type (gnu_type, quals);
        }
 
-      if (!gnu_decl)
-       gnu_decl = create_type_decl (gnu_entity_name, gnu_type,
-                                    artificial_p, debug_info_p,
-                                    gnat_entity);
-      else
+      /* If we already made a decl, just set the type, otherwise create it.  */
+      if (gnu_decl)
        {
          TREE_TYPE (gnu_decl) = gnu_type;
          TYPE_STUB_DECL (gnu_type) = gnu_decl;
        }
+      else
+       gnu_decl = create_type_decl (gnu_entity_name, gnu_type, artificial_p,
+                                    debug_info_p, gnat_entity);
     }
 
   /* If we got a type that is not dummy, back-annotate the alignment of the
@@ -5050,26 +5042,12 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
       && tree_fits_uhwi_p (TYPE_SIZE (gnu_type)))
     gnu_type = make_packable_type (gnu_type, false, max_align);
 
-  if (Has_Atomic_Components (gnat_array))
-    check_ok_for_atomic_type (gnu_type, gnat_array, true);
-
   /* Get and validate any specified Component_Size.  */
   gnu_comp_size
     = validate_size (Component_Size (gnat_array), gnu_type, gnat_array,
                     Is_Bit_Packed_Array (gnat_array) ? TYPE_DECL : VAR_DECL,
                     true, Has_Component_Size_Clause (gnat_array));
 
-  /* If the array has aliased components and the component size can be zero,
-     force at least unit size to ensure that the components have distinct
-     addresses.  */
-  if (!gnu_comp_size
-      && Has_Aliased_Components (gnat_array)
-      && (integer_zerop (TYPE_SIZE (gnu_type))
-         || (TREE_CODE (gnu_type) == ARRAY_TYPE
-             && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))))
-    gnu_comp_size
-      = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);
-
   /* If the component type is a RECORD_TYPE that has a self-referential size,
      then use the maximum size for the component size.  */
   if (!gnu_comp_size
@@ -5077,6 +5055,13 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
       && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
     gnu_comp_size = max_size (TYPE_SIZE (gnu_type), true);
 
+  /* If the array has aliased components and the component size is zero, force
+     the unit size to ensure that the components have distinct addresses.  */
+  if (!gnu_comp_size
+      && Has_Aliased_Components (gnat_array)
+      && integer_zerop (TYPE_SIZE (gnu_type)))
+    gnu_comp_size = bitsize_unit_node;
+
   /* Honor the component size.  This is not needed for bit-packed arrays.  */
   if (gnu_comp_size && !Is_Bit_Packed_Array (gnat_array))
     {
@@ -5099,6 +5084,33 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
                          gnat_array);
     }
 
+  /* This is a very special case where the array has aliased components and the
+     component size might be zero at run time.  As explained above, we force at
+     least the unit size but we don't want to build a distinct padding type for
+     each invocation (they are not canonicalized if they have variable size) so
+     we cache this special padding type as TYPE_PADDING_FOR_COMPONENT.  */
+  else if (Has_Aliased_Components (gnat_array)
+          && TREE_CODE (gnu_type) == ARRAY_TYPE
+          && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))
+    {
+      if (TYPE_PADDING_FOR_COMPONENT (gnu_type))
+       gnu_type = TYPE_PADDING_FOR_COMPONENT (gnu_type);
+      else
+       {
+         gnu_comp_size
+           = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);
+         TYPE_PADDING_FOR_COMPONENT (gnu_type)
+           = maybe_pad_type (gnu_type, gnu_comp_size, 0, gnat_array,
+                             true, false, definition, true);
+         gnu_type = TYPE_PADDING_FOR_COMPONENT (gnu_type);
+         create_type_decl (TYPE_NAME (gnu_type), gnu_type, true, debug_info_p,
+                           gnat_array);
+       }
+    }
+
+  if (Has_Atomic_Components (gnat_array) || Is_Atomic_Or_VFA (gnat_type))
+    check_ok_for_atomic_type (gnu_type, gnat_array, true);
+
   /* If the component type is a padded type made for a non-bit-packed array
      of scalars with reverse storage order, we need to propagate the reverse
      storage order to the padding type since it is the innermost enclosing
@@ -6141,6 +6153,11 @@ array_type_has_nonaliased_component (tree gnu_type, Entity_Id gnat_type)
       return TYPE_NONALIASED_COMPONENT (gnu_parent_type);
     }
 
+  /* Consider that an array of pointers has an aliased component, which is
+     sort of logical and helps with Taft Amendment types in LTO mode.  */
+  if (POINTER_TYPE_P (TREE_TYPE (gnu_type)))
+    return false;
+
   /* Otherwise, rely exclusively on properties of the element type.  */
   return type_for_nonaliased_component_p (TREE_TYPE (gnu_type));
 }
@@ -6918,7 +6935,8 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
        {
          const unsigned int type_align = TYPE_ALIGN (gnu_field_type);
 
-         if (TYPE_ALIGN (gnu_record_type) < type_align)
+         if (TYPE_ALIGN (gnu_record_type)
+             && TYPE_ALIGN (gnu_record_type) < type_align)
            SET_TYPE_ALIGN (gnu_record_type, type_align);
 
          /* If the position is not a multiple of the alignment of the type,
@@ -7212,6 +7230,28 @@ compare_field_bitpos (const PTR rt1, const PTR rt2)
   return ret ? ret : (int) (DECL_UID (field1) - DECL_UID (field2));
 }
 
+/* Sort the LIST of fields in reverse order of increasing position.  */
+
+static tree
+reverse_sort_field_list (tree list)
+{
+  const int len = list_length (list);
+  tree *field_arr = XALLOCAVEC (tree, len);
+
+  for (int i = 0; list; list = DECL_CHAIN (list), i++)
+    field_arr[i] = list;
+
+  qsort (field_arr, len, sizeof (tree), compare_field_bitpos);
+
+  for (int i = 0; i < len; i++)
+    {
+      DECL_CHAIN (field_arr[i]) = list;
+      list = field_arr[i];
+    }
+
+  return list;
+}
+
 /* Reverse function from gnat_to_gnu_field: return the GNAT field present in
    either GNAT_COMPONENT_LIST or the discriminants of GNAT_RECORD_TYPE, and
    corresponding to the GNU tree GNU_FIELD.  */
@@ -8021,7 +8061,23 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
 
   /* Chain the variant part at the end of the field list.  */
   if (gnu_variant_part)
-    gnu_field_list = chainon (gnu_field_list, gnu_variant_part);
+    {
+      /* We make an exception if the variant part is at offset 0, has a fixed
+        size, and there is a single rep'ed field placed after it because, in
+        this case, there is an obvious order of increasing position.  */
+      if (variants_have_rep
+         && TREE_CODE (DECL_SIZE_UNIT (gnu_variant_part)) == INTEGER_CST
+         && gnu_rep_list
+         && gnu_field_list == gnu_rep_list
+         && !tree_int_cst_lt (DECL_FIELD_OFFSET (gnu_rep_list),
+                              DECL_SIZE_UNIT (gnu_variant_part)))
+       {
+         DECL_CHAIN (gnu_variant_part) = gnu_field_list;
+         gnu_field_list = gnu_variant_part;
+       }
+      else
+       gnu_field_list = chainon (gnu_field_list, gnu_variant_part);
+    }
 
   if (cancel_alignment)
     SET_TYPE_ALIGN (gnu_record_type, 0);
@@ -8131,9 +8187,9 @@ annotate_value (tree gnu_size)
     case MIN_EXPR:             tcode = Min_Expr; break;
     case MAX_EXPR:             tcode = Max_Expr; break;
     case ABS_EXPR:             tcode = Abs_Expr; break;
-    case TRUTH_ANDIF_EXPR:     tcode = Truth_Andif_Expr; break;
-    case TRUTH_ORIF_EXPR:      tcode = Truth_Orif_Expr; break;
+    case TRUTH_ANDIF_EXPR:
     case TRUTH_AND_EXPR:       tcode = Truth_And_Expr; break;
+    case TRUTH_ORIF_EXPR:
     case TRUTH_OR_EXPR:                tcode = Truth_Or_Expr; break;
     case TRUTH_XOR_EXPR:       tcode = Truth_Xor_Expr; break;
     case TRUTH_NOT_EXPR:       tcode = Truth_Not_Expr; break;
@@ -8313,7 +8369,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
@@ -8323,31 +8380,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))));
@@ -8356,19 +8428,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));
          }
       }
 }
@@ -8487,7 +8567,8 @@ build_variant_list (tree qual_union_type, vec<subst_pair> subst_list,
       if (!integer_zerop (qual))
        {
          tree variant_type = TREE_TYPE (gnu_field), variant_subpart;
-         variant_desc v = { variant_type, gnu_field, qual, NULL_TREE };
+         variant_desc v
+           = { variant_type, gnu_field, qual, NULL_TREE, NULL_TREE };
 
          gnu_list.safe_push (v);
 
@@ -9261,7 +9342,6 @@ create_variant_part_from (tree old_variant_part,
 
       /* Finish up the new variant and create the field.  */
       finish_record_type (new_variant, nreverse (field_list), 2, debug_info_p);
-      compute_record_mode (new_variant);
       create_type_decl (TYPE_NAME (new_variant), new_variant, true,
                        debug_info_p, Empty);
 
@@ -9279,7 +9359,6 @@ create_variant_part_from (tree old_variant_part,
      reverse the field list because VARIANT_LIST has been traversed in reverse
      order.  */
   finish_record_type (new_union_type, union_field_list, 2, debug_info_p);
-  compute_record_mode (new_union_type);
   create_type_decl (TYPE_NAME (new_union_type), new_union_type, true,
                    debug_info_p, Empty);
 
@@ -9377,7 +9456,8 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
 {
   const bool is_subtype = (Ekind (gnat_new_type) == E_Record_Subtype);
   tree gnu_field_list = NULL_TREE;
-  bool selected_variant, all_constant_pos = true;
+  tree gnu_variable_field_list = NULL_TREE;
+  bool selected_variant;
   vec<variant_desc> gnu_variant_list;
 
   /* Look for REP and variant parts in the old type.  */
@@ -9461,6 +9541,7 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
         tree gnu_context = DECL_CONTEXT (gnu_old_field);
        tree gnu_field, gnu_field_type, gnu_size, gnu_pos;
        tree gnu_cont_type, gnu_last = NULL_TREE;
+       variant_desc *v = NULL;
 
        /* If the type is the same, retrieve the GCC type from the
           old field to take into account possible adjustments.  */
@@ -9509,7 +9590,6 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
          gnu_cont_type = gnu_new_type;
        else
          {
-           variant_desc *v;
            unsigned int i;
            tree rep_part;
 
@@ -9522,7 +9602,7 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
            if (v)
              gnu_cont_type = selected_variant ? gnu_new_type : v->new_type;
            else
-             /* The front-end may pass us "ghost" components if it fails to
+             /* The front-end may pass us zombie components if it fails to
                 recognize that a constrain statically selects a particular
                 variant.  Discard them.  */
              continue;
@@ -9538,8 +9618,16 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
        /* If the context is a variant, put it in the new variant directly.  */
        if (gnu_cont_type != gnu_new_type)
          {
-           DECL_CHAIN (gnu_field) = TYPE_FIELDS (gnu_cont_type);
-           TYPE_FIELDS (gnu_cont_type) = gnu_field;
+           if (TREE_CODE (gnu_pos) == INTEGER_CST)
+             {
+               DECL_CHAIN (gnu_field) = TYPE_FIELDS (gnu_cont_type);
+               TYPE_FIELDS (gnu_cont_type) = gnu_field;
+             }
+           else
+             {
+               DECL_CHAIN (gnu_field) = v->aux;
+               v->aux = gnu_field;
+             }
          }
 
        /* To match the layout crafted in components_to_record, if this is
@@ -9558,12 +9646,18 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
        /* Otherwise, put it after the other fields.  */
        else
          {
-           DECL_CHAIN (gnu_field) = gnu_field_list;
-           gnu_field_list = gnu_field;
-           if (!gnu_last)
-             gnu_last = gnu_field;
-           if (TREE_CODE (gnu_pos) != INTEGER_CST)
-             all_constant_pos = false;
+           if (TREE_CODE (gnu_pos) == INTEGER_CST)
+             {
+               DECL_CHAIN (gnu_field) = gnu_field_list;
+               gnu_field_list = gnu_field;
+               if (!gnu_last)
+                 gnu_last = gnu_field;
+             }
+           else
+             {
+               DECL_CHAIN (gnu_field) = gnu_variable_field_list;
+               gnu_variable_field_list = gnu_field;
+             }
          }
 
        /* For a stored discriminant in a derived type, replace the field.  */
@@ -9576,31 +9670,32 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
          save_gnu_tree (gnat_field, gnu_field, false);
       }
 
-  /* If there is no variant list or a selected variant and the fields all have
-     constant position, put them in order of increasing position to match that
-     of constant CONSTRUCTORs.  */
-  if ((!gnu_variant_list.exists () || selected_variant) && all_constant_pos)
-    {
-      const int len = list_length (gnu_field_list);
-      tree *field_arr = XALLOCAVEC (tree, len), t = gnu_field_list;
+  /* Put the fields with fixed position in order of increasing position.  */
+  if (gnu_field_list)
+    gnu_field_list = reverse_sort_field_list (gnu_field_list);
 
-      for (int i = 0; t; t = DECL_CHAIN (t), i++)
-       field_arr[i] = t;
+  /* Put the fields with variable position at the end.  */
+  if (gnu_variable_field_list)
+    gnu_field_list = chainon (gnu_variable_field_list, gnu_field_list);
 
-      qsort (field_arr, len, sizeof (tree), compare_field_bitpos);
+  /* If there is a variant list and no selected variant, we need to create the
+     nest of variant parts from the old nest.  */
+  if (gnu_variant_list.exists () && !selected_variant)
+    {
+      variant_desc *v;
+      unsigned int i;
 
-      gnu_field_list = NULL_TREE;
-      for (int i = 0; i < len; i++)
+      /* Same processing as above for the fields of each variant.  */
+      FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
        {
-         DECL_CHAIN (field_arr[i]) = gnu_field_list;
-         gnu_field_list = field_arr[i];
+         if (TYPE_FIELDS (v->new_type))
+           TYPE_FIELDS (v->new_type)
+             = reverse_sort_field_list (TYPE_FIELDS (v->new_type));
+         if (v->aux)
+           TYPE_FIELDS (v->new_type)
+             = chainon (v->aux, TYPE_FIELDS (v->new_type));
        }
-    }
 
-  /* If there is a variant list and no selected variant, we need to create the
-     nest of variant parts from the old nest.  */
-  else if (gnu_variant_list.exists () && !selected_variant)
-    {
       tree new_variant_part
        = create_variant_part_from (gnu_variant_part, gnu_variant_list,
                                    gnu_new_type, gnu_pos_list,
@@ -9612,17 +9707,10 @@ copy_and_substitute_in_layout (Entity_Id gnat_new_type,
   gnu_variant_list.release ();
   gnu_subst_list.release ();
 
-  gnu_field_list = nreverse (gnu_field_list);
-
   /* If NEW_TYPE is a subtype, it inherits all the attributes from OLD_TYPE.
      Otherwise sizes and alignment must be computed independently.  */
-  if (is_subtype)
-    {
-      finish_record_type (gnu_new_type, gnu_field_list, 2, debug_info_p);
-      compute_record_mode (gnu_new_type);
-    }
-  else
-    finish_record_type (gnu_new_type, gnu_field_list, 1, debug_info_p);
+  finish_record_type (gnu_new_type, nreverse (gnu_field_list),
+                     is_subtype ? 2 : 1, debug_info_p);
 
   /* Now go through the entities again looking for Itypes that we have not yet
      elaborated (e.g. Etypes of fields that have Original_Components).  */