------------------------------------------------------------------------------
--                                                                          --
--                         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 No (Csiz) or else 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) and then Present (Csiz) then

         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 Uint := Component_Size (Typ);
   begin
      return Number_Dimensions (Typ) = 2
        and then Is_Bit_Packed_Array (Typ)
        and then C in Uint_1 | Uint_2 | Uint_4; -- False if No_Uint
   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;
