------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             E X P _ P A K D                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;    use Atree;
with Checks;   use Checks;
with Einfo;    use Einfo;
with Errout;   use Errout;
with Exp_Dbug; use Exp_Dbug;
with Exp_Util; use Exp_Util;
with Layout;   use Layout;
with Lib.Xref; use Lib.Xref;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Sem;      use Sem;
with Sem_Aux;  use Sem_Aux;
with Sem_Ch3;  use Sem_Ch3;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
with Sem_Eval; use Sem_Eval;
with Sem_Res;  use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Snames;   use Snames;
with Stand;    use Stand;
with Targparm; use Targparm;
with Tbuild;   use Tbuild;
with Ttypes;   use Ttypes;
with Uintp;    use Uintp;

package body Exp_Pakd is

   ---------------------------
   -- Endian Considerations --
   ---------------------------

   --  As described in the specification, bit numbering in a packed array
   --  is consistent with bit numbering in a record representation clause,
   --  and hence dependent on the endianness of the machine:

   --    For little-endian machines, element zero is at the right hand end
   --    (low order end) of a bit field.

   --    For big-endian machines, element zero is at the left hand end
   --    (high order end) of a bit field.

   --  The shifts that are used to right justify a field therefore differ in
   --  the two cases. For the little-endian case, we can simply use the bit
   --  number (i.e. the element number * element size) as the count for a right
   --  shift. For the big-endian case, we have to subtract the shift count from
   --  an appropriate constant to use in the right shift. We use rotates
   --  instead of shifts (which is necessary in the store case to preserve
   --  other fields), and we expect that the backend will be able to change the
   --  right rotate into a left rotate, avoiding the subtract, if the machine
   --  architecture provides such an instruction.

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Compute_Linear_Subscript
     (Atyp   : Entity_Id;
      N      : Node_Id;
      Subscr : out Node_Id);
   --  Given a constrained array type Atyp, and an indexed component node N
   --  referencing an array object of this type, build an expression of type
   --  Standard.Integer representing the zero-based linear subscript value.
   --  This expression includes any required range checks.

   function Compute_Number_Components
      (N   : Node_Id;
       Typ : Entity_Id) return Node_Id;
   --  Build an expression that multiplies the length of the dimensions of the
   --  array, used to control array equality checks.

   procedure Convert_To_PAT_Type (Aexp : Node_Id);
   --  Given an expression of a packed array type, builds a corresponding
   --  expression whose type is the implementation type used to represent
   --  the packed array. Aexp is analyzed and resolved on entry and on exit.

   procedure Get_Base_And_Bit_Offset
     (N      : Node_Id;
      Base   : out Node_Id;
      Offset : out Node_Id);
   --  Given a node N for a name which involves a packed array reference,
   --  return the base object of the reference and build an expression of
   --  type Standard.Integer representing the zero-based offset in bits
   --  from Base'Address to the first bit of the reference.

   function Known_Aligned_Enough (Obj : Node_Id; Csiz : Nat) return Boolean;
   --  There are two versions of the Set routines, the ones used when the
   --  object is known to be sufficiently well aligned given the number of
   --  bits, and the ones used when the object is not known to be aligned.
   --  This routine is used to determine which set to use. Obj is a reference
   --  to the object, and Csiz is the component size of the packed array.
   --  True is returned if the alignment of object is known to be sufficient,
   --  defined as 1 for odd bit sizes, 4 for bit sizes divisible by 4, and
   --  2 otherwise.

   function Make_Shift_Left (N : Node_Id; S : Node_Id) return Node_Id;
   --  Build a left shift node, checking for the case of a shift count of zero

   function Make_Shift_Right (N : Node_Id; S : Node_Id) return Node_Id;
   --  Build a right shift node, checking for the case of a shift count of zero

   function RJ_Unchecked_Convert_To
     (Typ  : Entity_Id;
      Expr : Node_Id) return Node_Id;
   --  The packed array code does unchecked conversions which in some cases
   --  may involve non-discrete types with differing sizes. The semantics of
   --  such conversions is potentially endianness dependent, and the effect
   --  we want here for such a conversion is to do the conversion in size as
   --  though numeric items are involved, and we extend or truncate on the
   --  left side. This happens naturally in the little-endian case, but in
   --  the big endian case we can get left justification, when what we want
   --  is right justification. This routine does the unchecked conversion in
   --  a stepwise manner to ensure that it gives the expected result. Hence
   --  the name (RJ = Right justified). The parameters Typ and Expr are as
   --  for the case of a normal Unchecked_Convert_To call.

   procedure Setup_Enumeration_Packed_Array_Reference (N : Node_Id);
   --  This routine is called in the Get and Set case for arrays that are
   --  packed but not bit-packed, meaning that they have at least one
   --  subscript that is of an enumeration type with a non-standard
   --  representation. This routine modifies the given node to properly
   --  reference the corresponding packed array type.

   procedure Setup_Inline_Packed_Array_Reference
     (N      : Node_Id;
      Atyp   : Entity_Id;
      Obj    : in out Node_Id;
      Cmask  : out Uint;
      Shift  : out Node_Id);
   --  This procedure performs common processing on the N_Indexed_Component
   --  parameter given as N, whose prefix is a reference to a packed array.
   --  This is used for the get and set when the component size is 1, 2, 4,
   --  or for other component sizes when the packed array type is a modular
   --  type (i.e. the cases that are handled with inline code).
   --
   --  On entry:
   --
   --    N is the N_Indexed_Component node for the packed array reference
   --
   --    Atyp is the constrained array type (the actual subtype has been
   --    computed if necessary to obtain the constraints, but this is still
   --    the original array type, not the Packed_Array_Impl_Type value).
   --
   --    Obj is the object which is to be indexed. It is always of type Atyp.
   --
   --  On return:
   --
   --    Obj is the object containing the desired bit field. It is of type
   --    Unsigned, Long_Unsigned, or Long_Long_Unsigned, and is either the
   --    entire value, for the small static case, or the proper selected byte
   --    from the array in the large or dynamic case. This node is analyzed
   --    and resolved on return.
   --
   --    Shift is a node representing the shift count to be used in the
   --    rotate right instruction that positions the field for access.
   --    This node is analyzed and resolved on return.
   --
   --    Cmask is a mask corresponding to the width of the component field.
   --    Its value is 2 ** Csize - 1 (e.g. 2#1111# for component size of 4).
   --
   --  Note: in some cases the call to this routine may generate actions
   --  (for handling multi-use references and the generation of the packed
   --  array type on the fly). Such actions are inserted into the tree
   --  directly using Insert_Action.

   function Revert_Storage_Order (N : Node_Id) return Node_Id;
   --  Perform appropriate justification and byte ordering adjustments for N,
   --  an element of a packed array type, when both the component type and
   --  the enclosing packed array type have reverse scalar storage order.
   --  On little-endian targets, the value is left justified before byte
   --  swapping. The Etype of the returned expression is an integer type of
   --  an appropriate power-of-2 size.

   --------------------------
   -- Revert_Storage_Order --
   --------------------------

   function Revert_Storage_Order (N : Node_Id) return Node_Id is
      Loc     : constant Source_Ptr := Sloc (N);
      T       : constant Entity_Id := Etype (N);
      T_Size  : constant Uint := RM_Size (T);

      Swap_RE : RE_Id;
      Swap_F  : Entity_Id;
      Swap_T  : Entity_Id;
      --  Swapping function

      Arg      : Node_Id;
      Adjusted : Node_Id;
      Shift    : Uint;

   begin
      if T_Size <= 8 then

         --  Array component size is less than a byte: no swapping needed

         Swap_F := Empty;
         Swap_T := RTE (RE_Unsigned_8);

      else
         --  Select byte swapping function depending on array component size

         if T_Size <= 16 then
            Swap_RE := RE_Bswap_16;

         elsif T_Size <= 32 then
            Swap_RE := RE_Bswap_32;

         else pragma Assert (T_Size <= 64);
            Swap_RE := RE_Bswap_64;
         end if;

         Swap_F := RTE (Swap_RE);
         Swap_T := Etype (Swap_F);

      end if;

      Shift := Esize (Swap_T) - T_Size;

      Arg := RJ_Unchecked_Convert_To (Swap_T, N);

      if not Bytes_Big_Endian and then Shift > Uint_0 then
         Arg :=
           Make_Op_Shift_Left (Loc,
             Left_Opnd  => Arg,
             Right_Opnd => Make_Integer_Literal (Loc, Shift));
      end if;

      if Present (Swap_F) then
         Adjusted :=
           Make_Function_Call (Loc,
             Name                   => New_Occurrence_Of (Swap_F, Loc),
             Parameter_Associations => New_List (Arg));
      else
         Adjusted := Arg;
      end if;

      Set_Etype (Adjusted, Swap_T);
      return Adjusted;
   end Revert_Storage_Order;

   ------------------------------
   -- Compute_Linear_Subscript --
   ------------------------------

   procedure Compute_Linear_Subscript
     (Atyp   : Entity_Id;
      N      : Node_Id;
      Subscr : out Node_Id)
   is
      Loc    : constant Source_Ptr := Sloc (N);
      Oldsub : Node_Id;
      Newsub : Node_Id;
      Indx   : Node_Id;
      Styp   : Entity_Id;

   begin
      Subscr := Empty;

      --  Loop through dimensions

      Indx   := First_Index (Atyp);
      Oldsub := First (Expressions (N));

      while Present (Indx) loop
         Styp := Etype (Indx);
         Newsub := Relocate_Node (Oldsub);

         --  Get expression for the subscript value. First, if Do_Range_Check
         --  is set on a subscript, then we must do a range check against the
         --  original bounds (not the bounds of the packed array type). We do
         --  this by introducing a subtype conversion.

         if Do_Range_Check (Newsub)
           and then Etype (Newsub) /= Styp
         then
            Newsub := Convert_To (Styp, Newsub);
         end if;

         --  Now evolve the expression for the subscript. First convert
         --  the subscript to be zero based and of an integer type.

         --  Case of integer type, where we just subtract to get lower bound

         if Is_Integer_Type (Styp) then

            --  If length of integer type is smaller than standard integer,
            --  then we convert to integer first, then do the subtract

            --  Integer (subscript) - Integer (Styp'First)

            if Esize (Styp) < Esize (Standard_Integer) then
               Newsub :=
                 Make_Op_Subtract (Loc,
                   Left_Opnd => Convert_To (Standard_Integer, Newsub),
                 Right_Opnd =>
                   Convert_To (Standard_Integer,
                     Make_Attribute_Reference (Loc,
                       Prefix         => New_Occurrence_Of (Styp, Loc),
                       Attribute_Name => Name_First)));

            --  For larger integer types, subtract first, then convert to
            --  integer, this deals with strange long long integer bounds.

            --    Integer (subscript - Styp'First)

            else
               Newsub :=
                 Convert_To (Standard_Integer,
                   Make_Op_Subtract (Loc,
                     Left_Opnd => Newsub,
                   Right_Opnd =>
                     Make_Attribute_Reference (Loc,
                       Prefix         => New_Occurrence_Of (Styp, Loc),
                       Attribute_Name => Name_First)));
            end if;

         --  For the enumeration case, we have to use 'Pos to get the value
         --  to work with before subtracting the lower bound.

         --    Integer (Styp'Pos (subscr)) - Integer (Styp'Pos (Styp'First));

         --  This is not quite right for bizarre cases where the size of the
         --  enumeration type is > Integer'Size bits due to rep clause ???

         else
            pragma Assert (Is_Enumeration_Type (Styp));

            Newsub :=
              Make_Op_Subtract (Loc,
                Left_Opnd => Convert_To (Standard_Integer,
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Occurrence_Of (Styp, Loc),
                    Attribute_Name => Name_Pos,
                    Expressions    => New_List (Newsub))),

                Right_Opnd =>
                  Convert_To (Standard_Integer,
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Styp, Loc),
                      Attribute_Name => Name_Pos,
                      Expressions    => New_List (
                        Make_Attribute_Reference (Loc,
                          Prefix         => New_Occurrence_Of (Styp, Loc),
                          Attribute_Name => Name_First)))));
         end if;

         Set_Paren_Count (Newsub, 1);

         --  For the first subscript, we just copy that subscript value

         if No (Subscr) then
            Subscr := Newsub;

         --  Otherwise, we must multiply what we already have by the current
         --  stride and then add in the new value to the evolving subscript.

         else
            Subscr :=
              Make_Op_Add (Loc,
                Left_Opnd =>
                  Make_Op_Multiply (Loc,
                    Left_Opnd  => Subscr,
                    Right_Opnd =>
                      Make_Attribute_Reference (Loc,
                        Attribute_Name => Name_Range_Length,
                        Prefix         => New_Occurrence_Of (Styp, Loc))),
                Right_Opnd => Newsub);
         end if;

         --  Move to next subscript

         Next_Index (Indx);
         Next (Oldsub);
      end loop;
   end Compute_Linear_Subscript;

   -------------------------------
   -- Compute_Number_Components --
   -------------------------------

   function Compute_Number_Components
      (N   : Node_Id;
       Typ : Entity_Id) return Node_Id
   is
      Loc      : constant Source_Ptr := Sloc (N);
      Len_Expr : Node_Id;

   begin
      Len_Expr :=
        Make_Attribute_Reference (Loc,
          Attribute_Name => Name_Length,
          Prefix         => New_Occurrence_Of (Typ, Loc),
          Expressions    => New_List (Make_Integer_Literal (Loc, 1)));

      for J in 2 .. Number_Dimensions (Typ) loop
         Len_Expr :=
           Make_Op_Multiply (Loc,
             Left_Opnd  => Len_Expr,
             Right_Opnd =>
               Make_Attribute_Reference (Loc,
                Attribute_Name => Name_Length,
                Prefix         => New_Occurrence_Of (Typ, Loc),
                Expressions    => New_List (Make_Integer_Literal (Loc, J))));
      end loop;

      return Len_Expr;
   end Compute_Number_Components;

   -------------------------
   -- Convert_To_PAT_Type --
   -------------------------

   --  The PAT is always obtained from the actual subtype

   procedure Convert_To_PAT_Type (Aexp : Node_Id) is
      Act_ST : Entity_Id;

   begin
      Convert_To_Actual_Subtype (Aexp);
      Act_ST := Underlying_Type (Etype (Aexp));
      Create_Packed_Array_Impl_Type (Act_ST);

      --  Just replace the etype with the packed array type. This works because
      --  the expression will not be further analyzed, and Gigi considers the
      --  two types equivalent in any case.

      --  This is not strictly the case ??? If the reference is an actual in
      --  call, the expansion of the prefix is delayed, and must be reanalyzed,
      --  see Reset_Packed_Prefix. On the other hand, if the prefix is a simple
      --  array reference, reanalysis can produce spurious type errors when the
      --  PAT type is replaced again with the original type of the array. Same
      --  for the case of a dereference. Ditto for function calls: expansion
      --  may introduce additional actuals which will trigger errors if call is
      --  reanalyzed. The following is correct and minimal, but the handling of
      --  more complex packed expressions in actuals is confused. Probably the
      --  problem only remains for actuals in calls.

      Set_Etype (Aexp, Packed_Array_Impl_Type (Act_ST));

      if Is_Entity_Name (Aexp)
        or else
           (Nkind (Aexp) = N_Indexed_Component
             and then Is_Entity_Name (Prefix (Aexp)))
        or else Nkind_In (Aexp, N_Explicit_Dereference, N_Function_Call)
      then
         Set_Analyzed (Aexp);
      end if;
   end Convert_To_PAT_Type;

   -----------------------------------
   -- Create_Packed_Array_Impl_Type --
   -----------------------------------

   procedure Create_Packed_Array_Impl_Type (Typ : Entity_Id) is
      Loc      : constant Source_Ptr := Sloc (Typ);
      Ctyp     : constant Entity_Id  := Component_Type (Typ);
      Csize    : constant Uint       := Component_Size (Typ);

      Ancest   : Entity_Id;
      PB_Type  : Entity_Id;
      PASize   : Uint;
      Decl     : Node_Id;
      PAT      : Entity_Id;
      Len_Expr : Node_Id;
      Len_Bits : Uint;
      Bits_U1  : Node_Id;
      PAT_High : Node_Id;
      Btyp     : Entity_Id;
      Lit      : Node_Id;

      procedure Install_PAT;
      --  This procedure is called with Decl set to the declaration for the
      --  packed array type. It creates the type and installs it as required.

      procedure Set_PB_Type;
      --  Sets PB_Type to Packed_Bytes{1,2,4} as required by the alignment
      --  requirements (see documentation in the spec of this package).

      -----------------
      -- Install_PAT --
      -----------------

      procedure Install_PAT is
         Pushed_Scope : Boolean := False;

      begin
         --  We do not want to put the declaration we have created in the tree
         --  since it is often hard, and sometimes impossible to find a proper
         --  place for it (the impossible case arises for a packed array type
         --  with bounds depending on the discriminant, a declaration cannot
         --  be put inside the record, and the reference to the discriminant
         --  cannot be outside the record).

         --  The solution is to analyze the declaration while temporarily
         --  attached to the tree at an appropriate point, and then we install
         --  the resulting type as an Itype in the packed array type field of
         --  the original type, so that no explicit declaration is required.

         --  Note: the packed type is created in the scope of its parent type.
         --  There are at least some cases where the current scope is deeper,
         --  and so when this is the case, we temporarily reset the scope
         --  for the definition. This is clearly safe, since the first use
         --  of the packed array type will be the implicit reference from
         --  the corresponding unpacked type when it is elaborated.

         if Is_Itype (Typ) then
            Set_Parent (Decl, Associated_Node_For_Itype (Typ));
         else
            Set_Parent (Decl, Declaration_Node (Typ));
         end if;

         if Scope (Typ) /= Current_Scope then
            Push_Scope (Scope (Typ));
            Pushed_Scope := True;
         end if;

         Set_Is_Itype (PAT, True);
         Set_Is_Packed_Array_Impl_Type (PAT, True);
         Set_Packed_Array_Impl_Type (Typ, PAT);
         Analyze (Decl, Suppress => All_Checks);

         if Pushed_Scope then
            Pop_Scope;
         end if;

         --  Set Esize and RM_Size to the actual size of the packed object
         --  Do not reset RM_Size if already set, as happens in the case of
         --  a modular type.

         if Unknown_Esize (PAT) then
            Set_Esize (PAT, PASize);
         end if;

         if Unknown_RM_Size (PAT) then
            Set_RM_Size (PAT, PASize);
         end if;

         Adjust_Esize_Alignment (PAT);

         --  Set remaining fields of packed array type

         Init_Alignment                (PAT);
         Set_Parent                    (PAT, Empty);
         Set_Associated_Node_For_Itype (PAT, Typ);
         Set_Original_Array_Type       (PAT, Typ);

         --  Propagate representation aspects

         Set_Is_Atomic               (PAT, Is_Atomic                (Typ));
         Set_Is_Independent          (PAT, Is_Independent           (Typ));
         Set_Is_Volatile             (PAT, Is_Volatile              (Typ));
         Set_Is_Volatile_Full_Access (PAT, Is_Volatile_Full_Access  (Typ));
         Set_Treat_As_Volatile       (PAT, Treat_As_Volatile        (Typ));

         --  For a non-bit-packed array, propagate reverse storage order
         --  flag from original base type to packed array base type.

         if not Is_Bit_Packed_Array (Typ) then
            Set_Reverse_Storage_Order
              (Etype (PAT), Reverse_Storage_Order (Base_Type (Typ)));
         end if;

         --  We definitely do not want to delay freezing for packed array
         --  types. This is of particular importance for the itypes that are
         --  generated for record components depending on discriminants where
         --  there is no place to put the freeze node.

         Set_Has_Delayed_Freeze (PAT, False);
         Set_Has_Delayed_Freeze (Etype (PAT), False);

         --  If we did allocate a freeze node, then clear out the reference
         --  since it is obsolete (should we delete the freeze node???)

         Set_Freeze_Node (PAT, Empty);
         Set_Freeze_Node (Etype (PAT), Empty);
      end Install_PAT;

      -----------------
      -- Set_PB_Type --
      -----------------

      procedure Set_PB_Type is
      begin
         --  If the user has specified an explicit alignment for the
         --  type or component, take it into account.

         if Csize <= 2 or else Csize = 4 or else Csize mod 2 /= 0
           or else Alignment (Typ) = 1
           or else Component_Alignment (Typ) = Calign_Storage_Unit
         then
            PB_Type := RTE (RE_Packed_Bytes1);

         elsif Csize mod 4 /= 0
           or else Alignment (Typ) = 2
         then
            PB_Type := RTE (RE_Packed_Bytes2);

         else
            PB_Type := RTE (RE_Packed_Bytes4);
         end if;
      end Set_PB_Type;

   --  Start of processing for Create_Packed_Array_Impl_Type

   begin
      --  If we already have a packed array type, nothing to do

      if Present (Packed_Array_Impl_Type (Typ)) then
         return;
      end if;

      --  If our immediate ancestor subtype is constrained, and it already
      --  has a packed array type, then just share the same type, since the
      --  bounds must be the same. If the ancestor is not an array type but
      --  a private type, as can happen with multiple instantiations, create
      --  a new packed type, to avoid privacy issues.

      if Ekind (Typ) = E_Array_Subtype then
         Ancest := Ancestor_Subtype (Typ);

         if Present (Ancest)
           and then Is_Array_Type (Ancest)
           and then Is_Constrained (Ancest)
           and then Present (Packed_Array_Impl_Type (Ancest))
         then
            Set_Packed_Array_Impl_Type (Typ, Packed_Array_Impl_Type (Ancest));
            return;
         end if;
      end if;

      --  We preset the result type size from the size of the original array
      --  type, since this size clearly belongs to the packed array type. The
      --  size of the conceptual unpacked type is always set to unknown.

      PASize := RM_Size (Typ);

      --  Case of an array where at least one index is of an enumeration
      --  type with a non-standard representation, but the component size
      --  is not appropriate for bit packing. This is the case where we
      --  have Is_Packed set (we would never be in this unit otherwise),
      --  but Is_Bit_Packed_Array is false.

      --  Note that if the component size is appropriate for bit packing,
      --  then the circuit for the computation of the subscript properly
      --  deals with the non-standard enumeration type case by taking the
      --  Pos anyway.

      if not Is_Bit_Packed_Array (Typ) then

         --  Here we build a declaration:

         --    type tttP is array (index1, index2, ...) of component_type

         --  where index1, index2, are the index types. These are the same
         --  as the index types of the original array, except for the non-
         --  standard representation enumeration type case, where we have
         --  two subcases.

         --  For the unconstrained array case, we use

         --    Natural range <>

         --  For the constrained case, we use

         --    Natural range Enum_Type'Pos (Enum_Type'First) ..
         --                  Enum_Type'Pos (Enum_Type'Last);

         --  Note that tttP is created even if no index subtype is a non
         --  standard enumeration, because we still need to remove padding
         --  normally inserted for component alignment.

         PAT :=
           Make_Defining_Identifier (Loc,
             Chars => New_External_Name (Chars (Typ), 'P'));

         declare
            Indexes   : constant List_Id := New_List;
            Indx      : Node_Id;
            Indx_Typ  : Entity_Id;
            Enum_Case : Boolean;
            Typedef   : Node_Id;

         begin
            Indx := First_Index (Typ);

            while Present (Indx) loop
               Indx_Typ := Etype (Indx);

               Enum_Case := Is_Enumeration_Type (Indx_Typ)
                              and then Has_Non_Standard_Rep (Indx_Typ);

               --  Unconstrained case

               if not Is_Constrained (Typ) then
                  if Enum_Case then
                     Indx_Typ := Standard_Natural;
                  end if;

                  Append_To (Indexes, New_Occurrence_Of (Indx_Typ, Loc));

               --  Constrained case

               else
                  if not Enum_Case then
                     Append_To (Indexes, New_Occurrence_Of (Indx_Typ, Loc));

                  else
                     Append_To (Indexes,
                       Make_Subtype_Indication (Loc,
                         Subtype_Mark =>
                           New_Occurrence_Of (Standard_Natural, Loc),
                         Constraint =>
                           Make_Range_Constraint (Loc,
                             Range_Expression =>
                               Make_Range (Loc,
                                 Low_Bound =>
                                   Make_Attribute_Reference (Loc,
                                     Prefix         =>
                                       New_Occurrence_Of (Indx_Typ, Loc),
                                     Attribute_Name => Name_Pos,
                                     Expressions    => New_List (
                                       Make_Attribute_Reference (Loc,
                                         Prefix         =>
                                           New_Occurrence_Of (Indx_Typ, Loc),
                                         Attribute_Name => Name_First))),

                                 High_Bound =>
                                   Make_Attribute_Reference (Loc,
                                     Prefix         =>
                                       New_Occurrence_Of (Indx_Typ, Loc),
                                     Attribute_Name => Name_Pos,
                                     Expressions    => New_List (
                                       Make_Attribute_Reference (Loc,
                                         Prefix         =>
                                           New_Occurrence_Of (Indx_Typ, Loc),
                                         Attribute_Name => Name_Last)))))));

                  end if;
               end if;

               Next_Index (Indx);
            end loop;

            if not Is_Constrained (Typ) then
               Typedef :=
                 Make_Unconstrained_Array_Definition (Loc,
                   Subtype_Marks => Indexes,
                   Component_Definition =>
                     Make_Component_Definition (Loc,
                       Aliased_Present    => False,
                       Subtype_Indication =>
                          New_Occurrence_Of (Ctyp, Loc)));

            else
               Typedef :=
                  Make_Constrained_Array_Definition (Loc,
                    Discrete_Subtype_Definitions => Indexes,
                    Component_Definition =>
                      Make_Component_Definition (Loc,
                        Aliased_Present    => False,
                        Subtype_Indication =>
                          New_Occurrence_Of (Ctyp, Loc)));
            end if;

            Decl :=
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => PAT,
                Type_Definition     => Typedef);
         end;

         Install_PAT;
         return;

      --  Case of bit-packing required for unconstrained array. We create
      --  a subtype that is equivalent to use Packed_Bytes{1,2,4} as needed.

      elsif not Is_Constrained (Typ) then

         --  When generating standard DWARF (i.e when GNAT_Encodings is
         --  DWARF_GNAT_Encodings_Minimal), the ___XP suffix will be stripped
         --  by the back-end but generate it anyway to ease compiler debugging.
         --  This will help to distinguish implementation types from original
         --  packed arrays.

         PAT :=
           Make_Defining_Identifier (Loc,
             Chars => Make_Packed_Array_Impl_Type_Name (Typ, Csize));

         Set_PB_Type;

         Decl :=
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => PAT,
               Subtype_Indication => New_Occurrence_Of (PB_Type, Loc));

         Install_PAT;
         return;

      --  Remaining code is for the case of bit-packing for constrained array

      --  The name of the packed array subtype is

      --    ttt___XPsss

      --  where sss is the component size in bits and ttt is the name of
      --  the parent packed type.

      else
         PAT :=
           Make_Defining_Identifier (Loc,
             Chars => Make_Packed_Array_Impl_Type_Name (Typ, Csize));

         --  Build an expression for the length of the array in bits.
         --  This is the product of the length of each of the dimensions

         Len_Expr := Compute_Number_Components (Typ, Typ);

         --  Temporarily attach the length expression to the tree and analyze
         --  and resolve it, so that we can test its value. We assume that the
         --  total length fits in type Integer. This expression may involve
         --  discriminants, so we treat it as a default/per-object expression.

         Set_Parent (Len_Expr, Typ);
         Preanalyze_Spec_Expression (Len_Expr, Standard_Long_Long_Integer);

         --  Use a modular type if possible. We can do this if we have
         --  static bounds, and the length is small enough, and the length
         --  is not zero. We exclude the zero length case because the size
         --  of things is always at least one, and the zero length object
         --  would have an anomalous size.

         if Compile_Time_Known_Value (Len_Expr) then
            Len_Bits := Expr_Value (Len_Expr) * Csize;

            --  Check for size known to be too large

            if Len_Bits >
              Uint_2 ** (Standard_Integer_Size - 1) * System_Storage_Unit
            then
               if System_Storage_Unit = 8 then
                  Error_Msg_N
                    ("packed array size cannot exceed " &
                     "Integer''Last bytes", Typ);
               else
                  Error_Msg_N
                    ("packed array size cannot exceed " &
                     "Integer''Last storage units", Typ);
               end if;

               --  Reset length to arbitrary not too high value to continue

               Len_Expr := Make_Integer_Literal (Loc, 65535);
               Analyze_And_Resolve (Len_Expr, Standard_Long_Long_Integer);
            end if;

            --  We normally consider small enough to mean no larger than the
            --  value of System_Max_Binary_Modulus_Power, checking that in the
            --  case of values longer than word size, we have long shifts.

            if Len_Bits > 0
              and then
                (Len_Bits <= System_Word_Size
                   or else (Len_Bits <= System_Max_Binary_Modulus_Power
                              and then Support_Long_Shifts_On_Target))
            then
               --  We can use the modular type, it has the form:

               --    subtype tttPn is btyp
               --      range 0 .. 2 ** ((Typ'Length (1)
               --                * ... * Typ'Length (n)) * Csize) - 1;

               --  The bounds are statically known, and btyp is one of the
               --  unsigned types, depending on the length.

               if Len_Bits <= Standard_Short_Short_Integer_Size then
                  Btyp := RTE (RE_Short_Short_Unsigned);

               elsif Len_Bits <= Standard_Short_Integer_Size then
                  Btyp := RTE (RE_Short_Unsigned);

               elsif Len_Bits <= Standard_Integer_Size then
                  Btyp := RTE (RE_Unsigned);

               elsif Len_Bits <= Standard_Long_Integer_Size then
                  Btyp := RTE (RE_Long_Unsigned);

               else
                  Btyp := RTE (RE_Long_Long_Unsigned);
               end if;

               Lit := Make_Integer_Literal (Loc, 2 ** Len_Bits - 1);
               Set_Print_In_Hex (Lit);

               Decl :=
                 Make_Subtype_Declaration (Loc,
                   Defining_Identifier => PAT,
                     Subtype_Indication =>
                       Make_Subtype_Indication (Loc,
                         Subtype_Mark => New_Occurrence_Of (Btyp, Loc),

                         Constraint =>
                           Make_Range_Constraint (Loc,
                             Range_Expression =>
                               Make_Range (Loc,
                                 Low_Bound =>
                                   Make_Integer_Literal (Loc, 0),
                                 High_Bound => Lit))));

               if PASize = Uint_0 then
                  PASize := Len_Bits;
               end if;

               Install_PAT;

               --  Propagate a given alignment to the modular type. This can
               --  cause it to be under-aligned, but that's OK.

               if Present (Alignment_Clause (Typ)) then
                  Set_Alignment (PAT, Alignment (Typ));
               end if;

               return;
            end if;
         end if;

         --  Could not use a modular type, for all other cases, we build
         --  a packed array subtype:

         --    subtype tttPn is
         --      System.Packed_Bytes{1,2,4} (0 .. (Bits + 7) / 8 - 1);

         --  Bits is the length of the array in bits

         Set_PB_Type;

         Bits_U1 :=
           Make_Op_Add (Loc,
             Left_Opnd =>
               Make_Op_Multiply (Loc,
                 Left_Opnd  =>
                   Make_Integer_Literal (Loc, Csize),
                 Right_Opnd => Len_Expr),

             Right_Opnd =>
               Make_Integer_Literal (Loc, 7));

         Set_Paren_Count (Bits_U1, 1);

         PAT_High :=
           Make_Op_Subtract (Loc,
             Left_Opnd =>
               Make_Op_Divide (Loc,
                 Left_Opnd => Bits_U1,
                 Right_Opnd => Make_Integer_Literal (Loc, 8)),
             Right_Opnd => Make_Integer_Literal (Loc, 1));

         Decl :=
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => PAT,
               Subtype_Indication =>
                 Make_Subtype_Indication (Loc,
                   Subtype_Mark => New_Occurrence_Of (PB_Type, Loc),
                   Constraint =>
                     Make_Index_Or_Discriminant_Constraint (Loc,
                       Constraints => New_List (
                         Make_Range (Loc,
                           Low_Bound =>
                             Make_Integer_Literal (Loc, 0),
                           High_Bound =>
                             Convert_To (Standard_Integer, PAT_High))))));

         Install_PAT;

         --  Currently the code in this unit requires that packed arrays
         --  represented by non-modular arrays of bytes be on a byte
         --  boundary for bit sizes handled by System.Pack_nn units.
         --  That's because these units assume the array being accessed
         --  starts on a byte boundary.

         if Get_Id (UI_To_Int (Csize)) /= RE_Null then
            Set_Must_Be_On_Byte_Boundary (Typ);
         end if;
      end if;
   end Create_Packed_Array_Impl_Type;

   -----------------------------------
   -- Expand_Bit_Packed_Element_Set --
   -----------------------------------

   procedure Expand_Bit_Packed_Element_Set (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Lhs : constant Node_Id    := Name (N);

      Ass_OK : constant Boolean := Assignment_OK (Lhs);
      --  Used to preserve assignment OK status when assignment is rewritten

      Rhs : Node_Id := Expression (N);
      --  Initially Rhs is the right hand side value, it will be replaced
      --  later by an appropriate unchecked conversion for the assignment.

      Obj   : Node_Id;
      Atyp  : Entity_Id;
      PAT   : Entity_Id;
      Ctyp  : Entity_Id;
      Csiz  : Int;
      Cmask : Uint;

      Shift : Node_Id;
      --  The expression for the shift value that is required

      Shift_Used : Boolean := False;
      --  Set True if Shift has been used in the generated code at least once,
      --  so that it must be duplicated if used again.

      New_Lhs : Node_Id;
      New_Rhs : Node_Id;

      Rhs_Val_Known : Boolean;
      Rhs_Val       : Uint;
      --  If the value of the right hand side as an integer constant is
      --  known at compile time, Rhs_Val_Known is set True, and Rhs_Val
      --  contains the value. Otherwise Rhs_Val_Known is set False, and
      --  the Rhs_Val is undefined.

      function Get_Shift return Node_Id;
      --  Function used to get the value of Shift, making sure that it
      --  gets duplicated if the function is called more than once.

      ---------------
      -- Get_Shift --
      ---------------

      function Get_Shift return Node_Id is
      begin
         --  If we used the shift value already, then duplicate it. We
         --  set a temporary parent in case actions have to be inserted.

         if Shift_Used then
            Set_Parent (Shift, N);
            return Duplicate_Subexpr_No_Checks (Shift);

         --  If first time, use Shift unchanged, and set flag for first use

         else
            Shift_Used := True;
            return Shift;
         end if;
      end Get_Shift;

   --  Start of processing for Expand_Bit_Packed_Element_Set

   begin
      pragma Assert (Is_Bit_Packed_Array (Etype (Prefix (Lhs))));

      Obj := Relocate_Node (Prefix (Lhs));
      Convert_To_Actual_Subtype (Obj);
      Atyp := Etype (Obj);
      PAT  := Packed_Array_Impl_Type (Atyp);
      Ctyp := Component_Type (Atyp);
      Csiz := UI_To_Int (Component_Size (Atyp));

      --  We remove side effects, in case the rhs modifies the lhs, because we
      --  are about to transform the rhs into an expression that first READS
      --  the lhs, so we can do the necessary shifting and masking. Example:
      --  "X(2) := F(...);" where F modifies X(3). Otherwise, the side effect
      --  will be lost.

      Remove_Side_Effects (Rhs);

      --  We convert the right hand side to the proper subtype to ensure
      --  that an appropriate range check is made (since the normal range
      --  check from assignment will be lost in the transformations). This
      --  conversion is analyzed immediately so that subsequent processing
      --  can work with an analyzed Rhs (and e.g. look at its Etype)

      --  If the right-hand side is a string literal, create a temporary for
      --  it, constant-folding is not ready to wrap the bit representation
      --  of a string literal.

      if Nkind (Rhs) = N_String_Literal then
         declare
            Decl : Node_Id;
         begin
            Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'T', Rhs),
                Object_Definition   => New_Occurrence_Of (Ctyp, Loc),
                Expression          => New_Copy_Tree (Rhs));

            Insert_Actions (N, New_List (Decl));
            Rhs := New_Occurrence_Of (Defining_Identifier (Decl), Loc);
         end;
      end if;

      Rhs := Convert_To (Ctyp, Rhs);
      Set_Parent (Rhs, N);

      --  If we are building the initialization procedure for a packed array,
      --  and Initialize_Scalars is enabled, each component assignment is an
      --  out-of-range value by design.  Compile this value without checks,
      --  because a call to the array init_proc must not raise an exception.

      --  Condition is not consistent with description above, Within_Init_Proc
      --  is True also when we are building the IP for a record or protected
      --  type that has a packed array component???

      if Within_Init_Proc
        and then Initialize_Scalars
      then
         Analyze_And_Resolve (Rhs, Ctyp, Suppress => All_Checks);
      else
         Analyze_And_Resolve (Rhs, Ctyp);
      end if;

      --  Case of component size 1,2,4 or any component size for the modular
      --  case. These are the cases for which we can inline the code.

      if Csiz = 1 or else Csiz = 2 or else Csiz = 4
        or else (Present (PAT) and then Is_Modular_Integer_Type (PAT))
      then
         Setup_Inline_Packed_Array_Reference (Lhs, Atyp, Obj, Cmask, Shift);

         --  The statement to be generated is:

         --    Obj := atyp!((Obj and Mask1) or (shift_left (rhs, Shift)))

         --  or in the case of a freestanding Reverse_Storage_Order object,

         --    Obj := Swap (atyp!((Swap (Obj) and Mask1)
         --                         or (shift_left (rhs, Shift))))

         --      where Mask1 is obtained by shifting Cmask left Shift bits
         --      and then complementing the result.

         --      the "and Mask1" is omitted if rhs is constant and all 1 bits

         --      the "or ..." is omitted if rhs is constant and all 0 bits

         --      rhs is converted to the appropriate type

         --      The result is converted back to the array type, since
         --      otherwise we lose knowledge of the packed nature.

         --  Determine if right side is all 0 bits or all 1 bits

         if Compile_Time_Known_Value (Rhs) then
            Rhs_Val       := Expr_Rep_Value (Rhs);
            Rhs_Val_Known := True;

         --  The following test catches the case of an unchecked conversion of
         --  an integer literal. This results from optimizing aggregates of
         --  packed types.

         elsif Nkind (Rhs) = N_Unchecked_Type_Conversion
           and then Compile_Time_Known_Value (Expression (Rhs))
         then
            Rhs_Val       := Expr_Rep_Value (Expression (Rhs));
            Rhs_Val_Known := True;

         else
            Rhs_Val       := No_Uint;
            Rhs_Val_Known := False;
         end if;

         --  Some special checks for the case where the right hand value is
         --  known at compile time. Basically we have to take care of the
         --  implicit conversion to the subtype of the component object.

         if Rhs_Val_Known then

            --  If we have a biased component type then we must manually do the
            --  biasing, since we are taking responsibility in this case for
            --  constructing the exact bit pattern to be used.

            if Has_Biased_Representation (Ctyp) then
               Rhs_Val := Rhs_Val - Expr_Rep_Value (Type_Low_Bound (Ctyp));
            end if;

            --  For a negative value, we manually convert the two's complement
            --  value to a corresponding unsigned value, so that the proper
            --  field width is maintained. If we did not do this, we would
            --  get too many leading sign bits later on.

            if Rhs_Val < 0 then
               Rhs_Val := 2 ** UI_From_Int (Csiz) + Rhs_Val;
            end if;
         end if;

         --  Now create copies removing side effects. Note that in some complex
         --  cases, this may cause the fact that we have already set a packed
         --  array type on Obj to get lost. So we save the type of Obj, and
         --  make sure it is reset properly.

         New_Lhs := Duplicate_Subexpr (Obj, Name_Req => True);
         New_Rhs := Duplicate_Subexpr_No_Checks (Obj);

         --  First we deal with the "and"

         if not Rhs_Val_Known or else Rhs_Val /= Cmask then
            declare
               Mask1 : Node_Id;
               Lit   : Node_Id;

            begin
               if Compile_Time_Known_Value (Shift) then
                  Mask1 :=
                    Make_Integer_Literal (Loc,
                      Modulus (Etype (Obj)) - 1 -
                                 (Cmask * (2 ** Expr_Value (Get_Shift))));
                  Set_Print_In_Hex (Mask1);

               else
                  Lit := Make_Integer_Literal (Loc, Cmask);
                  Set_Print_In_Hex (Lit);
                  Mask1 :=
                    Make_Op_Not (Loc,
                      Right_Opnd => Make_Shift_Left (Lit, Get_Shift));
               end if;

               New_Rhs :=
                 Make_Op_And (Loc,
                   Left_Opnd  => New_Rhs,
                   Right_Opnd => Mask1);
            end;
         end if;

         --  Then deal with the "or"

         if not Rhs_Val_Known or else Rhs_Val /= 0 then
            declare
               Or_Rhs : Node_Id;

               procedure Fixup_Rhs;
               --  Adjust Rhs by bias if biased representation for components
               --  or remove extraneous high order sign bits if signed.

               procedure Fixup_Rhs is
                  Etyp : constant Entity_Id := Etype (Rhs);

               begin
                  --  For biased case, do the required biasing by simply
                  --  converting to the biased subtype (the conversion
                  --  will generate the required bias).

                  if Has_Biased_Representation (Ctyp) then
                     Rhs := Convert_To (Ctyp, Rhs);

                  --  For a signed integer type that is not biased, generate
                  --  a conversion to unsigned to strip high order sign bits.

                  elsif Is_Signed_Integer_Type (Ctyp) then
                     Rhs := Unchecked_Convert_To (RTE (Bits_Id (Csiz)), Rhs);
                  end if;

                  --  Set Etype, since it can be referenced before the node is
                  --  completely analyzed.

                  Set_Etype (Rhs, Etyp);

                  --  We now need to do an unchecked conversion of the
                  --  result to the target type, but it is important that
                  --  this conversion be a right justified conversion and
                  --  not a left justified conversion.

                  Rhs := RJ_Unchecked_Convert_To (Etype (Obj), Rhs);
               end Fixup_Rhs;

            begin
               if Rhs_Val_Known
                 and then Compile_Time_Known_Value (Get_Shift)
               then
                  Or_Rhs :=
                    Make_Integer_Literal (Loc,
                      Rhs_Val * (2 ** Expr_Value (Get_Shift)));
                  Set_Print_In_Hex (Or_Rhs);

               else
                  --  We have to convert the right hand side to Etype (Obj).
                  --  A special case arises if what we have now is a Val
                  --  attribute reference whose expression type is Etype (Obj).
                  --  This happens for assignments of fields from the same
                  --  array. In this case we get the required right hand side
                  --  by simply removing the inner attribute reference.

                  if Nkind (Rhs) = N_Attribute_Reference
                    and then Attribute_Name (Rhs) = Name_Val
                    and then Etype (First (Expressions (Rhs))) = Etype (Obj)
                  then
                     Rhs := Relocate_Node (First (Expressions (Rhs)));
                     Fixup_Rhs;

                  --  If the value of the right hand side is a known integer
                  --  value, then just replace it by an untyped constant,
                  --  which will be properly retyped when we analyze and
                  --  resolve the expression.

                  elsif Rhs_Val_Known then

                     --  Note that Rhs_Val has already been normalized to
                     --  be an unsigned value with the proper number of bits.

                     Rhs := Make_Integer_Literal (Loc, Rhs_Val);

                  --  Otherwise we need an unchecked conversion

                  else
                     Fixup_Rhs;
                  end if;

                  Or_Rhs := Make_Shift_Left (Rhs, Get_Shift);
               end if;

               if Nkind (New_Rhs) = N_Op_And then
                  Set_Paren_Count (New_Rhs, 1);
                  Set_Etype (New_Rhs, Etype (Left_Opnd (New_Rhs)));
               end if;

               New_Rhs :=
                 Make_Op_Or (Loc,
                   Left_Opnd  => New_Rhs,
                   Right_Opnd => Or_Rhs);
            end;
         end if;

         --  Now do the rewrite

         Rewrite (N,
           Make_Assignment_Statement (Loc,
             Name       => New_Lhs,
             Expression =>
               Unchecked_Convert_To (Etype (New_Lhs), New_Rhs)));
         Set_Assignment_OK (Name (N), Ass_OK);

      --  All other component sizes for non-modular case

      else
         --  We generate

         --    Set_nn (Arr'address, Subscr, Bits_nn!(Rhs))

         --  where Subscr is the computed linear subscript

         declare
            Bits_nn : constant Entity_Id := RTE (Bits_Id (Csiz));
            Set_nn  : Entity_Id;
            Subscr  : Node_Id;
            Atyp    : Entity_Id;
            Rev_SSO : Node_Id;

         begin
            if No (Bits_nn) then

               --  Error, most likely High_Integrity_Mode restriction

               return;
            end if;

            --  Acquire proper Set entity. We use the aligned or unaligned
            --  case as appropriate.

            if Known_Aligned_Enough (Obj, Csiz) then
               Set_nn := RTE (Set_Id (Csiz));
            else
               Set_nn := RTE (SetU_Id (Csiz));
            end if;

            --  Now generate the set reference

            Obj := Relocate_Node (Prefix (Lhs));
            Convert_To_Actual_Subtype (Obj);
            Atyp := Etype (Obj);
            Compute_Linear_Subscript (Atyp, Lhs, Subscr);

            --  Set indication of whether the packed array has reverse SSO

            Rev_SSO :=
              New_Occurrence_Of
                (Boolean_Literals (Reverse_Storage_Order (Atyp)), Loc);

            --  Below we must make the assumption that Obj is
            --  at least byte aligned, since otherwise its address
            --  cannot be taken. The assumption holds since the
            --  only arrays that can be misaligned are small packed
            --  arrays which are implemented as a modular type, and
            --  that is not the case here.

            Rewrite (N,
              Make_Procedure_Call_Statement (Loc,
                  Name => New_Occurrence_Of (Set_nn, Loc),
                  Parameter_Associations => New_List (
                    Make_Attribute_Reference (Loc,
                      Prefix         => Obj,
                      Attribute_Name => Name_Address),
                    Subscr,
                    Unchecked_Convert_To (Bits_nn, Convert_To (Ctyp, Rhs)),
                    Rev_SSO)));

         end;
      end if;

      Analyze (N, Suppress => All_Checks);
   end Expand_Bit_Packed_Element_Set;

   -------------------------------------
   -- Expand_Packed_Address_Reference --
   -------------------------------------

   procedure Expand_Packed_Address_Reference (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Base   : Node_Id;
      Offset : Node_Id;

   begin
      --  We build an expression that has the form

      --    outer_object'Address
      --      + (linear-subscript * component_size  for each array reference
      --      +  field'Bit_Position                 for each record field
      --      +  ...
      --      +  ...) / Storage_Unit;

      Get_Base_And_Bit_Offset (Prefix (N), Base, Offset);

      Rewrite (N,
        Unchecked_Convert_To (RTE (RE_Address),
          Make_Op_Add (Loc,
            Left_Opnd =>
              Unchecked_Convert_To (RTE (RE_Integer_Address),
                Make_Attribute_Reference (Loc,
                  Prefix         => Base,
                  Attribute_Name => Name_Address)),

            Right_Opnd =>
              Unchecked_Convert_To (RTE (RE_Integer_Address),
                Make_Op_Divide (Loc,
                  Left_Opnd => Offset,
                  Right_Opnd =>
                    Make_Integer_Literal (Loc, System_Storage_Unit))))));

      Analyze_And_Resolve (N, RTE (RE_Address));
   end Expand_Packed_Address_Reference;

   ---------------------------------
   -- Expand_Packed_Bit_Reference --
   ---------------------------------

   procedure Expand_Packed_Bit_Reference (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Base   : Node_Id;
      Offset : Node_Id;

   begin
      --  We build an expression that has the form

      --    (linear-subscript * component_size      for each array reference
      --      +  field'Bit_Position                 for each record field
      --      +  ...
      --      +  ...) mod Storage_Unit;

      Get_Base_And_Bit_Offset (Prefix (N), Base, Offset);

      Rewrite (N,
        Unchecked_Convert_To (Universal_Integer,
          Make_Op_Mod (Loc,
            Left_Opnd => Offset,
            Right_Opnd => Make_Integer_Literal (Loc, System_Storage_Unit))));

      Analyze_And_Resolve (N, Universal_Integer);
   end Expand_Packed_Bit_Reference;

   ------------------------------------
   -- Expand_Packed_Boolean_Operator --
   ------------------------------------

   --  This routine expands "a op b" for the packed cases

   procedure Expand_Packed_Boolean_Operator (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);
      L   : constant Node_Id    := Relocate_Node (Left_Opnd  (N));
      R   : constant Node_Id    := Relocate_Node (Right_Opnd (N));

      Ltyp : Entity_Id;
      Rtyp : Entity_Id;
      PAT  : Entity_Id;

   begin
      Convert_To_Actual_Subtype (L);
      Convert_To_Actual_Subtype (R);

      Ensure_Defined (Etype (L), N);
      Ensure_Defined (Etype (R), N);

      Apply_Length_Check (R, Etype (L));

      Ltyp := Etype (L);
      Rtyp := Etype (R);

      --  Deal with silly case of XOR where the subcomponent has a range
      --  True .. True where an exception must be raised.

      if Nkind (N) = N_Op_Xor then
         Silly_Boolean_Array_Xor_Test (N, Rtyp);
      end if;

      --  Now that that silliness is taken care of, get packed array type

      Convert_To_PAT_Type (L);
      Convert_To_PAT_Type (R);

      PAT := Etype (L);

      --  For the modular case, we expand a op b into

      --    rtyp!(pat!(a) op pat!(b))

      --  where rtyp is the Etype of the left operand. Note that we do not
      --  convert to the base type, since this would be unconstrained, and
      --  hence not have a corresponding packed array type set.

      --  Note that both operands must be modular for this code to be used

      if Is_Modular_Integer_Type (PAT)
           and then
         Is_Modular_Integer_Type (Etype (R))
      then
         declare
            P : Node_Id;

         begin
            if Nkind (N) = N_Op_And then
               P := Make_Op_And (Loc, L, R);

            elsif Nkind (N) = N_Op_Or then
               P := Make_Op_Or  (Loc, L, R);

            else -- Nkind (N) = N_Op_Xor
               P := Make_Op_Xor (Loc, L, R);
            end if;

            Rewrite (N, Unchecked_Convert_To (Ltyp, P));
         end;

      --  For the array case, we insert the actions

      --    Result : Ltype;

      --    System.Bit_Ops.Bit_And/Or/Xor
      --     (Left'Address,
      --      Ltype'Length * Ltype'Component_Size;
      --      Right'Address,
      --      Rtype'Length * Rtype'Component_Size
      --      Result'Address);

      --  where Left and Right are the Packed_Bytes{1,2,4} operands and
      --  the second argument and fourth arguments are the lengths of the
      --  operands in bits. Then we replace the expression by a reference
      --  to Result.

      --  Note that if we are mixing a modular and array operand, everything
      --  works fine, since we ensure that the modular representation has the
      --  same physical layout as the array representation (that's what the
      --  left justified modular stuff in the big-endian case is about).

      else
         declare
            Result_Ent : constant Entity_Id := Make_Temporary (Loc, 'T');
            E_Id       : RE_Id;

         begin
            if Nkind (N) = N_Op_And then
               E_Id := RE_Bit_And;

            elsif Nkind (N) = N_Op_Or then
               E_Id := RE_Bit_Or;

            else -- Nkind (N) = N_Op_Xor
               E_Id := RE_Bit_Xor;
            end if;

            Insert_Actions (N, New_List (

              Make_Object_Declaration (Loc,
                Defining_Identifier => Result_Ent,
                Object_Definition => New_Occurrence_Of (Ltyp, Loc)),

              Make_Procedure_Call_Statement (Loc,
                Name => New_Occurrence_Of (RTE (E_Id), Loc),
                  Parameter_Associations => New_List (

                    Make_Byte_Aligned_Attribute_Reference (Loc,
                      Prefix         => L,
                      Attribute_Name => Name_Address),

                    Make_Op_Multiply (Loc,
                      Left_Opnd =>
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of
                              (Etype (First_Index (Ltyp)), Loc),
                          Attribute_Name => Name_Range_Length),

                      Right_Opnd =>
                        Make_Integer_Literal (Loc, Component_Size (Ltyp))),

                    Make_Byte_Aligned_Attribute_Reference (Loc,
                      Prefix         => R,
                      Attribute_Name => Name_Address),

                    Make_Op_Multiply (Loc,
                      Left_Opnd =>
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of
                              (Etype (First_Index (Rtyp)), Loc),
                          Attribute_Name => Name_Range_Length),

                      Right_Opnd =>
                        Make_Integer_Literal (Loc, Component_Size (Rtyp))),

                    Make_Byte_Aligned_Attribute_Reference (Loc,
                      Prefix => New_Occurrence_Of (Result_Ent, Loc),
                      Attribute_Name => Name_Address)))));

            Rewrite (N,
              New_Occurrence_Of (Result_Ent, Loc));
         end;
      end if;

      Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
   end Expand_Packed_Boolean_Operator;

   -------------------------------------
   -- Expand_Packed_Element_Reference --
   -------------------------------------

   procedure Expand_Packed_Element_Reference (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Obj   : Node_Id;
      Atyp  : Entity_Id;
      PAT   : Entity_Id;
      Ctyp  : Entity_Id;
      Csiz  : Int;
      Shift : Node_Id;
      Cmask : Uint;
      Lit   : Node_Id;
      Arg   : Node_Id;

   begin
      --  If the node is an actual in a call, the prefix has not been fully
      --  expanded, to account for the additional expansion for in-out actuals
      --  (see expand_actuals for details). If the prefix itself is a packed
      --  reference as well, we have to recurse to complete the transformation
      --  of the prefix.

      if Nkind (Prefix (N)) = N_Indexed_Component
        and then not Analyzed (Prefix (N))
        and then Is_Bit_Packed_Array (Etype (Prefix (Prefix (N))))
      then
         Expand_Packed_Element_Reference (Prefix (N));
      end if;

      --  The prefix may be rewritten below as a conversion. If it is a source
      --  entity generate reference to it now, to prevent spurious warnings
      --  about unused entities.

      if Is_Entity_Name (Prefix (N))
        and then Comes_From_Source (Prefix (N))
      then
         Generate_Reference (Entity (Prefix (N)), Prefix (N), 'r');
      end if;

      --  If not bit packed, we have the enumeration case, which is easily
      --  dealt with (just adjust the subscripts of the indexed component)

      --  Note: this leaves the result as an indexed component, which is
      --  still a variable, so can be used in the assignment case, as is
      --  required in the enumeration case.

      if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
         Setup_Enumeration_Packed_Array_Reference (N);
         return;
      end if;

      --  Remaining processing is for the bit-packed case

      Obj := Relocate_Node (Prefix (N));
      Convert_To_Actual_Subtype (Obj);
      Atyp := Etype (Obj);
      PAT  := Packed_Array_Impl_Type (Atyp);
      Ctyp := Component_Type (Atyp);
      Csiz := UI_To_Int (Component_Size (Atyp));

      --  Case of component size 1,2,4 or any component size for the modular
      --  case. These are the cases for which we can inline the code.

      if Csiz = 1 or else Csiz = 2 or else Csiz = 4
        or else (Present (PAT) and then Is_Modular_Integer_Type (PAT))
      then
         Setup_Inline_Packed_Array_Reference (N, Atyp, Obj, Cmask, Shift);
         Lit := Make_Integer_Literal (Loc, Cmask);
         Set_Print_In_Hex (Lit);

         --  We generate a shift right to position the field, followed by a
         --  masking operation to extract the bit field, and we finally do an
         --  unchecked conversion to convert the result to the required target.

         --  Note that the unchecked conversion automatically deals with the
         --  bias if we are dealing with a biased representation. What will
         --  happen is that we temporarily generate the biased representation,
         --  but almost immediately that will be converted to the original
         --  unbiased component type, and the bias will disappear.

         Arg :=
           Make_Op_And (Loc,
             Left_Opnd  => Make_Shift_Right (Obj, Shift),
             Right_Opnd => Lit);
         Set_Etype (Arg, Ctyp);

         --  Component extraction is performed on a native endianness scalar
         --  value: if Atyp has reverse storage order, then it has been byte
         --  swapped, and if the component being extracted is itself of a
         --  composite type with reverse storage order, then we need to swap
         --  it back to its expected endianness after extraction.

         if Reverse_Storage_Order (Atyp)
           and then (Is_Record_Type (Ctyp) or else Is_Array_Type (Ctyp))
           and then Reverse_Storage_Order (Ctyp)
         then
            Arg := Revert_Storage_Order (Arg);
         end if;

         --  We needed to analyze this before we do the unchecked convert
         --  below, but we need it temporarily attached to the tree for
         --  this analysis (hence the temporary Set_Parent call).

         Set_Parent (Arg, Parent (N));
         Analyze_And_Resolve (Arg);

         Rewrite (N, RJ_Unchecked_Convert_To (Ctyp, Arg));

      --  All other component sizes for non-modular case

      else
         --  We generate

         --    Component_Type!(Get_nn (Arr'address, Subscr))

         --  where Subscr is the computed linear subscript

         declare
            Get_nn  : Entity_Id;
            Subscr  : Node_Id;
            Rev_SSO : constant Node_Id :=
              New_Occurrence_Of
                (Boolean_Literals (Reverse_Storage_Order (Atyp)), Loc);

         begin
            --  Acquire proper Get entity. We use the aligned or unaligned
            --  case as appropriate.

            if Known_Aligned_Enough (Obj, Csiz) then
               Get_nn := RTE (Get_Id (Csiz));
            else
               Get_nn := RTE (GetU_Id (Csiz));
            end if;

            --  Now generate the get reference

            Compute_Linear_Subscript (Atyp, N, Subscr);

            --  Below we make the assumption that Obj is at least byte
            --  aligned, since otherwise its address cannot be taken.
            --  The assumption holds since the only arrays that can be
            --  misaligned are small packed arrays which are implemented
            --  as a modular type, and that is not the case here.

            Rewrite (N,
              Unchecked_Convert_To (Ctyp,
                Make_Function_Call (Loc,
                  Name => New_Occurrence_Of (Get_nn, Loc),
                  Parameter_Associations => New_List (
                    Make_Attribute_Reference (Loc,
                      Prefix         => Obj,
                      Attribute_Name => Name_Address),
                    Subscr,
                    Rev_SSO))));
         end;
      end if;

      Analyze_And_Resolve (N, Ctyp, Suppress => All_Checks);
   end Expand_Packed_Element_Reference;

   ----------------------
   -- Expand_Packed_Eq --
   ----------------------

   --  Handles expansion of "=" on packed array types

   procedure Expand_Packed_Eq (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      L   : constant Node_Id    := Relocate_Node (Left_Opnd  (N));
      R   : constant Node_Id    := Relocate_Node (Right_Opnd (N));

      LLexpr : Node_Id;
      RLexpr : Node_Id;

      Ltyp : Entity_Id;
      Rtyp : Entity_Id;
      PAT  : Entity_Id;

   begin
      Convert_To_Actual_Subtype (L);
      Convert_To_Actual_Subtype (R);
      Ltyp := Underlying_Type (Etype (L));
      Rtyp := Underlying_Type (Etype (R));

      Convert_To_PAT_Type (L);
      Convert_To_PAT_Type (R);
      PAT := Etype (L);

      LLexpr :=
        Make_Op_Multiply (Loc,
          Left_Opnd  => Compute_Number_Components (N, Ltyp),
          Right_Opnd => Make_Integer_Literal (Loc, Component_Size (Ltyp)));

      RLexpr :=
        Make_Op_Multiply (Loc,
          Left_Opnd  => Compute_Number_Components (N, Rtyp),
          Right_Opnd => Make_Integer_Literal (Loc, Component_Size (Rtyp)));

      --  For the modular case, we transform the comparison to:

      --    Ltyp'Length = Rtyp'Length and then PAT!(L) = PAT!(R)

      --  where PAT is the packed array type. This works fine, since in the
      --  modular case we guarantee that the unused bits are always zeroes.
      --  We do have to compare the lengths because we could be comparing
      --  two different subtypes of the same base type.

      if Is_Modular_Integer_Type (PAT) then
         Rewrite (N,
           Make_And_Then (Loc,
             Left_Opnd =>
               Make_Op_Eq (Loc,
                 Left_Opnd  => LLexpr,
                 Right_Opnd => RLexpr),

             Right_Opnd =>
               Make_Op_Eq (Loc,
                 Left_Opnd => L,
                 Right_Opnd => R)));

      --  For the non-modular case, we call a runtime routine

      --    System.Bit_Ops.Bit_Eq
      --      (L'Address, L_Length, R'Address, R_Length)

      --  where PAT is the packed array type, and the lengths are the lengths
      --  in bits of the original packed arrays. This routine takes care of
      --  not comparing the unused bits in the last byte.

      else
         Rewrite (N,
           Make_Function_Call (Loc,
             Name => New_Occurrence_Of (RTE (RE_Bit_Eq), Loc),
             Parameter_Associations => New_List (
               Make_Byte_Aligned_Attribute_Reference (Loc,
                 Prefix         => L,
                 Attribute_Name => Name_Address),

               LLexpr,

               Make_Byte_Aligned_Attribute_Reference (Loc,
                 Prefix         => R,
                 Attribute_Name => Name_Address),

               RLexpr)));
      end if;

      Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
   end Expand_Packed_Eq;

   -----------------------
   -- Expand_Packed_Not --
   -----------------------

   --  Handles expansion of "not" on packed array types

   procedure Expand_Packed_Not (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Typ  : constant Entity_Id  := Etype (N);
      Opnd : constant Node_Id    := Relocate_Node (Right_Opnd (N));

      Rtyp : Entity_Id;
      PAT  : Entity_Id;
      Lit  : Node_Id;

   begin
      Convert_To_Actual_Subtype (Opnd);
      Rtyp := Etype (Opnd);

      --  Deal with silly False..False and True..True subtype case

      Silly_Boolean_Array_Not_Test (N, Rtyp);

      --  Now that the silliness is taken care of, get packed array type

      Convert_To_PAT_Type (Opnd);
      PAT := Etype (Opnd);

      --  For the case where the packed array type is a modular type, "not A"
      --  expands simply into:

      --     Rtyp!(PAT!(A) xor Mask)

      --  where PAT is the packed array type, Mask is a mask of all 1 bits of
      --  length equal to the size of this packed type, and Rtyp is the actual
      --  actual subtype of the operand.

      Lit := Make_Integer_Literal (Loc, 2 ** RM_Size (PAT) - 1);
      Set_Print_In_Hex (Lit);

      if not Is_Array_Type (PAT) then
         Rewrite (N,
           Unchecked_Convert_To (Rtyp,
             Make_Op_Xor (Loc,
               Left_Opnd  => Opnd,
               Right_Opnd => Lit)));

      --  For the array case, we insert the actions

      --    Result : Typ;

      --    System.Bit_Ops.Bit_Not
      --     (Opnd'Address,
      --      Typ'Length * Typ'Component_Size,
      --      Result'Address);

      --  where Opnd is the Packed_Bytes{1,2,4} operand and the second argument
      --  is the length of the operand in bits. We then replace the expression
      --  with a reference to Result.

      else
         declare
            Result_Ent : constant Entity_Id := Make_Temporary (Loc, 'T');

         begin
            Insert_Actions (N, New_List (
              Make_Object_Declaration (Loc,
                Defining_Identifier => Result_Ent,
                Object_Definition   => New_Occurrence_Of (Rtyp, Loc)),

              Make_Procedure_Call_Statement (Loc,
                Name => New_Occurrence_Of (RTE (RE_Bit_Not), Loc),
                  Parameter_Associations => New_List (
                    Make_Byte_Aligned_Attribute_Reference (Loc,
                      Prefix         => Opnd,
                      Attribute_Name => Name_Address),

                    Make_Op_Multiply (Loc,
                      Left_Opnd =>
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            New_Occurrence_Of
                              (Etype (First_Index (Rtyp)), Loc),
                          Attribute_Name => Name_Range_Length),

                      Right_Opnd =>
                        Make_Integer_Literal (Loc, Component_Size (Rtyp))),

                    Make_Byte_Aligned_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Result_Ent, Loc),
                      Attribute_Name => Name_Address)))));

            Rewrite (N, New_Occurrence_Of (Result_Ent, Loc));
         end;
      end if;

      Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
   end Expand_Packed_Not;

   -----------------------------
   -- Get_Base_And_Bit_Offset --
   -----------------------------

   procedure Get_Base_And_Bit_Offset
     (N      : Node_Id;
      Base   : out Node_Id;
      Offset : out Node_Id)
   is
      Loc    : Source_Ptr;
      Term   : Node_Id;
      Atyp   : Entity_Id;
      Subscr : Node_Id;

   begin
      Base   := N;
      Offset := Empty;

      --  We build up an expression serially that has the form

      --    linear-subscript * component_size       for each array reference
      --      +  field'Bit_Position                 for each record field
      --      +  ...

      loop
         Loc := Sloc (Base);

         if Nkind (Base) = N_Indexed_Component then
            Convert_To_Actual_Subtype (Prefix (Base));
            Atyp := Etype (Prefix (Base));
            Compute_Linear_Subscript (Atyp, Base, Subscr);

            Term :=
              Make_Op_Multiply (Loc,
                Left_Opnd => Subscr,
                Right_Opnd =>
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Occurrence_Of (Atyp, Loc),
                   Attribute_Name => Name_Component_Size));

         elsif Nkind (Base) = N_Selected_Component then
            Term :=
              Make_Attribute_Reference (Loc,
                Prefix         => Selector_Name (Base),
                Attribute_Name => Name_Bit_Position);

         else
            return;
         end if;

         if No (Offset) then
            Offset := Term;

         else
            Offset :=
              Make_Op_Add (Loc,
                Left_Opnd  => Offset,
                Right_Opnd => Term);
         end if;

         Base := Prefix (Base);
      end loop;
   end Get_Base_And_Bit_Offset;

   -------------------------------------
   -- Involves_Packed_Array_Reference --
   -------------------------------------

   function Involves_Packed_Array_Reference (N : Node_Id) return Boolean is
   begin
      if Nkind (N) = N_Indexed_Component
        and then Is_Bit_Packed_Array (Etype (Prefix (N)))
      then
         return True;

      elsif Nkind (N) = N_Selected_Component then
         return Involves_Packed_Array_Reference (Prefix (N));

      else
         return False;
      end if;
   end Involves_Packed_Array_Reference;

   --------------------------
   -- Known_Aligned_Enough --
   --------------------------

   function Known_Aligned_Enough (Obj : Node_Id; Csiz : Nat) return Boolean is
      Typ : constant Entity_Id := Etype (Obj);

      function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean;
      --  If the component is in a record that contains previous packed
      --  components, consider it unaligned because the back-end might
      --  choose to pack the rest of the record. Lead to less efficient code,
      --  but safer vis-a-vis of back-end choices.

      --------------------------------
      -- In_Partially_Packed_Record --
      --------------------------------

      function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean is
         Rec_Type  : constant Entity_Id := Scope (Comp);
         Prev_Comp : Entity_Id;

      begin
         Prev_Comp := First_Entity (Rec_Type);
         while Present (Prev_Comp) loop
            if Is_Packed (Etype (Prev_Comp)) then
               return True;

            elsif Prev_Comp = Comp then
               return False;
            end if;

            Next_Entity (Prev_Comp);
         end loop;

         return False;
      end  In_Partially_Packed_Record;

   --  Start of processing for Known_Aligned_Enough

   begin
      --  Odd bit sizes don't need alignment anyway

      if Csiz mod 2 = 1 then
         return True;

      --  If we have a specified alignment, see if it is sufficient, if not
      --  then we can't possibly be aligned enough in any case.

      elsif Known_Alignment (Etype (Obj)) then
         --  Alignment required is 4 if size is a multiple of 4, and
         --  2 otherwise (e.g. 12 bits requires 4, 10 bits requires 2)

         if Alignment (Etype (Obj)) < 4 - (Csiz mod 4) then
            return False;
         end if;
      end if;

      --  OK, alignment should be sufficient, if object is aligned

      --  If object is strictly aligned, then it is definitely aligned

      if Strict_Alignment (Typ) then
         return True;

      --  Case of subscripted array reference

      elsif Nkind (Obj) = N_Indexed_Component then

         --  If we have a pointer to an array, then this is definitely
         --  aligned, because pointers always point to aligned versions.

         if Is_Access_Type (Etype (Prefix (Obj))) then
            return True;

         --  Otherwise, go look at the prefix

         else
            return Known_Aligned_Enough (Prefix (Obj), Csiz);
         end if;

      --  Case of record field

      elsif Nkind (Obj) = N_Selected_Component then

         --  What is significant here is whether the record type is packed

         if Is_Record_Type (Etype (Prefix (Obj)))
           and then Is_Packed (Etype (Prefix (Obj)))
         then
            return False;

         --  Or the component has a component clause which might cause
         --  the component to become unaligned (we can't tell if the
         --  backend is doing alignment computations).

         elsif Present (Component_Clause (Entity (Selector_Name (Obj)))) then
            return False;

         elsif In_Partially_Packed_Record (Entity (Selector_Name (Obj))) then
            return False;

         --  In all other cases, go look at prefix

         else
            return Known_Aligned_Enough (Prefix (Obj), Csiz);
         end if;

      elsif Nkind (Obj) = N_Type_Conversion then
         return Known_Aligned_Enough (Expression (Obj), Csiz);

      --  For a formal parameter, it is safer to assume that it is not
      --  aligned, because the formal may be unconstrained while the actual
      --  is constrained. In this situation, a small constrained packed
      --  array, represented in modular form, may be unaligned.

      elsif Is_Entity_Name (Obj) then
         return not Is_Formal (Entity (Obj));
      else

      --  If none of the above, must be aligned
         return True;
      end if;
   end Known_Aligned_Enough;

   ---------------------
   -- Make_Shift_Left --
   ---------------------

   function Make_Shift_Left (N : Node_Id; S : Node_Id) return Node_Id is
      Nod : Node_Id;

   begin
      if Compile_Time_Known_Value (S) and then Expr_Value (S) = 0 then
         return N;
      else
         Nod :=
           Make_Op_Shift_Left (Sloc (N),
             Left_Opnd  => N,
             Right_Opnd => S);
         Set_Shift_Count_OK (Nod, True);
         return Nod;
      end if;
   end Make_Shift_Left;

   ----------------------
   -- Make_Shift_Right --
   ----------------------

   function Make_Shift_Right (N : Node_Id; S : Node_Id) return Node_Id is
      Nod : Node_Id;

   begin
      if Compile_Time_Known_Value (S) and then Expr_Value (S) = 0 then
         return N;
      else
         Nod :=
           Make_Op_Shift_Right (Sloc (N),
             Left_Opnd  => N,
             Right_Opnd => S);
         Set_Shift_Count_OK (Nod, True);
         return Nod;
      end if;
   end Make_Shift_Right;

   -----------------------------
   -- RJ_Unchecked_Convert_To --
   -----------------------------

   function RJ_Unchecked_Convert_To
     (Typ  : Entity_Id;
      Expr : Node_Id) return Node_Id
   is
      Source_Typ : constant Entity_Id := Etype (Expr);
      Target_Typ : constant Entity_Id := Typ;

      Src : Node_Id := Expr;

      Source_Siz : Nat;
      Target_Siz : Nat;

   begin
      Source_Siz := UI_To_Int (RM_Size (Source_Typ));
      Target_Siz := UI_To_Int (RM_Size (Target_Typ));

      --  For a little-endian target type stored byte-swapped on a
      --  big-endian machine, do not mask to Target_Siz bits.

      if Bytes_Big_Endian
           and then (Is_Record_Type (Target_Typ)
                       or else
                     Is_Array_Type (Target_Typ))
           and then Reverse_Storage_Order (Target_Typ)
      then
         Source_Siz := Target_Siz;
      end if;

      --  First step, if the source type is not a discrete type, then we first
      --  convert to a modular type of the source length, since otherwise, on
      --  a big-endian machine, we get left-justification. We do it for little-
      --  endian machines as well, because there might be junk bits that are
      --  not cleared if the type is not numeric. This can be done only if the
      --  source siz is different from 0 (i.e. known), otherwise we must trust
      --  the type declarations (case of non-discrete components).

      if Source_Siz /= 0
        and then Source_Siz /= Target_Siz
        and then not Is_Discrete_Type (Source_Typ)
      then
         Src := Unchecked_Convert_To (RTE (Bits_Id (Source_Siz)), Src);
      end if;

      --  In the big endian case, if the lengths of the two types differ, then
      --  we must worry about possible left justification in the conversion,
      --  and avoiding that is what this is all about.

      if Bytes_Big_Endian and then Source_Siz /= Target_Siz then

         --  Next step. If the target is not a discrete type, then we first
         --  convert to a modular type of the target length, since otherwise,
         --  on a big-endian machine, we get left-justification.

         if not Is_Discrete_Type (Target_Typ) then
            Src := Unchecked_Convert_To (RTE (Bits_Id (Target_Siz)), Src);
         end if;
      end if;

      --  And now we can do the final conversion to the target type

      return Unchecked_Convert_To (Target_Typ, Src);
   end RJ_Unchecked_Convert_To;

   ----------------------------------------------
   -- Setup_Enumeration_Packed_Array_Reference --
   ----------------------------------------------

   --  All we have to do here is to find the subscripts that correspond to the
   --  index positions that have non-standard enumeration types and insert a
   --  Pos attribute to get the proper subscript value.

   --  Finally the prefix must be uncheck-converted to the corresponding packed
   --  array type.

   --  Note that the component type is unchanged, so we do not need to fiddle
   --  with the types (Gigi always automatically takes the packed array type if
   --  it is set, as it will be in this case).

   procedure Setup_Enumeration_Packed_Array_Reference (N : Node_Id) is
      Pfx   : constant Node_Id   := Prefix (N);
      Typ   : constant Entity_Id := Etype (N);
      Exprs : constant List_Id   := Expressions (N);
      Expr  : Node_Id;

   begin
      --  If the array is unconstrained, then we replace the array reference
      --  with its actual subtype. This actual subtype will have a packed array
      --  type with appropriate bounds.

      if not Is_Constrained (Packed_Array_Impl_Type (Etype (Pfx))) then
         Convert_To_Actual_Subtype (Pfx);
      end if;

      Expr := First (Exprs);
      while Present (Expr) loop
         declare
            Loc      : constant Source_Ptr := Sloc (Expr);
            Expr_Typ : constant Entity_Id := Etype (Expr);

         begin
            if Is_Enumeration_Type (Expr_Typ)
              and then Has_Non_Standard_Rep (Expr_Typ)
            then
               Rewrite (Expr,
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Occurrence_Of (Expr_Typ, Loc),
                   Attribute_Name => Name_Pos,
                   Expressions    => New_List (Relocate_Node (Expr))));
               Analyze_And_Resolve (Expr, Standard_Natural);
            end if;
         end;

         Next (Expr);
      end loop;

      Rewrite (N,
        Make_Indexed_Component (Sloc (N),
          Prefix      =>
            Unchecked_Convert_To (Packed_Array_Impl_Type (Etype (Pfx)), Pfx),
          Expressions => Exprs));

      Analyze_And_Resolve (N, Typ);
   end Setup_Enumeration_Packed_Array_Reference;

   -----------------------------------------
   -- Setup_Inline_Packed_Array_Reference --
   -----------------------------------------

   procedure Setup_Inline_Packed_Array_Reference
     (N      : Node_Id;
      Atyp   : Entity_Id;
      Obj    : in out Node_Id;
      Cmask  : out Uint;
      Shift  : out Node_Id)
   is
      Loc  : constant Source_Ptr := Sloc (N);
      PAT  : Entity_Id;
      Otyp : Entity_Id;
      Csiz : Uint;
      Osiz : Uint;

   begin
      Csiz := Component_Size (Atyp);

      Convert_To_PAT_Type (Obj);
      PAT := Etype (Obj);

      Cmask := 2 ** Csiz - 1;

      if Is_Array_Type (PAT) then
         Otyp := Component_Type (PAT);
         Osiz := Component_Size (PAT);

      else
         Otyp := PAT;

         --  In the case where the PAT is a modular type, we want the actual
         --  size in bits of the modular value we use. This is neither the
         --  Object_Size nor the Value_Size, either of which may have been
         --  reset to strange values, but rather the minimum size. Note that
         --  since this is a modular type with full range, the issue of
         --  biased representation does not arise.

         Osiz := UI_From_Int (Minimum_Size (Otyp));
      end if;

      Compute_Linear_Subscript (Atyp, N, Shift);

      --  If the component size is not 1, then the subscript must be multiplied
      --  by the component size to get the shift count.

      if Csiz /= 1 then
         Shift :=
           Make_Op_Multiply (Loc,
             Left_Opnd  => Make_Integer_Literal (Loc, Csiz),
             Right_Opnd => Shift);
      end if;

      --  If we have the array case, then this shift count must be broken down
      --  into a byte subscript, and a shift within the byte.

      if Is_Array_Type (PAT) then

         declare
            New_Shift : Node_Id;

         begin
            --  We must analyze shift, since we will duplicate it

            Set_Parent (Shift, N);
            Analyze_And_Resolve
              (Shift, Standard_Integer, Suppress => All_Checks);

            --  The shift count within the word is
            --    shift mod Osiz

            New_Shift :=
              Make_Op_Mod (Loc,
                Left_Opnd  => Duplicate_Subexpr (Shift),
                Right_Opnd => Make_Integer_Literal (Loc, Osiz));

            --  The subscript to be used on the PAT array is
            --    shift / Osiz

            Obj :=
              Make_Indexed_Component (Loc,
                Prefix => Obj,
                Expressions => New_List (
                  Make_Op_Divide (Loc,
                    Left_Opnd  => Duplicate_Subexpr (Shift),
                    Right_Opnd => Make_Integer_Literal (Loc, Osiz))));

            Shift := New_Shift;
         end;

      --  For the modular integer case, the object to be manipulated is the
      --  entire array, so Obj is unchanged. Note that we will reset its type
      --  to PAT before returning to the caller.

      else
         null;
      end if;

      --  The one remaining step is to modify the shift count for the
      --  big-endian case. Consider the following example in a byte:

      --     xxxxxxxx  bits of byte
      --     vvvvvvvv  bits of value
      --     33221100  little-endian numbering
      --     00112233  big-endian numbering

      --  Here we have the case of 2-bit fields

      --  For the little-endian case, we already have the proper shift count
      --  set, e.g. for element 2, the shift count is 2*2 = 4.

      --  For the big endian case, we have to adjust the shift count, computing
      --  it as (N - F) - Shift, where N is the number of bits in an element of
      --  the array used to implement the packed array, F is the number of bits
      --  in a source array element, and Shift is the count so far computed.

      --  We also have to adjust if the storage order is reversed

      if Bytes_Big_Endian xor Reverse_Storage_Order (Base_Type (Atyp)) then
         Shift :=
           Make_Op_Subtract (Loc,
             Left_Opnd  => Make_Integer_Literal (Loc, Osiz - Csiz),
             Right_Opnd => Shift);
      end if;

      Set_Parent (Shift, N);
      Set_Parent (Obj, N);
      Analyze_And_Resolve (Obj,   Otyp,             Suppress => All_Checks);
      Analyze_And_Resolve (Shift, Standard_Integer, Suppress => All_Checks);

      --  Make sure final type of object is the appropriate packed type

      Set_Etype (Obj, Otyp);

   end Setup_Inline_Packed_Array_Reference;

end Exp_Pakd;
