------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             E X P _ A G G R                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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 Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Expander;       use Expander;
with Exp_Util;       use Exp_Util;
with Exp_Ch3;        use Exp_Ch3;
with Exp_Ch6;        use Exp_Ch6;
with Exp_Ch7;        use Exp_Ch7;
with Exp_Ch9;        use Exp_Ch9;
with Exp_Disp;       use Exp_Disp;
with Exp_Tss;        use Exp_Tss;
with Freeze;         use Freeze;
with Itypes;         use Itypes;
with Lib;            use Lib;
with Namet;          use Namet;
with Nmake;          use Nmake;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Ttypes;         use Ttypes;
with Sem;            use Sem;
with Sem_Aggr;       use Sem_Aggr;
with Sem_Aux;        use Sem_Aux;
with Sem_Case;       use Sem_Case;
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_Mech;       use Sem_Mech;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Snames;         use Snames;
with Stand;          use Stand;
with Stringt;        use Stringt;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;
with Urealp;         use Urealp;

package body Exp_Aggr is

   type Case_Bounds is record
     Choice_Lo   : Node_Id;
     Choice_Hi   : Node_Id;
     Choice_Node : Node_Id;
   end record;

   type Case_Table_Type is array (Nat range <>) of Case_Bounds;
   --  Table type used by Check_Case_Choices procedure

   procedure Expand_Delta_Array_Aggregate  (N : Node_Id; Deltas : List_Id);
   procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id);
   procedure Expand_Container_Aggregate (N : Node_Id);

   function Get_Base_Object (N : Node_Id) return Entity_Id;
   --  Return the base object, i.e. the outermost prefix object, that N refers
   --  to statically, or Empty if it cannot be determined. The assumption is
   --  that all dereferences are explicit in the tree rooted at N.

   function Has_Default_Init_Comps (N : Node_Id) return Boolean;
   --  N is an aggregate (record or array). Checks the presence of default
   --  initialization (<>) in any component (Ada 2005: AI-287).

   function Is_CCG_Supported_Aggregate (N : Node_Id) return Boolean;
   --  Return True if aggregate N is located in a context supported by the
   --  CCG backend; False otherwise.

   function Is_Static_Dispatch_Table_Aggregate (N : Node_Id) return Boolean;
   --  Returns true if N is an aggregate used to initialize the components
   --  of a statically allocated dispatch table.

   function Late_Expansion
     (N      : Node_Id;
      Typ    : Entity_Id;
      Target : Node_Id) return List_Id;
   --  This routine implements top-down expansion of nested aggregates. In
   --  doing so, it avoids the generation of temporaries at each level. N is
   --  a nested record or array aggregate with the Expansion_Delayed flag.
   --  Typ is the expected type of the aggregate. Target is a (duplicatable)
   --  expression that will hold the result of the aggregate expansion.

   function Make_OK_Assignment_Statement
     (Sloc       : Source_Ptr;
      Name       : Node_Id;
      Expression : Node_Id) return Node_Id;
   --  This is like Make_Assignment_Statement, except that Assignment_OK
   --  is set in the left operand. All assignments built by this unit use
   --  this routine. This is needed to deal with assignments to initialized
   --  constants that are done in place.

   function Must_Slide
     (Aggr     : Node_Id;
      Obj_Type : Entity_Id;
      Typ      : Entity_Id) return Boolean;
   --  A static array aggregate in an object declaration can in most cases be
   --  expanded in place. The one exception is when the aggregate is given
   --  with component associations that specify different bounds from those of
   --  the type definition in the object declaration. In this pathological
   --  case the aggregate must slide, and we must introduce an intermediate
   --  temporary to hold it.
   --
   --  The same holds in an assignment to one-dimensional array of arrays,
   --  when a component may be given with bounds that differ from those of the
   --  component type.

   function Number_Of_Choices (N : Node_Id) return Nat;
   --  Returns the number of discrete choices (not including the others choice
   --  if present) contained in (sub-)aggregate N.

   procedure Process_Transient_Component
     (Loc        : Source_Ptr;
      Comp_Typ   : Entity_Id;
      Init_Expr  : Node_Id;
      Fin_Call   : out Node_Id;
      Hook_Clear : out Node_Id;
      Aggr       : Node_Id := Empty;
      Stmts      : List_Id := No_List);
   --  Subsidiary to the expansion of array and record aggregates. Generate
   --  part of the necessary code to finalize a transient component. Comp_Typ
   --  is the component type. Init_Expr is the initialization expression of the
   --  component which is always a function call. Fin_Call is the finalization
   --  call used to clean up the transient function result. Hook_Clear is the
   --  hook reset statement. Aggr and Stmts both control the placement of the
   --  generated code. Aggr is the related aggregate. If present, all code is
   --  inserted prior to Aggr using Insert_Action. Stmts is the initialization
   --  statements of the component. If present, all code is added to Stmts.

   procedure Process_Transient_Component_Completion
     (Loc        : Source_Ptr;
      Aggr       : Node_Id;
      Fin_Call   : Node_Id;
      Hook_Clear : Node_Id;
      Stmts      : List_Id);
   --  Subsidiary to the expansion of array and record aggregates. Generate
   --  part of the necessary code to finalize a transient component. Aggr is
   --  the related aggregate. Fin_Clear is the finalization call used to clean
   --  up the transient component. Hook_Clear is the hook reset statment. Stmts
   --  is the initialization statement list for the component. All generated
   --  code is added to Stmts.

   procedure Sort_Case_Table (Case_Table : in out Case_Table_Type);
   --  Sort the Case Table using the Lower Bound of each Choice as the key.
   --  A simple insertion sort is used since the number of choices in a case
   --  statement of variant part will usually be small and probably in near
   --  sorted order.

   ------------------------------------------------------
   -- Local subprograms for Record Aggregate Expansion --
   ------------------------------------------------------

   function Is_Build_In_Place_Aggregate_Return (N : Node_Id) return Boolean;
   --  True if N is an aggregate (possibly qualified or converted) that is
   --  being returned from a build-in-place function.

   function Build_Record_Aggr_Code
     (N   : Node_Id;
      Typ : Entity_Id;
      Lhs : Node_Id) return List_Id;
   --  N is an N_Aggregate or an N_Extension_Aggregate. Typ is the type of the
   --  aggregate. Target is an expression containing the location on which the
   --  component by component assignments will take place. Returns the list of
   --  assignments plus all other adjustments needed for tagged and controlled
   --  types.

   procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
   --  Transform a record aggregate into a sequence of assignments performed
   --  component by component. N is an N_Aggregate or N_Extension_Aggregate.
   --  Typ is the type of the record aggregate.

   procedure Expand_Record_Aggregate
     (N           : Node_Id;
      Orig_Tag    : Node_Id := Empty;
      Parent_Expr : Node_Id := Empty);
   --  This is the top level procedure for record aggregate expansion.
   --  Expansion for record aggregates needs expand aggregates for tagged
   --  record types. Specifically Expand_Record_Aggregate adds the Tag
   --  field in front of the Component_Association list that was created
   --  during resolution by Resolve_Record_Aggregate.
   --
   --    N is the record aggregate node.
   --    Orig_Tag is the value of the Tag that has to be provided for this
   --      specific aggregate. It carries the tag corresponding to the type
   --      of the outermost aggregate during the recursive expansion
   --    Parent_Expr is the ancestor part of the original extension
   --      aggregate

   function Has_Mutable_Components (Typ : Entity_Id) return Boolean;
   --  Return true if one of the components is of a discriminated type with
   --  defaults. An aggregate for a type with mutable components must be
   --  expanded into individual assignments.

   function In_Place_Assign_OK
     (N             : Node_Id;
      Target_Object : Entity_Id := Empty) return Boolean;
   --  Predicate to determine whether an aggregate assignment can be done in
   --  place, because none of the new values can depend on the components of
   --  the target of the assignment.

   procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id);
   --  If the type of the aggregate is a type extension with renamed discrimi-
   --  nants, we must initialize the hidden discriminants of the parent.
   --  Otherwise, the target object must not be initialized. The discriminants
   --  are initialized by calling the initialization procedure for the type.
   --  This is incorrect if the initialization of other components has any
   --  side effects. We restrict this call to the case where the parent type
   --  has a variant part, because this is the only case where the hidden
   --  discriminants are accessed, namely when calling discriminant checking
   --  functions of the parent type, and when applying a stream attribute to
   --  an object of the derived type.

   -----------------------------------------------------
   -- Local Subprograms for Array Aggregate Expansion --
   -----------------------------------------------------

   function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean;
   --  Returns true if an aggregate assignment can be done by the back end

   function Aggr_Size_OK (N : Node_Id) return Boolean;
   --  Very large static aggregates present problems to the back-end, and are
   --  transformed into assignments and loops. This function verifies that the
   --  total number of components of an aggregate is acceptable for rewriting
   --  into a purely positional static form. Aggr_Size_OK must be called before
   --  calling Flatten.
   --
   --  This function also detects and warns about one-component aggregates that
   --  appear in a nonstatic context. Even if the component value is static,
   --  such an aggregate must be expanded into an assignment.

   function Backend_Processing_Possible (N : Node_Id) return Boolean;
   --  This function checks if array aggregate N can be processed directly
   --  by the backend. If this is the case, True is returned.

   function Build_Array_Aggr_Code
     (N           : Node_Id;
      Ctype       : Entity_Id;
      Index       : Node_Id;
      Into        : Node_Id;
      Scalar_Comp : Boolean;
      Indexes     : List_Id := No_List) return List_Id;
   --  This recursive routine returns a list of statements containing the
   --  loops and assignments that are needed for the expansion of the array
   --  aggregate N.
   --
   --    N is the (sub-)aggregate node to be expanded into code. This node has
   --    been fully analyzed, and its Etype is properly set.
   --
   --    Index is the index node corresponding to the array subaggregate N
   --
   --    Into is the target expression into which we are copying the aggregate.
   --    Note that this node may not have been analyzed yet, and so the Etype
   --    field may not be set.
   --
   --    Scalar_Comp is True if the component type of the aggregate is scalar
   --
   --    Indexes is the current list of expressions used to index the object we
   --    are writing into.

   procedure Convert_Array_Aggr_In_Allocator
     (Decl   : Node_Id;
      Aggr   : Node_Id;
      Target : Node_Id);
   --  If the aggregate appears within an allocator and can be expanded in
   --  place, this routine generates the individual assignments to components
   --  of the designated object. This is an optimization over the general
   --  case, where a temporary is first created on the stack and then used to
   --  construct the allocated object on the heap.

   procedure Convert_To_Positional
     (N                 : Node_Id;
      Handle_Bit_Packed : Boolean := False);
   --  If possible, convert named notation to positional notation. This
   --  conversion is possible only in some static cases. If the conversion is
   --  possible, then N is rewritten with the analyzed converted aggregate.
   --  The parameter Handle_Bit_Packed is usually set False (since we do
   --  not expect the back end to handle bit packed arrays, so the normal case
   --  of conversion is pointless), but in the special case of a call from
   --  Packed_Array_Aggregate_Handled, we set this parameter to True, since
   --  these are cases we handle in there.

   procedure Expand_Array_Aggregate (N : Node_Id);
   --  This is the top-level routine to perform array aggregate expansion.
   --  N is the N_Aggregate node to be expanded.

   function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean;
   --  For two-dimensional packed aggregates with constant bounds and constant
   --  components, it is preferable to pack the inner aggregates because the
   --  whole matrix can then be presented to the back-end as a one-dimensional
   --  list of literals. This is much more efficient than expanding into single
   --  component assignments. This function determines if the type Typ is for
   --  an array that is suitable for this optimization: it returns True if Typ
   --  is a two dimensional bit packed array with component size 1, 2, or 4.

   function Max_Aggregate_Size
     (N            : Node_Id;
      Default_Size : Nat := 5000) return Nat;
   --  Return the max size for a static aggregate N. Return Default_Size if no
   --  other special criteria trigger.

   function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean;
   --  Given an array aggregate, this function handles the case of a packed
   --  array aggregate with all constant values, where the aggregate can be
   --  evaluated at compile time. If this is possible, then N is rewritten
   --  to be its proper compile time value with all the components properly
   --  assembled. The expression is analyzed and resolved and True is returned.
   --  If this transformation is not possible, N is unchanged and False is
   --  returned.

   function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean;
   --  If the type of the aggregate is a two-dimensional bit_packed array
   --  it may be transformed into an array of bytes with constant values,
   --  and presented to the back-end as a static value. The function returns
   --  false if this transformation cannot be performed. THis is similar to,
   --  and reuses part of the machinery in Packed_Array_Aggregate_Handled.

   ------------------------------------
   -- Aggr_Assignment_OK_For_Backend --
   ------------------------------------

   --  Back-end processing by Gigi/gcc is possible only if all the following
   --  conditions are met:

   --    1. N consists of a single OTHERS choice, possibly recursively, or
   --       of a single choice, possibly recursively, if it is surrounded by
   --       a qualified expression whose subtype mark is unconstrained.

   --    2. The array type has no null ranges (the purpose of this is to
   --       avoid a bogus warning for an out-of-range value).

   --    3. The array type has no atomic components

   --    4. The component type is elementary

   --    5. The component size is a multiple of Storage_Unit

   --    6. The component size is Storage_Unit or the value is of the form
   --       M * (1 + A**1 + A**2 + .. A**(K-1)) where A = 2**(Storage_Unit)
   --       and M in 0 .. A-1. This can also be viewed as K occurrences of
   --       the Storage_Unit value M, concatenated together.

   --  The ultimate goal is to generate a call to a fast memset routine
   --  specifically optimized for the target.

   function Aggr_Assignment_OK_For_Backend (N : Node_Id) return Boolean is

      function Is_OK_Aggregate (Aggr : Node_Id) return Boolean;
      --  Return true if Aggr is suitable for back-end assignment

      ---------------------
      -- Is_OK_Aggregate --
      ---------------------

      function Is_OK_Aggregate (Aggr : Node_Id) return Boolean is
         Assoc : constant List_Id := Component_Associations (Aggr);

      begin
         --  An "others" aggregate is most likely OK, but see below

         if Is_Others_Aggregate (Aggr) then
            null;

         --  An aggregate with a single choice requires a qualified expression
         --  whose subtype mark is an unconstrained type because we need it to
         --  have the semantics of an "others" aggregate.

         elsif Nkind (Parent (N)) = N_Qualified_Expression
           and then not Is_Constrained (Entity (Subtype_Mark (Parent (N))))
           and then Is_Single_Aggregate (Aggr)
         then
            null;

         --  The other cases are not OK

         else
            return False;
         end if;

         --  In any case we do not support an iterated association

         return Nkind (First (Assoc)) /= N_Iterated_Component_Association;
      end Is_OK_Aggregate;

      Bounds    : Range_Nodes;
      Csiz      : Uint := No_Uint;
      Ctyp      : Entity_Id;
      Expr      : Node_Id;
      Index     : Entity_Id;
      Nunits    : Int;
      Remainder : Uint;
      Value     : Uint;

   --  Start of processing for Aggr_Assignment_OK_For_Backend

   begin
      --  Back end doesn't know about <>

      if Has_Default_Init_Comps (N) then
         return False;
      end if;

      --  Recurse as far as possible to find the innermost component type

      Ctyp := Etype (N);
      Expr := N;
      while Is_Array_Type (Ctyp) loop
         if Nkind (Expr) /= N_Aggregate
           or else not Is_OK_Aggregate (Expr)
         then
            return False;
         end if;

         Index := First_Index (Ctyp);
         while Present (Index) loop
            Bounds := Get_Index_Bounds (Index);

            if Is_Null_Range (Bounds.First, Bounds.Last) then
               return False;
            end if;

            Next_Index (Index);
         end loop;

         Expr := Expression (First (Component_Associations (Expr)));

         for J in 1 .. Number_Dimensions (Ctyp) - 1 loop
            if Nkind (Expr) /= N_Aggregate
              or else not Is_OK_Aggregate (Expr)
            then
               return False;
            end if;

            Expr := Expression (First (Component_Associations (Expr)));
         end loop;

         if Has_Atomic_Components (Ctyp) then
            return False;
         end if;

         Csiz := Component_Size (Ctyp);
         Ctyp := Component_Type (Ctyp);

         if Is_Full_Access (Ctyp) then
            return False;
         end if;
      end loop;

      --  Access types need to be dealt with specially

      if Is_Access_Type (Ctyp) then

         --  Component_Size is not set by Layout_Type if the component
         --  type is an access type ???

         Csiz := Esize (Ctyp);

         --  Fat pointers are rejected as they are not really elementary
         --  for the backend.

         if Csiz /= System_Address_Size then
            return False;
         end if;

         --  The supported expressions are NULL and constants, others are
         --  rejected upfront to avoid being analyzed below, which can be
         --  problematic for some of them, for example allocators.

         if Nkind (Expr) /= N_Null and then not Is_Entity_Name (Expr) then
            return False;
         end if;

      --  Scalar types are OK if their size is a multiple of Storage_Unit

      elsif Is_Scalar_Type (Ctyp) then
         pragma Assert (Present (Csiz));

         if Csiz mod System_Storage_Unit /= 0 then
            return False;
         end if;

      --  Composite types are rejected

      else
         return False;
      end if;

      --  If the expression has side effects (e.g. contains calls with
      --  potential side effects) reject as well. We only preanalyze the
      --  expression to prevent the removal of intended side effects.

      Preanalyze_And_Resolve (Expr, Ctyp);

      if not Side_Effect_Free (Expr) then
         return False;
      end if;

      --  The expression needs to be analyzed if True is returned

      Analyze_And_Resolve (Expr, Ctyp);

      --  Strip away any conversions from the expression as they simply
      --  qualify the real expression.

      while Nkind (Expr) in N_Unchecked_Type_Conversion | N_Type_Conversion
      loop
         Expr := Expression (Expr);
      end loop;

      Nunits := UI_To_Int (Csiz) / System_Storage_Unit;

      if Nunits = 1 then
         return True;
      end if;

      if not Compile_Time_Known_Value (Expr) then
         return False;
      end if;

      --  The only supported value for floating point is 0.0

      if Is_Floating_Point_Type (Ctyp) then
         return Expr_Value_R (Expr) = Ureal_0;
      end if;

      --  For other types, we can look into the value as an integer, which
      --  means the representation value for enumeration literals.

      Value := Expr_Rep_Value (Expr);

      if Has_Biased_Representation (Ctyp) then
         Value := Value - Expr_Value (Type_Low_Bound (Ctyp));
      end if;

      --  Values 0 and -1 immediately satisfy the last check

      if Value = Uint_0 or else Value = Uint_Minus_1 then
         return True;
      end if;

      --  We need to work with an unsigned value

      if Value < 0 then
         Value := Value + 2**(System_Storage_Unit * Nunits);
      end if;

      Remainder := Value rem 2**System_Storage_Unit;

      for J in 1 .. Nunits - 1 loop
         Value := Value / 2**System_Storage_Unit;

         if Value rem 2**System_Storage_Unit /= Remainder then
            return False;
         end if;
      end loop;

      return True;
   end Aggr_Assignment_OK_For_Backend;

   ------------------
   -- Aggr_Size_OK --
   ------------------

   function Aggr_Size_OK (N : Node_Id) return Boolean is
      Typ  : constant Entity_Id := Etype (N);
      Lo   : Node_Id;
      Hi   : Node_Id;
      Indx : Node_Id;
      Size : Uint;
      Lov  : Uint;
      Hiv  : Uint;

      Max_Aggr_Size : Nat;
      --  Determines the maximum size of an array aggregate produced by
      --  converting named to positional notation (e.g. from others clauses).
      --  This avoids running away with attempts to convert huge aggregates,
      --  which hit memory limits in the backend.

      function Component_Count (T : Entity_Id) return Nat;
      --  The limit is applied to the total number of subcomponents that the
      --  aggregate will have, which is the number of static expressions
      --  that will appear in the flattened array. This requires a recursive
      --  computation of the number of scalar components of the structure.

      ---------------------
      -- Component_Count --
      ---------------------

      function Component_Count (T : Entity_Id) return Nat is
         Res  : Nat := 0;
         Comp : Entity_Id;

      begin
         if Is_Scalar_Type (T) then
            return 1;

         elsif Is_Record_Type (T) then
            Comp := First_Component (T);
            while Present (Comp) loop
               Res := Res + Component_Count (Etype (Comp));
               Next_Component (Comp);
            end loop;

            return Res;

         elsif Is_Array_Type (T) then
            declare
               Lo : constant Node_Id :=
                 Type_Low_Bound (Etype (First_Index (T)));
               Hi : constant Node_Id :=
                 Type_High_Bound (Etype (First_Index (T)));

               Siz : constant Nat := Component_Count (Component_Type (T));

            begin
               --  Check for superflat arrays, i.e. arrays with such bounds
               --  as 4 .. 2, to insure that this function never returns a
               --  meaningless negative value.

               if not Compile_Time_Known_Value (Lo)
                 or else not Compile_Time_Known_Value (Hi)
                 or else Expr_Value (Hi) < Expr_Value (Lo)
               then
                  return 0;

               else
                  --  If the number of components is greater than Int'Last,
                  --  then return Int'Last, so caller will return False (Aggr
                  --  size is not OK). Otherwise, UI_To_Int will crash.

                  declare
                     UI : constant Uint :=
                            Expr_Value (Hi) - Expr_Value (Lo) + 1;
                  begin
                     if UI_Is_In_Int_Range (UI) then
                        return Siz * UI_To_Int (UI);
                     else
                        return Int'Last;
                     end if;
                  end;
               end if;
            end;

         else
            --  Can only be a null for an access type

            return 1;
         end if;
      end Component_Count;

   --  Start of processing for Aggr_Size_OK

   begin
      --  We bump the maximum size unless the aggregate has a single component
      --  association, which will be more efficient if implemented with a loop.
      --  The -gnatd_g switch disables this bumping.

      if (No (Expressions (N))
            and then No (Next (First (Component_Associations (N)))))
        or else Debug_Flag_Underscore_G
      then
         Max_Aggr_Size := Max_Aggregate_Size (N);
      else
         Max_Aggr_Size := Max_Aggregate_Size (N, 500_000);
      end if;

      Size := UI_From_Int (Component_Count (Component_Type (Typ)));

      Indx := First_Index (Typ);
      while Present (Indx) loop
         Lo  := Type_Low_Bound (Etype (Indx));
         Hi  := Type_High_Bound (Etype (Indx));

         --  Bounds need to be known at compile time

         if not Compile_Time_Known_Value (Lo)
           or else not Compile_Time_Known_Value (Hi)
         then
            return False;
         end if;

         Lov := Expr_Value (Lo);
         Hiv := Expr_Value (Hi);

         --  A flat array is always safe

         if Hiv < Lov then
            return True;
         end if;

         --  One-component aggregates are suspicious, and if the context type
         --  is an object declaration with nonstatic bounds it will trip gcc;
         --  such an aggregate must be expanded into a single assignment.

         if Hiv = Lov and then Nkind (Parent (N)) = N_Object_Declaration then
            declare
               Index_Type : constant Entity_Id :=
                 Etype
                   (First_Index (Etype (Defining_Identifier (Parent (N)))));
               Indx       : Node_Id;

            begin
               if not Compile_Time_Known_Value (Type_Low_Bound (Index_Type))
                 or else not Compile_Time_Known_Value
                               (Type_High_Bound (Index_Type))
               then
                  if Present (Component_Associations (N)) then
                     Indx :=
                       First
                         (Choice_List (First (Component_Associations (N))));

                     if Is_Entity_Name (Indx)
                       and then not Is_Type (Entity (Indx))
                     then
                        Error_Msg_N
                          ("single component aggregate in "
                           &  "non-static context??", Indx);
                        Error_Msg_N ("\maybe subtype name was meant??", Indx);
                     end if;
                  end if;

                  return False;
               end if;
            end;
         end if;

         declare
            Rng : constant Uint := Hiv - Lov + 1;

         begin
            --  Check if size is too large

            if not UI_Is_In_Int_Range (Rng) then
               return False;
            end if;

            --  Compute the size using universal arithmetic to avoid the
            --  possibility of overflow on very large aggregates.

            Size := Size * Rng;

            if Size <= 0
              or else Size > Max_Aggr_Size
            then
               return False;
            end if;
         end;

         --  Bounds must be in integer range, for later array construction

         if not UI_Is_In_Int_Range (Lov)
             or else
            not UI_Is_In_Int_Range (Hiv)
         then
            return False;
         end if;

         Next_Index (Indx);
      end loop;

      return True;
   end Aggr_Size_OK;

   ---------------------------------
   -- Backend_Processing_Possible --
   ---------------------------------

   --  Backend processing by Gigi/gcc is possible only if all the following
   --  conditions are met:

   --    1. N is fully positional

   --    2. N is not a bit-packed array aggregate;

   --    3. The size of N's array type must be known at compile time. Note
   --       that this implies that the component size is also known

   --    4. The array type of N does not follow the Fortran layout convention
   --       or if it does it must be 1 dimensional.

   --    5. The array component type may not be tagged (which could necessitate
   --       reassignment of proper tags).

   --    6. The array component type must not have unaligned bit components

   --    7. None of the components of the aggregate may be bit unaligned
   --       components.

   --    8. There cannot be delayed components, since we do not know enough
   --       at this stage to know if back end processing is possible.

   --    9. There cannot be any discriminated record components, since the
   --       back end cannot handle this complex case.

   --   10. No controlled actions need to be generated for components

   --   11. When generating C code, N must be part of a N_Object_Declaration

   --   12. When generating C code, N must not include function calls

   function Backend_Processing_Possible (N : Node_Id) return Boolean is
      Typ : constant Entity_Id := Etype (N);
      --  Typ is the correct constrained array subtype of the aggregate

      function Component_Check (N : Node_Id; Index : Node_Id) return Boolean;
      --  This routine checks components of aggregate N, enforcing checks
      --  1, 7, 8, 9, 11, and 12. In the multidimensional case, these checks
      --  are performed on subaggregates. The Index value is the current index
      --  being checked in the multidimensional case.

      ---------------------
      -- Component_Check --
      ---------------------

      function Component_Check (N : Node_Id; Index : Node_Id) return Boolean is
         function Ultimate_Original_Expression (N : Node_Id) return Node_Id;
         --  Given a type conversion or an unchecked type conversion N, return
         --  its innermost original expression.

         ----------------------------------
         -- Ultimate_Original_Expression --
         ----------------------------------

         function Ultimate_Original_Expression (N : Node_Id) return Node_Id is
            Expr : Node_Id := Original_Node (N);

         begin
            while Nkind (Expr) in
                    N_Type_Conversion | N_Unchecked_Type_Conversion
            loop
               Expr := Original_Node (Expression (Expr));
            end loop;

            return Expr;
         end Ultimate_Original_Expression;

         --  Local variables

         Expr : Node_Id;

      --  Start of processing for Component_Check

      begin
         --  Checks 1: (no component associations)

         if Present (Component_Associations (N)) then
            return False;
         end if;

         --  Checks 11: The C code generator cannot handle aggregates that are
         --  not part of an object declaration.

         if Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
            return False;
         end if;

         --  Checks on components

         --  Recurse to check subaggregates, which may appear in qualified
         --  expressions. If delayed, the front-end will have to expand.
         --  If the component is a discriminated record, treat as nonstatic,
         --  as the back-end cannot handle this properly.

         Expr := First (Expressions (N));
         while Present (Expr) loop

            --  Checks 8: (no delayed components)

            if Is_Delayed_Aggregate (Expr) then
               return False;
            end if;

            --  Checks 9: (no discriminated records)

            if Present (Etype (Expr))
              and then Is_Record_Type (Etype (Expr))
              and then Has_Discriminants (Etype (Expr))
            then
               return False;
            end if;

            --  Checks 7. Component must not be bit aligned component

            if Possible_Bit_Aligned_Component (Expr) then
               return False;
            end if;

            --  Checks 12: (no function call)

            if Modify_Tree_For_C
              and then
                Nkind (Ultimate_Original_Expression (Expr)) = N_Function_Call
            then
               return False;
            end if;

            --  Recursion to following indexes for multiple dimension case

            if Present (Next_Index (Index))
              and then not Component_Check (Expr, Next_Index (Index))
            then
               return False;
            end if;

            --  All checks for that component finished, on to next

            Next (Expr);
         end loop;

         return True;
      end Component_Check;

   --  Start of processing for Backend_Processing_Possible

   begin
      --  Checks 2 (array not bit packed) and 10 (no controlled actions)

      if Is_Bit_Packed_Array (Typ) or else Needs_Finalization (Typ) then
         return False;
      end if;

      --  If component is limited, aggregate must be expanded because each
      --  component assignment must be built in place.

      if Is_Limited_View (Component_Type (Typ)) then
         return False;
      end if;

      --  Checks 4 (array must not be multidimensional Fortran case)

      if Convention (Typ) = Convention_Fortran
        and then Number_Dimensions (Typ) > 1
      then
         return False;
      end if;

      --  Checks 3 (size of array must be known at compile time)

      if not Size_Known_At_Compile_Time (Typ) then
         return False;
      end if;

      --  Checks on components

      if not Component_Check (N, First_Index (Typ)) then
         return False;
      end if;

      --  Checks 5 (if the component type is tagged, then we may need to do
      --  tag adjustments. Perhaps this should be refined to check for any
      --  component associations that actually need tag adjustment, similar
      --  to the test in Component_OK_For_Backend for record aggregates with
      --  tagged components, but not clear whether it's worthwhile ???; in the
      --  case of virtual machines (no Tagged_Type_Expansion), object tags are
      --  handled implicitly).

      if Is_Tagged_Type (Component_Type (Typ))
        and then Tagged_Type_Expansion
      then
         return False;
      end if;

      --  Checks 6 (component type must not have bit aligned components)

      if Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)) then
         return False;
      end if;

      --  Backend processing is possible

      return True;
   end Backend_Processing_Possible;

   ---------------------------
   -- Build_Array_Aggr_Code --
   ---------------------------

   --  The code that we generate from a one dimensional aggregate is

   --  1. If the subaggregate contains discrete choices we

   --     (a) Sort the discrete choices

   --     (b) Otherwise for each discrete choice that specifies a range we
   --         emit a loop. If a range specifies a maximum of three values, or
   --         we are dealing with an expression we emit a sequence of
   --         assignments instead of a loop.

   --     (c) Generate the remaining loops to cover the others choice if any

   --  2. If the aggregate contains positional elements we

   --     (a) translate the positional elements in a series of assignments

   --     (b) Generate a final loop to cover the others choice if any.
   --         Note that this final loop has to be a while loop since the case

   --             L : Integer := Integer'Last;
   --             H : Integer := Integer'Last;
   --             A : array (L .. H) := (1, others =>0);

   --         cannot be handled by a for loop. Thus for the following

   --             array (L .. H) := (.. positional elements.., others =>E);

   --         we always generate something like:

   --             J : Index_Type := Index_Of_Last_Positional_Element;
   --             while J < H loop
   --                J := Index_Base'Succ (J)
   --                Tmp (J) := E;
   --             end loop;

   function Build_Array_Aggr_Code
     (N           : Node_Id;
      Ctype       : Entity_Id;
      Index       : Node_Id;
      Into        : Node_Id;
      Scalar_Comp : Boolean;
      Indexes     : List_Id := No_List) return List_Id
   is
      Loc          : constant Source_Ptr := Sloc (N);
      Index_Base   : constant Entity_Id  := Base_Type (Etype (Index));
      Index_Base_L : constant Node_Id := Type_Low_Bound (Index_Base);
      Index_Base_H : constant Node_Id := Type_High_Bound (Index_Base);

      function Add (Val : Int; To : Node_Id) return Node_Id;
      --  Returns an expression where Val is added to expression To, unless
      --  To+Val is provably out of To's base type range. To must be an
      --  already analyzed expression.

      function Empty_Range (L, H : Node_Id) return Boolean;
      --  Returns True if the range defined by L .. H is certainly empty

      function Equal (L, H : Node_Id) return Boolean;
      --  Returns True if L = H for sure

      function Index_Base_Name return Node_Id;
      --  Returns a new reference to the index type name

      function Gen_Assign
        (Ind     : Node_Id;
         Expr    : Node_Id;
         In_Loop : Boolean := False) return List_Id;
      --  Ind must be a side-effect-free expression. If the input aggregate N
      --  to Build_Loop contains no subaggregates, then this function returns
      --  the assignment statement:
      --
      --     Into (Indexes, Ind) := Expr;
      --
      --  Otherwise we call Build_Code recursively. Flag In_Loop should be set
      --  when the assignment appears within a generated loop.
      --
      --  Ada 2005 (AI-287): In case of default initialized component, Expr
      --  is empty and we generate a call to the corresponding IP subprogram.

      function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
      --  Nodes L and H must be side-effect-free expressions. If the input
      --  aggregate N to Build_Loop contains no subaggregates, this routine
      --  returns the for loop statement:
      --
      --     for J in Index_Base'(L) .. Index_Base'(H) loop
      --        Into (Indexes, J) := Expr;
      --     end loop;
      --
      --  Otherwise we call Build_Code recursively. As an optimization if the
      --  loop covers 3 or fewer scalar elements we generate a sequence of
      --  assignments.
      --  If the component association that generates the loop comes from an
      --  Iterated_Component_Association, the loop parameter has the name of
      --  the corresponding parameter in the original construct.

      function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id;
      --  Nodes L and H must be side-effect-free expressions. If the input
      --  aggregate N to Build_Loop contains no subaggregates, this routine
      --  returns the while loop statement:
      --
      --     J : Index_Base := L;
      --     while J < H loop
      --        J := Index_Base'Succ (J);
      --        Into (Indexes, J) := Expr;
      --     end loop;
      --
      --  Otherwise we call Build_Code recursively

      function Get_Assoc_Expr (Assoc : Node_Id) return Node_Id;
      --  For an association with a box, use value given by aspect
     --   Default_Component_Value of array type if specified, else use
     --   value given by aspect Default_Value for component type itself
     --   if specified, else return Empty.

      function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean;
      function Local_Expr_Value               (E : Node_Id) return Uint;
      --  These two Local routines are used to replace the corresponding ones
      --  in sem_eval because while processing the bounds of an aggregate with
      --  discrete choices whose index type is an enumeration, we build static
      --  expressions not recognized by Compile_Time_Known_Value as such since
      --  they have not yet been analyzed and resolved. All the expressions in
      --  question are things like Index_Base_Name'Val (Const) which we can
      --  easily recognize as being constant.

      ---------
      -- Add --
      ---------

      function Add (Val : Int; To : Node_Id) return Node_Id is
         Expr_Pos : Node_Id;
         Expr     : Node_Id;
         To_Pos   : Node_Id;
         U_To     : Uint;
         U_Val    : constant Uint := UI_From_Int (Val);

      begin
         --  Note: do not try to optimize the case of Val = 0, because
         --  we need to build a new node with the proper Sloc value anyway.

         --  First test if we can do constant folding

         if Local_Compile_Time_Known_Value (To) then
            U_To := Local_Expr_Value (To) + Val;

            --  Determine if our constant is outside the range of the index.
            --  If so return an Empty node. This empty node will be caught
            --  by Empty_Range below.

            if Compile_Time_Known_Value (Index_Base_L)
              and then U_To < Expr_Value (Index_Base_L)
            then
               return Empty;

            elsif Compile_Time_Known_Value (Index_Base_H)
              and then U_To > Expr_Value (Index_Base_H)
            then
               return Empty;
            end if;

            Expr_Pos := Make_Integer_Literal (Loc, U_To);
            Set_Is_Static_Expression (Expr_Pos);

            if not Is_Enumeration_Type (Index_Base) then
               Expr := Expr_Pos;

            --  If we are dealing with enumeration return
            --     Index_Base'Val (Expr_Pos)

            else
               Expr :=
                 Make_Attribute_Reference
                   (Loc,
                    Prefix         => Index_Base_Name,
                    Attribute_Name => Name_Val,
                    Expressions    => New_List (Expr_Pos));
            end if;

            return Expr;
         end if;

         --  If we are here no constant folding possible

         if not Is_Enumeration_Type (Index_Base) then
            Expr :=
              Make_Op_Add (Loc,
                Left_Opnd  => Duplicate_Subexpr (To),
                Right_Opnd => Make_Integer_Literal (Loc, U_Val));

         --  If we are dealing with enumeration return
         --    Index_Base'Val (Index_Base'Pos (To) + Val)

         else
            To_Pos :=
              Make_Attribute_Reference
                (Loc,
                 Prefix         => Index_Base_Name,
                 Attribute_Name => Name_Pos,
                 Expressions    => New_List (Duplicate_Subexpr (To)));

            Expr_Pos :=
              Make_Op_Add (Loc,
                Left_Opnd  => To_Pos,
                Right_Opnd => Make_Integer_Literal (Loc, U_Val));

            Expr :=
              Make_Attribute_Reference
                (Loc,
                 Prefix         => Index_Base_Name,
                 Attribute_Name => Name_Val,
                 Expressions    => New_List (Expr_Pos));
         end if;

         return Expr;
      end Add;

      -----------------
      -- Empty_Range --
      -----------------

      function Empty_Range (L, H : Node_Id) return Boolean is
         Is_Empty : Boolean := False;
         Low      : Node_Id;
         High     : Node_Id;

      begin
         --  First check if L or H were already detected as overflowing the
         --  index base range type by function Add above. If this is so Add
         --  returns the empty node.

         if No (L) or else No (H) then
            return True;
         end if;

         for J in 1 .. 3 loop
            case J is

               --  L > H    range is empty

               when 1 =>
                  Low  := L;
                  High := H;

               --  B_L > H  range must be empty

               when 2 =>
                  Low  := Index_Base_L;
                  High := H;

               --  L > B_H  range must be empty

               when 3 =>
                  Low  := L;
                  High := Index_Base_H;
            end case;

            if Local_Compile_Time_Known_Value (Low)
                 and then
               Local_Compile_Time_Known_Value (High)
            then
               Is_Empty :=
                 UI_Gt (Local_Expr_Value (Low), Local_Expr_Value (High));
            end if;

            exit when Is_Empty;
         end loop;

         return Is_Empty;
      end Empty_Range;

      -----------
      -- Equal --
      -----------

      function Equal (L, H : Node_Id) return Boolean is
      begin
         if L = H then
            return True;

         elsif Local_Compile_Time_Known_Value (L)
                 and then
               Local_Compile_Time_Known_Value (H)
         then
            return UI_Eq (Local_Expr_Value (L), Local_Expr_Value (H));
         end if;

         return False;
      end Equal;

      ----------------
      -- Gen_Assign --
      ----------------

      function Gen_Assign
        (Ind     : Node_Id;
         Expr    : Node_Id;
         In_Loop : Boolean := False) return List_Id
       is
         function Add_Loop_Actions (Lis : List_Id) return List_Id;
         --  Collect insert_actions generated in the construction of a loop,
         --  and prepend them to the sequence of assignments to complete the
         --  eventual body of the loop.

         procedure Initialize_Array_Component
           (Arr_Comp  : Node_Id;
            Comp_Typ  : Node_Id;
            Init_Expr : Node_Id;
            Stmts     : List_Id);
         --  Perform the initialization of array component Arr_Comp with
         --  expected type Comp_Typ. Init_Expr denotes the initialization
         --  expression of the array component. All generated code is added
         --  to list Stmts.

         procedure Initialize_Ctrl_Array_Component
           (Arr_Comp  : Node_Id;
            Comp_Typ  : Entity_Id;
            Init_Expr : Node_Id;
            Stmts     : List_Id);
         --  Perform the initialization of array component Arr_Comp when its
         --  expected type Comp_Typ needs finalization actions. Init_Expr is
         --  the initialization expression of the array component. All hook-
         --  related declarations are inserted prior to aggregate N. Remaining
         --  code is added to list Stmts.

         ----------------------
         -- Add_Loop_Actions --
         ----------------------

         function Add_Loop_Actions (Lis : List_Id) return List_Id is
            Res : List_Id;

         begin
            --  Ada 2005 (AI-287): Do nothing else in case of default
            --  initialized component.

            if No (Expr) then
               return Lis;

            elsif Nkind (Parent (Expr)) = N_Component_Association
              and then Present (Loop_Actions (Parent (Expr)))
            then
               Append_List (Lis, Loop_Actions (Parent (Expr)));
               Res := Loop_Actions (Parent (Expr));
               Set_Loop_Actions (Parent (Expr), No_List);
               return Res;

            else
               return Lis;
            end if;
         end Add_Loop_Actions;

         --------------------------------
         -- Initialize_Array_Component --
         --------------------------------

         procedure Initialize_Array_Component
           (Arr_Comp  : Node_Id;
            Comp_Typ  : Node_Id;
            Init_Expr : Node_Id;
            Stmts     : List_Id)
         is
            Exceptions_OK : constant Boolean :=
                              not Restriction_Active
                                    (No_Exception_Propagation);

            Finalization_OK : constant Boolean :=
                                Present (Comp_Typ)
                                  and then Needs_Finalization (Comp_Typ);

            Full_Typ  : constant Entity_Id := Underlying_Type (Comp_Typ);
            Adj_Call  : Node_Id;
            Blk_Stmts : List_Id;
            Init_Stmt : Node_Id;

         begin
            --  Protect the initialization statements from aborts. Generate:

            --    Abort_Defer;

            if Finalization_OK and Abort_Allowed then
               if Exceptions_OK then
                  Blk_Stmts := New_List;
               else
                  Blk_Stmts := Stmts;
               end if;

               Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));

            --  Otherwise aborts are not allowed. All generated code is added
            --  directly to the input list.

            else
               Blk_Stmts := Stmts;
            end if;

            --  Initialize the array element. Generate:

            --    Arr_Comp := Init_Expr;

            --  Note that the initialization expression is replicated because
            --  it has to be reevaluated within a generated loop.

            Init_Stmt :=
              Make_OK_Assignment_Statement (Loc,
                Name       => New_Copy_Tree (Arr_Comp),
                Expression => New_Copy_Tree (Init_Expr));
            Set_No_Ctrl_Actions (Init_Stmt);

            --  If this is an aggregate for an array of arrays, each
            --  subaggregate will be expanded as well, and even with
            --  No_Ctrl_Actions the assignments of inner components will
            --  require attachment in their assignments to temporaries. These
            --  temporaries must be finalized for each subaggregate. Generate:

            --    begin
            --       Arr_Comp := Init_Expr;
            --    end;

            if Finalization_OK and then Is_Array_Type (Comp_Typ) then
               Init_Stmt :=
                 Make_Block_Statement (Loc,
                   Handled_Statement_Sequence =>
                     Make_Handled_Sequence_Of_Statements (Loc,
                       Statements => New_List (Init_Stmt)));
            end if;

            Append_To (Blk_Stmts, Init_Stmt);

            --  Adjust the tag due to a possible view conversion. Generate:

            --    Arr_Comp._tag := Full_TypP;

            if Tagged_Type_Expansion
              and then Present (Comp_Typ)
              and then Is_Tagged_Type (Comp_Typ)
            then
               Append_To (Blk_Stmts,
                 Make_OK_Assignment_Statement (Loc,
                   Name       =>
                     Make_Selected_Component (Loc,
                       Prefix        => New_Copy_Tree (Arr_Comp),
                       Selector_Name =>
                         New_Occurrence_Of
                           (First_Tag_Component (Full_Typ), Loc)),

                   Expression =>
                     Unchecked_Convert_To (RTE (RE_Tag),
                       New_Occurrence_Of
                         (Node (First_Elmt (Access_Disp_Table (Full_Typ))),
                          Loc))));
            end if;

            --  Adjust the array component. Controlled subaggregates are not
            --  considered because each of their individual elements will
            --  receive an adjustment of its own. Generate:

            --    [Deep_]Adjust (Arr_Comp);

            if Finalization_OK
              and then not Is_Limited_Type (Comp_Typ)
              and then not Is_Build_In_Place_Function_Call (Init_Expr)
              and then not
                (Is_Array_Type (Comp_Typ)
                  and then Is_Controlled (Component_Type (Comp_Typ))
                  and then Nkind (Expr) = N_Aggregate)
            then
               Adj_Call :=
                 Make_Adjust_Call
                   (Obj_Ref => New_Copy_Tree (Arr_Comp),
                    Typ     => Comp_Typ);

               --  Guard against a missing [Deep_]Adjust when the component
               --  type was not frozen properly.

               if Present (Adj_Call) then
                  Append_To (Blk_Stmts, Adj_Call);
               end if;
            end if;

            --  Complete the protection of the initialization statements

            if Finalization_OK and Abort_Allowed then

               --  Wrap the initialization statements in a block to catch a
               --  potential exception. Generate:

               --    begin
               --       Abort_Defer;
               --       Arr_Comp := Init_Expr;
               --       Arr_Comp._tag := Full_TypP;
               --       [Deep_]Adjust (Arr_Comp);
               --    at end
               --       Abort_Undefer_Direct;
               --    end;

               if Exceptions_OK then
                  Append_To (Stmts,
                    Build_Abort_Undefer_Block (Loc,
                      Stmts   => Blk_Stmts,
                      Context => N));

               --  Otherwise exceptions are not propagated. Generate:

               --    Abort_Defer;
               --    Arr_Comp := Init_Expr;
               --    Arr_Comp._tag := Full_TypP;
               --    [Deep_]Adjust (Arr_Comp);
               --    Abort_Undefer;

               else
                  Append_To (Blk_Stmts,
                    Build_Runtime_Call (Loc, RE_Abort_Undefer));
               end if;
            end if;
         end Initialize_Array_Component;

         -------------------------------------
         -- Initialize_Ctrl_Array_Component --
         -------------------------------------

         procedure Initialize_Ctrl_Array_Component
           (Arr_Comp  : Node_Id;
            Comp_Typ  : Entity_Id;
            Init_Expr : Node_Id;
            Stmts     : List_Id)
         is
            Act_Aggr   : Node_Id;
            Act_Stmts  : List_Id;
            Expr       : Node_Id;
            Fin_Call   : Node_Id;
            Hook_Clear : Node_Id;

            In_Place_Expansion : Boolean;
            --  Flag set when a nonlimited controlled function call requires
            --  in-place expansion.

         begin
            --  Duplicate the initialization expression in case the context is
            --  a multi choice list or an "others" choice which plugs various
            --  holes in the aggregate. As a result the expression is no longer
            --  shared between the various components and is reevaluated for
            --  each such component.

            Expr := New_Copy_Tree (Init_Expr);
            Set_Parent (Expr, Parent (Init_Expr));

            --  Perform a preliminary analysis and resolution to determine what
            --  the initialization expression denotes. An unanalyzed function
            --  call may appear as an identifier or an indexed component.

            if Nkind (Expr) in N_Function_Call
                             | N_Identifier
                             | N_Indexed_Component
              and then not Analyzed (Expr)
            then
               Preanalyze_And_Resolve (Expr, Comp_Typ);
            end if;

            In_Place_Expansion :=
              Nkind (Expr) = N_Function_Call
                and then not Is_Build_In_Place_Result_Type (Comp_Typ);

            --  The initialization expression is a controlled function call.
            --  Perform in-place removal of side effects to avoid creating a
            --  transient scope, which leads to premature finalization.

            --  This in-place expansion is not performed for limited transient
            --  objects, because the initialization is already done in place.

            if In_Place_Expansion then

               --  Suppress the removal of side effects by general analysis,
               --  because this behavior is emulated here. This avoids the
               --  generation of a transient scope, which leads to out-of-order
               --  adjustment and finalization.

               Set_No_Side_Effect_Removal (Expr);

               --  When the transient component initialization is related to a
               --  range or an "others", keep all generated statements within
               --  the enclosing loop. This way the controlled function call
               --  will be evaluated at each iteration, and its result will be
               --  finalized at the end of each iteration.

               if In_Loop then
                  Act_Aggr  := Empty;
                  Act_Stmts := Stmts;

               --  Otherwise this is a single component initialization. Hook-
               --  related statements are inserted prior to the aggregate.

               else
                  Act_Aggr  := N;
                  Act_Stmts := No_List;
               end if;

               --  Install all hook-related declarations and prepare the clean
               --  up statements.

               Process_Transient_Component
                 (Loc        => Loc,
                  Comp_Typ   => Comp_Typ,
                  Init_Expr  => Expr,
                  Fin_Call   => Fin_Call,
                  Hook_Clear => Hook_Clear,
                  Aggr       => Act_Aggr,
                  Stmts      => Act_Stmts);
            end if;

            --  Use the noncontrolled component initialization circuitry to
            --  assign the result of the function call to the array element.
            --  This also performs subaggregate wrapping, tag adjustment, and
            --  [deep] adjustment of the array element.

            Initialize_Array_Component
              (Arr_Comp  => Arr_Comp,
               Comp_Typ  => Comp_Typ,
               Init_Expr => Expr,
               Stmts     => Stmts);

            --  At this point the array element is fully initialized. Complete
            --  the processing of the controlled array component by finalizing
            --  the transient function result.

            if In_Place_Expansion then
               Process_Transient_Component_Completion
                 (Loc        => Loc,
                  Aggr       => N,
                  Fin_Call   => Fin_Call,
                  Hook_Clear => Hook_Clear,
                  Stmts      => Stmts);
            end if;
         end Initialize_Ctrl_Array_Component;

         --  Local variables

         Stmts : constant List_Id := New_List;

         Comp_Typ     : Entity_Id := Empty;
         Expr_Q       : Node_Id;
         Indexed_Comp : Node_Id;
         Init_Call    : Node_Id;
         New_Indexes  : List_Id;

      --  Start of processing for Gen_Assign

      begin
         if No (Indexes) then
            New_Indexes := New_List;
         else
            New_Indexes := New_Copy_List_Tree (Indexes);
         end if;

         Append_To (New_Indexes, Ind);

         if Present (Next_Index (Index)) then
            return
              Add_Loop_Actions (
                Build_Array_Aggr_Code
                  (N           => Expr,
                   Ctype       => Ctype,
                   Index       => Next_Index (Index),
                   Into        => Into,
                   Scalar_Comp => Scalar_Comp,
                   Indexes     => New_Indexes));
         end if;

         --  If we get here then we are at a bottom-level (sub-)aggregate

         Indexed_Comp :=
           Checks_Off
             (Make_Indexed_Component (Loc,
                Prefix      => New_Copy_Tree (Into),
                Expressions => New_Indexes));

         Set_Assignment_OK (Indexed_Comp);

         --  Ada 2005 (AI-287): In case of default initialized component, Expr
         --  is not present (and therefore we also initialize Expr_Q to empty).

         if No (Expr) then
            Expr_Q := Empty;
         elsif Nkind (Expr) = N_Qualified_Expression then
            Expr_Q := Expression (Expr);
         else
            Expr_Q := Expr;
         end if;

         if Present (Etype (N)) and then Etype (N) /= Any_Composite then
            Comp_Typ := Component_Type (Etype (N));
            pragma Assert (Comp_Typ = Ctype); --  AI-287

         elsif Present (Next (First (New_Indexes))) then

            --  Ada 2005 (AI-287): Do nothing in case of default initialized
            --  component because we have received the component type in
            --  the formal parameter Ctype.

            --  ??? Some assert pragmas have been added to check if this new
            --  formal can be used to replace this code in all cases.

            if Present (Expr) then

               --  This is a multidimensional array. Recover the component type
               --  from the outermost aggregate, because subaggregates do not
               --  have an assigned type.

               declare
                  P : Node_Id;

               begin
                  P := Parent (Expr);
                  while Present (P) loop
                     if Nkind (P) = N_Aggregate
                       and then Present (Etype (P))
                     then
                        Comp_Typ := Component_Type (Etype (P));
                        exit;

                     else
                        P := Parent (P);
                     end if;
                  end loop;

                  pragma Assert (Comp_Typ = Ctype); --  AI-287
               end;
            end if;
         end if;

         --  Ada 2005 (AI-287): We only analyze the expression in case of non-
         --  default initialized components (otherwise Expr_Q is not present).

         if Present (Expr_Q)
           and then Nkind (Expr_Q) in N_Aggregate | N_Extension_Aggregate
         then
            --  At this stage the Expression may not have been analyzed yet
            --  because the array aggregate code has not been updated to use
            --  the Expansion_Delayed flag and avoid analysis altogether to
            --  solve the same problem (see Resolve_Aggr_Expr). So let us do
            --  the analysis of non-array aggregates now in order to get the
            --  value of Expansion_Delayed flag for the inner aggregate ???

            --  In the case of an iterated component association, the analysis
            --  of the generated loop will analyze the expression in the
            --  proper context, in which the loop parameter is visible.

            if Present (Comp_Typ) and then not Is_Array_Type (Comp_Typ) then
               if Nkind (Parent (Expr_Q)) = N_Iterated_Component_Association
                 or else Nkind (Parent (Parent ((Expr_Q)))) =
                           N_Iterated_Component_Association
               then
                  null;
               else
                  Analyze_And_Resolve (Expr_Q, Comp_Typ);
               end if;
            end if;

            if Is_Delayed_Aggregate (Expr_Q) then

               --  This is either a subaggregate of a multidimensional array,
               --  or a component of an array type whose component type is
               --  also an array. In the latter case, the expression may have
               --  component associations that provide different bounds from
               --  those of the component type, and sliding must occur. Instead
               --  of decomposing the current aggregate assignment, force the
               --  reanalysis of the assignment, so that a temporary will be
               --  generated in the usual fashion, and sliding will take place.

               if Nkind (Parent (N)) = N_Assignment_Statement
                 and then Is_Array_Type (Comp_Typ)
                 and then Present (Component_Associations (Expr_Q))
                 and then Must_Slide (N, Comp_Typ, Etype (Expr_Q))
               then
                  Set_Expansion_Delayed (Expr_Q, False);
                  Set_Analyzed (Expr_Q, False);

               else
                  return
                    Add_Loop_Actions (
                      Late_Expansion (Expr_Q, Etype (Expr_Q), Indexed_Comp));
               end if;
            end if;
         end if;

         if Present (Expr) then

            --  Handle an initialization expression of a controlled type in
            --  case it denotes a function call. In general such a scenario
            --  will produce a transient scope, but this will lead to wrong
            --  order of initialization, adjustment, and finalization in the
            --  context of aggregates.

            --    Target (1) := Ctrl_Func_Call;

            --    begin                                  --  scope
            --       Trans_Obj : ... := Ctrl_Func_Call;  --  object
            --       Target (1) := Trans_Obj;
            --       Finalize (Trans_Obj);
            --    end;
            --    Target (1)._tag := ...;
            --    Adjust (Target (1));

            --  In the example above, the call to Finalize occurs too early
            --  and as a result it may leave the array component in a bad
            --  state. Finalization of the transient object should really
            --  happen after adjustment.

            --  To avoid this scenario, perform in-place side-effect removal
            --  of the function call. This eliminates the transient property
            --  of the function result and ensures correct order of actions.

            --    Res : ... := Ctrl_Func_Call;
            --    Target (1) := Res;
            --    Target (1)._tag := ...;
            --    Adjust (Target (1));
            --    Finalize (Res);

            if Present (Comp_Typ)
              and then Needs_Finalization (Comp_Typ)
              and then Nkind (Expr) /= N_Aggregate
            then
               Initialize_Ctrl_Array_Component
                 (Arr_Comp  => Indexed_Comp,
                  Comp_Typ  => Comp_Typ,
                  Init_Expr => Expr,
                  Stmts     => Stmts);

            --  Otherwise perform simple component initialization

            else
               Initialize_Array_Component
                 (Arr_Comp  => Indexed_Comp,
                  Comp_Typ  => Comp_Typ,
                  Init_Expr => Expr,
                  Stmts     => Stmts);
            end if;

         --  Ada 2005 (AI-287): In case of default initialized component, call
         --  the initialization subprogram associated with the component type.
         --  If the component type is an access type, add an explicit null
         --  assignment, because for the back-end there is an initialization
         --  present for the whole aggregate, and no default initialization
         --  will take place.

         --  In addition, if the component type is controlled, we must call
         --  its Initialize procedure explicitly, because there is no explicit
         --  object creation that will invoke it otherwise.

         else
            if Present (Base_Init_Proc (Base_Type (Ctype)))
              or else Has_Task (Base_Type (Ctype))
            then
               Append_List_To (Stmts,
                 Build_Initialization_Call (Loc,
                   Id_Ref            => Indexed_Comp,
                   Typ               => Ctype,
                   With_Default_Init => True));

               --  If the component type has invariants, add an invariant
               --  check after the component is default-initialized. It will
               --  be analyzed and resolved before the code for initialization
               --  of other components.

               if Has_Invariants (Ctype) then
                  Set_Etype (Indexed_Comp, Ctype);
                  Append_To (Stmts, Make_Invariant_Call (Indexed_Comp));
               end if;

            elsif Is_Access_Type (Ctype) then
               Append_To (Stmts,
                 Make_Assignment_Statement (Loc,
                   Name       => New_Copy_Tree (Indexed_Comp),
                   Expression => Make_Null (Loc)));
            end if;

            if Needs_Finalization (Ctype) then
               Init_Call :=
                 Make_Init_Call
                   (Obj_Ref => New_Copy_Tree (Indexed_Comp),
                    Typ     => Ctype);

               --  Guard against a missing [Deep_]Initialize when the component
               --  type was not properly frozen.

               if Present (Init_Call) then
                  Append_To (Stmts, Init_Call);
               end if;
            end if;

            --  If Default_Initial_Condition applies to the component type,
            --  add a DIC check after the component is default-initialized,
            --  as well as after an Initialize procedure is called, in the
            --  case of components of a controlled type. It will be analyzed
            --  and resolved before the code for initialization of other
            --  components.

            --  Theoretically this might also be needed for cases where Expr
            --  is not empty, but a default init still applies, such as for
            --  Default_Value cases, in which case we won't get here. ???

            if Has_DIC (Ctype) and then Present (DIC_Procedure (Ctype)) then
               Append_To (Stmts,
                 Build_DIC_Call (Loc, New_Copy_Tree (Indexed_Comp), Ctype));
            end if;
         end if;

         return Add_Loop_Actions (Stmts);
      end Gen_Assign;

      --------------
      -- Gen_Loop --
      --------------

      function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id is
         Is_Iterated_Component : constant Boolean :=
           Parent_Kind (Expr) = N_Iterated_Component_Association;

         L_J : Node_Id;

         L_L : Node_Id;
         --  Index_Base'(L)

         L_H : Node_Id;
         --  Index_Base'(H)

         L_Range : Node_Id;
         --  Index_Base'(L) .. Index_Base'(H)

         L_Iteration_Scheme : Node_Id;
         --  L_J in Index_Base'(L) .. Index_Base'(H)

         L_Body : List_Id;
         --  The statements to execute in the loop

         S : constant List_Id := New_List;
         --  List of statements

         Tcopy : Node_Id;
         --  Copy of expression tree, used for checking purposes

      begin
         --  If loop bounds define an empty range return the null statement

         if Empty_Range (L, H) then
            Append_To (S, Make_Null_Statement (Loc));

            --  Ada 2005 (AI-287): Nothing else need to be done in case of
            --  default initialized component.

            if No (Expr) then
               null;

            else
               --  The expression must be type-checked even though no component
               --  of the aggregate will have this value. This is done only for
               --  actual components of the array, not for subaggregates. Do
               --  the check on a copy, because the expression may be shared
               --  among several choices, some of which might be non-null.

               if Present (Etype (N))
                 and then Is_Array_Type (Etype (N))
                 and then No (Next_Index (Index))
               then
                  Expander_Mode_Save_And_Set (False);
                  Tcopy := New_Copy_Tree (Expr);
                  Set_Parent (Tcopy, N);

                  --  For iterated_component_association analyze and resolve
                  --  the expression with name of the index parameter visible.
                  --  To manipulate scopes, we use entity of the implicit loop.

                  if Is_Iterated_Component then
                     declare
                        Index_Parameter : constant Entity_Id :=
                          Defining_Identifier (Parent (Expr));
                     begin
                        Push_Scope (Scope (Index_Parameter));
                        Enter_Name (Index_Parameter);
                        Analyze_And_Resolve
                          (Tcopy, Component_Type (Etype (N)));
                        End_Scope;
                     end;

                  --  For ordinary component association, just analyze and
                  --  resolve the expression.

                  else
                     Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
                  end if;

                  Expander_Mode_Restore;
               end if;
            end if;

            return S;

         --  If loop bounds are the same then generate an assignment, unless
         --  the parent construct is an Iterated_Component_Association.

         elsif Equal (L, H) and then not Is_Iterated_Component then
            return Gen_Assign (New_Copy_Tree (L), Expr);

         --  If H - L <= 2 then generate a sequence of assignments when we are
         --  processing the bottom most aggregate and it contains scalar
         --  components.

         elsif No (Next_Index (Index))
           and then Scalar_Comp
           and then Local_Compile_Time_Known_Value (L)
           and then Local_Compile_Time_Known_Value (H)
           and then Local_Expr_Value (H) - Local_Expr_Value (L) <= 2
           and then not Is_Iterated_Component
         then
            Append_List_To (S, Gen_Assign (New_Copy_Tree (L), Expr));
            Append_List_To (S, Gen_Assign (Add (1, To => L), Expr));

            if Local_Expr_Value (H) - Local_Expr_Value (L) = 2 then
               Append_List_To (S, Gen_Assign (Add (2, To => L), Expr));
            end if;

            return S;
         end if;

         --  Otherwise construct the loop, starting with the loop index L_J

         if Is_Iterated_Component then
            L_J :=
              Make_Defining_Identifier (Loc,
                Chars => (Chars (Defining_Identifier (Parent (Expr)))));

         else
            L_J := Make_Temporary (Loc, 'J', L);
         end if;

         --  Construct "L .. H" in Index_Base. We use a qualified expression
         --  for the bound to convert to the index base, but we don't need
         --  to do that if we already have the base type at hand.

         if Etype (L) = Index_Base then
            L_L := L;
         else
            L_L :=
              Make_Qualified_Expression (Loc,
                Subtype_Mark => Index_Base_Name,
                Expression   => New_Copy_Tree (L));
         end if;

         if Etype (H) = Index_Base then
            L_H := H;
         else
            L_H :=
              Make_Qualified_Expression (Loc,
                Subtype_Mark => Index_Base_Name,
                Expression   => New_Copy_Tree (H));
         end if;

         L_Range :=
           Make_Range (Loc,
             Low_Bound  => L_L,
             High_Bound => L_H);

         --  Construct "for L_J in Index_Base range L .. H"

         L_Iteration_Scheme :=
           Make_Iteration_Scheme
             (Loc,
              Loop_Parameter_Specification =>
                Make_Loop_Parameter_Specification
                  (Loc,
                   Defining_Identifier         => L_J,
                   Discrete_Subtype_Definition => L_Range));

         --  Construct the statements to execute in the loop body

         L_Body :=
           Gen_Assign (New_Occurrence_Of (L_J, Loc), Expr, In_Loop => True);

         --  Construct the final loop

         Append_To (S,
           Make_Implicit_Loop_Statement
             (Node             => N,
              Identifier       => Empty,
              Iteration_Scheme => L_Iteration_Scheme,
              Statements       => L_Body));

         --  A small optimization: if the aggregate is initialized with a box
         --  and the component type has no initialization procedure, remove the
         --  useless empty loop.

         if Nkind (First (S)) = N_Loop_Statement
           and then Is_Empty_List (Statements (First (S)))
         then
            return New_List (Make_Null_Statement (Loc));
         else
            return S;
         end if;
      end Gen_Loop;

      ---------------
      -- Gen_While --
      ---------------

      --  The code built is

      --     W_J : Index_Base := L;
      --     while W_J < H loop
      --        W_J := Index_Base'Succ (W);
      --        L_Body;
      --     end loop;

      function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
         W_J : Node_Id;

         W_Decl : Node_Id;
         --  W_J : Base_Type := L;

         W_Iteration_Scheme : Node_Id;
         --  while W_J < H

         W_Index_Succ : Node_Id;
         --  Index_Base'Succ (J)

         W_Increment : Node_Id;
         --  W_J := Index_Base'Succ (W)

         W_Body : constant List_Id := New_List;
         --  The statements to execute in the loop

         S : constant List_Id := New_List;
         --  list of statement

      begin
         --  If loop bounds define an empty range or are equal return null

         if Empty_Range (L, H) or else Equal (L, H) then
            Append_To (S, Make_Null_Statement (Loc));
            return S;
         end if;

         --  Build the decl of W_J

         W_J    := Make_Temporary (Loc, 'J', L);
         W_Decl :=
           Make_Object_Declaration
             (Loc,
              Defining_Identifier => W_J,
              Object_Definition   => Index_Base_Name,
              Expression          => L);

         --  Theoretically we should do a New_Copy_Tree (L) here, but we know
         --  that in this particular case L is a fresh Expr generated by
         --  Add which we are the only ones to use.

         Append_To (S, W_Decl);

         --  Construct " while W_J < H"

         W_Iteration_Scheme :=
           Make_Iteration_Scheme
             (Loc,
              Condition => Make_Op_Lt
                             (Loc,
                              Left_Opnd  => New_Occurrence_Of (W_J, Loc),
                              Right_Opnd => New_Copy_Tree (H)));

         --  Construct the statements to execute in the loop body

         W_Index_Succ :=
           Make_Attribute_Reference
             (Loc,
              Prefix         => Index_Base_Name,
              Attribute_Name => Name_Succ,
              Expressions    => New_List (New_Occurrence_Of (W_J, Loc)));

         W_Increment  :=
           Make_OK_Assignment_Statement
             (Loc,
              Name       => New_Occurrence_Of (W_J, Loc),
              Expression => W_Index_Succ);

         Append_To (W_Body, W_Increment);

         Append_List_To (W_Body,
           Gen_Assign (New_Occurrence_Of (W_J, Loc), Expr, In_Loop => True));

         --  Construct the final loop

         Append_To (S,
           Make_Implicit_Loop_Statement
             (Node             => N,
              Identifier       => Empty,
              Iteration_Scheme => W_Iteration_Scheme,
              Statements       => W_Body));

         return S;
      end Gen_While;

      --------------------
      -- Get_Assoc_Expr --
      --------------------

      function Get_Assoc_Expr (Assoc : Node_Id) return Node_Id is
         Typ : constant Entity_Id := Base_Type (Etype (N));

      begin
         if Box_Present (Assoc) then
            if Is_Scalar_Type (Ctype) then
               if Present (Default_Aspect_Component_Value (Typ)) then
                  return Default_Aspect_Component_Value (Typ);
               elsif Present (Default_Aspect_Value (Ctype)) then
                  return Default_Aspect_Value (Ctype);
               else
                  return Empty;
               end if;

            else
               return Empty;
            end if;

         else
            return Expression (Assoc);
         end if;
      end Get_Assoc_Expr;

      ---------------------
      -- Index_Base_Name --
      ---------------------

      function Index_Base_Name return Node_Id is
      begin
         return New_Occurrence_Of (Index_Base, Sloc (N));
      end Index_Base_Name;

      ------------------------------------
      -- Local_Compile_Time_Known_Value --
      ------------------------------------

      function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean is
      begin
         return Compile_Time_Known_Value (E)
           or else
             (Nkind (E) = N_Attribute_Reference
               and then Attribute_Name (E) = Name_Val
               and then Compile_Time_Known_Value (First (Expressions (E))));
      end Local_Compile_Time_Known_Value;

      ----------------------
      -- Local_Expr_Value --
      ----------------------

      function Local_Expr_Value (E : Node_Id) return Uint is
      begin
         if Compile_Time_Known_Value (E) then
            return Expr_Value (E);
         else
            return Expr_Value (First (Expressions (E)));
         end if;
      end Local_Expr_Value;

      --  Local variables

      New_Code : constant List_Id := New_List;

      Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
      Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
      --  The aggregate bounds of this specific subaggregate. Note that if the
      --  code generated by Build_Array_Aggr_Code is executed then these bounds
      --  are OK. Otherwise a Constraint_Error would have been raised.

      Aggr_Low  : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_L);
      Aggr_High : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_H);
      --  After Duplicate_Subexpr these are side-effect free

      Assoc  : Node_Id;
      Choice : Node_Id;
      Expr   : Node_Id;
      Typ    : Entity_Id;

      Bounds : Range_Nodes;
      Low    : Node_Id renames Bounds.First;
      High   : Node_Id renames Bounds.Last;

      Nb_Choices : Nat := 0;
      Table      : Case_Table_Type (1 .. Number_Of_Choices (N));
      --  Used to sort all the different choice values

      Nb_Elements : Int;
      --  Number of elements in the positional aggregate

      Others_Assoc : Node_Id := Empty;

   --  Start of processing for Build_Array_Aggr_Code

   begin
      --  First before we start, a special case. if we have a bit packed
      --  array represented as a modular type, then clear the value to
      --  zero first, to ensure that unused bits are properly cleared.

      Typ := Etype (N);

      if Present (Typ)
        and then Is_Bit_Packed_Array (Typ)
        and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ))
      then
         declare
            Zero : constant Node_Id := Make_Integer_Literal (Loc, Uint_0);
         begin
            Analyze_And_Resolve (Zero, Packed_Array_Impl_Type (Typ));
            Append_To (New_Code,
              Make_Assignment_Statement (Loc,
                Name       => New_Copy_Tree (Into),
                Expression => Unchecked_Convert_To (Typ, Zero)));
         end;
      end if;

      --  If the component type contains tasks, we need to build a Master
      --  entity in the current scope, because it will be needed if build-
      --  in-place functions are called in the expanded code.

      if Nkind (Parent (N)) = N_Object_Declaration and then Has_Task (Typ) then
         Build_Master_Entity (Defining_Identifier (Parent (N)));
      end if;

      --  STEP 1: Process component associations

      --  For those associations that may generate a loop, initialize
      --  Loop_Actions to collect inserted actions that may be crated.

      --  Skip this if no component associations

      if No (Expressions (N)) then

         --  STEP 1 (a): Sort the discrete choices

         Assoc := First (Component_Associations (N));
         while Present (Assoc) loop
            Choice := First (Choice_List (Assoc));
            while Present (Choice) loop
               if Nkind (Choice) = N_Others_Choice then
                  Others_Assoc := Assoc;
                  exit;
               end if;

               Bounds := Get_Index_Bounds (Choice);

               if Low /= High then
                  Set_Loop_Actions (Assoc, New_List);
               end if;

               Nb_Choices := Nb_Choices + 1;

               Table (Nb_Choices) :=
                  (Choice_Lo   => Low,
                   Choice_Hi   => High,
                   Choice_Node => Get_Assoc_Expr (Assoc));

               Next (Choice);
            end loop;

            Next (Assoc);
         end loop;

         --  If there is more than one set of choices these must be static
         --  and we can therefore sort them. Remember that Nb_Choices does not
         --  account for an others choice.

         if Nb_Choices > 1 then
            Sort_Case_Table (Table);
         end if;

         --  STEP 1 (b): take care of the whole set of discrete choices

         for J in 1 .. Nb_Choices loop
            Low  := Table (J).Choice_Lo;
            High := Table (J).Choice_Hi;
            Expr := Table (J).Choice_Node;
            Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
         end loop;

         --  STEP 1 (c): generate the remaining loops to cover others choice
         --  We don't need to generate loops over empty gaps, but if there is
         --  a single empty range we must analyze the expression for semantics

         if Present (Others_Assoc) then
            declare
               First    : Boolean := True;
               Dup_Expr : Node_Id;

            begin
               for J in 0 .. Nb_Choices loop
                  if J = 0 then
                     Low := Aggr_Low;
                  else
                     Low := Add (1, To => Table (J).Choice_Hi);
                  end if;

                  if J = Nb_Choices then
                     High := Aggr_High;
                  else
                     High := Add (-1, To => Table (J + 1).Choice_Lo);
                  end if;

                  --  If this is an expansion within an init proc, make
                  --  sure that discriminant references are replaced by
                  --  the corresponding discriminal.

                  if Inside_Init_Proc then
                     if Is_Entity_Name (Low)
                       and then Ekind (Entity (Low)) = E_Discriminant
                     then
                        Set_Entity (Low, Discriminal (Entity (Low)));
                     end if;

                     if Is_Entity_Name (High)
                       and then Ekind (Entity (High)) = E_Discriminant
                     then
                        Set_Entity (High, Discriminal (Entity (High)));
                     end if;
                  end if;

                  if First
                    or else not Empty_Range (Low, High)
                  then
                     First := False;

                     --  Duplicate the expression in case we will be generating
                     --  several loops. As a result the expression is no longer
                     --  shared between the loops and is reevaluated for each
                     --  such loop.

                     Expr := Get_Assoc_Expr (Others_Assoc);
                     Dup_Expr := New_Copy_Tree (Expr);
                     Copy_Parent (To => Dup_Expr, From => Expr);

                     Set_Loop_Actions (Others_Assoc, New_List);
                     Append_List
                       (Gen_Loop (Low, High, Dup_Expr), To => New_Code);
                  end if;
               end loop;
            end;
         end if;

      --  STEP 2: Process positional components

      else
         --  STEP 2 (a): Generate the assignments for each positional element
         --  Note that here we have to use Aggr_L rather than Aggr_Low because
         --  Aggr_L is analyzed and Add wants an analyzed expression.

         Expr        := First (Expressions (N));
         Nb_Elements := -1;
         while Present (Expr) loop
            Nb_Elements := Nb_Elements + 1;
            Append_List (Gen_Assign (Add (Nb_Elements, To => Aggr_L), Expr),
                         To => New_Code);
            Next (Expr);
         end loop;

         --  STEP 2 (b): Generate final loop if an others choice is present.
         --  Here Nb_Elements gives the offset of the last positional element.

         if Present (Component_Associations (N)) then
            Assoc := Last (Component_Associations (N));

            if Nkind (Assoc) = N_Iterated_Component_Association then
               --  Ada 2022: generate a loop to have a proper scope for
               --  the identifier that typically appears in the expression.
               --  The lower bound of the loop is the position after all
               --  previous positional components.

               Append_List (Gen_Loop (Add (Nb_Elements + 1, To => Aggr_L),
                                      Aggr_High,
                                      Expression (Assoc)),
                            To => New_Code);
            else
               --  Ada 2005 (AI-287)

               Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
                                       Aggr_High,
                                       Get_Assoc_Expr (Assoc)),
                            To => New_Code);
            end if;
         end if;
      end if;

      return New_Code;
   end Build_Array_Aggr_Code;

   ----------------------------
   -- Build_Record_Aggr_Code --
   ----------------------------

   function Build_Record_Aggr_Code
     (N   : Node_Id;
      Typ : Entity_Id;
      Lhs : Node_Id) return List_Id
   is
      Loc     : constant Source_Ptr := Sloc (N);
      L       : constant List_Id    := New_List;
      N_Typ   : constant Entity_Id  := Etype (N);

      Comp      : Node_Id;
      Instr     : Node_Id;
      Ref       : Node_Id;
      Target    : Entity_Id;
      Comp_Type : Entity_Id;
      Selector  : Entity_Id;
      Comp_Expr : Node_Id;
      Expr_Q    : Node_Id;

      --  If this is an internal aggregate, the External_Final_List is an
      --  expression for the controller record of the enclosing type.

      --  If the current aggregate has several controlled components, this
      --  expression will appear in several calls to attach to the finali-
      --  zation list, and it must not be shared.

      Ancestor_Is_Expression   : Boolean := False;
      Ancestor_Is_Subtype_Mark : Boolean := False;

      Init_Typ : Entity_Id := Empty;

      Finalization_Done : Boolean := False;
      --  True if Generate_Finalization_Actions has already been called; calls
      --  after the first do nothing.

      function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id;
      --  Returns the value that the given discriminant of an ancestor type
      --  should receive (in the absence of a conflict with the value provided
      --  by an ancestor part of an extension aggregate).

      procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id);
      --  Check that each of the discriminant values defined by the ancestor
      --  part of an extension aggregate match the corresponding values
      --  provided by either an association of the aggregate or by the
      --  constraint imposed by a parent type (RM95-4.3.2(8)).

      function Compatible_Int_Bounds
        (Agg_Bounds : Node_Id;
         Typ_Bounds : Node_Id) return Boolean;
      --  Return true if Agg_Bounds are equal or within Typ_Bounds. It is
      --  assumed that both bounds are integer ranges.

      procedure Generate_Finalization_Actions;
      --  Deal with the various controlled type data structure initializations
      --  (but only if it hasn't been done already).

      function Get_Constraint_Association (T : Entity_Id) return Node_Id;
      --  Returns the first discriminant association in the constraint
      --  associated with T, if any, otherwise returns Empty.

      function Get_Explicit_Discriminant_Value (D : Entity_Id) return Node_Id;
      --  If the ancestor part is an unconstrained type and further ancestors
      --  do not provide discriminants for it, check aggregate components for
      --  values of the discriminants.

      procedure Init_Hidden_Discriminants (Typ : Entity_Id; List : List_Id);
      --  If Typ is derived, and constrains discriminants of the parent type,
      --  these discriminants are not components of the aggregate, and must be
      --  initialized. The assignments are appended to List. The same is done
      --  if Typ derives fron an already constrained subtype of a discriminated
      --  parent type.

      procedure Init_Stored_Discriminants;
      --  If the type is derived and has inherited discriminants, generate
      --  explicit assignments for each, using the store constraint of the
      --  type. Note that both visible and stored discriminants must be
      --  initialized in case the derived type has some renamed and some
      --  constrained discriminants.

      procedure Init_Visible_Discriminants;
      --  If type has discriminants, retrieve their values from aggregate,
      --  and generate explicit assignments for each. This does not include
      --  discriminants inherited from ancestor, which are handled above.
      --  The type of the aggregate is a subtype created ealier using the
      --  given values of the discriminant components of the aggregate.

      procedure Initialize_Ctrl_Record_Component
        (Rec_Comp  : Node_Id;
         Comp_Typ  : Entity_Id;
         Init_Expr : Node_Id;
         Stmts     : List_Id);
      --  Perform the initialization of controlled record component Rec_Comp.
      --  Comp_Typ is the component type. Init_Expr is the initialization
      --  expression for the record component. Hook-related declarations are
      --  inserted prior to aggregate N using Insert_Action. All remaining
      --  generated code is added to list Stmts.

      procedure Initialize_Record_Component
        (Rec_Comp  : Node_Id;
         Comp_Typ  : Entity_Id;
         Init_Expr : Node_Id;
         Stmts     : List_Id);
      --  Perform the initialization of record component Rec_Comp. Comp_Typ
      --  is the component type. Init_Expr is the initialization expression
      --  of the record component. All generated code is added to list Stmts.

      function Is_Int_Range_Bounds (Bounds : Node_Id) return Boolean;
      --  Check whether Bounds is a range node and its lower and higher bounds
      --  are integers literals.

      function Replace_Type (Expr : Node_Id) return Traverse_Result;
      --  If the aggregate contains a self-reference, traverse each expression
      --  to replace a possible self-reference with a reference to the proper
      --  component of the target of the assignment.

      function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result;
      --  If default expression of a component mentions a discriminant of the
      --  type, it must be rewritten as the discriminant of the target object.

      ---------------------------------
      -- Ancestor_Discriminant_Value --
      ---------------------------------

      function Ancestor_Discriminant_Value (Disc : Entity_Id) return Node_Id is
         Assoc        : Node_Id;
         Assoc_Elmt   : Elmt_Id;
         Aggr_Comp    : Entity_Id;
         Corresp_Disc : Entity_Id;
         Current_Typ  : Entity_Id := Base_Type (Typ);
         Parent_Typ   : Entity_Id;
         Parent_Disc  : Entity_Id;
         Save_Assoc   : Node_Id := Empty;

      begin
         --  First check any discriminant associations to see if any of them
         --  provide a value for the discriminant.

         if Present (Discriminant_Specifications (Parent (Current_Typ))) then
            Assoc := First (Component_Associations (N));
            while Present (Assoc) loop
               Aggr_Comp := Entity (First (Choices (Assoc)));

               if Ekind (Aggr_Comp) = E_Discriminant then
                  Save_Assoc := Expression (Assoc);

                  Corresp_Disc := Corresponding_Discriminant (Aggr_Comp);
                  while Present (Corresp_Disc) loop

                     --  If found a corresponding discriminant then return the
                     --  value given in the aggregate. (Note: this is not
                     --  correct in the presence of side effects. ???)

                     if Disc = Corresp_Disc then
                        return Duplicate_Subexpr (Expression (Assoc));
                     end if;

                     Corresp_Disc := Corresponding_Discriminant (Corresp_Disc);
                  end loop;
               end if;

               Next (Assoc);
            end loop;
         end if;

         --  No match found in aggregate, so chain up parent types to find
         --  a constraint that defines the value of the discriminant.

         Parent_Typ := Etype (Current_Typ);
         while Current_Typ /= Parent_Typ loop
            if Has_Discriminants (Parent_Typ)
              and then not Has_Unknown_Discriminants (Parent_Typ)
            then
               Parent_Disc := First_Discriminant (Parent_Typ);

               --  We either get the association from the subtype indication
               --  of the type definition itself, or from the discriminant
               --  constraint associated with the type entity (which is
               --  preferable, but it's not always present ???)

               if Is_Empty_Elmt_List (Discriminant_Constraint (Current_Typ))
               then
                  Assoc := Get_Constraint_Association (Current_Typ);
                  Assoc_Elmt := No_Elmt;
               else
                  Assoc_Elmt :=
                    First_Elmt (Discriminant_Constraint (Current_Typ));
                  Assoc := Node (Assoc_Elmt);
               end if;

               --  Traverse the discriminants of the parent type looking
               --  for one that corresponds.

               while Present (Parent_Disc) and then Present (Assoc) loop
                  Corresp_Disc := Parent_Disc;
                  while Present (Corresp_Disc)
                    and then Disc /= Corresp_Disc
                  loop
                     Corresp_Disc := Corresponding_Discriminant (Corresp_Disc);
                  end loop;

                  if Disc = Corresp_Disc then
                     if Nkind (Assoc) = N_Discriminant_Association then
                        Assoc := Expression (Assoc);
                     end if;

                     --  If the located association directly denotes
                     --  a discriminant, then use the value of a saved
                     --  association of the aggregate. This is an approach
                     --  used to handle certain cases involving multiple
                     --  discriminants mapped to a single discriminant of
                     --  a descendant. It's not clear how to locate the
                     --  appropriate discriminant value for such cases. ???

                     if Is_Entity_Name (Assoc)
                       and then Ekind (Entity (Assoc)) = E_Discriminant
                     then
                        Assoc := Save_Assoc;
                     end if;

                     return Duplicate_Subexpr (Assoc);
                  end if;

                  Next_Discriminant (Parent_Disc);

                  if No (Assoc_Elmt) then
                     Next (Assoc);

                  else
                     Next_Elmt (Assoc_Elmt);

                     if Present (Assoc_Elmt) then
                        Assoc := Node (Assoc_Elmt);
                     else
                        Assoc := Empty;
                     end if;
                  end if;
               end loop;
            end if;

            Current_Typ := Parent_Typ;
            Parent_Typ := Etype (Current_Typ);
         end loop;

         --  In some cases there's no ancestor value to locate (such as
         --  when an ancestor part given by an expression defines the
         --  discriminant value).

         return Empty;
      end Ancestor_Discriminant_Value;

      ----------------------------------
      -- Check_Ancestor_Discriminants --
      ----------------------------------

      procedure Check_Ancestor_Discriminants (Anc_Typ : Entity_Id) is
         Discr      : Entity_Id;
         Disc_Value : Node_Id;
         Cond       : Node_Id;

      begin
         Discr := First_Discriminant (Base_Type (Anc_Typ));
         while Present (Discr) loop
            Disc_Value := Ancestor_Discriminant_Value (Discr);

            if Present (Disc_Value) then
               Cond := Make_Op_Ne (Loc,
                 Left_Opnd  =>
                   Make_Selected_Component (Loc,
                     Prefix        => New_Copy_Tree (Target),
                     Selector_Name => New_Occurrence_Of (Discr, Loc)),
                 Right_Opnd => Disc_Value);

               Append_To (L,
                 Make_Raise_Constraint_Error (Loc,
                   Condition => Cond,
                   Reason    => CE_Discriminant_Check_Failed));
            end if;

            Next_Discriminant (Discr);
         end loop;
      end Check_Ancestor_Discriminants;

      ---------------------------
      -- Compatible_Int_Bounds --
      ---------------------------

      function Compatible_Int_Bounds
        (Agg_Bounds : Node_Id;
         Typ_Bounds : Node_Id) return Boolean
      is
         Agg_Lo : constant Uint := Intval (Low_Bound  (Agg_Bounds));
         Agg_Hi : constant Uint := Intval (High_Bound (Agg_Bounds));
         Typ_Lo : constant Uint := Intval (Low_Bound  (Typ_Bounds));
         Typ_Hi : constant Uint := Intval (High_Bound (Typ_Bounds));
      begin
         return Typ_Lo <= Agg_Lo and then Agg_Hi <= Typ_Hi;
      end Compatible_Int_Bounds;

      -----------------------------------
      -- Generate_Finalization_Actions --
      -----------------------------------

      procedure Generate_Finalization_Actions is
      begin
         --  Do the work only the first time this is called

         if Finalization_Done then
            return;
         end if;

         Finalization_Done := True;

         --  Determine the external finalization list. It is either the
         --  finalization list of the outer scope or the one coming from an
         --  outer aggregate. When the target is not a temporary, the proper
         --  scope is the scope of the target rather than the potentially
         --  transient current scope.

         if Is_Controlled (Typ) and then Ancestor_Is_Subtype_Mark then
            Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
            Set_Assignment_OK (Ref);

            Append_To (L,
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of
                    (Find_Prim_Op (Init_Typ, Name_Initialize), Loc),
                Parameter_Associations => New_List (New_Copy_Tree (Ref))));
         end if;
      end Generate_Finalization_Actions;

      --------------------------------
      -- Get_Constraint_Association --
      --------------------------------

      function Get_Constraint_Association (T : Entity_Id) return Node_Id is
         Indic : Node_Id;
         Typ   : Entity_Id;

      begin
         Typ := T;

         --  If type is private, get constraint from full view. This was
         --  previously done in an instance context, but is needed whenever
         --  the ancestor part has a discriminant, possibly inherited through
         --  multiple derivations.

         if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
            Typ := Full_View (Typ);
         end if;

         Indic := Subtype_Indication (Type_Definition (Parent (Typ)));

         --  Verify that the subtype indication carries a constraint

         if Nkind (Indic) = N_Subtype_Indication
           and then Present (Constraint (Indic))
         then
            return First (Constraints (Constraint (Indic)));
         end if;

         return Empty;
      end Get_Constraint_Association;

      -------------------------------------
      -- Get_Explicit_Discriminant_Value --
      -------------------------------------

      function Get_Explicit_Discriminant_Value
        (D : Entity_Id) return Node_Id
      is
         Assoc  : Node_Id;
         Choice : Node_Id;
         Val    : Node_Id;

      begin
         --  The aggregate has been normalized and all associations have a
         --  single choice.

         Assoc := First (Component_Associations (N));
         while Present (Assoc) loop
            Choice := First (Choices (Assoc));

            if Chars (Choice) = Chars (D) then
               Val := Expression (Assoc);
               Remove (Assoc);
               return Val;
            end if;

            Next (Assoc);
         end loop;

         return Empty;
      end Get_Explicit_Discriminant_Value;

      -------------------------------
      -- Init_Hidden_Discriminants --
      -------------------------------

      procedure Init_Hidden_Discriminants (Typ : Entity_Id; List : List_Id) is
         function Is_Completely_Hidden_Discriminant
           (Discr : Entity_Id) return Boolean;
         --  Determine whether Discr is a completely hidden discriminant of
         --  type Typ.

         ---------------------------------------
         -- Is_Completely_Hidden_Discriminant --
         ---------------------------------------

         function Is_Completely_Hidden_Discriminant
           (Discr : Entity_Id) return Boolean
         is
            Item : Entity_Id;

         begin
            --  Use First/Next_Entity as First/Next_Discriminant do not yield
            --  completely hidden discriminants.

            Item := First_Entity (Typ);
            while Present (Item) loop
               if Ekind (Item) = E_Discriminant
                 and then Is_Completely_Hidden (Item)
                 and then Chars (Original_Record_Component (Item)) =
                          Chars (Discr)
               then
                  return True;
               end if;

               Next_Entity (Item);
            end loop;

            return False;
         end Is_Completely_Hidden_Discriminant;

         --  Local variables

         Base_Typ     : Entity_Id;
         Discr        : Entity_Id;
         Discr_Constr : Elmt_Id;
         Discr_Init   : Node_Id;
         Discr_Val    : Node_Id;
         In_Aggr_Type : Boolean;
         Par_Typ      : Entity_Id;

      --  Start of processing for Init_Hidden_Discriminants

      begin
         --  The constraints on the hidden discriminants, if present, are kept
         --  in the Stored_Constraint list of the type itself, or in that of
         --  the base type. If not in the constraints of the aggregate itself,
         --  we examine ancestors to find discriminants that are not renamed
         --  by other discriminants but constrained explicitly.

         In_Aggr_Type := True;

         Base_Typ := Base_Type (Typ);
         while Is_Derived_Type (Base_Typ)
           and then
             (Present (Stored_Constraint (Base_Typ))
               or else
                 (In_Aggr_Type and then Present (Stored_Constraint (Typ))))
         loop
            Par_Typ := Etype (Base_Typ);

            if not Has_Discriminants (Par_Typ) then
               return;
            end if;

            Discr := First_Discriminant (Par_Typ);

            --  We know that one of the stored-constraint lists is present

            if Present (Stored_Constraint (Base_Typ)) then
               Discr_Constr := First_Elmt (Stored_Constraint (Base_Typ));

            --  For private extension, stored constraint may be on full view

            elsif Is_Private_Type (Base_Typ)
              and then Present (Full_View (Base_Typ))
              and then Present (Stored_Constraint (Full_View (Base_Typ)))
            then
               Discr_Constr :=
                 First_Elmt (Stored_Constraint (Full_View (Base_Typ)));

            --  Otherwise, no discriminant to process

            else
               Discr_Constr := No_Elmt;
            end if;

            while Present (Discr) and then Present (Discr_Constr) loop
               Discr_Val := Node (Discr_Constr);

               --  The parent discriminant is renamed in the derived type,
               --  nothing to initialize.

               --    type Deriv_Typ (Discr : ...)
               --      is new Parent_Typ (Discr => Discr);

               if Is_Entity_Name (Discr_Val)
                 and then Ekind (Entity (Discr_Val)) = E_Discriminant
               then
                  null;

               --  When the parent discriminant is constrained at the type
               --  extension level, it does not appear in the derived type.

               --    type Deriv_Typ (Discr : ...)
               --      is new Parent_Typ (Discr        => Discr,
               --                         Hidden_Discr => Expression);

               elsif Is_Completely_Hidden_Discriminant (Discr) then
                  null;

               --  Otherwise initialize the discriminant

               else
                  Discr_Init :=
                    Make_OK_Assignment_Statement (Loc,
                      Name       =>
                        Make_Selected_Component (Loc,
                          Prefix        => New_Copy_Tree (Target),
                          Selector_Name => New_Occurrence_Of (Discr, Loc)),
                      Expression => New_Copy_Tree (Discr_Val));

                  Append_To (List, Discr_Init);
               end if;

               Next_Elmt (Discr_Constr);
               Next_Discriminant (Discr);
            end loop;

            In_Aggr_Type := False;
            Base_Typ := Base_Type (Par_Typ);
         end loop;
      end Init_Hidden_Discriminants;

      --------------------------------
      -- Init_Visible_Discriminants --
      --------------------------------

      procedure Init_Visible_Discriminants is
         Discriminant       : Entity_Id;
         Discriminant_Value : Node_Id;

      begin
         Discriminant := First_Discriminant (Typ);
         while Present (Discriminant) loop
            Comp_Expr :=
              Make_Selected_Component (Loc,
                Prefix        => New_Copy_Tree (Target),
                Selector_Name => New_Occurrence_Of (Discriminant, Loc));

            Discriminant_Value :=
              Get_Discriminant_Value
                (Discriminant, Typ, Discriminant_Constraint (N_Typ));

            Instr :=
              Make_OK_Assignment_Statement (Loc,
                Name       => Comp_Expr,
                Expression => New_Copy_Tree (Discriminant_Value));

            Append_To (L, Instr);

            Next_Discriminant (Discriminant);
         end loop;
      end Init_Visible_Discriminants;

      -------------------------------
      -- Init_Stored_Discriminants --
      -------------------------------

      procedure Init_Stored_Discriminants is
         Discriminant       : Entity_Id;
         Discriminant_Value : Node_Id;

      begin
         Discriminant := First_Stored_Discriminant (Typ);
         while Present (Discriminant) loop
            Comp_Expr :=
              Make_Selected_Component (Loc,
                Prefix        => New_Copy_Tree (Target),
                Selector_Name => New_Occurrence_Of (Discriminant, Loc));

            Discriminant_Value :=
              Get_Discriminant_Value
                (Discriminant, N_Typ, Discriminant_Constraint (N_Typ));

            Instr :=
              Make_OK_Assignment_Statement (Loc,
                Name       => Comp_Expr,
                Expression => New_Copy_Tree (Discriminant_Value));

            Append_To (L, Instr);

            Next_Stored_Discriminant (Discriminant);
         end loop;
      end Init_Stored_Discriminants;

      --------------------------------------
      -- Initialize_Ctrl_Record_Component --
      --------------------------------------

      procedure Initialize_Ctrl_Record_Component
        (Rec_Comp  : Node_Id;
         Comp_Typ  : Entity_Id;
         Init_Expr : Node_Id;
         Stmts     : List_Id)
      is
         Fin_Call   : Node_Id;
         Hook_Clear : Node_Id;

         In_Place_Expansion : Boolean;
         --  Flag set when a nonlimited controlled function call requires
         --  in-place expansion.

      begin
         --  Perform a preliminary analysis and resolution to determine what
         --  the initialization expression denotes. Unanalyzed function calls
         --  may appear as identifiers or indexed components.

         if Nkind (Init_Expr) in N_Function_Call
                               | N_Identifier
                               | N_Indexed_Component
           and then not Analyzed (Init_Expr)
         then
            Preanalyze_And_Resolve (Init_Expr, Comp_Typ);
         end if;

         In_Place_Expansion :=
           Nkind (Init_Expr) = N_Function_Call
             and then not Is_Build_In_Place_Result_Type (Comp_Typ);

         --  The initialization expression is a controlled function call.
         --  Perform in-place removal of side effects to avoid creating a
         --  transient scope.

         --  This in-place expansion is not performed for limited transient
         --  objects because the initialization is already done in place.

         if In_Place_Expansion then

            --  Suppress the removal of side effects by general analysis
            --  because this behavior is emulated here. This avoids the
            --  generation of a transient scope, which leads to out-of-order
            --  adjustment and finalization.

            Set_No_Side_Effect_Removal (Init_Expr);

            --  Install all hook-related declarations and prepare the clean up
            --  statements. The generated code follows the initialization order
            --  of individual components and discriminants, rather than being
            --  inserted prior to the aggregate. This ensures that a transient
            --  component which mentions a discriminant has proper visibility
            --  of the discriminant.

            Process_Transient_Component
              (Loc        => Loc,
               Comp_Typ   => Comp_Typ,
               Init_Expr  => Init_Expr,
               Fin_Call   => Fin_Call,
               Hook_Clear => Hook_Clear,
               Stmts      => Stmts);
         end if;

         --  Use the noncontrolled component initialization circuitry to
         --  assign the result of the function call to the record component.
         --  This also performs tag adjustment and [deep] adjustment of the
         --  record component.

         Initialize_Record_Component
           (Rec_Comp  => Rec_Comp,
            Comp_Typ  => Comp_Typ,
            Init_Expr => Init_Expr,
            Stmts     => Stmts);

         --  At this point the record component is fully initialized. Complete
         --  the processing of the controlled record component by finalizing
         --  the transient function result.

         if In_Place_Expansion then
            Process_Transient_Component_Completion
              (Loc        => Loc,
               Aggr       => N,
               Fin_Call   => Fin_Call,
               Hook_Clear => Hook_Clear,
               Stmts      => Stmts);
         end if;
      end Initialize_Ctrl_Record_Component;

      ---------------------------------
      -- Initialize_Record_Component --
      ---------------------------------

      procedure Initialize_Record_Component
        (Rec_Comp  : Node_Id;
         Comp_Typ  : Entity_Id;
         Init_Expr : Node_Id;
         Stmts     : List_Id)
      is
         Exceptions_OK : constant Boolean :=
                           not Restriction_Active (No_Exception_Propagation);

         Finalization_OK : constant Boolean := Needs_Finalization (Comp_Typ);

         Full_Typ  : constant Entity_Id := Underlying_Type (Comp_Typ);
         Adj_Call  : Node_Id;
         Blk_Stmts : List_Id;
         Init_Stmt : Node_Id;

      begin
         pragma Assert (Nkind (Init_Expr) in N_Subexpr);

         --  Protect the initialization statements from aborts. Generate:

         --    Abort_Defer;

         if Finalization_OK and Abort_Allowed then
            if Exceptions_OK then
               Blk_Stmts := New_List;
            else
               Blk_Stmts := Stmts;
            end if;

            Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));

         --  Otherwise aborts are not allowed. All generated code is added
         --  directly to the input list.

         else
            Blk_Stmts := Stmts;
         end if;

         --  Initialize the record component. Generate:

         --    Rec_Comp := Init_Expr;

         --  Note that the initialization expression is NOT replicated because
         --  only a single component may be initialized by it.

         Init_Stmt :=
           Make_OK_Assignment_Statement (Loc,
             Name       => New_Copy_Tree (Rec_Comp),
             Expression => Init_Expr);
         Set_No_Ctrl_Actions (Init_Stmt);

         Append_To (Blk_Stmts, Init_Stmt);

         --  Adjust the tag due to a possible view conversion. Generate:

         --    Rec_Comp._tag := Full_TypeP;

         if Tagged_Type_Expansion and then Is_Tagged_Type (Comp_Typ) then
            Append_To (Blk_Stmts,
              Make_OK_Assignment_Statement (Loc,
                Name       =>
                  Make_Selected_Component (Loc,
                    Prefix        => New_Copy_Tree (Rec_Comp),
                    Selector_Name =>
                      New_Occurrence_Of
                        (First_Tag_Component (Full_Typ), Loc)),

                Expression =>
                  Unchecked_Convert_To (RTE (RE_Tag),
                    New_Occurrence_Of
                      (Node (First_Elmt (Access_Disp_Table (Full_Typ))),
                       Loc))));
         end if;

         --  Adjust the component. Generate:

         --    [Deep_]Adjust (Rec_Comp);

         if Finalization_OK
           and then not Is_Limited_Type (Comp_Typ)
           and then not Is_Build_In_Place_Function_Call (Init_Expr)
         then
            Adj_Call :=
              Make_Adjust_Call
                (Obj_Ref => New_Copy_Tree (Rec_Comp),
                 Typ     => Comp_Typ);

            --  Guard against a missing [Deep_]Adjust when the component type
            --  was not properly frozen.

            if Present (Adj_Call) then
               Append_To (Blk_Stmts, Adj_Call);
            end if;
         end if;

         --  Complete the protection of the initialization statements

         if Finalization_OK and Abort_Allowed then

            --  Wrap the initialization statements in a block to catch a
            --  potential exception. Generate:

            --    begin
            --       Abort_Defer;
            --       Rec_Comp := Init_Expr;
            --       Rec_Comp._tag := Full_TypP;
            --       [Deep_]Adjust (Rec_Comp);
            --    at end
            --       Abort_Undefer_Direct;
            --    end;

            if Exceptions_OK then
               Append_To (Stmts,
                 Build_Abort_Undefer_Block (Loc,
                   Stmts   => Blk_Stmts,
                   Context => N));

            --  Otherwise exceptions are not propagated. Generate:

            --    Abort_Defer;
            --    Rec_Comp := Init_Expr;
            --    Rec_Comp._tag := Full_TypP;
            --    [Deep_]Adjust (Rec_Comp);
            --    Abort_Undefer;

            else
               Append_To (Blk_Stmts,
                 Build_Runtime_Call (Loc, RE_Abort_Undefer));
            end if;
         end if;
      end Initialize_Record_Component;

      -------------------------
      -- Is_Int_Range_Bounds --
      -------------------------

      function Is_Int_Range_Bounds (Bounds : Node_Id) return Boolean is
      begin
         return Nkind (Bounds) = N_Range
           and then Nkind (Low_Bound  (Bounds)) = N_Integer_Literal
           and then Nkind (High_Bound (Bounds)) = N_Integer_Literal;
      end Is_Int_Range_Bounds;

      ------------------
      -- Replace_Type --
      ------------------

      function Replace_Type (Expr : Node_Id) return Traverse_Result is
      begin
         --  Note regarding the Root_Type test below: Aggregate components for
         --  self-referential types include attribute references to the current
         --  instance, of the form: Typ'access, etc.. These references are
         --  rewritten as references to the target of the aggregate: the
         --  left-hand side of an assignment, the entity in a declaration,
         --  or a temporary. Without this test, we would improperly extended
         --  this rewriting to attribute references whose prefix was not the
         --  type of the aggregate.

         if Nkind (Expr) = N_Attribute_Reference
           and then Is_Entity_Name (Prefix (Expr))
           and then Is_Type (Entity (Prefix (Expr)))
           and then Root_Type (Etype (N)) = Root_Type (Entity (Prefix (Expr)))
         then
            if Is_Entity_Name (Lhs) then
               Rewrite (Prefix (Expr), New_Occurrence_Of (Entity (Lhs), Loc));

            else
               Rewrite (Expr,
                 Make_Attribute_Reference (Loc,
                   Attribute_Name => Name_Unrestricted_Access,
                   Prefix         => New_Copy_Tree (Lhs)));
               Set_Analyzed (Parent (Expr), False);
            end if;
         end if;

         return OK;
      end Replace_Type;

      --------------------------
      -- Rewrite_Discriminant --
      --------------------------

      function Rewrite_Discriminant (Expr : Node_Id) return Traverse_Result is
      begin
         if Is_Entity_Name (Expr)
           and then Present (Entity (Expr))
           and then Ekind (Entity (Expr)) = E_In_Parameter
           and then Present (Discriminal_Link (Entity (Expr)))
           and then Scope (Discriminal_Link (Entity (Expr))) =
                                                       Base_Type (Etype (N))
         then
            Rewrite (Expr,
              Make_Selected_Component (Loc,
                Prefix        => New_Copy_Tree (Lhs),
                Selector_Name => Make_Identifier (Loc, Chars (Expr))));

            --  The generated code will be reanalyzed, but if the reference
            --  to the discriminant appears within an already analyzed
            --  expression (e.g. a conditional) we must set its proper entity
            --  now. Context is an initialization procedure.

            Analyze (Expr);
         end if;

         return OK;
      end Rewrite_Discriminant;

      procedure Replace_Discriminants is
        new Traverse_Proc (Rewrite_Discriminant);

      procedure Replace_Self_Reference is
        new Traverse_Proc (Replace_Type);

   --  Start of processing for Build_Record_Aggr_Code

   begin
      if Has_Self_Reference (N) then
         Replace_Self_Reference (N);
      end if;

      --  If the target of the aggregate is class-wide, we must convert it
      --  to the actual type of the aggregate, so that the proper components
      --  are visible. We know already that the types are compatible.

      if Present (Etype (Lhs))
        and then Is_Class_Wide_Type (Etype (Lhs))
      then
         Target := Unchecked_Convert_To (Typ, Lhs);
      else
         Target := Lhs;
      end if;

      --  Deal with the ancestor part of extension aggregates or with the
      --  discriminants of the root type.

      if Nkind (N) = N_Extension_Aggregate then
         declare
            Ancestor : constant Node_Id := Ancestor_Part (N);
            Adj_Call : Node_Id;
            Assign   : List_Id;

         begin
            --  If the ancestor part is a subtype mark "T", we generate

            --     init-proc (T (tmp));  if T is constrained and
            --     init-proc (S (tmp));  where S applies an appropriate
            --                           constraint if T is unconstrained

            if Is_Entity_Name (Ancestor)
              and then Is_Type (Entity (Ancestor))
            then
               Ancestor_Is_Subtype_Mark := True;

               if Is_Constrained (Entity (Ancestor)) then
                  Init_Typ := Entity (Ancestor);

               --  For an ancestor part given by an unconstrained type mark,
               --  create a subtype constrained by appropriate corresponding
               --  discriminant values coming from either associations of the
               --  aggregate or a constraint on a parent type. The subtype will
               --  be used to generate the correct default value for the
               --  ancestor part.

               elsif Has_Discriminants (Entity (Ancestor)) then
                  declare
                     Anc_Typ    : constant Entity_Id := Entity (Ancestor);
                     Anc_Constr : constant List_Id   := New_List;
                     Discrim    : Entity_Id;
                     Disc_Value : Node_Id;
                     New_Indic  : Node_Id;
                     Subt_Decl  : Node_Id;

                  begin
                     Discrim := First_Discriminant (Anc_Typ);
                     while Present (Discrim) loop
                        Disc_Value := Ancestor_Discriminant_Value (Discrim);

                        --  If no usable discriminant in ancestors, check
                        --  whether aggregate has an explicit value for it.

                        if No (Disc_Value) then
                           Disc_Value :=
                             Get_Explicit_Discriminant_Value (Discrim);
                        end if;

                        Append_To (Anc_Constr, Disc_Value);
                        Next_Discriminant (Discrim);
                     end loop;

                     New_Indic :=
                       Make_Subtype_Indication (Loc,
                         Subtype_Mark => New_Occurrence_Of (Anc_Typ, Loc),
                         Constraint   =>
                           Make_Index_Or_Discriminant_Constraint (Loc,
                             Constraints => Anc_Constr));

                     Init_Typ := Create_Itype (Ekind (Anc_Typ), N);

                     Subt_Decl :=
                       Make_Subtype_Declaration (Loc,
                         Defining_Identifier => Init_Typ,
                         Subtype_Indication  => New_Indic);

                     --  Itypes must be analyzed with checks off Declaration
                     --  must have a parent for proper handling of subsidiary
                     --  actions.

                     Set_Parent (Subt_Decl, N);
                     Analyze (Subt_Decl, Suppress => All_Checks);
                  end;
               end if;

               Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
               Set_Assignment_OK (Ref);

               if not Is_Interface (Init_Typ) then
                  Append_List_To (L,
                    Build_Initialization_Call (Loc,
                      Id_Ref            => Ref,
                      Typ               => Init_Typ,
                      In_Init_Proc      => Within_Init_Proc,
                      With_Default_Init => Has_Default_Init_Comps (N)
                                             or else
                                           Has_Task (Base_Type (Init_Typ))));

                  if Is_Constrained (Entity (Ancestor))
                    and then Has_Discriminants (Entity (Ancestor))
                  then
                     Check_Ancestor_Discriminants (Entity (Ancestor));
                  end if;

                  --  If ancestor type has Default_Initialization_Condition,
                  --  add a DIC check after the ancestor object is initialized
                  --  by default.

                  if Has_DIC (Entity (Ancestor))
                    and then Present (DIC_Procedure (Entity (Ancestor)))
                  then
                     Append_To (L,
                       Build_DIC_Call
                         (Loc, New_Copy_Tree (Ref), Entity (Ancestor)));
                  end if;
               end if;

            --  Handle calls to C++ constructors

            elsif Is_CPP_Constructor_Call (Ancestor) then
               Init_Typ := Etype (Ancestor);
               Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
               Set_Assignment_OK (Ref);

               Append_List_To (L,
                 Build_Initialization_Call (Loc,
                   Id_Ref            => Ref,
                   Typ               => Init_Typ,
                   In_Init_Proc      => Within_Init_Proc,
                   With_Default_Init => Has_Default_Init_Comps (N),
                   Constructor_Ref   => Ancestor));

            --  Ada 2005 (AI-287): If the ancestor part is an aggregate of
            --  limited type, a recursive call expands the ancestor. Note that
            --  in the limited case, the ancestor part must be either a
            --  function call (possibly qualified) or aggregate (definitely
            --  qualified).

            elsif Is_Limited_Type (Etype (Ancestor))
              and then Nkind (Unqualify (Ancestor)) in
                         N_Aggregate | N_Extension_Aggregate
            then
               Ancestor_Is_Expression := True;

               --  Set up finalization data for enclosing record, because
               --  controlled subcomponents of the ancestor part will be
               --  attached to it.

               Generate_Finalization_Actions;

               Append_List_To (L,
                  Build_Record_Aggr_Code
                    (N   => Unqualify (Ancestor),
                     Typ => Etype (Unqualify (Ancestor)),
                     Lhs => Target));

            --  If the ancestor part is an expression "E", we generate

            --     T (tmp) := E;

            --  In Ada 2005, this includes the case of a (possibly qualified)
            --  limited function call. The assignment will turn into a
            --  build-in-place function call (for further details, see
            --  Make_Build_In_Place_Call_In_Assignment).

            else
               Ancestor_Is_Expression := True;
               Init_Typ := Etype (Ancestor);

               --  If the ancestor part is an aggregate, force its full
               --  expansion, which was delayed.

               if Nkind (Unqualify (Ancestor)) in
                    N_Aggregate | N_Extension_Aggregate
               then
                  Set_Analyzed (Ancestor, False);
                  Set_Analyzed (Expression (Ancestor), False);
               end if;

               Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
               Set_Assignment_OK (Ref);

               --  Make the assignment without usual controlled actions, since
               --  we only want to Adjust afterwards, but not to Finalize
               --  beforehand. Add manual Adjust when necessary.

               Assign := New_List (
                 Make_OK_Assignment_Statement (Loc,
                   Name       => Ref,
                   Expression => Ancestor));
               Set_No_Ctrl_Actions (First (Assign));

               --  Assign the tag now to make sure that the dispatching call in
               --  the subsequent deep_adjust works properly (unless
               --  Tagged_Type_Expansion where tags are implicit).

               if Tagged_Type_Expansion then
                  Instr :=
                    Make_OK_Assignment_Statement (Loc,
                      Name       =>
                        Make_Selected_Component (Loc,
                          Prefix        => New_Copy_Tree (Target),
                          Selector_Name =>
                            New_Occurrence_Of
                              (First_Tag_Component (Base_Type (Typ)), Loc)),

                      Expression =>
                        Unchecked_Convert_To (RTE (RE_Tag),
                          New_Occurrence_Of
                            (Node (First_Elmt
                               (Access_Disp_Table (Base_Type (Typ)))),
                             Loc)));

                  Set_Assignment_OK (Name (Instr));
                  Append_To (Assign, Instr);

                  --  Ada 2005 (AI-251): If tagged type has progenitors we must
                  --  also initialize tags of the secondary dispatch tables.

                  if Has_Interfaces (Base_Type (Typ)) then
                     Init_Secondary_Tags
                       (Typ            => Base_Type (Typ),
                        Target         => Target,
                        Stmts_List     => Assign,
                        Init_Tags_List => Assign);
                  end if;
               end if;

               --  Call Adjust manually

               if Needs_Finalization (Etype (Ancestor))
                 and then not Is_Limited_Type (Etype (Ancestor))
                 and then not Is_Build_In_Place_Function_Call (Ancestor)
               then
                  Adj_Call :=
                    Make_Adjust_Call
                      (Obj_Ref => New_Copy_Tree (Ref),
                       Typ     => Etype (Ancestor));

                  --  Guard against a missing [Deep_]Adjust when the ancestor
                  --  type was not properly frozen.

                  if Present (Adj_Call) then
                     Append_To (Assign, Adj_Call);
                  end if;
               end if;

               Append_To (L,
                 Make_Unsuppress_Block (Loc, Name_Discriminant_Check, Assign));

               if Has_Discriminants (Init_Typ) then
                  Check_Ancestor_Discriminants (Init_Typ);
               end if;
            end if;

            pragma Assert (Nkind (N) = N_Extension_Aggregate);
            pragma Assert
              (not (Ancestor_Is_Expression and Ancestor_Is_Subtype_Mark));
         end;

         --  Generate assignments of hidden discriminants. If the base type is
         --  an unchecked union, the discriminants are unknown to the back-end
         --  and absent from a value of the type, so assignments for them are
         --  not emitted.

         if Has_Discriminants (Typ)
           and then not Is_Unchecked_Union (Base_Type (Typ))
         then
            Init_Hidden_Discriminants (Typ, L);
         end if;

      --  Normal case (not an extension aggregate)

      else
         --  Generate the discriminant expressions, component by component.
         --  If the base type is an unchecked union, the discriminants are
         --  unknown to the back-end and absent from a value of the type, so
         --  assignments for them are not emitted.

         if Has_Discriminants (Typ)
           and then not Is_Unchecked_Union (Base_Type (Typ))
         then
            Init_Hidden_Discriminants (Typ, L);

            --  Generate discriminant init values for the visible discriminants

            Init_Visible_Discriminants;

            if Is_Derived_Type (N_Typ) then
               Init_Stored_Discriminants;
            end if;
         end if;
      end if;

      --  For CPP types we generate an implicit call to the C++ default
      --  constructor to ensure the proper initialization of the _Tag
      --  component.

      if Is_CPP_Class (Root_Type (Typ)) and then CPP_Num_Prims (Typ) > 0 then
         Invoke_Constructor : declare
            CPP_Parent : constant Entity_Id := Enclosing_CPP_Parent (Typ);

            procedure Invoke_IC_Proc (T : Entity_Id);
            --  Recursive routine used to climb to parents. Required because
            --  parents must be initialized before descendants to ensure
            --  propagation of inherited C++ slots.

            --------------------
            -- Invoke_IC_Proc --
            --------------------

            procedure Invoke_IC_Proc (T : Entity_Id) is
            begin
               --  Avoid generating extra calls. Initialization required
               --  only for types defined from the level of derivation of
               --  type of the constructor and the type of the aggregate.

               if T = CPP_Parent then
                  return;
               end if;

               Invoke_IC_Proc (Etype (T));

               --  Generate call to the IC routine

               if Present (CPP_Init_Proc (T)) then
                  Append_To (L,
                    Make_Procedure_Call_Statement (Loc,
                      Name => New_Occurrence_Of (CPP_Init_Proc (T), Loc)));
               end if;
            end Invoke_IC_Proc;

         --  Start of processing for Invoke_Constructor

         begin
            --  Implicit invocation of the C++ constructor

            if Nkind (N) = N_Aggregate then
               Append_To (L,
                 Make_Procedure_Call_Statement (Loc,
                   Name                   =>
                     New_Occurrence_Of (Base_Init_Proc (CPP_Parent), Loc),
                   Parameter_Associations => New_List (
                     Unchecked_Convert_To (CPP_Parent,
                       New_Copy_Tree (Lhs)))));
            end if;

            Invoke_IC_Proc (Typ);
         end Invoke_Constructor;
      end if;

      --  Generate the assignments, component by component

      --    tmp.comp1 := Expr1_From_Aggr;
      --    tmp.comp2 := Expr2_From_Aggr;
      --    ....

      Comp := First (Component_Associations (N));
      while Present (Comp) loop
         Selector := Entity (First (Choices (Comp)));

         --  C++ constructors

         if Is_CPP_Constructor_Call (Expression (Comp)) then
            Append_List_To (L,
              Build_Initialization_Call (Loc,
                Id_Ref            =>
                  Make_Selected_Component (Loc,
                    Prefix        => New_Copy_Tree (Target),
                    Selector_Name => New_Occurrence_Of (Selector, Loc)),
                Typ               => Etype (Selector),
                Enclos_Type       => Typ,
                With_Default_Init => True,
                Constructor_Ref   => Expression (Comp)));

         elsif Box_Present (Comp)
           and then Needs_Simple_Initialization (Etype (Selector))
         then
            Comp_Expr :=
              Make_Selected_Component (Loc,
                Prefix        => New_Copy_Tree (Target),
                Selector_Name => New_Occurrence_Of (Selector, Loc));

            Initialize_Record_Component
              (Rec_Comp  => Comp_Expr,
               Comp_Typ  => Etype (Selector),
               Init_Expr => Get_Simple_Init_Val
                              (Typ  => Etype (Selector),
                               N    => Comp,
                               Size =>
                                 (if Known_Esize (Selector)
                                  then Esize (Selector)
                                  else Uint_0)),
               Stmts     => L);

         --  Ada 2005 (AI-287): For each default-initialized component generate
         --  a call to the corresponding IP subprogram if available.

         elsif Box_Present (Comp)
           and then Has_Non_Null_Base_Init_Proc (Etype (Selector))
         then
            if Ekind (Selector) /= E_Discriminant then
               Generate_Finalization_Actions;
            end if;

            --  Ada 2005 (AI-287): If the component type has tasks then
            --  generate the activation chain and master entities (except
            --  in case of an allocator because in that case these entities
            --  are generated by Build_Task_Allocate_Block_With_Init_Stmts).

            declare
               Ctype            : constant Entity_Id := Etype (Selector);
               Inside_Allocator : Boolean            := False;
               P                : Node_Id            := Parent (N);

            begin
               if Is_Task_Type (Ctype) or else Has_Task (Ctype) then
                  while Present (P) loop
                     if Nkind (P) = N_Allocator then
                        Inside_Allocator := True;
                        exit;
                     end if;

                     P := Parent (P);
                  end loop;

                  if not Inside_Init_Proc and not Inside_Allocator then
                     Build_Activation_Chain_Entity (N);
                  end if;
               end if;
            end;

            Append_List_To (L,
              Build_Initialization_Call (Loc,
                Id_Ref            => Make_Selected_Component (Loc,
                                       Prefix        => New_Copy_Tree (Target),
                                       Selector_Name =>
                                         New_Occurrence_Of (Selector, Loc)),
                Typ               => Etype (Selector),
                Enclos_Type       => Typ,
                With_Default_Init => True));

         --  Prepare for component assignment

         elsif Ekind (Selector) /= E_Discriminant
           or else Nkind (N) = N_Extension_Aggregate
         then
            --  All the discriminants have now been assigned

            --  This is now a good moment to initialize and attach all the
            --  controllers. Their position may depend on the discriminants.

            if Ekind (Selector) /= E_Discriminant then
               Generate_Finalization_Actions;
            end if;

            Comp_Type := Underlying_Type (Etype (Selector));
            Comp_Expr :=
              Make_Selected_Component (Loc,
                Prefix        => New_Copy_Tree (Target),
                Selector_Name => New_Occurrence_Of (Selector, Loc));

            if Nkind (Expression (Comp)) = N_Qualified_Expression then
               Expr_Q := Expression (Expression (Comp));
            else
               Expr_Q := Expression (Comp);
            end if;

            --  Now either create the assignment or generate the code for the
            --  inner aggregate top-down.

            if Is_Delayed_Aggregate (Expr_Q) then

               --  We have the following case of aggregate nesting inside
               --  an object declaration:

               --    type Arr_Typ is array (Integer range <>) of ...;

               --    type Rec_Typ (...) is record
               --       Obj_Arr_Typ : Arr_Typ (A .. B);
               --    end record;

               --    Obj_Rec_Typ : Rec_Typ := (...,
               --      Obj_Arr_Typ => (X => (...), Y => (...)));

               --  The length of the ranges of the aggregate and Obj_Add_Typ
               --  are equal (B - A = Y - X), but they do not coincide (X /=
               --  A and B /= Y). This case requires array sliding which is
               --  performed in the following manner:

               --    subtype Arr_Sub is Arr_Typ (X .. Y);
               --    Temp : Arr_Sub;
               --    Temp (X) := (...);
               --    ...
               --    Temp (Y) := (...);
               --    Obj_Rec_Typ.Obj_Arr_Typ := Temp;

               if Ekind (Comp_Type) = E_Array_Subtype
                 and then Is_Int_Range_Bounds (Aggregate_Bounds (Expr_Q))
                 and then Is_Int_Range_Bounds (First_Index (Comp_Type))
                 and then not
                   Compatible_Int_Bounds
                     (Agg_Bounds => Aggregate_Bounds (Expr_Q),
                      Typ_Bounds => First_Index (Comp_Type))
               then
                  --  Create the array subtype with bounds equal to those of
                  --  the corresponding aggregate.

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

                     SubD : constant Node_Id :=
                       Make_Subtype_Declaration (Loc,
                         Defining_Identifier => SubE,
                         Subtype_Indication  =>
                           Make_Subtype_Indication (Loc,
                             Subtype_Mark =>
                               New_Occurrence_Of (Etype (Comp_Type), Loc),
                             Constraint =>
                               Make_Index_Or_Discriminant_Constraint
                                 (Loc,
                                  Constraints => New_List (
                                    New_Copy_Tree
                                      (Aggregate_Bounds (Expr_Q))))));

                     --  Create a temporary array of the above subtype which
                     --  will be used to capture the aggregate assignments.

                     TmpE : constant Entity_Id := Make_Temporary (Loc, 'A', N);

                     TmpD : constant Node_Id :=
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => TmpE,
                         Object_Definition   => New_Occurrence_Of (SubE, Loc));

                  begin
                     Set_No_Initialization (TmpD);
                     Append_To (L, SubD);
                     Append_To (L, TmpD);

                     --  Expand aggregate into assignments to the temp array

                     Append_List_To (L,
                       Late_Expansion (Expr_Q, Comp_Type,
                         New_Occurrence_Of (TmpE, Loc)));

                     --  Slide

                     Append_To (L,
                       Make_Assignment_Statement (Loc,
                         Name       => New_Copy_Tree (Comp_Expr),
                         Expression => New_Occurrence_Of (TmpE, Loc)));
                  end;

               --  Normal case (sliding not required)

               else
                  Append_List_To (L,
                    Late_Expansion (Expr_Q, Comp_Type, Comp_Expr));
               end if;

            --  Expr_Q is not delayed aggregate

            else
               if Has_Discriminants (Typ) then
                  Replace_Discriminants (Expr_Q);

                  --  If the component is an array type that depends on
                  --  discriminants, and the expression is a single Others
                  --  clause, create an explicit subtype for it because the
                  --  backend has troubles recovering the actual bounds.

                  if Nkind (Expr_Q) = N_Aggregate
                    and then Is_Array_Type (Comp_Type)
                    and then Present (Component_Associations (Expr_Q))
                  then
                     declare
                        Assoc : constant Node_Id :=
                                  First (Component_Associations (Expr_Q));
                        Decl  : Node_Id;

                     begin
                        if Nkind (First (Choices (Assoc))) = N_Others_Choice
                        then
                           Decl :=
                             Build_Actual_Subtype_Of_Component
                               (Comp_Type, Comp_Expr);

                           --  If the component type does not in fact depend on
                           --  discriminants, the subtype declaration is empty.

                           if Present (Decl) then
                              Append_To (L, Decl);
                              Set_Etype (Comp_Expr, Defining_Entity (Decl));
                           end if;
                        end if;
                     end;
                  end if;
               end if;

               if Modify_Tree_For_C
                 and then Nkind (Expr_Q) = N_Aggregate
                 and then Is_Array_Type (Etype (Expr_Q))
                 and then Present (First_Index (Etype (Expr_Q)))
               then
                  declare
                     Expr_Q_Type : constant Entity_Id := Etype (Expr_Q);
                  begin
                     Append_List_To (L,
                       Build_Array_Aggr_Code
                         (N           => Expr_Q,
                          Ctype       => Component_Type (Expr_Q_Type),
                          Index       => First_Index (Expr_Q_Type),
                          Into        => Comp_Expr,
                          Scalar_Comp =>
                            Is_Scalar_Type (Component_Type (Expr_Q_Type))));
                  end;

               else
                  --  Handle an initialization expression of a controlled type
                  --  in case it denotes a function call. In general such a
                  --  scenario will produce a transient scope, but this will
                  --  lead to wrong order of initialization, adjustment, and
                  --  finalization in the context of aggregates.

                  --    Target.Comp := Ctrl_Func_Call;

                  --    begin                                  --  scope
                  --       Trans_Obj : ... := Ctrl_Func_Call;  --  object
                  --       Target.Comp := Trans_Obj;
                  --       Finalize (Trans_Obj);
                  --    end
                  --    Target.Comp._tag := ...;
                  --    Adjust (Target.Comp);

                  --  In the example above, the call to Finalize occurs too
                  --  early and as a result it may leave the record component
                  --  in a bad state. Finalization of the transient object
                  --  should really happen after adjustment.

                  --  To avoid this scenario, perform in-place side-effect
                  --  removal of the function call. This eliminates the
                  --  transient property of the function result and ensures
                  --  correct order of actions.

                  --    Res : ... := Ctrl_Func_Call;
                  --    Target.Comp := Res;
                  --    Target.Comp._tag := ...;
                  --    Adjust (Target.Comp);
                  --    Finalize (Res);

                  if Needs_Finalization (Comp_Type)
                    and then Nkind (Expr_Q) /= N_Aggregate
                  then
                     Initialize_Ctrl_Record_Component
                       (Rec_Comp   => Comp_Expr,
                        Comp_Typ   => Etype (Selector),
                        Init_Expr  => Expr_Q,
                        Stmts      => L);

                  --  Otherwise perform single component initialization

                  else
                     Initialize_Record_Component
                       (Rec_Comp  => Comp_Expr,
                        Comp_Typ  => Etype (Selector),
                        Init_Expr => Expr_Q,
                        Stmts     => L);
                  end if;
               end if;
            end if;

         --  comment would be good here ???

         elsif Ekind (Selector) = E_Discriminant
           and then Nkind (N) /= N_Extension_Aggregate
           and then Nkind (Parent (N)) = N_Component_Association
           and then Is_Constrained (Typ)
         then
            --  We must check that the discriminant value imposed by the
            --  context is the same as the value given in the subaggregate,
            --  because after the expansion into assignments there is no
            --  record on which to perform a regular discriminant check.

            declare
               D_Val : Elmt_Id;
               Disc  : Entity_Id;

            begin
               D_Val := First_Elmt (Discriminant_Constraint (Typ));
               Disc  := First_Discriminant (Typ);
               while Chars (Disc) /= Chars (Selector) loop
                  Next_Discriminant (Disc);
                  Next_Elmt (D_Val);
               end loop;

               pragma Assert (Present (D_Val));

               --  This check cannot performed for components that are
               --  constrained by a current instance, because this is not a
               --  value that can be compared with the actual constraint.

               if Nkind (Node (D_Val)) /= N_Attribute_Reference
                 or else not Is_Entity_Name (Prefix (Node (D_Val)))
                 or else not Is_Type (Entity (Prefix (Node (D_Val))))
               then
                  Append_To (L,
                  Make_Raise_Constraint_Error (Loc,
                    Condition =>
                      Make_Op_Ne (Loc,
                        Left_Opnd  => New_Copy_Tree (Node (D_Val)),
                        Right_Opnd => Expression (Comp)),
                    Reason    => CE_Discriminant_Check_Failed));

               else
                  --  Find self-reference in previous discriminant assignment,
                  --  and replace with proper expression.

                  declare
                     Ass : Node_Id;

                  begin
                     Ass := First (L);
                     while Present (Ass) loop
                        if Nkind (Ass) = N_Assignment_Statement
                          and then Nkind (Name (Ass)) = N_Selected_Component
                          and then Chars (Selector_Name (Name (Ass))) =
                                                                 Chars (Disc)
                        then
                           Set_Expression
                             (Ass, New_Copy_Tree (Expression (Comp)));
                           exit;
                        end if;
                        Next (Ass);
                     end loop;
                  end;
               end if;
            end;
         end if;

         --  If the component association was specified with a box and the
         --  component type has a Default_Initial_Condition, then generate
         --  a call to the DIC procedure.

         if Has_DIC (Etype (Selector))
           and then Was_Default_Init_Box_Association (Comp)
           and then Present (DIC_Procedure (Etype (Selector)))
         then
            Append_To (L,
              Build_DIC_Call (Loc,
                Make_Selected_Component (Loc,
                  Prefix        => New_Copy_Tree (Target),
                  Selector_Name => New_Occurrence_Of (Selector, Loc)),
                Etype (Selector)));
         end if;

         Next (Comp);
      end loop;

      --  If the type is tagged, the tag needs to be initialized (unless we
      --  are in VM-mode where tags are implicit). It is done late in the
      --  initialization process because in some cases, we call the init
      --  proc of an ancestor which will not leave out the right tag.

      if Ancestor_Is_Expression then
         null;

      --  For CPP types we generated a call to the C++ default constructor
      --  before the components have been initialized to ensure the proper
      --  initialization of the _Tag component (see above).

      elsif Is_CPP_Class (Typ) then
         null;

      elsif Is_Tagged_Type (Typ) and then Tagged_Type_Expansion then
         Instr :=
           Make_OK_Assignment_Statement (Loc,
             Name =>
               Make_Selected_Component (Loc,
                 Prefix => New_Copy_Tree (Target),
                 Selector_Name =>
                   New_Occurrence_Of
                     (First_Tag_Component (Base_Type (Typ)), Loc)),

             Expression =>
               Unchecked_Convert_To (RTE (RE_Tag),
                 New_Occurrence_Of
                   (Node (First_Elmt (Access_Disp_Table (Base_Type (Typ)))),
                    Loc)));

         Append_To (L, Instr);

         --  Ada 2005 (AI-251): If the tagged type has been derived from an
         --  abstract interfaces we must also initialize the tags of the
         --  secondary dispatch tables.

         if Has_Interfaces (Base_Type (Typ)) then
            Init_Secondary_Tags
              (Typ            => Base_Type (Typ),
               Target         => Target,
               Stmts_List     => L,
               Init_Tags_List => L);
         end if;
      end if;

      --  If the controllers have not been initialized yet (by lack of non-
      --  discriminant components), let's do it now.

      Generate_Finalization_Actions;

      return L;
   end Build_Record_Aggr_Code;

   -------------------------------
   -- Convert_Aggr_In_Allocator --
   -------------------------------

   procedure Convert_Aggr_In_Allocator
     (Alloc :  Node_Id;
      Decl  :  Node_Id;
      Aggr  :  Node_Id)
   is
      Loc  : constant Source_Ptr := Sloc (Aggr);
      Typ  : constant Entity_Id  := Etype (Aggr);
      Temp : constant Entity_Id  := Defining_Identifier (Decl);

      Occ  : constant Node_Id :=
        Unchecked_Convert_To (Typ,
          Make_Explicit_Dereference (Loc, New_Occurrence_Of (Temp, Loc)));

   begin
      if Is_Array_Type (Typ) then
         Convert_Array_Aggr_In_Allocator (Decl, Aggr, Occ);

      elsif Has_Default_Init_Comps (Aggr) then
         declare
            L          : constant List_Id := New_List;
            Init_Stmts : List_Id;

         begin
            Init_Stmts := Late_Expansion (Aggr, Typ, Occ);

            if Has_Task (Typ) then
               Build_Task_Allocate_Block_With_Init_Stmts (L, Aggr, Init_Stmts);
               Insert_Actions (Alloc, L);
            else
               Insert_Actions (Alloc, Init_Stmts);
            end if;
         end;

      else
         Insert_Actions (Alloc, Late_Expansion (Aggr, Typ, Occ));
      end if;
   end Convert_Aggr_In_Allocator;

   --------------------------------
   -- Convert_Aggr_In_Assignment --
   --------------------------------

   procedure Convert_Aggr_In_Assignment (N : Node_Id) is
      Aggr : Node_Id            := Expression (N);
      Typ  : constant Entity_Id := Etype (Aggr);
      Occ  : constant Node_Id   := New_Copy_Tree (Name (N));

   begin
      if Nkind (Aggr) = N_Qualified_Expression then
         Aggr := Expression (Aggr);
      end if;

      Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ));
   end Convert_Aggr_In_Assignment;

   ---------------------------------
   -- Convert_Aggr_In_Object_Decl --
   ---------------------------------

   procedure Convert_Aggr_In_Object_Decl (N : Node_Id) is
      Obj  : constant Entity_Id  := Defining_Identifier (N);
      Aggr : Node_Id             := Expression (N);
      Loc  : constant Source_Ptr := Sloc (Aggr);
      Typ  : constant Entity_Id  := Etype (Aggr);
      Occ  : constant Node_Id    := New_Occurrence_Of (Obj, Loc);

      Has_Transient_Scope : Boolean := False;

      function Discriminants_Ok return Boolean;
      --  If the object type is constrained, the discriminants in the
      --  aggregate must be checked against the discriminants of the subtype.
      --  This cannot be done using Apply_Discriminant_Checks because after
      --  expansion there is no aggregate left to check.

      ----------------------
      -- Discriminants_Ok --
      ----------------------

      function Discriminants_Ok return Boolean is
         Cond  : Node_Id := Empty;
         Check : Node_Id;
         D     : Entity_Id;
         Disc1 : Elmt_Id;
         Disc2 : Elmt_Id;
         Val1  : Node_Id;
         Val2  : Node_Id;

      begin
         D := First_Discriminant (Typ);
         Disc1 := First_Elmt (Discriminant_Constraint (Typ));
         Disc2 := First_Elmt (Discriminant_Constraint (Etype (Obj)));
         while Present (Disc1) and then Present (Disc2) loop
            Val1 := Node (Disc1);
            Val2 := Node (Disc2);

            if not Is_OK_Static_Expression (Val1)
              or else not Is_OK_Static_Expression (Val2)
            then
               Check := Make_Op_Ne (Loc,
                 Left_Opnd  => Duplicate_Subexpr (Val1),
                 Right_Opnd => Duplicate_Subexpr (Val2));

               if No (Cond) then
                  Cond := Check;

               else
                  Cond := Make_Or_Else (Loc,
                    Left_Opnd => Cond,
                    Right_Opnd => Check);
               end if;

            elsif Expr_Value (Val1) /= Expr_Value (Val2) then
               Apply_Compile_Time_Constraint_Error (Aggr,
                 Msg    => "incorrect value for discriminant&??",
                 Reason => CE_Discriminant_Check_Failed,
                 Ent    => D);
               return False;
            end if;

            Next_Discriminant (D);
            Next_Elmt (Disc1);
            Next_Elmt (Disc2);
         end loop;

         --  If any discriminant constraint is nonstatic, emit a check

         if Present (Cond) then
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition => Cond,
                Reason    => CE_Discriminant_Check_Failed));
         end if;

         return True;
      end Discriminants_Ok;

   --  Start of processing for Convert_Aggr_In_Object_Decl

   begin
      Set_Assignment_OK (Occ);

      if Nkind (Aggr) = N_Qualified_Expression then
         Aggr := Expression (Aggr);
      end if;

      if Has_Discriminants (Typ)
        and then Typ /= Etype (Obj)
        and then Is_Constrained (Etype (Obj))
        and then not Discriminants_Ok
      then
         return;
      end if;

      --  If the context is an extended return statement, it has its own
      --  finalization machinery (i.e. works like a transient scope) and
      --  we do not want to create an additional one, because objects on
      --  the finalization list of the return must be moved to the caller's
      --  finalization list to complete the return.

      --  Similarly if the aggregate is limited, it is built in place, and the
      --  controlled components are not assigned to intermediate temporaries
      --  so there is no need for a transient scope in this case either.

      if Requires_Transient_Scope (Typ)
        and then Ekind (Current_Scope) /= E_Return_Statement
        and then not Is_Limited_Type (Typ)
      then
         Establish_Transient_Scope (Aggr, Manage_Sec_Stack => False);
         Has_Transient_Scope := True;
      end if;

      declare
         Stmts : constant List_Id := Late_Expansion (Aggr, Typ, Occ);
         Stmt  : Node_Id;
         Param : Node_Id;

      begin
         --  If Obj is already frozen or if N is wrapped in a transient scope,
         --  Stmts do not need to be saved in Initialization_Statements since
         --  there is no freezing issue.

         if Is_Frozen (Obj) or else Has_Transient_Scope then
            Insert_Actions_After (N, Stmts);
         else
            Stmt := Make_Compound_Statement (Sloc (N), Actions => Stmts);
            Insert_Action_After (N, Stmt);

            --  Insert_Action_After may freeze Obj in which case we should
            --  remove the compound statement just created and simply insert
            --  Stmts after N.

            if Is_Frozen (Obj) then
               Remove (Stmt);
               Insert_Actions_After (N, Stmts);
            else
               Set_Initialization_Statements (Obj, Stmt);
            end if;
         end if;

         --  If Typ has controlled components and a call to a Slice_Assign
         --  procedure is part of the initialization statements, then we
         --  need to initialize the array component since Slice_Assign will
         --  need to adjust it.

         if Has_Controlled_Component (Typ) then
            Stmt := First (Stmts);

            while Present (Stmt) loop
               if Nkind (Stmt) = N_Procedure_Call_Statement
                 and then Get_TSS_Name (Entity (Name (Stmt)))
                            = TSS_Slice_Assign
               then
                  Param := First (Parameter_Associations (Stmt));
                  Insert_Actions
                    (Stmt,
                     Build_Initialization_Call
                       (Sloc (N), New_Copy_Tree (Param), Etype (Param)));
               end if;

               Next (Stmt);
            end loop;
         end if;
      end;

      Set_No_Initialization (N);

      --  After expansion the expression can be removed from the declaration
      --  except if the object is class-wide, in which case the aggregate
      --  provides the actual type.

      if not Is_Class_Wide_Type (Etype (Obj)) then
         Set_Expression (N, Empty);
      end if;

      Initialize_Discriminants (N, Typ);
   end Convert_Aggr_In_Object_Decl;

   -------------------------------------
   -- Convert_Array_Aggr_In_Allocator --
   -------------------------------------

   procedure Convert_Array_Aggr_In_Allocator
     (Decl   : Node_Id;
      Aggr   : Node_Id;
      Target : Node_Id)
   is
      Typ       : constant Entity_Id := Etype (Aggr);
      Ctyp      : constant Entity_Id := Component_Type (Typ);
      Aggr_Code : List_Id;
      New_Aggr  : Node_Id;

   begin
      --  The target is an explicit dereference of the allocated object

      --  If the assignment can be done directly by the back end, then
      --  reset Set_Expansion_Delayed and do not expand further.

      if not CodePeer_Mode
        and then not Modify_Tree_For_C
        and then Aggr_Assignment_OK_For_Backend (Aggr)
      then
         New_Aggr := New_Copy_Tree (Aggr);
         Set_Expansion_Delayed (New_Aggr, False);

         Aggr_Code :=
           New_List (
             Make_OK_Assignment_Statement (Sloc (New_Aggr),
               Name       => Target,
               Expression => New_Aggr));

      --  Or else, generate component assignments to it, as for an aggregate
      --  that appears on the right-hand side of an assignment statement.

      else
         Aggr_Code :=
           Build_Array_Aggr_Code (Aggr,
             Ctype       => Ctyp,
             Index       => First_Index (Typ),
             Into        => Target,
             Scalar_Comp => Is_Scalar_Type (Ctyp));
      end if;

      Insert_Actions_After (Decl, Aggr_Code);
   end Convert_Array_Aggr_In_Allocator;

   ------------------------
   -- In_Place_Assign_OK --
   ------------------------

   function In_Place_Assign_OK
     (N             : Node_Id;
      Target_Object : Entity_Id := Empty) return Boolean
   is
      Is_Array : constant Boolean := Is_Array_Type (Etype (N));

      Aggr_In     : Node_Id;
      Aggr_Bounds : Range_Nodes;
      Obj_In      : Node_Id;
      Obj_Bounds  : Range_Nodes;
      Parent_Kind : Node_Kind;
      Parent_Node : Node_Id;

      function Safe_Aggregate (Aggr : Node_Id) return Boolean;
      --  Check recursively that each component of a (sub)aggregate does not
      --  depend on the variable being assigned to.

      function Safe_Component (Expr : Node_Id) return Boolean;
      --  Verify that an expression cannot depend on the target being assigned
      --  to. Return true for compile-time known values, stand-alone objects,
      --  parameters passed by copy, calls to functions that return by copy,
      --  selected components thereof only if the aggregate's type is an array,
      --  indexed components and slices thereof only if the aggregate's type is
      --  a record, and simple expressions involving only these as operands.
      --  This is OK whatever the target because, for a component to overlap
      --  with the target, it must be either a direct reference to a component
      --  of the target, in which case there must be a matching selection or
      --  indexation or slicing, or an indirect reference to such a component,
      --  which is excluded by the above condition. Additionally, if the target
      --  is statically known, return true for arbitrarily nested selections,
      --  indexations or slicings, provided that their ultimate prefix is not
      --  the target itself.

      --------------------
      -- Safe_Aggregate --
      --------------------

      function Safe_Aggregate (Aggr : Node_Id) return Boolean is
         Expr : Node_Id;

      begin
         if Nkind (Parent (Aggr)) = N_Iterated_Component_Association then
            return False;
         end if;

         if Present (Expressions (Aggr)) then
            Expr := First (Expressions (Aggr));
            while Present (Expr) loop
               if Nkind (Expr) = N_Aggregate then
                  if not Safe_Aggregate (Expr) then
                     return False;
                  end if;

               elsif not Safe_Component (Expr) then
                  return False;
               end if;

               Next (Expr);
            end loop;
         end if;

         if Present (Component_Associations (Aggr)) then
            Expr := First (Component_Associations (Aggr));
            while Present (Expr) loop
               if Nkind (Expression (Expr)) = N_Aggregate then
                  if not Safe_Aggregate (Expression (Expr)) then
                     return False;
                  end if;

               --  If association has a box, no way to determine yet whether
               --  default can be assigned in place.

               elsif Box_Present (Expr) then
                  return False;

               elsif not Safe_Component (Expression (Expr)) then
                  return False;
               end if;

               Next (Expr);
            end loop;
         end if;

         return True;
      end Safe_Aggregate;

      --------------------
      -- Safe_Component --
      --------------------

      function Safe_Component (Expr : Node_Id) return Boolean is
         Comp : Node_Id := Expr;

         function Check_Component (C : Node_Id; T_OK : Boolean) return Boolean;
         --  Do the recursive traversal, after copy. If T_OK is True, return
         --  True for a stand-alone object only if the target is statically
         --  known and distinct from the object. At the top level, we start
         --  with T_OK set to False and set it to True at a deeper level only
         --  if we cannot disambiguate the component here without statically
         --  knowing the target. Note that this is not optimal, we should do
         --  something along the lines of Denotes_Same_Prefix for that.

         ---------------------
         -- Check_Component --
         ---------------------

         function Check_Component (C : Node_Id; T_OK : Boolean) return Boolean
         is

            function SDO (E : Entity_Id) return Uint;
            --  Return the Scope Depth Of the enclosing dynamic scope of E

            ---------
            -- SDO --
            ---------

            function SDO (E : Entity_Id) return Uint is
            begin
               return Scope_Depth (Enclosing_Dynamic_Scope (E));
            end SDO;

         --  Start of processing for Check_Component

         begin
            if Is_Overloaded (C) then
               return False;

            elsif Compile_Time_Known_Value (C) then
               return True;
            end if;

            case Nkind (C) is
               when N_Attribute_Reference =>
                  return Check_Component (Prefix (C), T_OK);

               when N_Function_Call =>
                  if Nkind (Name (C)) = N_Explicit_Dereference then
                     return not Returns_By_Ref (Etype (Name (C)));
                  else
                     return not Returns_By_Ref (Entity (Name (C)));
                  end if;

               when N_Indexed_Component | N_Slice =>
                  --  In a target record, these operations cannot determine
                  --  alone a component so we can recurse whatever the target.
                  return Check_Component (Prefix (C), T_OK or else Is_Array);

               when N_Selected_Component =>
                  --  In a target array, this operation cannot determine alone
                  --  a component so we can recurse whatever the target.
                  return
                    Check_Component (Prefix (C), T_OK or else not Is_Array);

               when N_Type_Conversion | N_Unchecked_Type_Conversion =>
                  return Check_Component (Expression (C), T_OK);

               when N_Binary_Op =>
                  return Check_Component (Left_Opnd (C), T_OK)
                    and then Check_Component (Right_Opnd (C), T_OK);

               when N_Unary_Op =>
                  return Check_Component (Right_Opnd (C), T_OK);

               when others =>
                  if Is_Entity_Name (C) and then Is_Object (Entity (C)) then
                     --  Case of a formal parameter component. It's either
                     --  trivial if passed by copy or very annoying if not,
                     --  because in the latter case it's almost equivalent
                     --  to a dereference, so the path-based disambiguation
                     --  logic is totally off and we always need the target.

                     if Is_Formal (Entity (C)) then

                        --  If it is passed by copy, then this is safe

                        if Mechanism (Entity (C)) = By_Copy then
                           return True;

                        --  Otherwise, this is safe if the target is present
                        --  and is at least as deeply nested as the component.

                        else
                           return Present (Target_Object)
                             and then not Is_Formal (Target_Object)
                             and then SDO (Target_Object) >= SDO (Entity (C));
                        end if;

                     --  For a renamed object, recurse

                     elsif Present (Renamed_Object (Entity (C))) then
                        return
                          Check_Component (Renamed_Object (Entity (C)), T_OK);

                     --  If this is safe whatever the target, we are done

                     elsif not T_OK then
                        return True;

                     --  If there is no target or the component is the target,
                     --  this is not safe.

                     elsif No (Target_Object)
                       or else Entity (C) = Target_Object
                     then
                        return False;

                     --  Case of a formal parameter target. This is safe if it
                     --  is at most as deeply nested as the component.

                     elsif Is_Formal (Target_Object) then
                        return SDO (Target_Object) <= SDO (Entity (C));

                     --  For distinct stand-alone objects, this is safe

                     else
                        return True;
                     end if;

                  --  For anything else than an object, this is not safe

                  else
                     return False;
                  end if;
            end case;
         end Check_Component;

      --  Start of processing for Safe_Component

      begin
         --  If the component appears in an association that may correspond
         --  to more than one element, it is not analyzed before expansion
         --  into assignments, to avoid side effects. We analyze, but do not
         --  resolve the copy, to obtain sufficient entity information for
         --  the checks that follow. If component is overloaded we assume
         --  an unsafe function call.

         if not Analyzed (Comp) then
            if Is_Overloaded (Expr) then
               return False;

            elsif Nkind (Expr) = N_Allocator then

               --  For now, too complex to analyze

               return False;

            elsif Nkind (Parent (Expr)) = N_Iterated_Component_Association then

               --  Ditto for iterated component associations, which in general
               --  require an enclosing loop and involve nonstatic expressions.

               return False;
            end if;

            Comp := New_Copy_Tree (Expr);
            Set_Parent (Comp, Parent (Expr));
            Analyze (Comp);
         end if;

         if Nkind (Comp) = N_Aggregate then
            return Safe_Aggregate (Comp);
         else
            return Check_Component (Comp, False);
         end if;
      end Safe_Component;

   --  Start of processing for In_Place_Assign_OK

   begin
      --  By-copy semantic cannot be guaranteed for controlled objects

      if Needs_Finalization (Etype (N)) then
         return False;
      end if;

      Parent_Node := Parent (N);
      Parent_Kind := Nkind (Parent_Node);

      if Parent_Kind = N_Qualified_Expression then
         Parent_Node := Parent (Parent_Node);
         Parent_Kind := Nkind (Parent_Node);
      end if;

      --  On assignment, sliding can take place, so we cannot do the
      --  assignment in place unless the bounds of the aggregate are
      --  statically equal to those of the target.

      --  If the aggregate is given by an others choice, the bounds are
      --  derived from the left-hand side, and the assignment is safe if
      --  the expression is.

      if Is_Array
        and then Present (Component_Associations (N))
        and then not Is_Others_Aggregate (N)
      then
         Aggr_In := First_Index (Etype (N));

         --  Context is an assignment

         if Parent_Kind = N_Assignment_Statement then
            Obj_In := First_Index (Etype (Name (Parent_Node)));

         --  Context is an allocator. Check the bounds of the aggregate against
         --  those of the designated type, except in the case where the type is
         --  unconstrained (and then we can directly return true, see below).

         else pragma Assert (Parent_Kind = N_Allocator);
            declare
               Desig_Typ : constant Entity_Id :=
                                         Designated_Type (Etype (Parent_Node));
            begin
               if not Is_Constrained (Desig_Typ) then
                  return True;
               end if;

               Obj_In := First_Index (Desig_Typ);
            end;
         end if;

         while Present (Aggr_In) loop
            Aggr_Bounds := Get_Index_Bounds (Aggr_In);
            Obj_Bounds := Get_Index_Bounds (Obj_In);

            --  We require static bounds for the target and a static matching
            --  of low bound for the aggregate.

            if not Compile_Time_Known_Value (Obj_Bounds.First)
              or else not Compile_Time_Known_Value (Obj_Bounds.Last)
              or else not Compile_Time_Known_Value (Aggr_Bounds.First)
              or else Expr_Value (Aggr_Bounds.First) /=
                      Expr_Value (Obj_Bounds.First)
            then
               return False;

            --  For an assignment statement we require static matching of
            --  bounds. Ditto for an allocator whose qualified expression
            --  is a constrained type. If the expression in the allocator
            --  is an unconstrained array, we accept an upper bound that
            --  is not static, to allow for nonstatic expressions of the
            --  base type. Clearly there are further possibilities (with
            --  diminishing returns) for safely building arrays in place
            --  here.

            elsif Parent_Kind = N_Assignment_Statement
              or else Is_Constrained (Etype (Parent_Node))
            then
               if not Compile_Time_Known_Value (Aggr_Bounds.Last)
                 or else Expr_Value (Aggr_Bounds.Last) /=
                         Expr_Value (Obj_Bounds.Last)
               then
                  return False;
               end if;
            end if;

            Next_Index (Aggr_In);
            Next_Index (Obj_In);
         end loop;
      end if;

      --  Now check the component values themselves, except for an allocator
      --  for which the target is newly allocated memory.

      if Parent_Kind = N_Allocator then
         return True;
      else
         return Safe_Aggregate (N);
      end if;
   end In_Place_Assign_OK;

   ----------------------------
   -- Convert_To_Assignments --
   ----------------------------

   procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      T    : Entity_Id;
      Temp : Entity_Id;

      Aggr_Code   : List_Id;
      Instr       : Node_Id;
      Target_Expr : Node_Id;
      Parent_Kind : Node_Kind;
      Unc_Decl    : Boolean := False;
      Parent_Node : Node_Id;

   begin
      pragma Assert (Nkind (N) in N_Aggregate | N_Extension_Aggregate);
      pragma Assert (not Is_Static_Dispatch_Table_Aggregate (N));
      pragma Assert (Is_Record_Type (Typ));

      Parent_Node := Parent (N);
      Parent_Kind := Nkind (Parent_Node);

      if Parent_Kind = N_Qualified_Expression then
         --  Check if we are in an unconstrained declaration because in this
         --  case the current delayed expansion mechanism doesn't work when
         --  the declared object size depends on the initializing expr.

         Parent_Node := Parent (Parent_Node);
         Parent_Kind := Nkind (Parent_Node);

         if Parent_Kind = N_Object_Declaration then
            Unc_Decl :=
              not Is_Entity_Name (Object_Definition (Parent_Node))
                or else (Nkind (N) = N_Aggregate
                          and then
                            Has_Discriminants
                              (Entity (Object_Definition (Parent_Node))))
                or else Is_Class_Wide_Type
                          (Entity (Object_Definition (Parent_Node)));
         end if;
      end if;

      --  Just set the Delay flag in the cases where the transformation will be
      --  done top down from above.

      if
         --  Internal aggregate (transformed when expanding the parent)

         Parent_Kind in
           N_Aggregate | N_Extension_Aggregate | N_Component_Association

         --  Allocator (see Convert_Aggr_In_Allocator)

         or else Parent_Kind = N_Allocator

         --  Object declaration (see Convert_Aggr_In_Object_Decl)

         or else (Parent_Kind = N_Object_Declaration and then not Unc_Decl)

         --  Safe assignment (see Convert_Aggr_Assignments). So far only the
         --  assignments in init procs are taken into account.

         or else (Parent_Kind = N_Assignment_Statement
                   and then Inside_Init_Proc)

         --  (Ada 2005) An inherently limited type in a return statement, which
         --  will be handled in a build-in-place fashion, and may be rewritten
         --  as an extended return and have its own finalization machinery.
         --  In the case of a simple return, the aggregate needs to be delayed
         --  until the scope for the return statement has been created, so
         --  that any finalization chain will be associated with that scope.
         --  For extended returns, we delay expansion to avoid the creation
         --  of an unwanted transient scope that could result in premature
         --  finalization of the return object (which is built in place
         --  within the caller's scope).

         or else Is_Build_In_Place_Aggregate_Return (N)
      then
         Set_Expansion_Delayed (N);
         return;
      end if;

      --  Otherwise, if a transient scope is required, create it now. If we
      --  are within an initialization procedure do not create such, because
      --  the target of the assignment must not be declared within a local
      --  block, and because cleanup will take place on return from the
      --  initialization procedure.

      --  Should the condition be more restrictive ???

      if Requires_Transient_Scope (Typ) and then not Inside_Init_Proc then
         Establish_Transient_Scope (N, Manage_Sec_Stack => False);
      end if;

      --  If the aggregate is nonlimited, create a temporary, since aggregates
      --  have "by copy" semantics. If it is limited and context is an
      --  assignment, this is a subaggregate for an enclosing aggregate being
      --  expanded. It must be built in place, so use target of the current
      --  assignment.

      if Is_Limited_Type (Typ)
        and then Parent_Kind = N_Assignment_Statement
      then
         Target_Expr := New_Copy_Tree (Name (Parent_Node));
         Insert_Actions (Parent_Node,
           Build_Record_Aggr_Code (N, Typ, Target_Expr));
         Rewrite (Parent_Node, Make_Null_Statement (Loc));

      --  Do not declare a temporary to initialize an aggregate assigned to
      --  a target when in-place assignment is possible, i.e. preserving the
      --  by-copy semantic of aggregates. This avoids large stack usage and
      --  generates more efficient code.

      elsif Parent_Kind = N_Assignment_Statement
        and then In_Place_Assign_OK (N, Get_Base_Object (Name (Parent_Node)))
      then
         declare
            Lhs : constant Node_Id := Name (Parent_Node);
         begin
            --  Apply discriminant check if required

            if Has_Discriminants (Etype (N)) then
               Apply_Discriminant_Check (N, Etype (Lhs), Lhs);
            end if;

            --  The check just above may have replaced the aggregate with a CE

            if Nkind (N) in N_Aggregate | N_Extension_Aggregate then
               Target_Expr := New_Copy_Tree (Lhs);
               Insert_Actions (Parent_Node,
                 Build_Record_Aggr_Code (N, Typ, Target_Expr));
               Rewrite (Parent_Node, Make_Null_Statement (Loc));
            end if;
         end;

      else
         Temp := Make_Temporary (Loc, 'A', N);

         --  If the type inherits unknown discriminants, use the view with
         --  known discriminants if available.

         if Has_Unknown_Discriminants (Typ)
           and then Present (Underlying_Record_View (Typ))
         then
            T := Underlying_Record_View (Typ);
         else
            T := Typ;
         end if;

         Instr :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
             Object_Definition   => New_Occurrence_Of (T, Loc));

         Set_No_Initialization (Instr);
         Insert_Action (N, Instr);
         Initialize_Discriminants (Instr, T);

         Target_Expr := New_Occurrence_Of (Temp, Loc);
         Aggr_Code   := Build_Record_Aggr_Code (N, T, Target_Expr);

         --  Save the last assignment statement associated with the aggregate
         --  when building a controlled object. This reference is utilized by
         --  the finalization machinery when marking an object as successfully
         --  initialized.

         if Needs_Finalization (T) then
            Set_Last_Aggregate_Assignment (Temp, Last (Aggr_Code));
         end if;

         Insert_Actions (N, Aggr_Code);
         Rewrite (N, New_Occurrence_Of (Temp, Loc));
         Analyze_And_Resolve (N, T);
      end if;
   end Convert_To_Assignments;

   ---------------------------
   -- Convert_To_Positional --
   ---------------------------

   procedure Convert_To_Positional
     (N                 : Node_Id;
      Handle_Bit_Packed : Boolean := False)
   is
      Typ                  : constant Entity_Id := Etype (N);
      Dims                 : constant Nat := Number_Dimensions (Typ);
      Max_Others_Replicate : constant Nat := Max_Aggregate_Size (N);

      Static_Components : Boolean := True;

      procedure Check_Static_Components;
      --  Check whether all components of the aggregate are compile-time known
      --  values, and can be passed as is to the back-end without further
      --  expansion.

      function Flatten
        (N    : Node_Id;
         Dims : Nat;
         Ix   : Node_Id;
         Ixb  : Node_Id) return Boolean;
      --  Convert the aggregate into a purely positional form if possible after
      --  checking that the bounds of all dimensions are known to be static.

      function Is_Flat (N : Node_Id; Dims : Nat) return Boolean;
      --  Return True if the aggregate N is flat (which is not trivial in the
      --  case of multidimensional aggregates).

      function Is_Static_Element (N : Node_Id; Dims : Nat) return Boolean;
      --  Return True if N, an element of a component association list, i.e.
      --  N_Component_Association or N_Iterated_Component_Association, has a
      --  compile-time known value and can be passed as is to the back-end
      --  without further expansion.
      --  An Iterated_Component_Association is treated as nonstatic in most
      --  cases for now, so there are possibilities for optimization.

      -----------------------------
      -- Check_Static_Components --
      -----------------------------

      --  Could use some comments in this body ???

      procedure Check_Static_Components is
         Assoc : Node_Id;
         Expr  : Node_Id;

      begin
         Static_Components := True;

         if Nkind (N) = N_String_Literal then
            null;

         elsif Present (Expressions (N)) then
            Expr := First (Expressions (N));
            while Present (Expr) loop
               if Nkind (Expr) /= N_Aggregate
                 or else not Compile_Time_Known_Aggregate (Expr)
                 or else Expansion_Delayed (Expr)
               then
                  Static_Components := False;
                  exit;
               end if;

               Next (Expr);
            end loop;
         end if;

         if Nkind (N) = N_Aggregate
           and then Present (Component_Associations (N))
         then
            Assoc := First (Component_Associations (N));
            while Present (Assoc) loop
               if not Is_Static_Element (Assoc, Dims) then
                  Static_Components := False;
                  exit;
               end if;

               Next (Assoc);
            end loop;
         end if;
      end Check_Static_Components;

      -------------
      -- Flatten --
      -------------

      function Flatten
        (N    : Node_Id;
         Dims : Nat;
         Ix   : Node_Id;
         Ixb  : Node_Id) return Boolean
      is
         Loc : constant Source_Ptr := Sloc (N);
         Blo : constant Node_Id    := Type_Low_Bound (Etype (Ixb));
         Lo  : constant Node_Id    := Type_Low_Bound (Etype (Ix));
         Hi  : constant Node_Id    := Type_High_Bound (Etype (Ix));

         function Cannot_Flatten_Next_Aggr (Expr : Node_Id) return Boolean;
         --  Return true if Expr is an aggregate for the next dimension that
         --  cannot be recursively flattened.

         ------------------------------
         -- Cannot_Flatten_Next_Aggr --
         ------------------------------

         function Cannot_Flatten_Next_Aggr (Expr : Node_Id) return Boolean is
         begin
            return Nkind (Expr) = N_Aggregate
              and then Present (Next_Index (Ix))
              and then not
                Flatten (Expr, Dims - 1, Next_Index (Ix), Next_Index (Ixb));
         end Cannot_Flatten_Next_Aggr;

         --  Local variables

         Lov            : Uint;
         Hiv            : Uint;
         Others_Present : Boolean;

      --  Start of processing for Flatten

      begin
         if Nkind (Original_Node (N)) = N_String_Literal then
            return True;
         end if;

         if not Compile_Time_Known_Value (Lo)
           or else not Compile_Time_Known_Value (Hi)
         then
            return False;
         end if;

         Lov := Expr_Value (Lo);
         Hiv := Expr_Value (Hi);

         --  Check if there is an others choice

         Others_Present := False;

         if Present (Component_Associations (N)) then
            declare
               Assoc   : Node_Id;
               Choice  : Node_Id;

            begin
               Assoc := First (Component_Associations (N));
               while Present (Assoc) loop

                  --  If this is a box association, flattening is in general
                  --  not possible because at this point we cannot tell if the
                  --  default is static or even exists.

                  if Box_Present (Assoc) then
                     return False;

                  elsif Nkind (Assoc) = N_Iterated_Component_Association then
                     return False;
                  end if;

                  Choice := First (Choice_List (Assoc));

                  while Present (Choice) loop
                     if Nkind (Choice) = N_Others_Choice then
                        Others_Present := True;
                     end if;

                     Next (Choice);
                  end loop;

                  Next (Assoc);
               end loop;
            end;
         end if;

         --  If the low bound is not known at compile time and others is not
         --  present we can proceed since the bounds can be obtained from the
         --  aggregate.

         if Hiv < Lov
           or else (not Compile_Time_Known_Value (Blo) and then Others_Present)
         then
            return False;
         end if;

         --  Determine if set of alternatives is suitable for conversion and
         --  build an array containing the values in sequence.

         declare
            Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
                     of Node_Id := (others => Empty);
            --  The values in the aggregate sorted appropriately

            Vlist : List_Id;
            --  Same data as Vals in list form

            Rep_Count : Nat;
            --  Used to validate Max_Others_Replicate limit

            Elmt         : Node_Id;
            Expr         : Node_Id;
            Num          : Int := UI_To_Int (Lov);
            Choice_Index : Int;
            Choice       : Node_Id;
            Lo, Hi       : Node_Id;

         begin
            if Present (Expressions (N)) then
               Elmt := First (Expressions (N));
               while Present (Elmt) loop
                  --  In the case of a multidimensional array, check that the
                  --  aggregate can be recursively flattened.

                  if Cannot_Flatten_Next_Aggr (Elmt) then
                     return False;
                  end if;

                  --  Duplicate expression for each index it covers

                  Vals (Num) := New_Copy_Tree (Elmt);
                  Num := Num + 1;

                  Next (Elmt);
               end loop;
            end if;

            if No (Component_Associations (N)) then
               return True;
            end if;

            Elmt := First (Component_Associations (N));

            Component_Loop : while Present (Elmt) loop
               Expr := Expression (Elmt);

               --  In the case of a multidimensional array, check that the
               --  aggregate can be recursively flattened.

               if Cannot_Flatten_Next_Aggr (Expr) then
                  return False;
               end if;

               Choice := First (Choice_List (Elmt));
               Choice_Loop : while Present (Choice) loop

                  --  If we have an others choice, fill in the missing elements
                  --  subject to the limit established by Max_Others_Replicate.

                  if Nkind (Choice) = N_Others_Choice then
                     Rep_Count := 0;

                     --  If the expression involves a construct that generates
                     --  a loop, we must generate individual assignments and
                     --  no flattening is possible.

                     if Nkind (Expr) = N_Quantified_Expression then
                        return False;
                     end if;

                     for J in Vals'Range loop
                        if No (Vals (J)) then
                           Vals (J)  := New_Copy_Tree (Expr);
                           Rep_Count := Rep_Count + 1;

                           --  Check for maximum others replication. Note that
                           --  we skip this test if either of the restrictions
                           --  No_Implicit_Loops or No_Elaboration_Code is
                           --  active, if this is a preelaborable unit or
                           --  a predefined unit, or if the unit must be
                           --  placed in data memory. This also ensures that
                           --  predefined units get the same level of constant
                           --  folding in Ada 95 and Ada 2005, where their
                           --  categorization has changed.

                           declare
                              P : constant Entity_Id :=
                                    Cunit_Entity (Current_Sem_Unit);

                           begin
                              --  Check if duplication is always OK and, if so,
                              --  continue processing.

                              if Restriction_Active (No_Implicit_Loops) then
                                 null;

                              --  If duplication is not always OK, continue
                              --  only if either the element is static or is
                              --  an aggregate (we already know it is OK).

                              elsif not Is_Static_Element (Elmt, Dims)
                                and then Nkind (Expr) /= N_Aggregate
                              then
                                 return False;

                              --  Check if duplication is OK for elaboration
                              --  purposes and, if so, continue processing.

                              elsif Restriction_Active (No_Elaboration_Code)
                                or else
                                  (Ekind (Current_Scope) = E_Package
                                    and then
                                   Static_Elaboration_Desired (Current_Scope))
                                or else Is_Preelaborated (P)
                                or else (Ekind (P) = E_Package_Body
                                          and then
                                         Is_Preelaborated (Spec_Entity (P)))
                                or else
                                  Is_Predefined_Unit (Get_Source_Unit (P))
                              then
                                 null;

                              --  Otherwise, check that the replication count
                              --  is not too high.

                              elsif Rep_Count > Max_Others_Replicate then
                                 return False;
                              end if;
                           end;
                        end if;
                     end loop;

                     if Rep_Count = 0
                       and then Warn_On_Redundant_Constructs
                     then
                        Error_Msg_N ("there are no others?r?", Elmt);
                     end if;

                     exit Component_Loop;

                  --  Case of a subtype mark, identifier or expanded name

                  elsif Is_Entity_Name (Choice)
                    and then Is_Type (Entity (Choice))
                  then
                     Lo := Type_Low_Bound  (Etype (Choice));
                     Hi := Type_High_Bound (Etype (Choice));

                  --  Case of subtype indication

                  elsif Nkind (Choice) = N_Subtype_Indication then
                     Lo := Low_Bound  (Range_Expression (Constraint (Choice)));
                     Hi := High_Bound (Range_Expression (Constraint (Choice)));

                  --  Case of a range

                  elsif Nkind (Choice) = N_Range then
                     Lo := Low_Bound (Choice);
                     Hi := High_Bound (Choice);

                  --  Normal subexpression case

                  else pragma Assert (Nkind (Choice) in N_Subexpr);
                     if not Compile_Time_Known_Value (Choice) then
                        return False;

                     else
                        Choice_Index := UI_To_Int (Expr_Value (Choice));

                        if Choice_Index in Vals'Range then
                           Vals (Choice_Index) := New_Copy_Tree (Expr);
                           goto Continue;

                        --  Choice is statically out-of-range, will be
                        --  rewritten to raise Constraint_Error.

                        else
                           return False;
                        end if;
                     end if;
                  end if;

                  --  Range cases merge with Lo,Hi set

                  if not Compile_Time_Known_Value (Lo)
                       or else
                     not Compile_Time_Known_Value (Hi)
                  then
                     return False;

                  else
                     for J in UI_To_Int (Expr_Value (Lo)) ..
                              UI_To_Int (Expr_Value (Hi))
                     loop
                        Vals (J) := New_Copy_Tree (Expr);
                     end loop;
                  end if;

               <<Continue>>
                  Next (Choice);
               end loop Choice_Loop;

               Next (Elmt);
            end loop Component_Loop;

            --  If we get here the conversion is possible

            Vlist := New_List;
            for J in Vals'Range loop
               Append (Vals (J), Vlist);
            end loop;

            Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
            Set_Aggregate_Bounds (N, Aggregate_Bounds (Original_Node (N)));
            return True;
         end;
      end Flatten;

      -------------
      -- Is_Flat --
      -------------

      function Is_Flat (N : Node_Id; Dims : Nat) return Boolean is
         Elmt : Node_Id;

      begin
         if Dims = 0 then
            return True;

         elsif Nkind (N) = N_Aggregate then
            if Present (Component_Associations (N)) then
               return False;

            else
               Elmt := First (Expressions (N));
               while Present (Elmt) loop
                  if not Is_Flat (Elmt, Dims - 1) then
                     return False;
                  end if;

                  Next (Elmt);
               end loop;

               return True;
            end if;
         else
            return True;
         end if;
      end Is_Flat;

      -------------------------
      --  Is_Static_Element  --
      -------------------------

      function Is_Static_Element (N : Node_Id; Dims : Nat) return Boolean is
         Expr : constant Node_Id := Expression (N);

      begin
         --  In most cases the interesting expressions are unambiguously static

         if Compile_Time_Known_Value (Expr) then
            return True;

         elsif Nkind (N) = N_Iterated_Component_Association then
            return False;

         elsif Nkind (Expr) = N_Aggregate
           and then Compile_Time_Known_Aggregate (Expr)
           and then not Expansion_Delayed (Expr)
         then
            return True;

         --  However, one may write static expressions that are syntactically
         --  ambiguous, so preanalyze the expression before checking it again,
         --  but only at the innermost level for a multidimensional array.

         elsif Dims = 1 then
            Preanalyze_And_Resolve (Expr, Component_Type (Typ));
            return Compile_Time_Known_Value (Expr);

         else
            return False;
         end if;
      end Is_Static_Element;

   --  Start of processing for Convert_To_Positional

   begin
      --  Only convert to positional when generating C in case of an
      --  object declaration, this is the only case where aggregates are
      --  supported in C.

      if Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
         return;
      end if;

      --  Ada 2005 (AI-287): Do not convert in case of default initialized
      --  components because in this case will need to call the corresponding
      --  IP procedure.

      if Has_Default_Init_Comps (N) then
         return;
      end if;

      --  A subaggregate may have been flattened but is not known to be
      --  Compile_Time_Known. Set that flag in cases that cannot require
      --  elaboration code, so that the aggregate can be used as the
      --  initial value of a thread-local variable.

      if Is_Flat (N, Dims) then
         if Static_Array_Aggregate (N) then
            Set_Compile_Time_Known_Aggregate (N);
         end if;

         return;
      end if;

      if Is_Bit_Packed_Array (Typ) and then not Handle_Bit_Packed then
         return;
      end if;

      --  Do not convert to positional if controlled components are involved
      --  since these require special processing

      if Has_Controlled_Component (Typ) then
         return;
      end if;

      Check_Static_Components;

      --  If the size is known, or all the components are static, try to
      --  build a fully positional aggregate.

      --  The size of the type may not be known for an aggregate with
      --  discriminated array components, but if the components are static
      --  it is still possible to verify statically that the length is
      --  compatible with the upper bound of the type, and therefore it is
      --  worth flattening such aggregates as well.

      if Aggr_Size_OK (N)
        and then
          Flatten (N, Dims, First_Index (Typ), First_Index (Base_Type (Typ)))
      then
         if Static_Components then
            Set_Compile_Time_Known_Aggregate (N);
            Set_Expansion_Delayed (N, False);
         end if;

         Analyze_And_Resolve (N, Typ);
      end if;

      --  If Static_Elaboration_Desired has been specified, diagnose aggregates
      --  that will still require initialization code.

      if (Ekind (Current_Scope) = E_Package
        and then Static_Elaboration_Desired (Current_Scope))
        and then Nkind (Parent (N)) = N_Object_Declaration
      then
         declare
            Expr : Node_Id;

         begin
            if Nkind (N) = N_Aggregate and then Present (Expressions (N)) then
               Expr := First (Expressions (N));
               while Present (Expr) loop
                  if not Compile_Time_Known_Value (Expr) then
                     Error_Msg_N
                       ("non-static object requires elaboration code??", N);
                     exit;
                  end if;

                  Next (Expr);
               end loop;

               if Present (Component_Associations (N)) then
                  Error_Msg_N ("object requires elaboration code??", N);
               end if;
            end if;
         end;
      end if;
   end Convert_To_Positional;

   ----------------------------
   -- Expand_Array_Aggregate --
   ----------------------------

   --  Array aggregate expansion proceeds as follows:

   --  1. If requested we generate code to perform all the array aggregate
   --     bound checks, specifically

   --         (a) Check that the index range defined by aggregate bounds is
   --             compatible with corresponding index subtype.

   --         (b) If an others choice is present check that no aggregate
   --             index is outside the bounds of the index constraint.

   --         (c) For multidimensional arrays make sure that all subaggregates
   --             corresponding to the same dimension have the same bounds.

   --  2. Check for packed array aggregate which can be converted to a
   --     constant so that the aggregate disappears completely.

   --  3. Check case of nested aggregate. Generally nested aggregates are
   --     handled during the processing of the parent aggregate.

   --  4. Check if the aggregate can be statically processed. If this is the
   --     case pass it as is to Gigi. Note that a necessary condition for
   --     static processing is that the aggregate be fully positional.

   --  5. If in-place aggregate expansion is possible (i.e. no need to create
   --     a temporary) then mark the aggregate as such and return. Otherwise
   --     create a new temporary and generate the appropriate initialization
   --     code.

   procedure Expand_Array_Aggregate (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);

      Typ  : constant Entity_Id := Etype (N);
      Ctyp : constant Entity_Id := Component_Type (Typ);
      --  Typ is the correct constrained array subtype of the aggregate
      --  Ctyp is the corresponding component type.

      Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
      --  Number of aggregate index dimensions

      Aggr_Low  : array (1 .. Aggr_Dimension) of Node_Id;
      Aggr_High : array (1 .. Aggr_Dimension) of Node_Id;
      --  Low and High bounds of the constraint for each aggregate index

      Aggr_Index_Typ : array (1 .. Aggr_Dimension) of Entity_Id;
      --  The type of each index

      In_Place_Assign_OK_For_Declaration : Boolean := False;
      --  True if we are to generate an in-place assignment for a declaration

      Maybe_In_Place_OK : Boolean;
      --  If the type is neither controlled nor packed and the aggregate
      --  is the expression in an assignment, assignment in place may be
      --  possible, provided other conditions are met on the LHS.

      Others_Present : array (1 .. Aggr_Dimension) of Boolean :=
        (others => False);
      --  If Others_Present (J) is True, then there is an others choice in one
      --  of the subaggregates of N at dimension J.

      procedure Build_Constrained_Type (Positional : Boolean);
      --  If the subtype is not static or unconstrained, build a constrained
      --  type using the computable sizes of the aggregate and its sub-
      --  aggregates.

      procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id);
      --  Checks that the bounds of Aggr_Bounds are within the bounds defined
      --  by Index_Bounds.

      procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos);
      --  Checks that in a multidimensional array aggregate all subaggregates
      --  corresponding to the same dimension have the same bounds. Sub_Aggr is
      --  an array subaggregate. Dim is the dimension corresponding to the
      --  subaggregate.

      procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos);
      --  Computes the values of array Others_Present. Sub_Aggr is the array
      --  subaggregate we start the computation from. Dim is the dimension
      --  corresponding to the subaggregate.

      procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
      --  Checks that if an others choice is present in any subaggregate, no
      --  aggregate index is outside the bounds of the index constraint.
      --  Sub_Aggr is an array subaggregate. Dim is the dimension corresponding
      --  to the subaggregate.

      function Safe_Left_Hand_Side (N : Node_Id) return Boolean;
      --  In addition to Maybe_In_Place_OK, in order for an aggregate to be
      --  built directly into the target of the assignment it must be free
      --  of side effects. N is the LHS of an assignment.

      procedure Two_Pass_Aggregate_Expansion (N : Node_Id);
      --  If the aggregate consists only of iterated associations then the
      --  aggregate is constructed in two steps:
      --  a) Build an expression to compute the number of elements
      --     generated by each iterator, and use the expression to allocate
      --     the destination aggregate.
      --  b) Generate the loops corresponding to each iterator to insert
      --     the elements in their proper positions.

      ----------------------------
      -- Build_Constrained_Type --
      ----------------------------

      procedure Build_Constrained_Type (Positional : Boolean) is
         Loc      : constant Source_Ptr := Sloc (N);
         Agg_Type : constant Entity_Id  := Make_Temporary (Loc, 'A');
         Comp     : Node_Id;
         Decl     : Node_Id;
         Typ      : constant Entity_Id := Etype (N);
         Indexes  : constant List_Id   := New_List;
         Num      : Nat;
         Sub_Agg  : Node_Id;

      begin
         --  If the aggregate is purely positional, all its subaggregates
         --  have the same size. We collect the dimensions from the first
         --  subaggregate at each level.

         if Positional then
            Sub_Agg := N;

            for D in 1 .. Number_Dimensions (Typ) loop
               Sub_Agg := First (Expressions (Sub_Agg));

               Comp := Sub_Agg;
               Num := 0;
               while Present (Comp) loop
                  Num := Num + 1;
                  Next (Comp);
               end loop;

               Append_To (Indexes,
                 Make_Range (Loc,
                   Low_Bound  => Make_Integer_Literal (Loc, 1),
                   High_Bound => Make_Integer_Literal (Loc, Num)));
            end loop;

         else
            --  We know the aggregate type is unconstrained and the aggregate
            --  is not processable by the back end, therefore not necessarily
            --  positional. Retrieve each dimension bounds (computed earlier).

            for D in 1 .. Number_Dimensions (Typ) loop
               Append_To (Indexes,
                 Make_Range (Loc,
                   Low_Bound  => Aggr_Low  (D),
                   High_Bound => Aggr_High (D)));
            end loop;
         end if;

         Decl :=
           Make_Full_Type_Declaration (Loc,
               Defining_Identifier => Agg_Type,
               Type_Definition     =>
                 Make_Constrained_Array_Definition (Loc,
                   Discrete_Subtype_Definitions => Indexes,
                   Component_Definition         =>
                     Make_Component_Definition (Loc,
                       Aliased_Present    => False,
                       Subtype_Indication =>
                         New_Occurrence_Of (Component_Type (Typ), Loc))));

         Insert_Action (N, Decl);
         Analyze (Decl);
         Set_Etype (N, Agg_Type);
         Set_Is_Itype (Agg_Type);
         Freeze_Itype (Agg_Type, N);
      end Build_Constrained_Type;

      ------------------
      -- Check_Bounds --
      ------------------

      procedure Check_Bounds (Aggr_Bounds_Node, Index_Bounds_Node : Node_Id) is
         Aggr_Bounds : constant Range_Nodes :=
           Get_Index_Bounds (Aggr_Bounds_Node);
         Ind_Bounds  : constant Range_Nodes :=
           Get_Index_Bounds (Index_Bounds_Node);

         Cond : Node_Id := Empty;

      begin
         --  Generate the following test:

         --    [constraint_error when
         --      Aggr_Bounds.First <= Aggr_Bounds.Last and then
         --        (Aggr_Bounds.First < Ind_Bounds.First
         --         or else Aggr_Bounds.Last > Ind_Bounds.Last)]

         --  As an optimization try to see if some tests are trivially vacuous
         --  because we are comparing an expression against itself.

         if Aggr_Bounds.First = Ind_Bounds.First
           and then Aggr_Bounds.Last = Ind_Bounds.Last
         then
            Cond := Empty;

         elsif Aggr_Bounds.Last = Ind_Bounds.Last then
            Cond :=
              Make_Op_Lt (Loc,
                Left_Opnd  =>
                  Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
                Right_Opnd =>
                  Duplicate_Subexpr_Move_Checks (Ind_Bounds.First));

         elsif Aggr_Bounds.First = Ind_Bounds.First then
            Cond :=
              Make_Op_Gt (Loc,
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Bounds.Last),
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Bounds.Last));

         else
            Cond :=
              Make_Or_Else (Loc,
                Left_Opnd =>
                  Make_Op_Lt (Loc,
                    Left_Opnd  =>
                      Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
                    Right_Opnd =>
                      Duplicate_Subexpr_Move_Checks (Ind_Bounds.First)),

                Right_Opnd =>
                  Make_Op_Gt (Loc,
                    Left_Opnd  => Duplicate_Subexpr (Aggr_Bounds.Last),
                    Right_Opnd => Duplicate_Subexpr (Ind_Bounds.Last)));
         end if;

         if Present (Cond) then
            Cond :=
              Make_And_Then (Loc,
                Left_Opnd =>
                  Make_Op_Le (Loc,
                    Left_Opnd  =>
                      Duplicate_Subexpr_Move_Checks (Aggr_Bounds.First),
                    Right_Opnd =>
                      Duplicate_Subexpr_Move_Checks (Aggr_Bounds.Last)),

                Right_Opnd => Cond);

            Set_Analyzed (Left_Opnd  (Left_Opnd (Cond)), False);
            Set_Analyzed (Right_Opnd (Left_Opnd (Cond)), False);
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition => Cond,
                Reason    => CE_Range_Check_Failed));
         end if;
      end Check_Bounds;

      ----------------------------
      -- Check_Same_Aggr_Bounds --
      ----------------------------

      procedure Check_Same_Aggr_Bounds (Sub_Aggr : Node_Id; Dim : Pos) is
         Sub_Lo : constant Node_Id := Low_Bound (Aggregate_Bounds (Sub_Aggr));
         Sub_Hi : constant Node_Id := High_Bound (Aggregate_Bounds (Sub_Aggr));
         --  The bounds of this specific subaggregate

         Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
         Aggr_Hi : constant Node_Id := Aggr_High (Dim);
         --  The bounds of the aggregate for this dimension

         Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
         --  The index type for this dimension.xxx

         Cond  : Node_Id := Empty;
         Assoc : Node_Id;
         Expr  : Node_Id;

      begin
         --  If index checks are on generate the test

         --    [constraint_error when
         --      Aggr_Lo /= Sub_Lo or else Aggr_Hi /= Sub_Hi]

         --  As an optimization try to see if some tests are trivially vacuos
         --  because we are comparing an expression against itself. Also for
         --  the first dimension the test is trivially vacuous because there
         --  is just one aggregate for dimension 1.

         if Index_Checks_Suppressed (Ind_Typ) then
            Cond := Empty;

         elsif Dim = 1 or else (Aggr_Lo = Sub_Lo and then Aggr_Hi = Sub_Hi)
         then
            Cond := Empty;

         elsif Aggr_Hi = Sub_Hi then
            Cond :=
              Make_Op_Ne (Loc,
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo));

         elsif Aggr_Lo = Sub_Lo then
            Cond :=
              Make_Op_Ne (Loc,
                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
                Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Hi));

         else
            Cond :=
              Make_Or_Else (Loc,
                Left_Opnd =>
                  Make_Op_Ne (Loc,
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo)),

                Right_Opnd =>
                  Make_Op_Ne (Loc,
                    Left_Opnd  => Duplicate_Subexpr (Aggr_Hi),
                    Right_Opnd => Duplicate_Subexpr (Sub_Hi)));
         end if;

         if Present (Cond) then
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition => Cond,
                Reason    => CE_Length_Check_Failed));
         end if;

         --  Now look inside the subaggregate to see if there is more work

         if Dim < Aggr_Dimension then

            --  Process positional components

            if Present (Expressions (Sub_Aggr)) then
               Expr := First (Expressions (Sub_Aggr));
               while Present (Expr) loop
                  Check_Same_Aggr_Bounds (Expr, Dim + 1);
                  Next (Expr);
               end loop;
            end if;

            --  Process component associations

            if Present (Component_Associations (Sub_Aggr)) then
               Assoc := First (Component_Associations (Sub_Aggr));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Check_Same_Aggr_Bounds (Expr, Dim + 1);
                  Next (Assoc);
               end loop;
            end if;
         end if;
      end Check_Same_Aggr_Bounds;

      ----------------------------
      -- Compute_Others_Present --
      ----------------------------

      procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos) is
         Assoc : Node_Id;
         Expr  : Node_Id;

      begin
         if Present (Component_Associations (Sub_Aggr)) then
            Assoc := Last (Component_Associations (Sub_Aggr));

            if Nkind (First (Choice_List (Assoc))) = N_Others_Choice then
               Others_Present (Dim) := True;

               --  An others_clause may be superfluous if previous components
               --  cover the full given range of a constrained array. In such
               --  a case an others_clause does not contribute any additional
               --  components and has not been analyzed. We analyze it now to
               --  detect type errors in the expression, even though no code
               --  will be generated for it.

               if Dim = Aggr_Dimension
                 and then Nkind (Assoc) /= N_Iterated_Component_Association
                 and then not Analyzed (Expression (Assoc))
                 and then not Box_Present (Assoc)
               then
                  Preanalyze_And_Resolve (Expression (Assoc), Ctyp);
               end if;
            end if;
         end if;

         --  Now look inside the subaggregate to see if there is more work

         if Dim < Aggr_Dimension then

            --  Process positional components

            if Present (Expressions (Sub_Aggr)) then
               Expr := First (Expressions (Sub_Aggr));
               while Present (Expr) loop
                  Compute_Others_Present (Expr, Dim + 1);
                  Next (Expr);
               end loop;
            end if;

            --  Process component associations

            if Present (Component_Associations (Sub_Aggr)) then
               Assoc := First (Component_Associations (Sub_Aggr));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Compute_Others_Present (Expr, Dim + 1);
                  Next (Assoc);
               end loop;
            end if;
         end if;
      end Compute_Others_Present;

      ------------------
      -- Others_Check --
      ------------------

      procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos) is
         Aggr_Lo : constant Node_Id := Aggr_Low (Dim);
         Aggr_Hi : constant Node_Id := Aggr_High (Dim);
         --  The bounds of the aggregate for this dimension

         Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
         --  The index type for this dimension

         Need_To_Check : Boolean := False;

         Choices_Lo : Node_Id := Empty;
         Choices_Hi : Node_Id := Empty;
         --  The lowest and highest discrete choices for a named subaggregate

         Nb_Choices : Int := -1;
         --  The number of discrete non-others choices in this subaggregate

         Nb_Elements : Uint := Uint_0;
         --  The number of elements in a positional aggregate

         Cond : Node_Id := Empty;

         Assoc  : Node_Id;
         Choice : Node_Id;
         Expr   : Node_Id;

      begin
         --  Check if we have an others choice. If we do make sure that this
         --  subaggregate contains at least one element in addition to the
         --  others choice.

         if Range_Checks_Suppressed (Ind_Typ) then
            Need_To_Check := False;

         elsif Present (Expressions (Sub_Aggr))
           and then Present (Component_Associations (Sub_Aggr))
         then
            Need_To_Check := True;

         elsif Present (Component_Associations (Sub_Aggr)) then
            Assoc := Last (Component_Associations (Sub_Aggr));

            if Nkind (First (Choice_List (Assoc))) /= N_Others_Choice then
               Need_To_Check := False;

            else
               --  Count the number of discrete choices. Start with -1 because
               --  the others choice does not count.

               --  Is there some reason we do not use List_Length here ???

               Nb_Choices := -1;
               Assoc := First (Component_Associations (Sub_Aggr));
               while Present (Assoc) loop
                  Choice := First (Choice_List (Assoc));
                  while Present (Choice) loop
                     Nb_Choices := Nb_Choices + 1;
                     Next (Choice);
                  end loop;

                  Next (Assoc);
               end loop;

               --  If there is only an others choice nothing to do

               Need_To_Check := (Nb_Choices > 0);
            end if;

         else
            Need_To_Check := False;
         end if;

         --  If we are dealing with a positional subaggregate with an others
         --  choice then compute the number or positional elements.

         if Need_To_Check and then Present (Expressions (Sub_Aggr)) then
            Expr := First (Expressions (Sub_Aggr));
            Nb_Elements := Uint_0;
            while Present (Expr) loop
               Nb_Elements := Nb_Elements + 1;
               Next (Expr);
            end loop;

         --  If the aggregate contains discrete choices and an others choice
         --  compute the smallest and largest discrete choice values.

         elsif Need_To_Check then
            Compute_Choices_Lo_And_Choices_Hi : declare

               Table : Case_Table_Type (1 .. Nb_Choices);
               --  Used to sort all the different choice values

               J    : Pos := 1;

            begin
               Assoc := First (Component_Associations (Sub_Aggr));
               while Present (Assoc) loop
                  Choice := First (Choice_List (Assoc));
                  while Present (Choice) loop
                     if Nkind (Choice) = N_Others_Choice then
                        exit;
                     end if;

                     declare
                        Bounds : constant Range_Nodes :=
                          Get_Index_Bounds (Choice);
                     begin
                        Table (J).Choice_Lo := Bounds.First;
                        Table (J).Choice_Hi := Bounds.Last;
                     end;

                     J := J + 1;
                     Next (Choice);
                  end loop;

                  Next (Assoc);
               end loop;

               --  Sort the discrete choices

               Sort_Case_Table (Table);

               Choices_Lo := Table (1).Choice_Lo;
               Choices_Hi := Table (Nb_Choices).Choice_Hi;
            end Compute_Choices_Lo_And_Choices_Hi;
         end if;

         --  If no others choice in this subaggregate, or the aggregate
         --  comprises only an others choice, nothing to do.

         if not Need_To_Check then
            Cond := Empty;

         --  If we are dealing with an aggregate containing an others choice
         --  and positional components, we generate the following test:

         --    if Ind_Typ'Pos (Aggr_Lo) + (Nb_Elements - 1) >
         --            Ind_Typ'Pos (Aggr_Hi)
         --    then
         --       raise Constraint_Error;
         --    end if;

         --  in the general case, but the following simpler test:

         --    [constraint_error when
         --      Aggr_Lo + (Nb_Elements - 1) > Aggr_Hi];

         --  instead if the index type is a signed integer.

         elsif Nb_Elements > Uint_0 then
            if Nb_Elements = Uint_1 then
               Cond :=
                 Make_Op_Gt (Loc,
                   Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
                   Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi));

            elsif Is_Signed_Integer_Type (Ind_Typ) then
               Cond :=
                 Make_Op_Gt (Loc,
                   Left_Opnd  =>
                     Make_Op_Add (Loc,
                       Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
                       Right_Opnd =>
                         Make_Integer_Literal (Loc, Nb_Elements - 1)),
                   Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi));

            else
               Cond :=
                 Make_Op_Gt (Loc,
                   Left_Opnd  =>
                     Make_Op_Add (Loc,
                       Left_Opnd  =>
                         Make_Attribute_Reference (Loc,
                           Prefix         => New_Occurrence_Of (Ind_Typ, Loc),
                           Attribute_Name => Name_Pos,
                           Expressions    =>
                             New_List
                               (Duplicate_Subexpr_Move_Checks (Aggr_Lo))),
                   Right_Opnd => Make_Integer_Literal (Loc, Nb_Elements - 1)),

                   Right_Opnd =>
                     Make_Attribute_Reference (Loc,
                       Prefix         => New_Occurrence_Of (Ind_Typ, Loc),
                       Attribute_Name => Name_Pos,
                       Expressions    => New_List (
                         Duplicate_Subexpr_Move_Checks (Aggr_Hi))));
            end if;

         --  If we are dealing with an aggregate containing an others choice
         --  and discrete choices we generate the following test:

         --    [constraint_error when
         --      Choices_Lo < Aggr_Lo or else Choices_Hi > Aggr_Hi];

         else
            Cond :=
              Make_Or_Else (Loc,
                Left_Opnd =>
                  Make_Op_Lt (Loc,
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Choices_Lo),
                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Lo)),

                Right_Opnd =>
                  Make_Op_Gt (Loc,
                    Left_Opnd  => Duplicate_Subexpr (Choices_Hi),
                    Right_Opnd => Duplicate_Subexpr (Aggr_Hi)));
         end if;

         if Present (Cond) then
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition => Cond,
                Reason    => CE_Length_Check_Failed));
            --  Questionable reason code, shouldn't that be a
            --  CE_Range_Check_Failed ???
         end if;

         --  Now look inside the subaggregate to see if there is more work

         if Dim < Aggr_Dimension then

            --  Process positional components

            if Present (Expressions (Sub_Aggr)) then
               Expr := First (Expressions (Sub_Aggr));
               while Present (Expr) loop
                  Others_Check (Expr, Dim + 1);
                  Next (Expr);
               end loop;
            end if;

            --  Process component associations

            if Present (Component_Associations (Sub_Aggr)) then
               Assoc := First (Component_Associations (Sub_Aggr));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Others_Check (Expr, Dim + 1);
                  Next (Assoc);
               end loop;
            end if;
         end if;
      end Others_Check;

      -------------------------
      -- Safe_Left_Hand_Side --
      -------------------------

      function Safe_Left_Hand_Side (N : Node_Id) return Boolean is
         function Is_Safe_Index (Indx : Node_Id) return Boolean;
         --  If the left-hand side includes an indexed component, check that
         --  the indexes are free of side effects.

         -------------------
         -- Is_Safe_Index --
         -------------------

         function Is_Safe_Index (Indx : Node_Id) return Boolean is
         begin
            if Is_Entity_Name (Indx) then
               return True;

            elsif Nkind (Indx) = N_Integer_Literal then
               return True;

            elsif Nkind (Indx) = N_Function_Call
              and then Is_Entity_Name (Name (Indx))
              and then Has_Pragma_Pure_Function (Entity (Name (Indx)))
            then
               return True;

            elsif Nkind (Indx) = N_Type_Conversion
              and then Is_Safe_Index (Expression (Indx))
            then
               return True;

            else
               return False;
            end if;
         end Is_Safe_Index;

      --  Start of processing for Safe_Left_Hand_Side

      begin
         if Is_Entity_Name (N) then
            return True;

         elsif Nkind (N) in N_Explicit_Dereference | N_Selected_Component
           and then Safe_Left_Hand_Side (Prefix (N))
         then
            return True;

         elsif Nkind (N) = N_Indexed_Component
           and then Safe_Left_Hand_Side (Prefix (N))
           and then Is_Safe_Index (First (Expressions (N)))
         then
            return True;

         elsif Nkind (N) = N_Unchecked_Type_Conversion then
            return Safe_Left_Hand_Side (Expression (N));

         else
            return False;
         end if;
      end Safe_Left_Hand_Side;

      ----------------------------------
      -- Two_Pass_Aggregate_Expansion --
      ----------------------------------

      procedure Two_Pass_Aggregate_Expansion (N : Node_Id) is
         Loc        : constant Source_Ptr := Sloc (N);
         Comp_Type  : constant Entity_Id := Etype (N);
         Index_Id   : constant Entity_Id := Make_Temporary (Loc, 'I', N);
         Index_Type : constant Entity_Id := Etype (First_Index (Etype (N)));
         Size_Id    : constant Entity_Id := Make_Temporary (Loc, 'I', N);
         TmpE       : constant Entity_Id := Make_Temporary (Loc, 'A', N);

         Assoc    : Node_Id := First (Component_Associations (N));
         Incr     : Node_Id;
         Iter     : Node_Id;
         New_Comp : Node_Id;
         One_Loop : Node_Id;

         Size_Expr_Code : List_Id;
         Insertion_Code : List_Id := New_List;

      begin
         Size_Expr_Code := New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Size_Id,
             Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc),
             Expression          => Make_Integer_Literal (Loc, 0)));

         --  First pass: execute the iterators to count the number of elements
         --  that will be generated.

         while Present (Assoc) loop
            Iter := Iterator_Specification (Assoc);
            Incr := Make_Assignment_Statement (Loc,
                      Name => New_Occurrence_Of (Size_Id, Loc),
                      Expression =>
                        Make_Op_Add (Loc,
                         Left_Opnd  => New_Occurrence_Of (Size_Id, Loc),
                         Right_Opnd => Make_Integer_Literal (Loc, 1)));

            One_Loop := Make_Loop_Statement (Loc,
              Iteration_Scheme =>
                Make_Iteration_Scheme (Loc,
                  Iterator_Specification =>  New_Copy_Tree (Iter)),
                Statements => New_List (Incr));

            Append (One_Loop, Size_Expr_Code);
            Next (Assoc);
         end loop;

         Insert_Actions (N, Size_Expr_Code);

         --  Build a constrained subtype with the calculated length
         --  and declare the proper bounded aggregate object.
         --  The index type is some discrete type, so the bounds of the
         --  constructed array are computed as T'Val (T'Pos (ineger bound));

         declare
            Pos_Lo : constant Node_Id :=
              Make_Attribute_Reference (Loc,
                Prefix => New_Occurrence_Of (Index_Type, Loc),
                Attribute_Name => Name_Pos,
                Expressions => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix => New_Occurrence_Of (Index_Type, Loc),
                    Attribute_Name => Name_First)));

            Aggr_Lo : constant Node_Id :=
               Make_Attribute_Reference (Loc,
                 Prefix => New_Occurrence_Of (Index_Type, Loc),
                 Attribute_Name => Name_Val,
                 Expressions => New_List (New_Copy_Tree (Pos_Lo)));

            --  Hi = Index_type'Pos (Lo + Size -1).

            Pos_Hi : constant Node_Id :=
               Make_Op_Add (Loc,
                 Left_Opnd => New_Copy_Tree (Pos_Lo),
                 Right_Opnd =>
                   Make_Op_Subtract (Loc,
                     Left_Opnd  => New_Occurrence_Of (Size_Id, Loc),
                     Right_Opnd => Make_Integer_Literal (Loc, 1)));

            --  Corresponding index value

            Aggr_Hi : constant Node_Id :=
               Make_Attribute_Reference (Loc,
                 Prefix => New_Occurrence_Of (Index_Type, Loc),
                 Attribute_Name => Name_Val,
                 Expressions => New_List (New_Copy_Tree (Pos_Hi)));

            SubE : constant Entity_Id := Make_Temporary (Loc, 'T');
            SubD : constant Node_Id :=
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => SubE,
                Subtype_Indication  =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (Etype (Comp_Type), Loc),
                    Constraint =>
                      Make_Index_Or_Discriminant_Constraint
                        (Loc,
                         Constraints =>
                           New_List (Make_Range (Loc, Aggr_Lo, Aggr_Hi)))));

               --  Create a temporary array of the above subtype which
               --  will be used to capture the aggregate assignments.

               TmpD : constant Node_Id :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => TmpE,
                   Object_Definition   => New_Occurrence_Of (SubE, Loc));
         begin
            Insert_Actions (N, New_List (SubD, TmpD));
         end;

         --  Second pass: use the iterators to generate the elements of the
         --  aggregate. Insertion index starts at Index_Type'First. We
         --  assume that the second evaluation of each iterator generates
         --  the same number of elements as the first pass, and consider
         --  that the execution is erroneous (even if the RM does not state
         --  this explicitly) if the number of elements generated differs
         --  between first and second pass.

         Assoc := First (Component_Associations (N));

         --  Initialize insertion position to first array component.

         Insertion_Code := New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Index_Id,
             Object_Definition   =>
               New_Occurrence_Of (Index_Type, Loc),
             Expression =>
               Make_Attribute_Reference (Loc,
                 Prefix => New_Occurrence_Of (Index_Type, Loc),
                 Attribute_Name => Name_First)));

         while Present (Assoc) loop
            Iter := Iterator_Specification (Assoc);
            New_Comp := Make_Assignment_Statement (Loc,
               Name =>
                 Make_Indexed_Component (Loc,
                    Prefix => New_Occurrence_Of (TmpE, Loc),
                    Expressions =>
                      New_List (New_Occurrence_Of (Index_Id, Loc))),
               Expression => New_Copy_Tree (Expression (Assoc)));

            --  Advance index position for insertion.

            Incr := Make_Assignment_Statement (Loc,
                      Name => New_Occurrence_Of (Index_Id, Loc),
                      Expression =>
                        Make_Attribute_Reference (Loc,
                          Prefix =>
                            New_Occurrence_Of (Index_Type, Loc),
                          Attribute_Name => Name_Succ,
                          Expressions =>
                            New_List (New_Occurrence_Of (Index_Id, Loc))));

            --  Add guard to skip last increment when upper bound is reached.

            Incr := Make_If_Statement (Loc,
               Condition =>
                  Make_Op_Ne (Loc,
                  Left_Opnd  => New_Occurrence_Of (Index_Id, Loc),
                  Right_Opnd =>
                    Make_Attribute_Reference (Loc,
                      Prefix => New_Occurrence_Of (Index_Type, Loc),
                      Attribute_Name => Name_Last)),
               Then_Statements => New_List (Incr));

            One_Loop := Make_Loop_Statement (Loc,
              Iteration_Scheme =>
                Make_Iteration_Scheme (Loc,
                  Iterator_Specification =>  Copy_Separate_Tree (Iter)),
                Statements => New_List (New_Comp, Incr));

            Append (One_Loop, Insertion_Code);
            Next (Assoc);
         end loop;

         Insert_Actions (N, Insertion_Code);

         --  Depending on context this may not work for build-in-place
         --  arrays ???

         Rewrite (N, New_Occurrence_Of (TmpE, Loc));

      end Two_Pass_Aggregate_Expansion;

      --  Local variables

      Tmp : Entity_Id;
      --  Holds the temporary aggregate value

      Tmp_Decl : Node_Id;
      --  Holds the declaration of Tmp

      Aggr_Code   : List_Id;
      Parent_Node : Node_Id;
      Parent_Kind : Node_Kind;

   --  Start of processing for Expand_Array_Aggregate

   begin
      --  Do not touch the special aggregates of attributes used for Asm calls

      if Is_RTE (Ctyp, RE_Asm_Input_Operand)
        or else Is_RTE (Ctyp, RE_Asm_Output_Operand)
      then
         return;

      --  Do not expand an aggregate for an array type which contains tasks if
      --  the aggregate is associated with an unexpanded return statement of a
      --  build-in-place function. The aggregate is expanded when the related
      --  return statement (rewritten into an extended return) is processed.
      --  This delay ensures that any temporaries and initialization code
      --  generated for the aggregate appear in the proper return block and
      --  use the correct _chain and _master.

      elsif Has_Task (Base_Type (Etype (N)))
        and then Nkind (Parent (N)) = N_Simple_Return_Statement
        and then Is_Build_In_Place_Function
                   (Return_Applies_To (Return_Statement_Entity (Parent (N))))
      then
         return;

      elsif Present (Component_Associations (N))
        and then Nkind (First (Component_Associations (N))) =
                 N_Iterated_Component_Association
        and then
          Present (Iterator_Specification (First (Component_Associations (N))))
      then
         Two_Pass_Aggregate_Expansion (N);
         return;

      --  Do not attempt expansion if error already detected. We may reach this
      --  point in spite of previous errors when compiling with -gnatq, to
      --  force all possible errors (this is the usual ACATS mode).

      elsif Error_Posted (N) then
         return;
      end if;

      --  If the semantic analyzer has determined that aggregate N will raise
      --  Constraint_Error at run time, then the aggregate node has been
      --  replaced with an N_Raise_Constraint_Error node and we should
      --  never get here.

      pragma Assert (not Raises_Constraint_Error (N));

      --  STEP 1a

      --  Check that the index range defined by aggregate bounds is
      --  compatible with corresponding index subtype.

      Index_Compatibility_Check : declare
         Aggr_Index_Range : Node_Id := First_Index (Typ);
         --  The current aggregate index range

         Index_Constraint : Node_Id := First_Index (Etype (Typ));
         --  The corresponding index constraint against which we have to
         --  check the above aggregate index range.

      begin
         Compute_Others_Present (N, 1);

         for J in 1 .. Aggr_Dimension loop
            --  There is no need to emit a check if an others choice is present
            --  for this array aggregate dimension since in this case one of
            --  N's subaggregates has taken its bounds from the context and
            --  these bounds must have been checked already. In addition all
            --  subaggregates corresponding to the same dimension must all have
            --  the same bounds (checked in (c) below).

            if not Range_Checks_Suppressed (Etype (Index_Constraint))
              and then not Others_Present (J)
            then
               --  We don't use Checks.Apply_Range_Check here because it emits
               --  a spurious check. Namely it checks that the range defined by
               --  the aggregate bounds is nonempty. But we know this already
               --  if we get here.

               Check_Bounds (Aggr_Index_Range, Index_Constraint);
            end if;

            --  Save the low and high bounds of the aggregate index as well as
            --  the index type for later use in checks (b) and (c) below.

            Aggr_Low  (J) := Low_Bound (Aggr_Index_Range);
            Aggr_High (J) := High_Bound (Aggr_Index_Range);

            Aggr_Index_Typ (J) := Etype (Index_Constraint);

            Next_Index (Aggr_Index_Range);
            Next_Index (Index_Constraint);
         end loop;
      end Index_Compatibility_Check;

      --  STEP 1b

      --  If an others choice is present check that no aggregate index is
      --  outside the bounds of the index constraint.

      Others_Check (N, 1);

      --  STEP 1c

      --  For multidimensional arrays make sure that all subaggregates
      --  corresponding to the same dimension have the same bounds.

      if Aggr_Dimension > 1 then
         Check_Same_Aggr_Bounds (N, 1);
      end if;

      --  STEP 1d

      --  If we have a default component value, or simple initialization is
      --  required for the component type, then we replace <> in component
      --  associations by the required default value.

      declare
         Default_Val : Node_Id;
         Assoc       : Node_Id;

      begin
         if (Present (Default_Aspect_Component_Value (Typ))
              or else Needs_Simple_Initialization (Ctyp))
           and then Present (Component_Associations (N))
         then
            Assoc := First (Component_Associations (N));
            while Present (Assoc) loop
               if Nkind (Assoc) = N_Component_Association
                 and then Box_Present (Assoc)
               then
                  Set_Box_Present (Assoc, False);

                  if Present (Default_Aspect_Component_Value (Typ)) then
                     Default_Val := Default_Aspect_Component_Value (Typ);
                  else
                     Default_Val := Get_Simple_Init_Val (Ctyp, N);
                  end if;

                  Set_Expression (Assoc, New_Copy_Tree (Default_Val));
                  Analyze_And_Resolve (Expression (Assoc), Ctyp);
               end if;

               Next (Assoc);
            end loop;
         end if;
      end;

      --  STEP 2

      --  Here we test for is packed array aggregate that we can handle at
      --  compile time. If so, return with transformation done. Note that we do
      --  this even if the aggregate is nested, because once we have done this
      --  processing, there is no more nested aggregate.

      if Packed_Array_Aggregate_Handled (N) then
         return;
      end if;

      --  At this point we try to convert to positional form

      Convert_To_Positional (N);

      --  If the result is no longer an aggregate (e.g. it may be a string
      --  literal, or a temporary which has the needed value), then we are
      --  done, since there is no longer a nested aggregate.

      if Nkind (N) /= N_Aggregate then
         return;

      --  We are also done if the result is an analyzed aggregate, indicating
      --  that Convert_To_Positional succeeded and reanalyzed the rewritten
      --  aggregate.

      elsif Analyzed (N) and then Is_Rewrite_Substitution (N) then
         return;
      end if;

      --  If all aggregate components are compile-time known and the aggregate
      --  has been flattened, nothing left to do. The same occurs if the
      --  aggregate is used to initialize the components of a statically
      --  allocated dispatch table.

      if Compile_Time_Known_Aggregate (N)
        or else Is_Static_Dispatch_Table_Aggregate (N)
      then
         Set_Expansion_Delayed (N, False);
         return;
      end if;

      --  Now see if back end processing is possible

      if Backend_Processing_Possible (N) then

         --  If the aggregate is static but the constraints are not, build
         --  a static subtype for the aggregate, so that Gigi can place it
         --  in static memory. Perform an unchecked_conversion to the non-
         --  static type imposed by the context.

         declare
            Itype      : constant Entity_Id := Etype (N);
            Index      : Node_Id;
            Needs_Type : Boolean := False;

         begin
            Index := First_Index (Itype);
            while Present (Index) loop
               if not Is_OK_Static_Subtype (Etype (Index)) then
                  Needs_Type := True;
                  exit;
               else
                  Next_Index (Index);
               end if;
            end loop;

            if Needs_Type then
               Build_Constrained_Type (Positional => True);
               Rewrite (N, Unchecked_Convert_To (Itype, N));
               Analyze (N);
            end if;
         end;

         return;
      end if;

      --  STEP 3

      --  Delay expansion for nested aggregates: it will be taken care of when
      --  the parent aggregate is expanded.

      Parent_Node := Parent (N);
      Parent_Kind := Nkind (Parent_Node);

      if Parent_Kind = N_Qualified_Expression then
         Parent_Node := Parent (Parent_Node);
         Parent_Kind := Nkind (Parent_Node);
      end if;

      if Parent_Kind = N_Aggregate
        or else Parent_Kind = N_Extension_Aggregate
        or else Parent_Kind = N_Component_Association
        or else (Parent_Kind = N_Object_Declaration
                  and then Needs_Finalization (Typ))
        or else (Parent_Kind = N_Assignment_Statement
                  and then Inside_Init_Proc)
      then
         Set_Expansion_Delayed (N, not Static_Array_Aggregate (N));
         return;
      end if;

      --  STEP 4

      --  Check whether in-place aggregate expansion is possible

      --  For object declarations we build the aggregate in place, unless
      --  the array is bit-packed.

      --  For assignments we do the assignment in place if all the component
      --  associations have compile-time known values, or are default-
      --  initialized limited components, e.g. tasks. For other cases we
      --  create a temporary. A full analysis for safety of in-place assignment
      --  is delicate.

      --  For allocators we assign to the designated object in place if the
      --  aggregate meets the same conditions as other in-place assignments.
      --  In this case the aggregate may not come from source but was created
      --  for default initialization, e.g. with Initialize_Scalars.

      if Requires_Transient_Scope (Typ) then
         Establish_Transient_Scope (N, Manage_Sec_Stack => False);
      end if;

      --  An array of limited components is built in place

      if Is_Limited_Type (Typ) then
         Maybe_In_Place_OK := True;

      elsif Has_Default_Init_Comps (N) then
         Maybe_In_Place_OK := False;

      elsif Is_Bit_Packed_Array (Typ)
        or else Has_Controlled_Component (Typ)
      then
         Maybe_In_Place_OK := False;

      elsif Parent_Kind = N_Assignment_Statement then
         Maybe_In_Place_OK :=
           In_Place_Assign_OK (N, Get_Base_Object (Name (Parent_Node)));

      elsif Parent_Kind = N_Allocator then
         Maybe_In_Place_OK := In_Place_Assign_OK (N);

      else
         Maybe_In_Place_OK := False;
      end if;

      --  If this is an array of tasks, it will be expanded into build-in-place
      --  assignments. Build an activation chain for the tasks now.

      if Has_Task (Etype (N)) then
         Build_Activation_Chain_Entity (N);
      end if;

      --  Perform in-place expansion of aggregate in an object declaration.
      --  Note: actions generated for the aggregate will be captured in an
      --  expression-with-actions statement so that they can be transferred
      --  to freeze actions later if there is an address clause for the
      --  object. (Note: we don't use a block statement because this would
      --  cause generated freeze nodes to be elaborated in the wrong scope).

      --  Arrays of limited components must be built in place. The code
      --  previously excluded controlled components but this is an old
      --  oversight: the rules in 7.6 (17) are clear.

      if Comes_From_Source (Parent_Node)
        and then Parent_Kind = N_Object_Declaration
        and then Present (Expression (Parent_Node))
        and then not
          Must_Slide (N, Etype (Defining_Identifier (Parent_Node)), Typ)
        and then not Is_Bit_Packed_Array (Typ)
      then
         In_Place_Assign_OK_For_Declaration := True;
         Tmp := Defining_Identifier (Parent_Node);
         Set_No_Initialization (Parent_Node);
         Set_Expression (Parent_Node, Empty);

         --  Set kind and type of the entity, for use in the analysis
         --  of the subsequent assignments. If the nominal type is not
         --  constrained, build a subtype from the known bounds of the
         --  aggregate. If the declaration has a subtype mark, use it,
         --  otherwise use the itype of the aggregate.

         Mutate_Ekind (Tmp, E_Variable);

         if not Is_Constrained (Typ) then
            Build_Constrained_Type (Positional => False);

         elsif Is_Entity_Name (Object_Definition (Parent_Node))
           and then Is_Constrained (Entity (Object_Definition (Parent_Node)))
         then
            Set_Etype (Tmp, Entity (Object_Definition (Parent_Node)));

         else
            Set_Size_Known_At_Compile_Time (Typ, False);
            Set_Etype (Tmp, Typ);
         end if;

      elsif Maybe_In_Place_OK and then Parent_Kind = N_Allocator then
         Set_Expansion_Delayed (N);
         return;

      --  Limited arrays in return statements are expanded when
      --  enclosing construct is expanded.

      elsif Maybe_In_Place_OK
        and then Parent_Kind = N_Simple_Return_Statement
      then
         Set_Expansion_Delayed (N);
         return;

      --  In the remaining cases the aggregate appears in the RHS of an
      --  assignment, which may be part of the expansion of an object
      --  delaration. If the aggregate is an actual in a call, itself
      --  possibly in a RHS, building it in the target is not possible.

      elsif Maybe_In_Place_OK
        and then Nkind (Parent_Node) not in N_Subprogram_Call
        and then Safe_Left_Hand_Side (Name (Parent_Node))
      then
         Tmp := Name (Parent_Node);

         if Etype (Tmp) /= Etype (N) then
            Apply_Length_Check (N, Etype (Tmp));

            if Nkind (N) = N_Raise_Constraint_Error then

               --  Static error, nothing further to expand

               return;
            end if;
         end if;

      --  If a slice assignment has an aggregate with a single others_choice,
      --  the assignment can be done in place even if bounds are not static,
      --  by converting it into a loop over the discrete range of the slice.

      elsif Maybe_In_Place_OK
        and then Nkind (Name (Parent_Node)) = N_Slice
        and then Is_Others_Aggregate (N)
      then
         Tmp := Name (Parent_Node);

         --  Set type of aggregate to be type of lhs in assignment, in order
         --  to suppress redundant length checks.

         Set_Etype (N, Etype (Tmp));

      --  Step 5

      --  In-place aggregate expansion is not possible

      else
         Maybe_In_Place_OK := False;
         Tmp := Make_Temporary (Loc, 'A', N);
         Tmp_Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Tmp,
             Object_Definition   => New_Occurrence_Of (Typ, Loc));
         Set_No_Initialization (Tmp_Decl, True);
         Set_Warnings_Off (Tmp);

         --  If we are within a loop, the temporary will be pushed on the
         --  stack at each iteration. If the aggregate is the expression
         --  for an allocator, it will be immediately copied to the heap
         --  and can be reclaimed at once. We create a transient scope
         --  around the aggregate for this purpose.

         if Ekind (Current_Scope) = E_Loop
           and then Parent_Kind = N_Allocator
         then
            Establish_Transient_Scope (N, Manage_Sec_Stack => False);
         end if;

         Insert_Action (N, Tmp_Decl);
      end if;

      --  Construct and insert the aggregate code. We can safely suppress index
      --  checks because this code is guaranteed not to raise CE on index
      --  checks. However we should *not* suppress all checks.

      declare
         Target : Node_Id;

      begin
         if Nkind (Tmp) = N_Defining_Identifier then
            Target := New_Occurrence_Of (Tmp, Loc);

         else
            if Has_Default_Init_Comps (N)
              and then not Maybe_In_Place_OK
            then
               --  Ada 2005 (AI-287): This case has not been analyzed???

               raise Program_Error;
            end if;

            --  Name in assignment is explicit dereference

            Target := New_Copy (Tmp);
         end if;

         --  If we are to generate an in-place assignment for a declaration or
         --  an assignment statement, and the assignment can be done directly
         --  by the back end, then do not expand further.

         --  ??? We can also do that if in-place expansion is not possible but
         --  then we could go into an infinite recursion.

         if (In_Place_Assign_OK_For_Declaration or else Maybe_In_Place_OK)
           and then not CodePeer_Mode
           and then not Modify_Tree_For_C
           and then not Possible_Bit_Aligned_Component (Target)
           and then not Is_Possibly_Unaligned_Slice (Target)
           and then Aggr_Assignment_OK_For_Backend (N)
         then
            if Maybe_In_Place_OK then
               return;
            end if;

            Aggr_Code :=
              New_List (
                Make_Assignment_Statement (Loc,
                  Name       => Target,
                  Expression => New_Copy_Tree (N)));

         else
            Aggr_Code :=
              Build_Array_Aggr_Code (N,
                Ctype       => Ctyp,
                Index       => First_Index (Typ),
                Into        => Target,
                Scalar_Comp => Is_Scalar_Type (Ctyp));
         end if;

         --  Save the last assignment statement associated with the aggregate
         --  when building a controlled object. This reference is utilized by
         --  the finalization machinery when marking an object as successfully
         --  initialized.

         if Needs_Finalization (Typ)
           and then Is_Entity_Name (Target)
           and then Present (Entity (Target))
           and then Ekind (Entity (Target)) in E_Constant | E_Variable
         then
            Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
         end if;
      end;

      --  If the aggregate is the expression in a declaration, the expanded
      --  code must be inserted after it. The defining entity might not come
      --  from source if this is part of an inlined body, but the declaration
      --  itself will.
      --  The test below looks very specialized and kludgy???

      if Comes_From_Source (Tmp)
        or else
          (Nkind (Parent (N)) = N_Object_Declaration
            and then Comes_From_Source (Parent (N))
            and then Tmp = Defining_Entity (Parent (N)))
      then
         if Parent_Kind /= N_Object_Declaration or else Is_Frozen (Tmp) then
            Insert_Actions_After (Parent_Node, Aggr_Code);
         else
            declare
               Comp_Stmt : constant Node_Id :=
                 Make_Compound_Statement
                   (Sloc (Parent_Node), Actions => Aggr_Code);
            begin
               Insert_Action_After (Parent_Node, Comp_Stmt);
               Set_Initialization_Statements (Tmp, Comp_Stmt);
            end;
         end if;
      else
         Insert_Actions (N, Aggr_Code);
      end if;

      --  If the aggregate has been assigned in place, remove the original
      --  assignment.

      if Parent_Kind = N_Assignment_Statement and then Maybe_In_Place_OK then
         Rewrite (Parent_Node, Make_Null_Statement (Loc));

      --  Or else, if a temporary was created, replace the aggregate with it

      elsif Parent_Kind /= N_Object_Declaration
        or else Tmp /= Defining_Identifier (Parent_Node)
      then
         Rewrite (N, New_Occurrence_Of (Tmp, Loc));
         Analyze_And_Resolve (N, Typ);
      end if;
   end Expand_Array_Aggregate;

   ------------------------
   -- Expand_N_Aggregate --
   ------------------------

   procedure Expand_N_Aggregate (N : Node_Id) is
      T : constant Entity_Id := Etype (N);
   begin
      --  Record aggregate case

      if Is_Record_Type (T)
        and then not Is_Private_Type (T)
      then
         Expand_Record_Aggregate (N);

      elsif Has_Aspect (T, Aspect_Aggregate) then
         Expand_Container_Aggregate (N);

      --  Array aggregate case

      else
         --  A special case, if we have a string subtype with bounds 1 .. N,
         --  where N is known at compile time, and the aggregate is of the
         --  form (others => 'x'), with a single choice and no expressions,
         --  and N is less than 80 (an arbitrary limit for now), then replace
         --  the aggregate by the equivalent string literal (but do not mark
         --  it as static since it is not).

         --  Note: this entire circuit is redundant with respect to code in
         --  Expand_Array_Aggregate that collapses others choices to positional
         --  form, but there are two problems with that circuit:

         --    a) It is limited to very small cases due to ill-understood
         --       interactions with bootstrapping. That limit is removed by
         --       use of the No_Implicit_Loops restriction.

         --    b) It incorrectly ends up with the resulting expressions being
         --       considered static when they are not. For example, the
         --       following test should fail:

         --           pragma Restrictions (No_Implicit_Loops);
         --           package NonSOthers4 is
         --              B  : constant String (1 .. 6) := (others => 'A');
         --              DH : constant String (1 .. 8) := B & "BB";
         --              X : Integer;
         --              pragma Export (C, X, Link_Name => DH);
         --           end;

         --       But it succeeds (DH looks static to pragma Export)

         --    To be sorted out ???

         if Present (Component_Associations (N)) then
            declare
               CA : constant Node_Id := First (Component_Associations (N));
               MX : constant         := 80;

            begin
               if Nkind (First (Choice_List (CA))) = N_Others_Choice
                 and then Nkind (Expression (CA)) = N_Character_Literal
                 and then No (Expressions (N))
               then
                  declare
                     X  : constant Node_Id := First_Index (T);
                     EC : constant Node_Id := Expression (CA);
                     CV : constant Uint    := Char_Literal_Value (EC);
                     CC : constant Int     := UI_To_Int (CV);

                  begin
                     if Nkind (X) = N_Range
                       and then Compile_Time_Known_Value (Low_Bound (X))
                       and then Expr_Value (Low_Bound (X)) = 1
                       and then Compile_Time_Known_Value (High_Bound (X))
                     then
                        declare
                           Hi : constant Uint := Expr_Value (High_Bound (X));

                        begin
                           if Hi <= MX then
                              Start_String;

                              for J in 1 .. UI_To_Int (Hi) loop
                                 Store_String_Char (Char_Code (CC));
                              end loop;

                              Rewrite (N,
                                Make_String_Literal (Sloc (N),
                                  Strval => End_String));

                              if CC >= Int (2 ** 16) then
                                 Set_Has_Wide_Wide_Character (N);
                              elsif CC >= Int (2 ** 8) then
                                 Set_Has_Wide_Character (N);
                              end if;

                              Analyze_And_Resolve (N, T);
                              Set_Is_Static_Expression (N, False);
                              return;
                           end if;
                        end;
                     end if;
                  end;
               end if;
            end;
         end if;

         --  Not that special case, so normal expansion of array aggregate

         Expand_Array_Aggregate (N);
      end if;

   exception
      when RE_Not_Available =>
         return;
   end Expand_N_Aggregate;

   --------------------------------
   -- Expand_Container_Aggregate --
   --------------------------------

   procedure Expand_Container_Aggregate (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id := Etype (N);
      Asp : constant Node_Id := Find_Value_Of_Aspect (Typ, Aspect_Aggregate);

      Empty_Subp          : Node_Id := Empty;
      Add_Named_Subp      : Node_Id := Empty;
      Add_Unnamed_Subp    : Node_Id := Empty;
      New_Indexed_Subp    : Node_Id := Empty;
      Assign_Indexed_Subp : Node_Id := Empty;

      Aggr_Code : constant List_Id   := New_List;
      Temp      : constant Entity_Id := Make_Temporary (Loc, 'C', N);

      Comp      : Node_Id;
      Decl      : Node_Id;
      Default   : Node_Id;
      Init_Stat : Node_Id;
      Siz       : Int;

      --  The following are used when the size of the aggregate is not
      --  static and requires a dynamic evaluation.
      Siz_Decl   : Node_Id;
      Siz_Exp    : Node_Id := Empty;
      Count_Type : Entity_Id;

      function Aggregate_Size return Int;
      --  Compute number of entries in aggregate, including choices
      --  that cover a range or subtype, as well as iterated constructs.
      --  Return -1 if the size is not known statically, in which case
      --  allocate a default size for the aggregate, or build an expression
      --  to estimate the size dynamically.

      function Build_Siz_Exp (Comp : Node_Id) return Int;
      --  When the aggregate contains a single Iterated_Component_Association
      --  or Element_Association with non-static bounds, build an expression
      --  to be used as the allocated size of the container. This may be an
      --  overestimate if a filter is present, but is a safe approximation.
      --  If bounds are dynamic the aggregate is created in two passes, and
      --  the first generates a loop for the sole purpose of computing the
      --  number of elements that will be generated on the seocnd pass.

      procedure Expand_Iterated_Component (Comp : Node_Id);
      --  Handle iterated_component_association and iterated_Element
      --  association by generating a loop over the specified range,
      --  given either by a loop parameter specification or an iterator
      --  specification.

      --------------------
      -- Aggregate_Size --
      --------------------

      function Aggregate_Size return Int is
         Comp   : Node_Id;
         Choice : Node_Id;
         Lo, Hi : Node_Id;
         Siz     : Int := 0;

         procedure Add_Range_Size;
         --  Compute number of components specified by a component association
         --  given by a range or subtype name.

         --------------------
         -- Add_Range_Size --
         --------------------

         procedure Add_Range_Size is
         begin
            --  The bounds of the discrete range are integers or enumeration
            --  literals

            if Nkind (Lo) = N_Integer_Literal then
               Siz := Siz + UI_To_Int (Intval (Hi))
                          - UI_To_Int (Intval (Lo)) + 1;
            else
               Siz := Siz + UI_To_Int (Enumeration_Pos (Hi))
                          - UI_To_Int (Enumeration_Pos (Lo)) + 1;
            end if;
         end Add_Range_Size;

      begin
         --  Aggregate is either all positional or all named.

         if Present (Expressions (N)) then
            Siz := List_Length (Expressions (N));
         end if;

         if Present (Component_Associations (N)) then
            Comp := First (Component_Associations (N));
            --  If there is a single component association it can be
            --  an iterated component with dynamic bounds or an element
            --  iterator over an iterable object. If it is an array
            --  we can use the attribute Length to get its size;
            --  for a predefined container the function Length plays
            --  the same role. There is no available mechanism for
            --  user-defined containers. For now we treat all of these
            --  as dynamic.

            if List_Length (Component_Associations (N)) = 1
              and then Nkind (Comp) in N_Iterated_Component_Association |
                                       N_Iterated_Element_Association
            then
               return Build_Siz_Exp (Comp);
            end if;

            --  Otherwise all associations must specify static sizes.

            while Present (Comp) loop
               Choice := First (Choice_List (Comp));

               while Present (Choice) loop
                  Analyze (Choice);

                  if Nkind (Choice) = N_Range then
                     Lo := Low_Bound (Choice);
                     Hi := High_Bound (Choice);
                     Add_Range_Size;

                  elsif Is_Entity_Name (Choice)
                    and then Is_Type (Entity (Choice))
                  then
                     Lo := Type_Low_Bound (Entity (Choice));
                     Hi := Type_High_Bound (Entity (Choice));
                     Add_Range_Size;

                     Rewrite (Choice,
                       Make_Range (Loc,
                         New_Copy_Tree (Lo),
                         New_Copy_Tree (Hi)));

                  else
                     --  Single choice (syntax excludes a subtype
                     --  indication).

                     Siz := Siz + 1;
                  end if;

                  Next (Choice);
               end loop;
               Next (Comp);
            end loop;
         end if;

         return Siz;
      end Aggregate_Size;

      -------------------
      -- Build_Siz_Exp --
      -------------------

      function Build_Siz_Exp (Comp : Node_Id) return Int is
         Lo, Hi : Node_Id;
      begin
         if Nkind (Comp) = N_Range then
            Lo := Low_Bound (Comp);
            Hi := High_Bound (Comp);
            Analyze (Lo);
            Analyze (Hi);

            --  Compute static size when possible.

            if Is_Static_Expression (Lo)
              and then Is_Static_Expression (Hi)
            then
               if Nkind (Lo) = N_Integer_Literal then
                  Siz := UI_To_Int (Intval (Hi)) - UI_To_Int (Intval (Lo)) + 1;
               else
                  Siz := UI_To_Int (Enumeration_Pos (Hi))
                       - UI_To_Int (Enumeration_Pos (Lo)) + 1;
               end if;
               return Siz;

            else
               Siz_Exp :=
                 Make_Op_Add (Sloc (Comp),
                   Left_Opnd =>
                     Make_Op_Subtract (Sloc (Comp),
                       Left_Opnd => New_Copy_Tree (Hi),
                       Right_Opnd => New_Copy_Tree (Lo)),
                   Right_Opnd =>
                     Make_Integer_Literal (Loc, 1));
               return -1;
            end if;

         elsif Nkind (Comp) = N_Iterated_Component_Association then
            return Build_Siz_Exp (First (Discrete_Choices (Comp)));

         elsif Nkind (Comp) = N_Iterated_Element_Association then
            return -1;

            --  ??? Need to create code for a loop and add to generated code,
            --  as is done for array aggregates with iterated element
            --  associations, instead of using Append operations.

         else
            return -1;
         end if;
      end Build_Siz_Exp;

      -------------------------------
      -- Expand_Iterated_Component --
      -------------------------------

      procedure Expand_Iterated_Component (Comp : Node_Id) is
         Expr    : constant Node_Id := Expression (Comp);

         Key_Expr           : Node_Id := Empty;
         Loop_Id            : Entity_Id;
         L_Range            : Node_Id;
         L_Iteration_Scheme : Node_Id;
         Loop_Stat          : Node_Id;
         Params             : List_Id;
         Stats              : List_Id;

      begin
         if Nkind (Comp) = N_Iterated_Element_Association then
            Key_Expr := Key_Expression (Comp);

            --  We create a new entity as loop identifier in all cases,
            --  as is done for generated loops elsewhere, as the loop
            --  structure has been previously analyzed.

            if Present (Iterator_Specification (Comp)) then

               --  Either an Iterator_Specification or a Loop_Parameter_
               --  Specification is present.

               L_Iteration_Scheme :=
                 Make_Iteration_Scheme (Loc,
                   Iterator_Specification => Iterator_Specification (Comp));
               Loop_Id :=
                  Make_Defining_Identifier (Loc,
                    Chars => Chars (Defining_Identifier
                               (Iterator_Specification (Comp))));
               Set_Defining_Identifier
                  (Iterator_Specification (L_Iteration_Scheme), Loop_Id);

            else
               L_Iteration_Scheme :=
                 Make_Iteration_Scheme (Loc,
                   Loop_Parameter_Specification =>
                     Loop_Parameter_Specification (Comp));
               Loop_Id :=
                 Make_Defining_Identifier (Loc,
                   Chars => Chars (Defining_Identifier
                              (Loop_Parameter_Specification (Comp))));
               Set_Defining_Identifier
                 (Loop_Parameter_Specification
                    (L_Iteration_Scheme), Loop_Id);
            end if;
         else

            --  Iterated_Component_Association.

            Loop_Id :=
              Make_Defining_Identifier (Loc,
                Chars => Chars (Defining_Identifier (Comp)));

            if Present (Iterator_Specification (Comp)) then
               L_Iteration_Scheme :=
                 Make_Iteration_Scheme (Loc,
                   Iterator_Specification => Iterator_Specification (Comp));

            else
               --  Loop_Parameter_Specifcation is parsed with a choice list.
               --  where the range is the first (and only) choice.

               L_Range := Relocate_Node (First (Discrete_Choices (Comp)));

               L_Iteration_Scheme :=
                 Make_Iteration_Scheme (Loc,
                   Loop_Parameter_Specification =>
                     Make_Loop_Parameter_Specification (Loc,
                       Defining_Identifier => Loop_Id,
                       Discrete_Subtype_Definition => L_Range));
            end if;
         end if;

         --  Build insertion statement. For a positional aggregate, only the
         --  expression is needed. For a named aggregate, the loop variable,
         --  whose type is that of the key, is an additional parameter for
         --  the insertion operation.
         --  If a Key_Expression is present, it serves as the additional
         --  parameter. Otherwise the key is given by the loop parameter
         --  itself.

         if Present (Add_Unnamed_Subp)
           and then No (Add_Named_Subp)
         then
            Stats := New_List
              (Make_Procedure_Call_Statement (Loc,
                 Name => New_Occurrence_Of (Entity (Add_Unnamed_Subp), Loc),
                 Parameter_Associations =>
                   New_List (New_Occurrence_Of (Temp, Loc),
                     New_Copy_Tree (Expr))));
         else
            --  Named or indexed aggregate, for which a key is present,
            --  possibly with a specified key_expression.

            if Present (Key_Expr) then
               Params := New_List (New_Occurrence_Of (Temp, Loc),
                            New_Copy_Tree (Key_Expr),
                            New_Copy_Tree (Expr));
            else
               Params := New_List (New_Occurrence_Of (Temp, Loc),
                            New_Occurrence_Of (Loop_Id, Loc),
                            New_Copy_Tree (Expr));
            end if;

            Stats := New_List
              (Make_Procedure_Call_Statement (Loc,
                 Name => New_Occurrence_Of (Entity (Add_Named_Subp), Loc),
                 Parameter_Associations => Params));
         end if;

         Loop_Stat :=  Make_Implicit_Loop_Statement
                         (Node             => N,
                          Identifier       => Empty,
                          Iteration_Scheme => L_Iteration_Scheme,
                          Statements       => Stats);
         Append (Loop_Stat, Aggr_Code);

      end Expand_Iterated_Component;

      --  Start of processing for Expand_Container_Aggregate

   begin
      Parse_Aspect_Aggregate (Asp,
        Empty_Subp, Add_Named_Subp, Add_Unnamed_Subp,
        New_Indexed_Subp, Assign_Indexed_Subp);

      --  The constructor for bounded containers is a function with
      --  a parameter that sets the size of the container. If the
      --  size cannot be determined statically we use a default value
      --  or a dynamic expression.

      Siz := Aggregate_Size;

      if Ekind (Entity (Empty_Subp)) = E_Function
        and then Present (First_Formal (Entity (Empty_Subp)))
      then
         Default := Default_Value (First_Formal (Entity (Empty_Subp)));

         --  If aggregate size is not static, we can use default value
         --  of formal parameter for allocation. We assume that this
         --  (implementation-dependent) value is static, even though
         --   the AI does not require it.

         --  Create declaration for size: a constant literal in the simple
         --  case, an expression if iterated component associations may be
         --  involved, the default otherwise.

         Count_Type := Etype (First_Formal (Entity (Empty_Subp)));
         if Siz = -1 then
            if No (Siz_Exp) then
               Siz := UI_To_Int (Intval (Default));
               Siz_Exp := Make_Integer_Literal (Loc, Siz);

            else
               Siz_Exp := Make_Type_Conversion (Loc,
                  Subtype_Mark =>
                    New_Occurrence_Of (Count_Type, Loc),
                  Expression => Siz_Exp);
            end if;

         else
            Siz_Exp := Make_Integer_Literal (Loc, Siz);
         end if;

         Siz_Decl := Make_Object_Declaration (Loc,
            Defining_Identifier => Make_Temporary (Loc, 'S', N),
            Object_Definition =>
               New_Occurrence_Of (Count_Type, Loc),
               Expression => Siz_Exp);
         Append (Siz_Decl, Aggr_Code);

         if Nkind (Siz_Exp) = N_Integer_Literal then
            Init_Stat :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp,
                Object_Definition   => New_Occurrence_Of (Typ, Loc),
                Expression => Make_Function_Call (Loc,
                  Name => New_Occurrence_Of (Entity (Empty_Subp), Loc),
                  Parameter_Associations =>
                    New_List
                      (New_Occurrence_Of
                        (Defining_Identifier (Siz_Decl), Loc))));

         else
            Init_Stat :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp,
                Object_Definition   => New_Occurrence_Of (Typ, Loc),
                Expression => Make_Function_Call (Loc,
                  Name =>
                    New_Occurrence_Of (Entity (New_Indexed_Subp), Loc),
                  Parameter_Associations =>
                    New_List (
                      Make_Integer_Literal (Loc, 1),
                      New_Occurrence_Of
                        (Defining_Identifier (Siz_Decl), Loc))));
         end if;

         Append (Init_Stat, Aggr_Code);

         --  Size is dynamic: Create declaration for object, and intitialize
         --  with a call to the null container, or an assignment to it.

      else
         Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
             Object_Definition   => New_Occurrence_Of (Typ, Loc));

         Insert_Action (N, Decl);

         --  The Empty entity is either a parameterless function, or
         --  a constant.

         if Ekind (Entity (Empty_Subp)) = E_Function then
            Init_Stat := Make_Assignment_Statement (Loc,
              Name => New_Occurrence_Of (Temp, Loc),
              Expression => Make_Function_Call (Loc,
                Name => New_Occurrence_Of (Entity (Empty_Subp), Loc)));

         else
            Init_Stat := Make_Assignment_Statement (Loc,
              Name => New_Occurrence_Of (Temp, Loc),
              Expression => New_Occurrence_Of (Entity (Empty_Subp), Loc));
         end if;

         Append (Init_Stat, Aggr_Code);
      end if;

      ---------------------------
      --  Positional aggregate --
      ---------------------------

      --  If the aggregate is positional the aspect must include
      --  an Add_Unnamed subprogram.

      if Present (Add_Unnamed_Subp) then
         if Present (Expressions (N)) then
            declare
               Insert : constant Entity_Id := Entity (Add_Unnamed_Subp);
               Comp   : Node_Id;
               Stat   : Node_Id;

            begin
               Comp := First (Expressions (N));
               while Present (Comp) loop
                  Stat := Make_Procedure_Call_Statement (Loc,
                    Name => New_Occurrence_Of (Insert, Loc),
                    Parameter_Associations =>
                      New_List (New_Occurrence_Of (Temp, Loc),
                        New_Copy_Tree (Comp)));
                  Append (Stat, Aggr_Code);
                  Next (Comp);
               end loop;
            end;
         end if;

         --  Indexed aggregates are handled below. Unnamed aggregates
         --  such as sets may include iterated component associations.

         if No (New_Indexed_Subp) then
            Comp := First (Component_Associations (N));
            while Present (Comp) loop
               if Nkind (Comp) = N_Iterated_Component_Association then
                  Expand_Iterated_Component (Comp);
               end if;
               Next (Comp);
            end loop;
         end if;

      ---------------------
      -- Named_Aggregate --
      ---------------------

      elsif Present (Add_Named_Subp) then
         declare
            Insert : constant Entity_Id := Entity (Add_Named_Subp);
            Stat   : Node_Id;
            Key    : Node_Id;
         begin
            Comp := First (Component_Associations (N));

            --  Each component association may contain several choices;
            --  generate an insertion statement for each.

            while Present (Comp) loop
               if Nkind (Comp) in N_Iterated_Component_Association
                                | N_Iterated_Element_Association
               then
                  Expand_Iterated_Component (Comp);
               else
                  Key := First (Choices (Comp));

                  while Present (Key) loop
                     Stat := Make_Procedure_Call_Statement (Loc,
                       Name => New_Occurrence_Of (Insert, Loc),
                       Parameter_Associations =>
                         New_List (New_Occurrence_Of (Temp, Loc),
                           New_Copy_Tree (Key),
                           New_Copy_Tree (Expression (Comp))));
                     Append (Stat, Aggr_Code);

                     Next (Key);
                  end loop;
               end if;

               Next (Comp);
            end loop;
         end;
      end if;

      -----------------------
      -- Indexed_Aggregate --
      -----------------------

      --  For an indexed aggregate there must be an Assigned_Indexeed
      --  subprogram. Note that unlike array aggregates, a container
      --  aggregate must be fully positional or fully indexed. In the
      --  first case the expansion has already taken place.
      --  TBA: the keys for an indexed aggregate must provide a dense
      --  range with no repetitions.

      if Present (Assign_Indexed_Subp)
        and then Present (Component_Associations (N))
      then
         declare
            Insert : constant Entity_Id := Entity (Assign_Indexed_Subp);
            Index_Type : constant Entity_Id :=
               Etype (Next_Formal (First_Formal (Insert)));

            function  Expand_Range_Component
              (Rng  : Node_Id;
               Expr : Node_Id) return Node_Id;
            --  Transform a component assoication with a range into an
            --  explicit loop. If the choice is a subtype name, it is
            --  rewritten as a range with the corresponding bounds, which
            --  are known to be static.

            Comp   : Node_Id;
            Index  : Node_Id;
            Pos    : Int := 0;
            Stat   : Node_Id;
            Key    : Node_Id;

            -----------------------------
            -- Expand_Raange_Component --
            -----------------------------

            function Expand_Range_Component
              (Rng  : Node_Id;
               Expr : Node_Id) return Node_Id
            is
               Loop_Id : constant Entity_Id :=
                 Make_Temporary (Loc, 'T');

               L_Iteration_Scheme : Node_Id;
               Stats              : List_Id;

            begin
               L_Iteration_Scheme :=
                 Make_Iteration_Scheme (Loc,
                   Loop_Parameter_Specification =>
                     Make_Loop_Parameter_Specification (Loc,
                       Defining_Identifier => Loop_Id,
                       Discrete_Subtype_Definition => New_Copy_Tree (Rng)));

               Stats := New_List
                 (Make_Procedure_Call_Statement (Loc,
                    Name =>
                      New_Occurrence_Of (Entity (Assign_Indexed_Subp), Loc),
                    Parameter_Associations =>
                      New_List (New_Occurrence_Of (Temp, Loc),
                        New_Occurrence_Of (Loop_Id, Loc),
                        New_Copy_Tree (Expr))));

               return  Make_Implicit_Loop_Statement
                         (Node             => N,
                          Identifier       => Empty,
                          Iteration_Scheme => L_Iteration_Scheme,
                          Statements       => Stats);
            end Expand_Range_Component;

         begin
            if Siz > 0 then

               --  Modify the call to the constructor to allocate the
               --  required size for the aggregwte : call the provided
               --  constructor rather than the Empty aggregate.

               Index :=  Make_Op_Add (Loc,
                 Left_Opnd => New_Copy_Tree (Type_Low_Bound (Index_Type)),
                 Right_Opnd => Make_Integer_Literal (Loc, Siz - 1));

               Set_Expression (Init_Stat,
                  Make_Function_Call (Loc,
                    Name =>
                      New_Occurrence_Of (Entity (New_Indexed_Subp), Loc),
                    Parameter_Associations =>
                      New_List (
                         New_Copy_Tree (Type_Low_Bound (Index_Type)),
                         Index)));
            end if;

            if Present (Expressions (N)) then
               Comp := First (Expressions (N));

               while Present (Comp) loop

                  --  Compute index position for successive components
                  --  in the list of expressions, and use the indexed
                  --  assignment procedure for each.

                  Index := Make_Op_Add (Loc,
                    Left_Opnd => Type_Low_Bound (Index_Type),
                    Right_Opnd => Make_Integer_Literal (Loc, Pos));

                  Stat := Make_Procedure_Call_Statement (Loc,
                    Name => New_Occurrence_Of (Insert, Loc),
                    Parameter_Associations =>
                      New_List (New_Occurrence_Of (Temp, Loc),
                      Index,
                      New_Copy_Tree (Comp)));

                  Pos := Pos + 1;

                  Append (Stat, Aggr_Code);
                  Next (Comp);
               end loop;
            end if;

            if Present (Component_Associations (N)) then
               Comp := First (Component_Associations (N));

               --  The choice may be a static value, or a range with
               --  static bounds.

               while Present (Comp) loop
                  if Nkind (Comp) = N_Component_Association then
                     Key := First (Choices (Comp));
                     while Present (Key) loop

                        --  If the expression is a box, the corresponding
                        --  component (s) is left uninitialized.

                        if Box_Present (Comp) then
                           goto Next_Key;

                        elsif Nkind (Key) = N_Range then

                           --  Create loop for tne specified range,
                           --  with copies of the expression.

                           Stat :=
                             Expand_Range_Component (Key, Expression (Comp));

                        else
                           Stat := Make_Procedure_Call_Statement (Loc,
                             Name => New_Occurrence_Of
                                (Entity (Assign_Indexed_Subp), Loc),
                                Parameter_Associations =>
                                  New_List (New_Occurrence_Of (Temp, Loc),
                                  New_Copy_Tree (Key),
                                  New_Copy_Tree (Expression (Comp))));
                        end if;

                        Append (Stat, Aggr_Code);

                        <<Next_Key>>
                        Next (Key);
                     end loop;

                  else
                     --  Iterated component association. Discard
                     --  positional insertion procedure.

                     Add_Named_Subp := Assign_Indexed_Subp;
                     Add_Unnamed_Subp := Empty;
                     Expand_Iterated_Component (Comp);
                  end if;

                  Next (Comp);
               end loop;
            end if;
         end;
      end if;

      Insert_Actions (N, Aggr_Code);
      Rewrite (N, New_Occurrence_Of (Temp, Loc));
      Analyze_And_Resolve (N, Typ);
   end Expand_Container_Aggregate;

   ------------------------------
   -- Expand_N_Delta_Aggregate --
   ------------------------------

   procedure Expand_N_Delta_Aggregate (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Typ  : constant Entity_Id  := Etype (Expression (N));
      Decl : Node_Id;

   begin
      Decl :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Make_Temporary (Loc, 'T'),
          Object_Definition   => New_Occurrence_Of (Typ, Loc),
          Expression          => New_Copy_Tree (Expression (N)));

      if Is_Array_Type (Etype (N)) then
         Expand_Delta_Array_Aggregate (N, New_List (Decl));
      else
         Expand_Delta_Record_Aggregate (N, New_List (Decl));
      end if;
   end Expand_N_Delta_Aggregate;

   ----------------------------------
   -- Expand_Delta_Array_Aggregate --
   ----------------------------------

   procedure Expand_Delta_Array_Aggregate (N : Node_Id; Deltas : List_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Temp  : constant Entity_Id  := Defining_Identifier (First (Deltas));
      Assoc : Node_Id;

      function Generate_Loop (C : Node_Id) return Node_Id;
      --  Generate a loop containing individual component assignments for
      --  choices that are ranges, subtype indications, subtype names, and
      --  iterated component associations.

      -------------------
      -- Generate_Loop --
      -------------------

      function Generate_Loop (C : Node_Id) return Node_Id is
         Sl : constant Source_Ptr := Sloc (C);
         Ix : Entity_Id;

      begin
         if Nkind (Parent (C)) = N_Iterated_Component_Association then
            Ix :=
              Make_Defining_Identifier (Loc,
                Chars => (Chars (Defining_Identifier (Parent (C)))));
         else
            Ix := Make_Temporary (Sl, 'I');
         end if;

         return
           Make_Loop_Statement (Loc,
             Iteration_Scheme =>
               Make_Iteration_Scheme (Sl,
                 Loop_Parameter_Specification =>
                   Make_Loop_Parameter_Specification (Sl,
                     Defining_Identifier         => Ix,
                     Discrete_Subtype_Definition => New_Copy_Tree (C))),

              Statements      => New_List (
                Make_Assignment_Statement (Sl,
                  Name       =>
                    Make_Indexed_Component (Sl,
                      Prefix      => New_Occurrence_Of (Temp, Sl),
                      Expressions => New_List (New_Occurrence_Of (Ix, Sl))),
                  Expression => New_Copy_Tree (Expression (Assoc)))),
              End_Label       => Empty);
      end Generate_Loop;

      --  Local variables

      Choice : Node_Id;

   --  Start of processing for Expand_Delta_Array_Aggregate

   begin
      Assoc := First (Component_Associations (N));
      while Present (Assoc) loop
         Choice := First (Choice_List (Assoc));
         if Nkind (Assoc) = N_Iterated_Component_Association then
            while Present (Choice) loop
               Append_To (Deltas, Generate_Loop (Choice));
               Next (Choice);
            end loop;

         else
            while Present (Choice) loop

               --  Choice can be given by a range, a subtype indication, a
               --  subtype name, a scalar value, or an entity.

               if Nkind (Choice) = N_Range
                 or else (Is_Entity_Name (Choice)
                           and then Is_Type (Entity (Choice)))
               then
                  Append_To (Deltas, Generate_Loop (Choice));

               elsif Nkind (Choice) = N_Subtype_Indication then
                  Append_To (Deltas,
                    Generate_Loop (Range_Expression (Constraint (Choice))));

               else
                  Append_To (Deltas,
                    Make_Assignment_Statement (Sloc (Choice),
                      Name       =>
                        Make_Indexed_Component (Sloc (Choice),
                          Prefix      => New_Occurrence_Of (Temp, Loc),
                          Expressions => New_List (New_Copy_Tree (Choice))),
                      Expression => New_Copy_Tree (Expression (Assoc))));
               end if;

               Next (Choice);
            end loop;
         end if;

         Next (Assoc);
      end loop;

      Insert_Actions (N, Deltas);
      Rewrite (N, New_Occurrence_Of (Temp, Loc));
   end Expand_Delta_Array_Aggregate;

   -----------------------------------
   -- Expand_Delta_Record_Aggregate --
   -----------------------------------

   procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Temp   : constant Entity_Id  := Defining_Identifier (First (Deltas));
      Assoc  : Node_Id;
      Choice : Node_Id;

   begin
      Assoc := First (Component_Associations (N));

      while Present (Assoc) loop
         Choice := First (Choice_List (Assoc));
         while Present (Choice) loop
            Append_To (Deltas,
              Make_Assignment_Statement (Sloc (Choice),
                Name       =>
                  Make_Selected_Component (Sloc (Choice),
                    Prefix        => New_Occurrence_Of (Temp, Loc),
                    Selector_Name => Make_Identifier (Loc, Chars (Choice))),
                Expression => New_Copy_Tree (Expression (Assoc))));
            Next (Choice);
         end loop;

         Next (Assoc);
      end loop;

      Insert_Actions (N, Deltas);
      Rewrite (N, New_Occurrence_Of (Temp, Loc));
   end Expand_Delta_Record_Aggregate;

   ----------------------------------
   -- Expand_N_Extension_Aggregate --
   ----------------------------------

   --  If the ancestor part is an expression, add a component association for
   --  the parent field. If the type of the ancestor part is not the direct
   --  parent of the expected type, build recursively the needed ancestors.
   --  If the ancestor part is a subtype_mark, replace aggregate with a
   --  declaration for a temporary of the expected type, followed by
   --  individual assignments to the given components.

   procedure Expand_N_Extension_Aggregate (N : Node_Id) is
      A   : constant Node_Id    := Ancestor_Part (N);
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

   begin
      --  If the ancestor is a subtype mark, an init proc must be called
      --  on the resulting object which thus has to be materialized in
      --  the front-end

      if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
         Convert_To_Assignments (N, Typ);

      --  The extension aggregate is transformed into a record aggregate
      --  of the following form (c1 and c2 are inherited components)

      --   (Exp with c3 => a, c4 => b)
      --      ==> (c1 => Exp.c1, c2 => Exp.c2, c3 => a, c4 => b)

      else
         Set_Etype (N, Typ);

         if Tagged_Type_Expansion then
            Expand_Record_Aggregate (N,
              Orig_Tag    =>
                New_Occurrence_Of
                  (Node (First_Elmt (Access_Disp_Table (Typ))), Loc),
              Parent_Expr => A);

         --  No tag is needed in the case of a VM

         else
            Expand_Record_Aggregate (N, Parent_Expr => A);
         end if;
      end if;

   exception
      when RE_Not_Available =>
         return;
   end Expand_N_Extension_Aggregate;

   -----------------------------
   -- Expand_Record_Aggregate --
   -----------------------------

   procedure Expand_Record_Aggregate
     (N           : Node_Id;
      Orig_Tag    : Node_Id := Empty;
      Parent_Expr : Node_Id := Empty)
   is
      Loc      : constant Source_Ptr := Sloc  (N);
      Comps    : constant List_Id    := Component_Associations (N);
      Typ      : constant Entity_Id  := Etype (N);
      Base_Typ : constant Entity_Id  := Base_Type (Typ);

      Static_Components : Boolean := True;
      --  Flag to indicate whether all components are compile-time known,
      --  and the aggregate can be constructed statically and handled by
      --  the back-end. Set to False by Component_OK_For_Backend.

      procedure Build_Back_End_Aggregate;
      --  Build a proper aggregate to be handled by the back-end

      function Compile_Time_Known_Composite_Value (N : Node_Id) return Boolean;
      --  Returns true if N is an expression of composite type which can be
      --  fully evaluated at compile time without raising constraint error.
      --  Such expressions can be passed as is to Gigi without any expansion.
      --
      --  This returns true for N_Aggregate with Compile_Time_Known_Aggregate
      --  set and constants whose expression is such an aggregate, recursively.

      function Component_OK_For_Backend return Boolean;
      --  Check for presence of a component which makes it impossible for the
      --  backend to process the aggregate, thus requiring the use of a series
      --  of assignment statements. Cases checked for are a nested aggregate
      --  needing Late_Expansion, the presence of a tagged component which may
      --  need tag adjustment, and a bit unaligned component reference.
      --
      --  We also force expansion into assignments if a component is of a
      --  mutable type (including a private type with discriminants) because
      --  in that case the size of the component to be copied may be smaller
      --  than the side of the target, and there is no simple way for gigi
      --  to compute the size of the object to be copied.
      --
      --  NOTE: This is part of the ongoing work to define precisely the
      --  interface between front-end and back-end handling of aggregates.
      --  In general it is desirable to pass aggregates as they are to gigi,
      --  in order to minimize elaboration code. This is one case where the
      --  semantics of Ada complicate the analysis and lead to anomalies in
      --  the gcc back-end if the aggregate is not expanded into assignments.
      --
      --  NOTE: This sets the global Static_Components to False in most, but
      --  not all, cases when it returns False.

      function Has_Per_Object_Constraint (L : List_Id) return Boolean;
      --  Return True if any element of L has Has_Per_Object_Constraint set.
      --  L should be the Choices component of an N_Component_Association.

      function Has_Visible_Private_Ancestor (Id : E) return Boolean;
      --  If any ancestor of the current type is private, the aggregate
      --  cannot be built in place. We cannot rely on Has_Private_Ancestor,
      --  because it will not be set when type and its parent are in the
      --  same scope, and the parent component needs expansion.

      function Top_Level_Aggregate (N : Node_Id) return Node_Id;
      --  For nested aggregates return the ultimate enclosing aggregate; for
      --  non-nested aggregates return N.

      ------------------------------
      -- Build_Back_End_Aggregate --
      ------------------------------

      procedure Build_Back_End_Aggregate is
         Comp      : Entity_Id;
         New_Comp  : Node_Id;
         Tag_Value : Node_Id;

      begin
         if Nkind (N) = N_Aggregate then

            --  If the aggregate is static and can be handled by the back-end,
            --  nothing left to do.

            if Static_Components then
               Set_Compile_Time_Known_Aggregate (N);
               Set_Expansion_Delayed (N, False);
            end if;
         end if;

         --  If no discriminants, nothing special to do

         if not Has_Discriminants (Typ) then
            null;

         --  Case of discriminants present

         elsif Is_Derived_Type (Typ) then

            --  For untagged types, non-stored discriminants are replaced with
            --  stored discriminants, which are the ones that gigi uses to
            --  describe the type and its components.

            Generate_Aggregate_For_Derived_Type : declare
               procedure Prepend_Stored_Values (T : Entity_Id);
               --  Scan the list of stored discriminants of the type, and add
               --  their values to the aggregate being built.

               ---------------------------
               -- Prepend_Stored_Values --
               ---------------------------

               procedure Prepend_Stored_Values (T : Entity_Id) is
                  Discr      : Entity_Id;
                  First_Comp : Node_Id := Empty;

               begin
                  Discr := First_Stored_Discriminant (T);
                  while Present (Discr) loop
                     New_Comp :=
                       Make_Component_Association (Loc,
                         Choices    => New_List (
                           New_Occurrence_Of (Discr, Loc)),
                         Expression =>
                           New_Copy_Tree
                             (Get_Discriminant_Value
                                (Discr,
                                 Typ,
                                 Discriminant_Constraint (Typ))));

                     if No (First_Comp) then
                        Prepend_To (Component_Associations (N), New_Comp);
                     else
                        Insert_After (First_Comp, New_Comp);
                     end if;

                     First_Comp := New_Comp;
                     Next_Stored_Discriminant (Discr);
                  end loop;
               end Prepend_Stored_Values;

               --  Local variables

               Constraints : constant List_Id := New_List;

               Discr    : Entity_Id;
               Decl     : Node_Id;
               Num_Disc : Nat := 0;
               Num_Stor : Nat := 0;

            --  Start of processing for Generate_Aggregate_For_Derived_Type

            begin
               --  Remove the associations for the discriminant of derived type

               declare
                  First_Comp : Node_Id;

               begin
                  First_Comp := First (Component_Associations (N));
                  while Present (First_Comp) loop
                     Comp := First_Comp;
                     Next (First_Comp);

                     if Ekind (Entity (First (Choices (Comp)))) =
                          E_Discriminant
                     then
                        Remove (Comp);
                        Num_Disc := Num_Disc + 1;
                     end if;
                  end loop;
               end;

               --  Insert stored discriminant associations in the correct
               --  order. If there are more stored discriminants than new
               --  discriminants, there is at least one new discriminant that
               --  constrains more than one of the stored discriminants. In
               --  this case we need to construct a proper subtype of the
               --  parent type, in order to supply values to all the
               --  components. Otherwise there is one-one correspondence
               --  between the constraints and the stored discriminants.

               Discr := First_Stored_Discriminant (Base_Type (Typ));
               while Present (Discr) loop
                  Num_Stor := Num_Stor + 1;
                  Next_Stored_Discriminant (Discr);
               end loop;

               --  Case of more stored discriminants than new discriminants

               if Num_Stor > Num_Disc then

                  --  Create a proper subtype of the parent type, which is the
                  --  proper implementation type for the aggregate, and convert
                  --  it to the intended target type.

                  Discr := First_Stored_Discriminant (Base_Type (Typ));
                  while Present (Discr) loop
                     New_Comp :=
                       New_Copy_Tree
                         (Get_Discriminant_Value
                            (Discr,
                             Typ,
                             Discriminant_Constraint (Typ)));

                     Append (New_Comp, Constraints);
                     Next_Stored_Discriminant (Discr);
                  end loop;

                  Decl :=
                    Make_Subtype_Declaration (Loc,
                      Defining_Identifier => Make_Temporary (Loc, 'T'),
                      Subtype_Indication  =>
                        Make_Subtype_Indication (Loc,
                          Subtype_Mark =>
                            New_Occurrence_Of (Etype (Base_Type (Typ)), Loc),
                          Constraint   =>
                            Make_Index_Or_Discriminant_Constraint
                              (Loc, Constraints)));

                  Insert_Action (N, Decl);
                  Prepend_Stored_Values (Base_Type (Typ));

                  Set_Etype (N, Defining_Identifier (Decl));
                  Set_Analyzed (N);

                  Rewrite (N, Unchecked_Convert_To (Typ, N));
                  Analyze (N);

               --  Case where we do not have fewer new discriminants than
               --  stored discriminants, so in this case we can simply use the
               --  stored discriminants of the subtype.

               else
                  Prepend_Stored_Values (Typ);
               end if;
            end Generate_Aggregate_For_Derived_Type;
         end if;

         if Is_Tagged_Type (Typ) then

            --  In the tagged case, _parent and _tag component must be created

            --  Reset Null_Present unconditionally. Tagged records always have
            --  at least one field (the tag or the parent).

            Set_Null_Record_Present (N, False);

            --  When the current aggregate comes from the expansion of an
            --  extension aggregate, the parent expr is replaced by an
            --  aggregate formed by selected components of this expr.

            if Present (Parent_Expr) and then Is_Empty_List (Comps) then
               Comp := First_Component_Or_Discriminant (Typ);
               while Present (Comp) loop

                  --  Skip all expander-generated components

                  if not Comes_From_Source (Original_Record_Component (Comp))
                  then
                     null;

                  else
                     New_Comp :=
                       Make_Selected_Component (Loc,
                         Prefix        =>
                           Unchecked_Convert_To (Typ,
                             Duplicate_Subexpr (Parent_Expr, True)),
                         Selector_Name => New_Occurrence_Of (Comp, Loc));

                     Append_To (Comps,
                       Make_Component_Association (Loc,
                         Choices    => New_List (
                           New_Occurrence_Of (Comp, Loc)),
                         Expression => New_Comp));

                     Analyze_And_Resolve (New_Comp, Etype (Comp));
                  end if;

                  Next_Component_Or_Discriminant (Comp);
               end loop;
            end if;

            --  Compute the value for the Tag now, if the type is a root it
            --  will be included in the aggregate right away, otherwise it will
            --  be propagated to the parent aggregate.

            if Present (Orig_Tag) then
               Tag_Value := Orig_Tag;

            elsif not Tagged_Type_Expansion then
               Tag_Value := Empty;

            else
               Tag_Value :=
                 New_Occurrence_Of
                   (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
            end if;

            --  For a derived type, an aggregate for the parent is formed with
            --  all the inherited components.

            if Is_Derived_Type (Typ) then
               declare
                  First_Comp   : Node_Id;
                  Parent_Comps : List_Id;
                  Parent_Aggr  : Node_Id;
                  Parent_Name  : Node_Id;

               begin
                  --  Remove the inherited component association from the
                  --  aggregate and store them in the parent aggregate

                  First_Comp   := First (Component_Associations (N));
                  Parent_Comps := New_List;
                  while Present (First_Comp)
                    and then
                      Scope (Original_Record_Component
                               (Entity (First (Choices (First_Comp))))) /=
                                                                    Base_Typ
                  loop
                     Comp := First_Comp;
                     Next (First_Comp);
                     Remove (Comp);
                     Append (Comp, Parent_Comps);
                  end loop;

                  Parent_Aggr :=
                    Make_Aggregate (Loc,
                      Component_Associations => Parent_Comps);
                  Set_Etype (Parent_Aggr, Etype (Base_Type (Typ)));

                  --  Find the _parent component

                  Comp := First_Component (Typ);
                  while Chars (Comp) /= Name_uParent loop
                     Next_Component (Comp);
                  end loop;

                  Parent_Name := New_Occurrence_Of (Comp, Loc);

                  --  Insert the parent aggregate

                  Prepend_To (Component_Associations (N),
                    Make_Component_Association (Loc,
                      Choices    => New_List (Parent_Name),
                      Expression => Parent_Aggr));

                  --  Expand recursively the parent propagating the right Tag

                  Expand_Record_Aggregate
                    (Parent_Aggr, Tag_Value, Parent_Expr);

                  --  The ancestor part may be a nested aggregate that has
                  --  delayed expansion: recheck now.

                  if not Component_OK_For_Backend then
                     Convert_To_Assignments (N, Typ);
                  end if;
               end;

            --  For a root type, the tag component is added (unless compiling
            --  for the VMs, where tags are implicit).

            elsif Tagged_Type_Expansion then
               declare
                  Tag_Name  : constant Node_Id :=
                                New_Occurrence_Of
                                  (First_Tag_Component (Typ), Loc);
                  Typ_Tag   : constant Entity_Id := RTE (RE_Tag);
                  Conv_Node : constant Node_Id :=
                                Unchecked_Convert_To (Typ_Tag, Tag_Value);

               begin
                  Set_Etype (Conv_Node, Typ_Tag);
                  Prepend_To (Component_Associations (N),
                    Make_Component_Association (Loc,
                      Choices    => New_List (Tag_Name),
                      Expression => Conv_Node));
               end;
            end if;
         end if;
      end Build_Back_End_Aggregate;

      ----------------------------------------
      -- Compile_Time_Known_Composite_Value --
      ----------------------------------------

      function Compile_Time_Known_Composite_Value
        (N : Node_Id) return Boolean
      is
      begin
         --  If we have an entity name, then see if it is the name of a
         --  constant and if so, test the corresponding constant value.

         if Is_Entity_Name (N) then
            declare
               E : constant Entity_Id := Entity (N);
               V : Node_Id;
            begin
               if Ekind (E) /= E_Constant then
                  return False;
               else
                  V := Constant_Value (E);
                  return Present (V)
                    and then Compile_Time_Known_Composite_Value (V);
               end if;
            end;

         --  We have a value, see if it is compile time known

         else
            if Nkind (N) = N_Aggregate then
               return Compile_Time_Known_Aggregate (N);
            end if;

            --  All other types of values are not known at compile time

            return False;
         end if;

      end Compile_Time_Known_Composite_Value;

      ------------------------------
      -- Component_OK_For_Backend --
      ------------------------------

      function Component_OK_For_Backend return Boolean is
         C      : Node_Id;
         Expr_Q : Node_Id;

      begin
         C := First (Comps);
         while Present (C) loop

            --  If the component has box initialization, expansion is needed
            --  and component is not ready for backend.

            if Box_Present (C) then
               return False;
            end if;

            if Nkind (Expression (C)) = N_Qualified_Expression then
               Expr_Q := Expression (Expression (C));
            else
               Expr_Q := Expression (C);
            end if;

            --  Return False for array components whose bounds raise
            --  constraint error.

            declare
               Comp : constant Entity_Id := First (Choices (C));
               Indx : Node_Id;

            begin
               if Present (Etype (Comp))
                 and then Is_Array_Type (Etype (Comp))
               then
                  Indx := First_Index (Etype (Comp));
                  while Present (Indx) loop
                     if Nkind (Type_Low_Bound (Etype (Indx))) =
                          N_Raise_Constraint_Error
                       or else Nkind (Type_High_Bound (Etype (Indx))) =
                                 N_Raise_Constraint_Error
                     then
                        return False;
                     end if;

                     Next_Index (Indx);
                  end loop;
               end if;
            end;

            --  Return False if the aggregate has any associations for tagged
            --  components that may require tag adjustment.

            --  These are cases where the source expression may have a tag that
            --  could differ from the component tag (e.g., can occur for type
            --  conversions and formal parameters). (Tag adjustment not needed
            --  if Tagged_Type_Expansion because object tags are implicit in
            --  the machine.)

            if Is_Tagged_Type (Etype (Expr_Q))
              and then
                (Nkind (Expr_Q) = N_Type_Conversion
                  or else
                    (Is_Entity_Name (Expr_Q)
                      and then Is_Formal (Entity (Expr_Q))))
              and then Tagged_Type_Expansion
            then
               Static_Components := False;
               return False;

            elsif Is_Delayed_Aggregate (Expr_Q) then
               Static_Components := False;
               return False;

            elsif Nkind (Expr_Q) = N_Quantified_Expression then
               Static_Components := False;
               return False;

            elsif Possible_Bit_Aligned_Component (Expr_Q) then
               Static_Components := False;
               return False;

            elsif Modify_Tree_For_C
              and then Nkind (C) = N_Component_Association
              and then Has_Per_Object_Constraint (Choices (C))
            then
               Static_Components := False;
               return False;

            elsif Modify_Tree_For_C
              and then Nkind (Expr_Q) = N_Identifier
              and then Is_Array_Type (Etype (Expr_Q))
            then
               Static_Components := False;
               return False;

            elsif Modify_Tree_For_C
              and then Nkind (Expr_Q) = N_Type_Conversion
              and then Is_Array_Type (Etype (Expr_Q))
            then
               Static_Components := False;
               return False;
            end if;

            if Is_Elementary_Type (Etype (Expr_Q)) then
               if not Compile_Time_Known_Value (Expr_Q) then
                  Static_Components := False;
               end if;

            elsif not Compile_Time_Known_Composite_Value (Expr_Q) then
               Static_Components := False;

               if Is_Private_Type (Etype (Expr_Q))
                 and then Has_Discriminants (Etype (Expr_Q))
               then
                  return False;
               end if;
            end if;

            Next (C);
         end loop;

         return True;
      end Component_OK_For_Backend;

      -------------------------------
      -- Has_Per_Object_Constraint --
      -------------------------------

      function Has_Per_Object_Constraint (L : List_Id) return Boolean is
         N : Node_Id := First (L);
      begin
         while Present (N) loop
            if Is_Entity_Name (N)
              and then Present (Entity (N))
              and then Has_Per_Object_Constraint (Entity (N))
            then
               return True;
            end if;

            Next (N);
         end loop;

         return False;
      end Has_Per_Object_Constraint;

      -----------------------------------
      --  Has_Visible_Private_Ancestor --
      -----------------------------------

      function Has_Visible_Private_Ancestor (Id : E) return Boolean is
         R  : constant Entity_Id := Root_Type (Id);
         T1 : Entity_Id := Id;

      begin
         loop
            if Is_Private_Type (T1) then
               return True;

            elsif T1 = R then
               return False;

            else
               T1 := Etype (T1);
            end if;
         end loop;
      end Has_Visible_Private_Ancestor;

      -------------------------
      -- Top_Level_Aggregate --
      -------------------------

      function Top_Level_Aggregate (N : Node_Id) return Node_Id is
         Aggr : Node_Id;

      begin
         Aggr := N;
         while Present (Parent (Aggr))
           and then Nkind (Parent (Aggr)) in
                      N_Aggregate | N_Component_Association
         loop
            Aggr := Parent (Aggr);
         end loop;

         return Aggr;
      end Top_Level_Aggregate;

      --  Local variables

      Top_Level_Aggr : constant Node_Id := Top_Level_Aggregate (N);

   --  Start of processing for Expand_Record_Aggregate

   begin
      --  If the aggregate is to be assigned to a full access variable, we have
      --  to prevent a piecemeal assignment even if the aggregate is to be
      --  expanded. We create a temporary for the aggregate, and assign the
      --  temporary instead, so that the back end can generate an atomic move
      --  for it.

      if Is_Full_Access_Aggregate (N) then
         return;

      --  No special management required for aggregates used to initialize
      --  statically allocated dispatch tables

      elsif Is_Static_Dispatch_Table_Aggregate (N) then
         return;

      --  Case pattern aggregates need to remain as aggregates

      elsif Is_Case_Choice_Pattern (N) then
         return;
      end if;

      --  If the pragma Aggregate_Individually_Assign is set, always convert to
      --  assignments.

      if Aggregate_Individually_Assign then
         Convert_To_Assignments (N, Typ);

      --  Ada 2005 (AI-318-2): We need to convert to assignments if components
      --  are build-in-place function calls. The assignments will each turn
      --  into a build-in-place function call. If components are all static,
      --  we can pass the aggregate to the back end regardless of limitedness.

      --  Extension aggregates, aggregates in extended return statements, and
      --  aggregates for C++ imported types must be expanded.

      elsif Ada_Version >= Ada_2005 and then Is_Limited_View (Typ) then
         if Nkind (Parent (N)) not in
              N_Component_Association | N_Object_Declaration
         then
            Convert_To_Assignments (N, Typ);

         elsif Nkind (N) = N_Extension_Aggregate
           or else Convention (Typ) = Convention_CPP
         then
            Convert_To_Assignments (N, Typ);

         elsif not Size_Known_At_Compile_Time (Typ)
           or else not Component_OK_For_Backend
           or else not Static_Components
         then
            Convert_To_Assignments (N, Typ);

         --  In all other cases, build a proper aggregate to be handled by
         --  the back-end.

         else
            Build_Back_End_Aggregate;
         end if;

      --  Gigi doesn't properly handle temporaries of variable size so we
      --  generate it in the front-end

      elsif not Size_Known_At_Compile_Time (Typ)
        and then Tagged_Type_Expansion
      then
         Convert_To_Assignments (N, Typ);

      --  An aggregate used to initialize a controlled object must be turned
      --  into component assignments as the components themselves may require
      --  finalization actions such as adjustment.

      elsif Needs_Finalization (Typ) then
         Convert_To_Assignments (N, Typ);

      --  Ada 2005 (AI-287): In case of default initialized components we
      --  convert the aggregate into assignments.

      elsif Has_Default_Init_Comps (N) then
         Convert_To_Assignments (N, Typ);

      --  Check components

      elsif not Component_OK_For_Backend then
         Convert_To_Assignments (N, Typ);

      --  If an ancestor is private, some components are not inherited and we
      --  cannot expand into a record aggregate.

      elsif Has_Visible_Private_Ancestor (Typ) then
         Convert_To_Assignments (N, Typ);

      --  ??? The following was done to compile fxacc00.ads in the ACVCs. Gigi
      --  is not able to handle the aggregate for Late_Request.

      elsif Is_Tagged_Type (Typ) and then Has_Discriminants (Typ) then
         Convert_To_Assignments (N, Typ);

      --  If the tagged types covers interface types we need to initialize all
      --  hidden components containing pointers to secondary dispatch tables.

      elsif Is_Tagged_Type (Typ) and then Has_Interfaces (Typ) then
         Convert_To_Assignments (N, Typ);

      --  If some components are mutable, the size of the aggregate component
      --  may be distinct from the default size of the type component, so
      --  we need to expand to insure that the back-end copies the proper
      --  size of the data. However, if the aggregate is the initial value of
      --  a constant, the target is immutable and might be built statically
      --  if components are appropriate.

      elsif Has_Mutable_Components (Typ)
        and then
          (Nkind (Parent (Top_Level_Aggr)) /= N_Object_Declaration
            or else not Constant_Present (Parent (Top_Level_Aggr))
            or else not Static_Components)
      then
         Convert_To_Assignments (N, Typ);

      --  If the type involved has bit aligned components, then we are not sure
      --  that the back end can handle this case correctly.

      elsif Type_May_Have_Bit_Aligned_Components (Typ) then
         Convert_To_Assignments (N, Typ);

      --  When generating C, only generate an aggregate when declaring objects
      --  since C does not support aggregates in e.g. assignment statements.

      elsif Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
         Convert_To_Assignments (N, Typ);

      --  In all other cases, build a proper aggregate to be handled by gigi

      else
         Build_Back_End_Aggregate;
      end if;
   end Expand_Record_Aggregate;

   ---------------------
   -- Get_Base_Object --
   ---------------------

   function Get_Base_Object (N : Node_Id) return Entity_Id is
      R : Node_Id;

   begin
      R := Get_Referenced_Object (N);

      while Nkind (R) in N_Indexed_Component | N_Selected_Component | N_Slice
      loop
         R := Get_Referenced_Object (Prefix (R));
      end loop;

      if Is_Entity_Name (R) and then Is_Object (Entity (R)) then
         return Entity (R);
      else
         return Empty;
      end if;
   end Get_Base_Object;

   ----------------------------
   -- Has_Default_Init_Comps --
   ----------------------------

   function Has_Default_Init_Comps (N : Node_Id) return Boolean is
      Assoc : Node_Id;
      Expr  : Node_Id;
      --  Component association and expression, respectively

   begin
      pragma Assert (Nkind (N) in N_Aggregate | N_Extension_Aggregate);

      if Has_Self_Reference (N) then
         return True;
      end if;

      Assoc := First (Component_Associations (N));
      while Present (Assoc) loop
         --  Each component association has either a box or an expression

         pragma Assert (Box_Present (Assoc) xor Present (Expression (Assoc)));

         --  Check if any direct component has default initialized components

         if Box_Present (Assoc) then
            return True;

         --  Recursive call in case of aggregate expression

         else
            Expr := Expression (Assoc);

            if Nkind (Expr) in N_Aggregate | N_Extension_Aggregate
              and then Has_Default_Init_Comps (Expr)
            then
               return True;
            end if;
         end if;

         Next (Assoc);
      end loop;

      return False;
   end Has_Default_Init_Comps;

   ----------------------------------------
   -- Is_Build_In_Place_Aggregate_Return --
   ----------------------------------------

   function Is_Build_In_Place_Aggregate_Return (N : Node_Id) return Boolean is
      P : Node_Id := Parent (N);

   begin
      while Nkind (P) = N_Qualified_Expression loop
         P := Parent (P);
      end loop;

      if Nkind (P) = N_Simple_Return_Statement then
         null;

      elsif Nkind (Parent (P)) = N_Extended_Return_Statement then
         P := Parent (P);

      else
         return False;
      end if;

      return
        Is_Build_In_Place_Function
          (Return_Applies_To (Return_Statement_Entity (P)));
   end Is_Build_In_Place_Aggregate_Return;

   --------------------------
   -- Is_Delayed_Aggregate --
   --------------------------

   function Is_Delayed_Aggregate (N : Node_Id) return Boolean is
      Node : Node_Id   := N;
      Kind : Node_Kind := Nkind (Node);

   begin
      if Kind = N_Qualified_Expression then
         Node := Expression (Node);
         Kind := Nkind (Node);
      end if;

      return Kind in N_Aggregate | N_Extension_Aggregate
        and then Expansion_Delayed (Node);
   end Is_Delayed_Aggregate;

   --------------------------------
   -- Is_CCG_Supported_Aggregate --
   --------------------------------

   function Is_CCG_Supported_Aggregate
     (N : Node_Id) return Boolean
   is
      P : Node_Id := Parent (N);

   begin
      --  Aggregates are not supported for nonstandard rep clauses, since they
      --  may lead to extra padding fields in CCG.

      if Is_Record_Type (Etype (N))
        and then Has_Non_Standard_Rep (Etype (N))
      then
         return False;
      end if;

      while Present (P) and then Nkind (P) = N_Aggregate loop
         P := Parent (P);
      end loop;

      --  Check cases where aggregates are supported by the CCG backend

      if Nkind (P) = N_Object_Declaration then
         declare
            P_Typ : constant Entity_Id := Etype (Defining_Identifier (P));

         begin
            if Is_Record_Type (P_Typ) then
               return True;
            else
               return Compile_Time_Known_Bounds (P_Typ);
            end if;
         end;

      elsif Nkind (P) = N_Qualified_Expression then
         if Nkind (Parent (P)) = N_Object_Declaration then
            declare
               P_Typ : constant Entity_Id :=
                         Etype (Defining_Identifier (Parent (P)));
            begin
               if Is_Record_Type (P_Typ) then
                  return True;
               else
                  return Compile_Time_Known_Bounds (P_Typ);
               end if;
            end;

         elsif Nkind (Parent (P)) = N_Allocator then
            return True;
         end if;
      end if;

      return False;
   end Is_CCG_Supported_Aggregate;

   ----------------------------------------
   -- Is_Static_Dispatch_Table_Aggregate --
   ----------------------------------------

   function Is_Static_Dispatch_Table_Aggregate (N : Node_Id) return Boolean is
      Typ : constant Entity_Id := Base_Type (Etype (N));

   begin
      return Building_Static_Dispatch_Tables
        and then Tagged_Type_Expansion

         --  Avoid circularity when rebuilding the compiler

        and then not Is_RTU (Cunit_Entity (Get_Source_Unit (N)), Ada_Tags)
        and then (Is_RTE (Typ, RE_Dispatch_Table_Wrapper)
                    or else
                  Is_RTE (Typ, RE_Address_Array)
                    or else
                  Is_RTE (Typ, RE_Type_Specific_Data)
                    or else
                  Is_RTE (Typ, RE_Tag_Table)
                    or else
                  Is_RTE (Typ, RE_Object_Specific_Data)
                    or else
                  Is_RTE (Typ, RE_Interface_Data)
                    or else
                  Is_RTE (Typ, RE_Interfaces_Array)
                    or else
                  Is_RTE (Typ, RE_Interface_Data_Element));
   end Is_Static_Dispatch_Table_Aggregate;

   -----------------------------
   -- Is_Two_Dim_Packed_Array --
   -----------------------------

   function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean is
      C : constant Int := UI_To_Int (Component_Size (Typ));
   begin
      return Number_Dimensions (Typ) = 2
        and then Is_Bit_Packed_Array (Typ)
        and then (C = 1 or else C = 2 or else C = 4);
   end Is_Two_Dim_Packed_Array;

   --------------------
   -- Late_Expansion --
   --------------------

   function Late_Expansion
     (N      : Node_Id;
      Typ    : Entity_Id;
      Target : Node_Id) return List_Id
   is
      Aggr_Code : List_Id;
      New_Aggr  : Node_Id;

   begin
      if Is_Array_Type (Typ) then
         --  If the assignment can be done directly by the back end, then
         --  reset Set_Expansion_Delayed and do not expand further.

         if not CodePeer_Mode
           and then not Modify_Tree_For_C
           and then not Possible_Bit_Aligned_Component (Target)
           and then not Is_Possibly_Unaligned_Slice (Target)
           and then Aggr_Assignment_OK_For_Backend (N)
         then
            New_Aggr := New_Copy_Tree (N);
            Set_Expansion_Delayed (New_Aggr, False);

            Aggr_Code :=
              New_List (
                Make_OK_Assignment_Statement (Sloc (New_Aggr),
                  Name       => Target,
                  Expression => New_Aggr));

         --  Or else, generate component assignments to it

         else
            Aggr_Code :=
              Build_Array_Aggr_Code
                (N           => N,
                 Ctype       => Component_Type (Typ),
                 Index       => First_Index (Typ),
                 Into        => Target,
                 Scalar_Comp => Is_Scalar_Type (Component_Type (Typ)),
                 Indexes     => No_List);
         end if;

      --  Directly or indirectly (e.g. access protected procedure) a record

      else
         Aggr_Code := Build_Record_Aggr_Code (N, Typ, Target);
      end if;

      --  Save the last assignment statement associated with the aggregate
      --  when building a controlled object. This reference is utilized by
      --  the finalization machinery when marking an object as successfully
      --  initialized.

      if Needs_Finalization (Typ)
        and then Is_Entity_Name (Target)
        and then Present (Entity (Target))
        and then Ekind (Entity (Target)) in E_Constant | E_Variable
      then
         Set_Last_Aggregate_Assignment (Entity (Target), Last (Aggr_Code));
      end if;

      return Aggr_Code;
   end Late_Expansion;

   ----------------------------------
   -- Make_OK_Assignment_Statement --
   ----------------------------------

   function Make_OK_Assignment_Statement
     (Sloc       : Source_Ptr;
      Name       : Node_Id;
      Expression : Node_Id) return Node_Id
   is
   begin
      Set_Assignment_OK (Name);
      return Make_Assignment_Statement (Sloc, Name, Expression);
   end Make_OK_Assignment_Statement;

   ------------------------
   -- Max_Aggregate_Size --
   ------------------------

   function Max_Aggregate_Size
     (N            : Node_Id;
      Default_Size : Nat := 5000) return Nat
   is
      function Use_Small_Size (N : Node_Id) return Boolean;
      --  True if we should return a very small size, which means large
      --  aggregates will be implemented as a loop when possible (potentially
      --  transformed to memset calls).

      function Aggr_Context (N : Node_Id) return Node_Id;
      --  Return the context in which the aggregate appears, not counting
      --  qualified expressions and similar.

      ------------------
      -- Aggr_Context --
      ------------------

      function Aggr_Context (N : Node_Id) return Node_Id is
         Result : Node_Id := Parent (N);
      begin
         if Nkind (Result) in N_Qualified_Expression
                            | N_Type_Conversion
                            | N_Unchecked_Type_Conversion
                            | N_If_Expression
                            | N_Case_Expression
                            | N_Component_Association
                            | N_Aggregate
         then
            Result := Aggr_Context (Result);
         end if;

         return Result;
      end Aggr_Context;

      --------------------
      -- Use_Small_Size --
      --------------------

      function Use_Small_Size (N : Node_Id) return Boolean is
         C : constant Node_Id := Aggr_Context (N);
         --  The decision depends on the context in which the aggregate occurs,
         --  and for variable declarations, whether we are nested inside a
         --  subprogram.
      begin
         case Nkind (C) is
            --  True for assignment statements and similar

            when N_Assignment_Statement
               | N_Simple_Return_Statement
               | N_Allocator
               | N_Attribute_Reference
            =>
               return True;

            --  True for nested variable declarations. False for library level
            --  variables, and for constants (whether or not nested).

            when N_Object_Declaration =>
               return not Constant_Present (C)
                 and then Ekind (Current_Scope) in Subprogram_Kind;

            --  False for all other contexts

            when others =>
               return False;
         end case;
      end Use_Small_Size;

      --  Local variables

      Typ : constant Entity_Id := Etype (N);

   --  Start of processing for Max_Aggregate_Size

   begin
      --  We use a small limit in CodePeer mode where we favor loops instead of
      --  thousands of single assignments (from large aggregates).

      --  We also increase the limit to 2**24 (about 16 million) if
      --  Restrictions (No_Elaboration_Code) or Restrictions
      --  (No_Implicit_Loops) is specified, since in either case we are at risk
      --  of declaring the program illegal because of this limit. We also
      --  increase the limit when Static_Elaboration_Desired, given that this
      --  means that objects are intended to be placed in data memory.

      --  Same if the aggregate is for a packed two-dimensional array, because
      --  if components are static it is much more efficient to construct a
      --  one-dimensional equivalent array with static components.

      if CodePeer_Mode then
         return 100;
      elsif Restriction_Active (No_Elaboration_Code)
        or else Restriction_Active (No_Implicit_Loops)
        or else Is_Two_Dim_Packed_Array (Typ)
        or else (Ekind (Current_Scope) = E_Package
                   and then Static_Elaboration_Desired (Current_Scope))
      then
         return 2 ** 24;
      elsif Use_Small_Size (N) then
         return 64;
      end if;

      return Default_Size;
   end Max_Aggregate_Size;

   -----------------------
   -- Number_Of_Choices --
   -----------------------

   function Number_Of_Choices (N : Node_Id) return Nat is
      Assoc  : Node_Id;
      Choice : Node_Id;

      Nb_Choices : Nat := 0;

   begin
      if Present (Expressions (N)) then
         return 0;
      end if;

      Assoc := First (Component_Associations (N));
      while Present (Assoc) loop
         Choice := First (Choice_List (Assoc));
         while Present (Choice) loop
            if Nkind (Choice) /= N_Others_Choice then
               Nb_Choices := Nb_Choices + 1;
            end if;

            Next (Choice);
         end loop;

         Next (Assoc);
      end loop;

      return Nb_Choices;
   end Number_Of_Choices;

   ------------------------------------
   -- Packed_Array_Aggregate_Handled --
   ------------------------------------

   --  The current version of this procedure will handle at compile time
   --  any array aggregate that meets these conditions:

   --    One and two dimensional, bit packed
   --    Underlying packed type is modular type
   --    Bounds are within 32-bit Int range
   --    All bounds and values are static

   --  Note: for now, in the 2-D case, we only handle component sizes of
   --  1, 2, 4 (cases where an integral number of elements occupies a byte).

   function Packed_Array_Aggregate_Handled (N : Node_Id) return Boolean is
      Loc  : constant Source_Ptr := Sloc (N);
      Typ  : constant Entity_Id  := Etype (N);
      Ctyp : constant Entity_Id  := Component_Type (Typ);

      Not_Handled : exception;
      --  Exception raised if this aggregate cannot be handled

   begin
      --  Handle one- or two dimensional bit packed array

      if not Is_Bit_Packed_Array (Typ)
        or else Number_Dimensions (Typ) > 2
      then
         return False;
      end if;

      --  If two-dimensional, check whether it can be folded, and transformed
      --  into a one-dimensional aggregate for the Packed_Array_Impl_Type of
      --  the original type.

      if Number_Dimensions (Typ) = 2 then
         return Two_Dim_Packed_Array_Handled (N);
      end if;

      if not Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)) then
         return False;
      end if;

      if not Is_Scalar_Type (Ctyp) then
         return False;
      end if;

      declare
         Csiz  : constant Nat := UI_To_Int (Component_Size (Typ));

         function Get_Component_Val (N : Node_Id) return Uint;
         --  Given a expression value N of the component type Ctyp, returns a
         --  value of Csiz (component size) bits representing this value. If
         --  the value is nonstatic or any other reason exists why the value
         --  cannot be returned, then Not_Handled is raised.

         -----------------------
         -- Get_Component_Val --
         -----------------------

         function Get_Component_Val (N : Node_Id) return Uint is
            Val  : Uint;

         begin
            --  We have to analyze the expression here before doing any further
            --  processing here. The analysis of such expressions is deferred
            --  till expansion to prevent some problems of premature analysis.

            Analyze_And_Resolve (N, Ctyp);

            --  Must have a compile time value. String literals have to be
            --  converted into temporaries as well, because they cannot easily
            --  be converted into their bit representation.

            if not Compile_Time_Known_Value (N)
              or else Nkind (N) = N_String_Literal
            then
               raise Not_Handled;
            end if;

            Val := Expr_Rep_Value (N);

            --  Adjust for bias, and strip proper number of bits

            if Has_Biased_Representation (Ctyp) then
               Val := Val - Expr_Value (Type_Low_Bound (Ctyp));
            end if;

            return Val mod Uint_2 ** Csiz;
         end Get_Component_Val;

         Bounds : constant Range_Nodes := Get_Index_Bounds (First_Index (Typ));

      --  Here we know we have a one dimensional bit packed array

      begin
         --  Cannot do anything if bounds are dynamic

         if not (Compile_Time_Known_Value (Bounds.First)
                   and then
                 Compile_Time_Known_Value (Bounds.Last))
         then
            return False;
         end if;

         declare
            Bounds_Vals : Range_Values;
            --  Compile-time known values of bounds
         begin
            --  Or are silly out of range of int bounds

            Bounds_Vals.First := Expr_Value (Bounds.First);
            Bounds_Vals.Last := Expr_Value (Bounds.Last);

            if not UI_Is_In_Int_Range (Bounds_Vals.First)
                 or else
               not UI_Is_In_Int_Range (Bounds_Vals.Last)
            then
               return False;
            end if;

            --  At this stage we have a suitable aggregate for handling at
            --  compile time. The only remaining checks are that the values of
            --  expressions in the aggregate are compile-time known (checks are
            --  performed by Get_Component_Val), and that any subtypes or
            --  ranges are statically known.

            --  If the aggregate is not fully positional at this stage, then
            --  convert it to positional form. Either this will fail, in which
            --  case we can do nothing, or it will succeed, in which case we
            --  have succeeded in handling the aggregate and transforming it
            --  into a modular value, or it will stay an aggregate, in which
            --  case we have failed to create a packed value for it.

            if Present (Component_Associations (N)) then
               Convert_To_Positional (N, Handle_Bit_Packed => True);
               return Nkind (N) /= N_Aggregate;
            end if;

            --  Otherwise we are all positional, so convert to proper value

            declare
               Len : constant Nat :=
                 Int'Max (0, UI_To_Int (Bounds_Vals.Last) -
                             UI_To_Int (Bounds_Vals.First) + 1);
               --  The length of the array (number of elements)

               Aggregate_Val : Uint;
               --  Value of aggregate. The value is set in the low order bits
               --  of this value. For the little-endian case, the values are
               --  stored from low-order to high-order and for the big-endian
               --  case the values are stored from high order to low order.
               --  Note that gigi will take care of the conversions to left
               --  justify the value in the big endian case (because of left
               --  justified modular type processing), so we do not have to
               --  worry about that here.

               Lit : Node_Id;
               --  Integer literal for resulting constructed value

               Shift : Nat;
               --  Shift count from low order for next value

               Incr : Int;
               --  Shift increment for loop

               Expr : Node_Id;
               --  Next expression from positional parameters of aggregate

               Left_Justified : Boolean;
               --  Set True if we are filling the high order bits of the target
               --  value (i.e. the value is left justified).

            begin
               --  For little endian, we fill up the low order bits of the
               --  target value. For big endian we fill up the high order bits
               --  of the target value (which is a left justified modular
               --  value).

               Left_Justified := Bytes_Big_Endian;

               --  Switch justification if using -gnatd8

               if Debug_Flag_8 then
                  Left_Justified := not Left_Justified;
               end if;

               --  Switch justfification if reverse storage order

               if Reverse_Storage_Order (Base_Type (Typ)) then
                  Left_Justified := not Left_Justified;
               end if;

               if Left_Justified then
                  Shift := Csiz * (Len - 1);
                  Incr  := -Csiz;
               else
                  Shift := 0;
                  Incr  := +Csiz;
               end if;

               --  Loop to set the values

               if Len = 0 then
                  Aggregate_Val := Uint_0;
               else
                  Expr := First (Expressions (N));
                  Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;

                  for J in 2 .. Len loop
                     Shift := Shift + Incr;
                     Next (Expr);
                     Aggregate_Val :=
                       Aggregate_Val +
                       Get_Component_Val (Expr) * Uint_2 ** Shift;
                  end loop;
               end if;

               --  Now we can rewrite with the proper value

               Lit := Make_Integer_Literal (Loc, Intval => Aggregate_Val);
               Set_Print_In_Hex (Lit);

               --  Construct the expression using this literal. Note that it
               --  is important to qualify the literal with its proper modular
               --  type since universal integer does not have the required
               --  range and also this is a left justified modular type,
               --  which is important in the big-endian case.

               Rewrite (N,
                 Unchecked_Convert_To (Typ,
                   Make_Qualified_Expression (Loc,
                     Subtype_Mark =>
                       New_Occurrence_Of (Packed_Array_Impl_Type (Typ), Loc),
                     Expression   => Lit)));

               Analyze_And_Resolve (N, Typ);
               return True;
            end;
         end;
      end;

   exception
      when Not_Handled =>
         return False;
   end Packed_Array_Aggregate_Handled;

   ----------------------------
   -- Has_Mutable_Components --
   ----------------------------

   function Has_Mutable_Components (Typ : Entity_Id) return Boolean is
      Comp : Entity_Id;
      Ctyp : Entity_Id;

   begin
      Comp := First_Component (Typ);
      while Present (Comp) loop
         Ctyp := Underlying_Type (Etype (Comp));
         if Is_Record_Type (Ctyp)
           and then Has_Discriminants (Ctyp)
           and then not Is_Constrained (Ctyp)
         then
            return True;
         end if;

         Next_Component (Comp);
      end loop;

      return False;
   end Has_Mutable_Components;

   ------------------------------
   -- Initialize_Discriminants --
   ------------------------------

   procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Bas  : constant Entity_Id  := Base_Type (Typ);
      Par  : constant Entity_Id  := Etype (Bas);
      Decl : constant Node_Id    := Parent (Par);
      Ref  : Node_Id;

   begin
      if Is_Tagged_Type (Bas)
        and then Is_Derived_Type (Bas)
        and then Has_Discriminants (Par)
        and then Has_Discriminants (Bas)
        and then Number_Discriminants (Bas) /= Number_Discriminants (Par)
        and then Nkind (Decl) = N_Full_Type_Declaration
        and then Nkind (Type_Definition (Decl)) = N_Record_Definition
        and then
          Present (Variant_Part (Component_List (Type_Definition (Decl))))
        and then Nkind (N) /= N_Extension_Aggregate
      then

         --   Call init proc to set discriminants.
         --   There should eventually be a special procedure for this ???

         Ref := New_Occurrence_Of (Defining_Identifier (N), Loc);
         Insert_Actions_After (N,
           Build_Initialization_Call (Sloc (N), Ref, Typ));
      end if;
   end Initialize_Discriminants;

   ----------------
   -- Must_Slide --
   ----------------

   function Must_Slide
     (Aggr     : Node_Id;
      Obj_Type : Entity_Id;
      Typ      : Entity_Id) return Boolean
   is
   begin
      --  No sliding if the type of the object is not established yet, if it is
      --  an unconstrained type whose actual subtype comes from the aggregate,
      --  or if the two types are identical. If the aggregate contains only
      --  an Others_Clause it gets its type from the context and no sliding
      --  is involved either.

      if not Is_Array_Type (Obj_Type) then
         return False;

      elsif not Is_Constrained (Obj_Type) then
         return False;

      elsif Typ = Obj_Type then
         return False;

      elsif Is_Others_Aggregate (Aggr) then
         return False;

      else
         --  Sliding can only occur along the first dimension
         --  If any the bounds of non-static sliding is required
         --  to force potential range checks.

         declare
            Bounds1 : constant Range_Nodes :=
              Get_Index_Bounds (First_Index (Typ));
            Bounds2 : constant Range_Nodes :=
              Get_Index_Bounds (First_Index (Obj_Type));

         begin
            if not Is_OK_Static_Expression (Bounds1.First) or else
               not Is_OK_Static_Expression (Bounds2.First) or else
               not Is_OK_Static_Expression (Bounds1.Last) or else
               not Is_OK_Static_Expression (Bounds2.Last)
            then
               return True;

            else
               return Expr_Value (Bounds1.First) /= Expr_Value (Bounds2.First)
                        or else
                      Expr_Value (Bounds1.Last) /= Expr_Value (Bounds2.Last);
            end if;
         end;
      end if;
   end Must_Slide;

   ---------------------------------
   -- Process_Transient_Component --
   ---------------------------------

   procedure Process_Transient_Component
     (Loc        : Source_Ptr;
      Comp_Typ   : Entity_Id;
      Init_Expr  : Node_Id;
      Fin_Call   : out Node_Id;
      Hook_Clear : out Node_Id;
      Aggr       : Node_Id := Empty;
      Stmts      : List_Id := No_List)
   is
      procedure Add_Item (Item : Node_Id);
      --  Insert arbitrary node Item into the tree depending on the values of
      --  Aggr and Stmts.

      --------------
      -- Add_Item --
      --------------

      procedure Add_Item (Item : Node_Id) is
      begin
         if Present (Aggr) then
            Insert_Action (Aggr, Item);
         else
            pragma Assert (Present (Stmts));
            Append_To (Stmts, Item);
         end if;
      end Add_Item;

      --  Local variables

      Hook_Assign : Node_Id;
      Hook_Decl   : Node_Id;
      Ptr_Decl    : Node_Id;
      Res_Decl    : Node_Id;
      Res_Id      : Entity_Id;
      Res_Typ     : Entity_Id;

   --  Start of processing for Process_Transient_Component

   begin
      --  Add the access type, which provides a reference to the function
      --  result. Generate:

      --    type Res_Typ is access all Comp_Typ;

      Res_Typ := Make_Temporary (Loc, 'A');
      Mutate_Ekind (Res_Typ, E_General_Access_Type);
      Set_Directly_Designated_Type (Res_Typ, Comp_Typ);

      Add_Item
        (Make_Full_Type_Declaration (Loc,
           Defining_Identifier => Res_Typ,
           Type_Definition     =>
             Make_Access_To_Object_Definition (Loc,
               All_Present        => True,
               Subtype_Indication => New_Occurrence_Of (Comp_Typ, Loc))));

      --  Add the temporary which captures the result of the function call.
      --  Generate:

      --    Res : constant Res_Typ := Init_Expr'Reference;

      --  Note that this temporary is effectively a transient object because
      --  its lifetime is bounded by the current array or record component.

      Res_Id := Make_Temporary (Loc, 'R');
      Mutate_Ekind (Res_Id, E_Constant);
      Set_Etype (Res_Id, Res_Typ);

      --  Mark the transient object as successfully processed to avoid double
      --  finalization.

      Set_Is_Finalized_Transient (Res_Id);

      --  Signal the general finalization machinery that this transient object
      --  should not be considered for finalization actions because its cleanup
      --  will be performed by Process_Transient_Component_Completion.

      Set_Is_Ignored_Transient (Res_Id);

      Res_Decl :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Res_Id,
          Constant_Present    => True,
          Object_Definition   => New_Occurrence_Of (Res_Typ, Loc),
          Expression          =>
            Make_Reference (Loc, New_Copy_Tree (Init_Expr)));

      Add_Item (Res_Decl);

      --  Construct all pieces necessary to hook and finalize the transient
      --  result.

      Build_Transient_Object_Statements
        (Obj_Decl    => Res_Decl,
         Fin_Call    => Fin_Call,
         Hook_Assign => Hook_Assign,
         Hook_Clear  => Hook_Clear,
         Hook_Decl   => Hook_Decl,
         Ptr_Decl    => Ptr_Decl);

      --  Add the access type which provides a reference to the transient
      --  result. Generate:

      --    type Ptr_Typ is access all Comp_Typ;

      Add_Item (Ptr_Decl);

      --  Add the temporary which acts as a hook to the transient result.
      --  Generate:

      --    Hook : Ptr_Typ := null;

      Add_Item (Hook_Decl);

      --  Attach the transient result to the hook. Generate:

      --    Hook := Ptr_Typ (Res);

      Add_Item (Hook_Assign);

      --  The original initialization expression now references the value of
      --  the temporary function result. Generate:

      --    Res.all

      Rewrite (Init_Expr,
        Make_Explicit_Dereference (Loc,
          Prefix => New_Occurrence_Of (Res_Id, Loc)));
   end Process_Transient_Component;

   --------------------------------------------
   -- Process_Transient_Component_Completion --
   --------------------------------------------

   procedure Process_Transient_Component_Completion
     (Loc        : Source_Ptr;
      Aggr       : Node_Id;
      Fin_Call   : Node_Id;
      Hook_Clear : Node_Id;
      Stmts      : List_Id)
   is
      Exceptions_OK : constant Boolean :=
                        not Restriction_Active (No_Exception_Propagation);

   begin
      pragma Assert (Present (Hook_Clear));

      --  Generate the following code if exception propagation is allowed:

      --    declare
      --       Abort : constant Boolean := Triggered_By_Abort;
      --         <or>
      --       Abort : constant Boolean := False;  --  no abort

      --       E      : Exception_Occurrence;
      --       Raised : Boolean := False;

      --    begin
      --       [Abort_Defer;]

      --       begin
      --          Hook := null;
      --          [Deep_]Finalize (Res.all);

      --       exception
      --          when others =>
      --             if not Raised then
      --                Raised := True;
      --                Save_Occurrence (E,
      --                  Get_Curent_Excep.all.all);
      --             end if;
      --       end;

      --       [Abort_Undefer;]

      --       if Raised and then not Abort then
      --          Raise_From_Controlled_Operation (E);
      --       end if;
      --    end;

      if Exceptions_OK then
         Abort_And_Exception : declare
            Blk_Decls : constant List_Id := New_List;
            Blk_Stmts : constant List_Id := New_List;
            Fin_Stmts : constant List_Id := New_List;

            Fin_Data : Finalization_Exception_Data;

         begin
            --  Create the declarations of the two flags and the exception
            --  occurrence.

            Build_Object_Declarations (Fin_Data, Blk_Decls, Loc);

            --  Generate:
            --    Abort_Defer;

            if Abort_Allowed then
               Append_To (Blk_Stmts,
                 Build_Runtime_Call (Loc, RE_Abort_Defer));
            end if;

            --  Wrap the hook clear and the finalization call in order to trap
            --  a potential exception.

            Append_To (Fin_Stmts, Hook_Clear);

            if Present (Fin_Call) then
               Append_To (Fin_Stmts, Fin_Call);
            end if;

            Append_To (Blk_Stmts,
              Make_Block_Statement (Loc,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements         => Fin_Stmts,
                    Exception_Handlers => New_List (
                      Build_Exception_Handler (Fin_Data)))));

            --  Generate:
            --    Abort_Undefer;

            if Abort_Allowed then
               Append_To (Blk_Stmts,
                 Build_Runtime_Call (Loc, RE_Abort_Undefer));
            end if;

            --  Reraise the potential exception with a proper "upgrade" to
            --  Program_Error if needed.

            Append_To (Blk_Stmts, Build_Raise_Statement (Fin_Data));

            --  Wrap everything in a block

            Append_To (Stmts,
              Make_Block_Statement (Loc,
                Declarations               => Blk_Decls,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => Blk_Stmts)));
         end Abort_And_Exception;

      --  Generate the following code if exception propagation is not allowed
      --  and aborts are allowed:

      --    begin
      --       Abort_Defer;
      --       Hook := null;
      --       [Deep_]Finalize (Res.all);
      --    at end
      --       Abort_Undefer_Direct;
      --    end;

      elsif Abort_Allowed then
         Abort_Only : declare
            Blk_Stmts : constant List_Id := New_List;

         begin
            Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
            Append_To (Blk_Stmts, Hook_Clear);

            if Present (Fin_Call) then
               Append_To (Blk_Stmts, Fin_Call);
            end if;

            Append_To (Stmts,
              Build_Abort_Undefer_Block (Loc,
                Stmts   => Blk_Stmts,
                Context => Aggr));
         end Abort_Only;

      --  Otherwise generate:

      --    Hook := null;
      --    [Deep_]Finalize (Res.all);

      else
         Append_To (Stmts, Hook_Clear);

         if Present (Fin_Call) then
            Append_To (Stmts, Fin_Call);
         end if;
      end if;
   end Process_Transient_Component_Completion;

   ---------------------
   -- Sort_Case_Table --
   ---------------------

   procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
      L : constant Int := Case_Table'First;
      U : constant Int := Case_Table'Last;
      K : Int;
      J : Int;
      T : Case_Bounds;

   begin
      K := L;
      while K /= U loop
         T := Case_Table (K + 1);

         J := K + 1;
         while J /= L
           and then Expr_Value (Case_Table (J - 1).Choice_Lo) >
                    Expr_Value (T.Choice_Lo)
         loop
            Case_Table (J) := Case_Table (J - 1);
            J := J - 1;
         end loop;

         Case_Table (J) := T;
         K := K + 1;
      end loop;
   end Sort_Case_Table;

   ----------------------------
   -- Static_Array_Aggregate --
   ----------------------------

   function Static_Array_Aggregate (N : Node_Id) return Boolean is
      function Is_Static_Component (Nod : Node_Id) return Boolean;
      --  Return True if Nod has a compile-time known value and can be passed
      --  as is to the back-end without further expansion.

      ---------------------------
      --  Is_Static_Component  --
      ---------------------------

      function Is_Static_Component (Nod : Node_Id) return Boolean is
      begin
         if Nkind (Nod) in N_Integer_Literal | N_Real_Literal then
            return True;

         elsif Is_Entity_Name (Nod)
           and then Present (Entity (Nod))
           and then Ekind (Entity (Nod)) = E_Enumeration_Literal
         then
            return True;

         elsif Nkind (Nod) = N_Aggregate
           and then Compile_Time_Known_Aggregate (Nod)
         then
            return True;

         else
            return False;
         end if;
      end Is_Static_Component;

      --  Local variables

      Bounds : constant Node_Id   := Aggregate_Bounds (N);
      Typ    : constant Entity_Id := Etype (N);

      Agg  : Node_Id;
      Expr : Node_Id;
      Lo   : Node_Id;
      Hi   : Node_Id;

   --  Start of processing for Static_Array_Aggregate

   begin
      if Is_Packed (Typ) or else Has_Discriminants (Component_Type (Typ)) then
         return False;
      end if;

      if Present (Bounds)
        and then Nkind (Bounds) = N_Range
        and then Nkind (Low_Bound  (Bounds)) = N_Integer_Literal
        and then Nkind (High_Bound (Bounds)) = N_Integer_Literal
      then
         Lo := Low_Bound  (Bounds);
         Hi := High_Bound (Bounds);

         if No (Component_Associations (N)) then

            --  Verify that all components are static

            Expr := First (Expressions (N));
            while Present (Expr) loop
               if not Is_Static_Component (Expr) then
                  return False;
               end if;

               Next (Expr);
            end loop;

            return True;

         else
            --  We allow only a single named association, either a static
            --  range or an others_clause, with a static expression.

            Expr := First (Component_Associations (N));

            if Present (Expressions (N)) then
               return False;

            elsif Present (Next (Expr)) then
               return False;

            elsif Present (Next (First (Choice_List (Expr)))) then
               return False;

            else
               --  The aggregate is static if all components are literals,
               --  or else all its components are static aggregates for the
               --  component type. We also limit the size of a static aggregate
               --  to prevent runaway static expressions.

               if not Is_Static_Component (Expression (Expr)) then
                  return False;
               end if;

               if not Aggr_Size_OK (N) then
                  return False;
               end if;

               --  Create a positional aggregate with the right number of
               --  copies of the expression.

               Agg := Make_Aggregate (Sloc (N), New_List, No_List);

               for I in UI_To_Int (Intval (Lo)) .. UI_To_Int (Intval (Hi))
               loop
                  Append_To (Expressions (Agg), New_Copy (Expression (Expr)));

                  --  The copied expression must be analyzed and resolved.
                  --  Besides setting the type, this ensures that static
                  --  expressions are appropriately marked as such.

                  Analyze_And_Resolve
                    (Last (Expressions (Agg)), Component_Type (Typ));
               end loop;

               Set_Aggregate_Bounds (Agg, Bounds);
               Set_Etype (Agg, Typ);
               Set_Analyzed (Agg);
               Rewrite (N, Agg);
               Set_Compile_Time_Known_Aggregate (N);

               return True;
            end if;
         end if;

      else
         return False;
      end if;
   end Static_Array_Aggregate;

   ----------------------------------
   -- Two_Dim_Packed_Array_Handled --
   ----------------------------------

   function Two_Dim_Packed_Array_Handled (N : Node_Id) return Boolean is
      Loc          : constant Source_Ptr := Sloc (N);
      Typ          : constant Entity_Id  := Etype (N);
      Ctyp         : constant Entity_Id  := Component_Type (Typ);
      Comp_Size    : constant Int        := UI_To_Int (Component_Size (Typ));
      Packed_Array : constant Entity_Id  :=
                       Packed_Array_Impl_Type (Base_Type (Typ));

      One_Comp : Node_Id;
      --  Expression in original aggregate

      One_Dim : Node_Id;
      --  One-dimensional subaggregate

   begin

      --  For now, only deal with cases where an integral number of elements
      --  fit in a single byte. This includes the most common boolean case.

      if not (Comp_Size = 1 or else
              Comp_Size = 2 or else
              Comp_Size = 4)
      then
         return False;
      end if;

      Convert_To_Positional (N, Handle_Bit_Packed => True);

      --  Verify that all components are static

      if Nkind (N) = N_Aggregate
        and then Compile_Time_Known_Aggregate (N)
      then
         null;

      --  The aggregate may have been reanalyzed and converted already

      elsif Nkind (N) /= N_Aggregate then
         return True;

      --  If component associations remain, the aggregate is not static

      elsif Present (Component_Associations (N)) then
         return False;

      else
         One_Dim := First (Expressions (N));
         while Present (One_Dim) loop
            if Present (Component_Associations (One_Dim)) then
               return False;
            end if;

            One_Comp := First (Expressions (One_Dim));
            while Present (One_Comp) loop
               if not Is_OK_Static_Expression (One_Comp) then
                  return False;
               end if;

               Next (One_Comp);
            end loop;

            Next (One_Dim);
         end loop;
      end if;

      --  Two-dimensional aggregate is now fully positional so pack one
      --  dimension to create a static one-dimensional array, and rewrite
      --  as an unchecked conversion to the original type.

      declare
         Byte_Size : constant Int := UI_To_Int (Component_Size (Packed_Array));
         --  The packed array type is a byte array

         Packed_Num : Nat;
         --  Number of components accumulated in current byte

         Comps : List_Id;
         --  Assembled list of packed values for equivalent aggregate

         Comp_Val : Uint;
         --  Integer value of component

         Incr : Int;
         --  Step size for packing

         Init_Shift : Int;
         --  Endian-dependent start position for packing

         Shift : Int;
         --  Current insertion position

         Val : Int;
         --  Component of packed array being assembled

      begin
         Comps := New_List;
         Val   := 0;
         Packed_Num := 0;

         --  Account for endianness. See corresponding comment in
         --  Packed_Array_Aggregate_Handled concerning the following.

         if Bytes_Big_Endian
           xor Debug_Flag_8
           xor Reverse_Storage_Order (Base_Type (Typ))
         then
            Init_Shift := Byte_Size - Comp_Size;
            Incr := -Comp_Size;
         else
            Init_Shift := 0;
            Incr := +Comp_Size;
         end if;

         --  Iterate over each subaggregate

         Shift := Init_Shift;
         One_Dim := First (Expressions (N));
         while Present (One_Dim) loop
            One_Comp := First (Expressions (One_Dim));
            while Present (One_Comp) loop
               if Packed_Num = Byte_Size / Comp_Size then

                  --  Byte is complete, add to list of expressions

                  Append (Make_Integer_Literal (Sloc (One_Dim), Val), Comps);
                  Val := 0;
                  Shift := Init_Shift;
                  Packed_Num := 0;

               else
                  Comp_Val := Expr_Rep_Value (One_Comp);

                  --  Adjust for bias, and strip proper number of bits

                  if Has_Biased_Representation (Ctyp) then
                     Comp_Val := Comp_Val - Expr_Value (Type_Low_Bound (Ctyp));
                  end if;

                  Comp_Val := Comp_Val mod Uint_2 ** Comp_Size;
                  Val := UI_To_Int (Val + Comp_Val * Uint_2 ** Shift);
                  Shift := Shift + Incr;
                  Next (One_Comp);
                  Packed_Num := Packed_Num + 1;
               end if;
            end loop;

            Next (One_Dim);
         end loop;

         if Packed_Num > 0 then

            --  Add final incomplete byte if present

            Append (Make_Integer_Literal (Sloc (One_Dim), Val), Comps);
         end if;

         Rewrite (N,
             Unchecked_Convert_To (Typ,
               Make_Qualified_Expression (Loc,
                 Subtype_Mark => New_Occurrence_Of (Packed_Array, Loc),
                 Expression   => Make_Aggregate (Loc, Expressions => Comps))));
         Analyze_And_Resolve (N);
         return True;
      end;
   end Two_Dim_Packed_Array_Handled;

end Exp_Aggr;
