------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ 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 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_Ch6;        use Exp_Ch6;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Itypes;         use Itypes;
with Lib;            use Lib;
with Lib.Xref;       use Lib.Xref;
with Namet;          use Namet;
with Namet.Sp;       use Namet.Sp;
with Nmake;          use Nmake;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Case;       use Sem_Case;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch5;        use Sem_Ch5;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch13;       use Sem_Ch13;
with Sem_Dim;        use Sem_Dim;
with Sem_Eval;       use Sem_Eval;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sem_Type;       use Sem_Type;
with Sem_Warn;       use Sem_Warn;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Snames;         use Snames;
with Stringt;        use Stringt;
with Stand;          use Stand;
with Style;          use Style;
with Targparm;       use Targparm;
with Tbuild;         use Tbuild;
with Ttypes;         use Ttypes;
with Uintp;          use Uintp;

package body Sem_Aggr is

   type Case_Bounds is record
      Lo : Node_Id;
      --  Low bound of choice. Once we sort the Case_Table, then entries
      --  will be in order of ascending Choice_Lo values.

      Hi : Node_Id;
      --  High Bound of choice. The sort does not pay any attention to the
      --  high bound, so choices 1 .. 4 and 1 .. 5 could be in either order.

      Highest : Uint;
      --  If there are duplicates or missing entries, then in the sorted
      --  table, this records the highest value among Choice_Hi values
      --  seen so far, including this entry.

      Choice : Node_Id;
      --  The node of the choice
   end record;

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

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

   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 choices in a case statement will
   --  usually be in near sorted order.

   procedure Check_Can_Never_Be_Null (Typ : Entity_Id; Expr : Node_Id);
   --  Ada 2005 (AI-231): Check bad usage of null for a component for which
   --  null exclusion (NOT NULL) is specified. Typ can be an E_Array_Type for
   --  the array case (the component type of the array will be used) or an
   --  E_Component/E_Discriminant entity in the record case, in which case the
   --  type of the component will be used for the test. If Typ is any other
   --  kind of entity, the call is ignored. Expr is the component node in the
   --  aggregate which is known to have a null value. A warning message will be
   --  issued if the component is null excluding.
   --
   --  It would be better to pass the proper type for Typ ???

   procedure Check_Expr_OK_In_Limited_Aggregate (Expr : Node_Id);
   --  Check that Expr is either not limited or else is one of the cases of
   --  expressions allowed for a limited component association (namely, an
   --  aggregate, function call, or <> notation). Report error for violations.
   --  Expression is also OK in an instance or inlining context, because we
   --  have already preanalyzed and it is known to be type correct.

   ------------------------------------------------------
   -- Subprograms used for RECORD AGGREGATE Processing --
   ------------------------------------------------------

   procedure Resolve_Record_Aggregate (N : Node_Id; Typ : Entity_Id);
   --  This procedure performs all the semantic checks required for record
   --  aggregates. Note that for aggregates analysis and resolution go
   --  hand in hand. Aggregate analysis has been delayed up to here and
   --  it is done while resolving the aggregate.
   --
   --    N is the N_Aggregate node.
   --    Typ is the record type for the aggregate resolution
   --
   --  While performing the semantic checks, this procedure builds a new
   --  Component_Association_List where each record field appears alone in a
   --  Component_Choice_List along with its corresponding expression. The
   --  record fields in the Component_Association_List appear in the same order
   --  in which they appear in the record type Typ.
   --
   --  Once this new Component_Association_List is built and all the semantic
   --  checks performed, the original aggregate subtree is replaced with the
   --  new named record aggregate just built. This new record aggregate has no
   --  positional associations, so its Expressions field is set to No_List.
   --  Note that subtree substitution is performed with Rewrite so as to be
   --  able to retrieve the original aggregate.
   --
   --  The aggregate subtree manipulation performed by Resolve_Record_Aggregate
   --  yields the aggregate format expected by Gigi. Typically, this kind of
   --  tree manipulations are done in the expander. However, because the
   --  semantic checks that need to be performed on record aggregates really go
   --  hand in hand with the record aggregate normalization, the aggregate
   --  subtree transformation is performed during resolution rather than
   --  expansion. Had we decided otherwise we would have had to duplicate most
   --  of the code in the expansion procedure Expand_Record_Aggregate. Note,
   --  however, that all the expansion concerning aggregates for tagged records
   --  is done in Expand_Record_Aggregate.
   --
   --  The algorithm of Resolve_Record_Aggregate proceeds as follows:
   --
   --  1. Make sure that the record type against which the record aggregate
   --     has to be resolved is not abstract. Furthermore if the type is a
   --     null aggregate make sure the input aggregate N is also null.
   --
   --  2. Verify that the structure of the aggregate is that of a record
   --     aggregate. Specifically, look for component associations and ensure
   --     that each choice list only has identifiers or the N_Others_Choice
   --     node. Also make sure that if present, the N_Others_Choice occurs
   --     last and by itself.
   --
   --  3. If Typ contains discriminants, the values for each discriminant is
   --     looked for. If the record type Typ has variants, we check that the
   --     expressions corresponding to each discriminant ruling the (possibly
   --     nested) variant parts of Typ, are static. This allows us to determine
   --     the variant parts to which the rest of the aggregate must conform.
   --     The names of discriminants with their values are saved in a new
   --     association list, New_Assoc_List which is later augmented with the
   --     names and values of the remaining components in the record type.
   --
   --     During this phase we also make sure that every discriminant is
   --     assigned exactly one value. Note that when several values for a given
   --     discriminant are found, semantic processing continues looking for
   --     further errors. In this case it's the first discriminant value found
   --     which we will be recorded.
   --
   --     IMPORTANT NOTE: For derived tagged types this procedure expects
   --     First_Discriminant and Next_Discriminant to give the correct list
   --     of discriminants, in the correct order.
   --
   --  4. After all the discriminant values have been gathered, we can set the
   --     Etype of the record aggregate. If Typ contains no discriminants this
   --     is straightforward: the Etype of N is just Typ, otherwise a new
   --     implicit constrained subtype of Typ is built to be the Etype of N.
   --
   --  5. Gather the remaining record components according to the discriminant
   --     values. This involves recursively traversing the record type
   --     structure to see what variants are selected by the given discriminant
   --     values. This processing is a little more convoluted if Typ is a
   --     derived tagged types since we need to retrieve the record structure
   --     of all the ancestors of Typ.
   --
   --  6. After gathering the record components we look for their values in the
   --     record aggregate and emit appropriate error messages should we not
   --     find such values or should they be duplicated.
   --
   --  7. We then make sure no illegal component names appear in the record
   --     aggregate and make sure that the type of the record components
   --     appearing in a same choice list is the same. Finally we ensure that
   --     the others choice, if present, is used to provide the value of at
   --     least a record component.
   --
   --  8. The original aggregate node is replaced with the new named aggregate
   --     built in steps 3 through 6, as explained earlier.
   --
   --  Given the complexity of record aggregate resolution, the primary goal of
   --  this routine is clarity and simplicity rather than execution and storage
   --  efficiency. If there are only positional components in the aggregate the
   --  running time is linear. If there are associations the running time is
   --  still linear as long as the order of the associations is not too far off
   --  the order of the components in the record type. If this is not the case
   --  the running time is at worst quadratic in the size of the association
   --  list.

   procedure Check_Misspelled_Component
     (Elements  : Elist_Id;
      Component : Node_Id);
   --  Give possible misspelling diagnostic if Component is likely to be a
   --  misspelling of one of the components of the Assoc_List. This is called
   --  by Resolve_Aggr_Expr after producing an invalid component error message.

   -----------------------------------------------------
   -- Subprograms used for ARRAY AGGREGATE Processing --
   -----------------------------------------------------

   function Resolve_Array_Aggregate
     (N              : Node_Id;
      Index          : Node_Id;
      Index_Constr   : Node_Id;
      Component_Typ  : Entity_Id;
      Others_Allowed : Boolean) return Boolean;
   --  This procedure performs the semantic checks for an array aggregate.
   --  True is returned if the aggregate resolution succeeds.
   --
   --  The procedure works by recursively checking each nested aggregate.
   --  Specifically, after checking a sub-aggregate nested at the i-th level
   --  we recursively check all the subaggregates at the i+1-st level (if any).
   --  Note that for aggregates analysis and resolution go hand in hand.
   --  Aggregate analysis has been delayed up to here and it is done while
   --  resolving the aggregate.
   --
   --    N is the current N_Aggregate node to be checked.
   --
   --    Index is the index node corresponding to the array sub-aggregate that
   --    we are currently checking (RM 4.3.3 (8)). Its Etype is the
   --    corresponding index type (or subtype).
   --
   --    Index_Constr is the node giving the applicable index constraint if
   --    any (RM 4.3.3 (10)). It "is a constraint provided by certain
   --    contexts [...] that can be used to determine the bounds of the array
   --    value specified by the aggregate". If Others_Allowed below is False
   --    there is no applicable index constraint and this node is set to Index.
   --
   --    Component_Typ is the array component type.
   --
   --    Others_Allowed indicates whether an others choice is allowed
   --    in the context where the top-level aggregate appeared.
   --
   --  The algorithm of Resolve_Array_Aggregate proceeds as follows:
   --
   --  1. Make sure that the others choice, if present, is by itself and
   --     appears last in the sub-aggregate. Check that we do not have
   --     positional and named components in the array sub-aggregate (unless
   --     the named association is an others choice). Finally if an others
   --     choice is present, make sure it is allowed in the aggregate context.
   --
   --  2. If the array sub-aggregate contains discrete_choices:
   --
   --     (A) Verify their validity. Specifically verify that:
   --
   --        (a) If a null range is present it must be the only possible
   --            choice in the array aggregate.
   --
   --        (b) Ditto for a non static range.
   --
   --        (c) Ditto for a non static expression.
   --
   --        In addition this step analyzes and resolves each discrete_choice,
   --        making sure that its type is the type of the corresponding Index.
   --        If we are not at the lowest array aggregate level (in the case of
   --        multi-dimensional aggregates) then invoke Resolve_Array_Aggregate
   --        recursively on each component expression. Otherwise, resolve the
   --        bottom level component expressions against the expected component
   --        type ONLY IF the component corresponds to a single discrete choice
   --        which is not an others choice (to see why read the DELAYED
   --        COMPONENT RESOLUTION below).
   --
   --     (B) Determine the bounds of the sub-aggregate and lowest and
   --         highest choice values.
   --
   --  3. For positional aggregates:
   --
   --     (A) Loop over the component expressions either recursively invoking
   --         Resolve_Array_Aggregate on each of these for multi-dimensional
   --         array aggregates or resolving the bottom level component
   --         expressions against the expected component type.
   --
   --     (B) Determine the bounds of the positional sub-aggregates.
   --
   --  4. Try to determine statically whether the evaluation of the array
   --     sub-aggregate raises Constraint_Error. If yes emit proper
   --     warnings. The precise checks are the following:
   --
   --     (A) Check that the index range defined by aggregate bounds is
   --         compatible with corresponding index subtype.
   --         We also check against the base type. In fact it could be that
   --         Low/High bounds of the base type are static whereas those of
   --         the index subtype are not. Thus if we can statically catch
   --         a problem with respect to the base type we are guaranteed
   --         that the same problem will arise with the index subtype
   --
   --     (B) If we are dealing with a named aggregate containing an others
   --         choice and at least one discrete choice then make sure the range
   --         specified by the discrete choices does not overflow the
   --         aggregate bounds. We also check against the index type and base
   --         type bounds for the same reasons given in (A).
   --
   --     (C) If we are dealing with a positional aggregate with an others
   --         choice make sure the number of positional elements specified
   --         does not overflow the aggregate bounds. We also check against
   --         the index type and base type bounds as mentioned in (A).
   --
   --     Finally construct an N_Range node giving the sub-aggregate bounds.
   --     Set the Aggregate_Bounds field of the sub-aggregate to be this
   --     N_Range. The routine Array_Aggr_Subtype below uses such N_Ranges
   --     to build the appropriate aggregate subtype. Aggregate_Bounds
   --     information is needed during expansion.
   --
   --  DELAYED COMPONENT RESOLUTION: The resolution of bottom level component
   --  expressions in an array aggregate may call Duplicate_Subexpr or some
   --  other routine that inserts code just outside the outermost aggregate.
   --  If the array aggregate contains discrete choices or an others choice,
   --  this may be wrong. Consider for instance the following example.
   --
   --    type Rec is record
   --       V : Integer := 0;
   --    end record;
   --
   --    type Acc_Rec is access Rec;
   --    Arr : array (1..3) of Acc_Rec := (1 .. 3 => new Rec);
   --
   --  Then the transformation of "new Rec" that occurs during resolution
   --  entails the following code modifications
   --
   --    P7b : constant Acc_Rec := new Rec;
   --    RecIP (P7b.all);
   --    Arr : array (1..3) of Acc_Rec := (1 .. 3 => P7b);
   --
   --  This code transformation is clearly wrong, since we need to call
   --  "new Rec" for each of the 3 array elements. To avoid this problem we
   --  delay resolution of the components of non positional array aggregates
   --  to the expansion phase. As an optimization, if the discrete choice
   --  specifies a single value we do not delay resolution.

   function Array_Aggr_Subtype (N : Node_Id; Typ : Entity_Id) return Entity_Id;
   --  This routine returns the type or subtype of an array aggregate.
   --
   --    N is the array aggregate node whose type we return.
   --
   --    Typ is the context type in which N occurs.
   --
   --  This routine creates an implicit array subtype whose bounds are
   --  those defined by the aggregate. When this routine is invoked
   --  Resolve_Array_Aggregate has already processed aggregate N. Thus the
   --  Aggregate_Bounds of each sub-aggregate, is an N_Range node giving the
   --  sub-aggregate bounds. When building the aggregate itype, this function
   --  traverses the array aggregate N collecting such Aggregate_Bounds and
   --  constructs the proper array aggregate itype.
   --
   --  Note that in the case of multidimensional aggregates each inner
   --  sub-aggregate corresponding to a given array dimension, may provide a
   --  different bounds. If it is possible to determine statically that
   --  some sub-aggregates corresponding to the same index do not have the
   --  same bounds, then a warning is emitted. If such check is not possible
   --  statically (because some sub-aggregate bounds are dynamic expressions)
   --  then this job is left to the expander. In all cases the particular
   --  bounds that this function will chose for a given dimension is the first
   --  N_Range node for a sub-aggregate corresponding to that dimension.
   --
   --  Note that the Raises_Constraint_Error flag of an array aggregate
   --  whose evaluation is determined to raise CE by Resolve_Array_Aggregate,
   --  is set in Resolve_Array_Aggregate but the aggregate is not
   --  immediately replaced with a raise CE. In fact, Array_Aggr_Subtype must
   --  first construct the proper itype for the aggregate (Gigi needs
   --  this). After constructing the proper itype we will eventually replace
   --  the top-level aggregate with a raise CE (done in Resolve_Aggregate).
   --  Of course in cases such as:
   --
   --     type Arr is array (integer range <>) of Integer;
   --     A : Arr := (positive range -1 .. 2 => 0);
   --
   --  The bounds of the aggregate itype are cooked up to look reasonable
   --  (in this particular case the bounds will be 1 .. 2).

   procedure Make_String_Into_Aggregate (N : Node_Id);
   --  A string literal can appear in a context in which a one dimensional
   --  array of characters is expected. This procedure simply rewrites the
   --  string as an aggregate, prior to resolution.

   ---------------------------------
   --  Delta aggregate processing --
   ---------------------------------

   procedure Resolve_Delta_Array_Aggregate  (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Delta_Record_Aggregate (N : Node_Id; Typ : Entity_Id);

   ------------------------
   -- Array_Aggr_Subtype --
   ------------------------

   function Array_Aggr_Subtype
     (N   : Node_Id;
      Typ : Entity_Id) return Entity_Id
   is
      Aggr_Dimension : constant Pos := Number_Dimensions (Typ);
      --  Number of aggregate index dimensions

      Aggr_Range : array (1 .. Aggr_Dimension) of Node_Id := (others => Empty);
      --  Constrained N_Range of each index dimension in our aggregate itype

      Aggr_Low  : array (1 .. Aggr_Dimension) of Node_Id := (others => Empty);
      Aggr_High : array (1 .. Aggr_Dimension) of Node_Id := (others => Empty);
      --  Low and High bounds for each index dimension in our aggregate itype

      Is_Fully_Positional : Boolean := True;

      procedure Collect_Aggr_Bounds (N : Node_Id; Dim : Pos);
      --  N is an array (sub-)aggregate. Dim is the dimension corresponding
      --  to (sub-)aggregate N. This procedure collects and removes the side
      --  effects of the constrained N_Range nodes corresponding to each index
      --  dimension of our aggregate itype. These N_Range nodes are collected
      --  in Aggr_Range above.
      --
      --  Likewise collect in Aggr_Low & Aggr_High above the low and high
      --  bounds of each index dimension. If, when collecting, two bounds
      --  corresponding to the same dimension are static and found to differ,
      --  then emit a warning, and mark N as raising Constraint_Error.

      -------------------------
      -- Collect_Aggr_Bounds --
      -------------------------

      procedure Collect_Aggr_Bounds (N : Node_Id; Dim : Pos) is
         This_Range : constant Node_Id := Aggregate_Bounds (N);
         --  The aggregate range node of this specific sub-aggregate

         This_Low  : constant Node_Id := Low_Bound  (Aggregate_Bounds (N));
         This_High : constant Node_Id := High_Bound (Aggregate_Bounds (N));
         --  The aggregate bounds of this specific sub-aggregate

         Assoc : Node_Id;
         Expr  : Node_Id;

      begin
         Remove_Side_Effects (This_Low,  Variable_Ref => True);
         Remove_Side_Effects (This_High, Variable_Ref => True);

         --  Collect the first N_Range for a given dimension that you find.
         --  For a given dimension they must be all equal anyway.

         if No (Aggr_Range (Dim)) then
            Aggr_Low (Dim)   := This_Low;
            Aggr_High (Dim)  := This_High;
            Aggr_Range (Dim) := This_Range;

         else
            if Compile_Time_Known_Value (This_Low) then
               if not Compile_Time_Known_Value (Aggr_Low (Dim)) then
                  Aggr_Low (Dim) := This_Low;

               elsif Expr_Value (This_Low) /= Expr_Value (Aggr_Low (Dim)) then
                  Set_Raises_Constraint_Error (N);
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Error_Msg_N ("sub-aggregate low bound mismatch<<", N);
                  Error_Msg_N ("\Constraint_Error [<<", N);
               end if;
            end if;

            if Compile_Time_Known_Value (This_High) then
               if not Compile_Time_Known_Value (Aggr_High (Dim)) then
                  Aggr_High (Dim) := This_High;

               elsif
                 Expr_Value (This_High) /= Expr_Value (Aggr_High (Dim))
               then
                  Set_Raises_Constraint_Error (N);
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Error_Msg_N ("sub-aggregate high bound mismatch<<", N);
                  Error_Msg_N ("\Constraint_Error [<<", N);
               end if;
            end if;
         end if;

         if Dim < Aggr_Dimension then

            --  Process positional components

            if Present (Expressions (N)) then
               Expr := First (Expressions (N));
               while Present (Expr) loop
                  Collect_Aggr_Bounds (Expr, Dim + 1);
                  Next (Expr);
               end loop;
            end if;

            --  Process component associations

            if Present (Component_Associations (N)) then
               Is_Fully_Positional := False;

               Assoc := First (Component_Associations (N));
               while Present (Assoc) loop
                  Expr := Expression (Assoc);
                  Collect_Aggr_Bounds (Expr, Dim + 1);
                  Next (Assoc);
               end loop;
            end if;
         end if;
      end Collect_Aggr_Bounds;

      --  Array_Aggr_Subtype variables

      Itype : Entity_Id;
      --  The final itype of the overall aggregate

      Index_Constraints : constant List_Id := New_List;
      --  The list of index constraints of the aggregate itype

   --  Start of processing for Array_Aggr_Subtype

   begin
      --  Make sure that the list of index constraints is properly attached to
      --  the tree, and then collect the aggregate bounds.

      --  If no aggregaate bounds have been set, this is an aggregate with
      --  iterator specifications and a dynamic size to be determined by
      --  first pass of expanded code.

      if No (Aggregate_Bounds (N)) then
         return Typ;
      end if;

      Set_Parent (Index_Constraints, N);
      Collect_Aggr_Bounds (N, 1);

      --  Build the list of constrained indexes of our aggregate itype

      for J in 1 .. Aggr_Dimension loop
         Create_Index : declare
            Index_Base : constant Entity_Id :=
                           Base_Type (Etype (Aggr_Range (J)));
            Index_Typ  : Entity_Id;

         begin
            --  Construct the Index subtype, and associate it with the range
            --  construct that generates it.

            Index_Typ :=
              Create_Itype (Subtype_Kind (Ekind (Index_Base)), Aggr_Range (J));

            Set_Etype (Index_Typ, Index_Base);

            if Is_Character_Type (Index_Base) then
               Set_Is_Character_Type (Index_Typ);
            end if;

            Set_Size_Info      (Index_Typ,                (Index_Base));
            Set_RM_Size        (Index_Typ, RM_Size        (Index_Base));
            Set_First_Rep_Item (Index_Typ, First_Rep_Item (Index_Base));
            Set_Scalar_Range   (Index_Typ, Aggr_Range (J));

            if Is_Discrete_Or_Fixed_Point_Type (Index_Typ) then
               Set_RM_Size (Index_Typ, UI_From_Int (Minimum_Size (Index_Typ)));
            end if;

            Set_Etype (Aggr_Range (J), Index_Typ);

            Append (Aggr_Range (J), To => Index_Constraints);
         end Create_Index;
      end loop;

      --  Now build the Itype

      Itype := Create_Itype (E_Array_Subtype, N);

      Set_First_Rep_Item         (Itype, First_Rep_Item        (Typ));
      Set_Convention             (Itype, Convention            (Typ));
      Set_Depends_On_Private     (Itype, Has_Private_Component (Typ));
      Set_Etype                  (Itype, Base_Type             (Typ));
      Set_Has_Alignment_Clause   (Itype, Has_Alignment_Clause  (Typ));
      Set_Is_Aliased             (Itype, Is_Aliased            (Typ));
      Set_Is_Independent         (Itype, Is_Independent        (Typ));
      Set_Depends_On_Private     (Itype, Depends_On_Private    (Typ));

      Copy_Suppress_Status (Index_Check,  Typ, Itype);
      Copy_Suppress_Status (Length_Check, Typ, Itype);

      Set_First_Index    (Itype, First (Index_Constraints));
      Set_Is_Constrained (Itype, True);
      Set_Is_Internal    (Itype, True);

      if Has_Predicates (Typ) then
         Set_Has_Predicates (Itype);

         --  If the base type has a predicate, capture the predicated parent
         --  or the existing predicate function for SPARK use.

         if Present (Predicate_Function (Typ)) then
            Set_Predicate_Function (Itype, Predicate_Function (Typ));

         elsif Is_Itype (Typ) then
            Set_Predicated_Parent (Itype, Predicated_Parent (Typ));

         else
            Set_Predicated_Parent (Itype, Typ);
         end if;
      end if;

      --  A simple optimization: purely positional aggregates of static
      --  components should be passed to gigi unexpanded whenever possible, and
      --  regardless of the staticness of the bounds themselves. Subsequent
      --  checks in exp_aggr verify that type is not packed, etc.

      Set_Size_Known_At_Compile_Time
        (Itype,
         Is_Fully_Positional
           and then Comes_From_Source (N)
           and then Size_Known_At_Compile_Time (Component_Type (Typ)));

      --  We always need a freeze node for a packed array subtype, so that we
      --  can build the Packed_Array_Impl_Type corresponding to the subtype. If
      --  expansion is disabled, the packed array subtype is not built, and we
      --  must not generate a freeze node for the type, or else it will appear
      --  incomplete to gigi.

      if Is_Packed (Itype)
        and then not In_Spec_Expression
        and then Expander_Active
      then
         Freeze_Itype (Itype, N);
      end if;

      return Itype;
   end Array_Aggr_Subtype;

   --------------------------------
   -- Check_Misspelled_Component --
   --------------------------------

   procedure Check_Misspelled_Component
     (Elements  : Elist_Id;
      Component : Node_Id)
   is
      Max_Suggestions   : constant := 2;

      Nr_Of_Suggestions : Natural := 0;
      Suggestion_1      : Entity_Id := Empty;
      Suggestion_2      : Entity_Id := Empty;
      Component_Elmt    : Elmt_Id;

   begin
      --  All the components of List are matched against Component and a count
      --  is maintained of possible misspellings. When at the end of the
      --  analysis there are one or two (not more) possible misspellings,
      --  these misspellings will be suggested as possible corrections.

      Component_Elmt := First_Elmt (Elements);
      while Nr_Of_Suggestions <= Max_Suggestions
        and then Present (Component_Elmt)
      loop
         if Is_Bad_Spelling_Of
              (Chars (Node (Component_Elmt)),
               Chars (Component))
         then
            Nr_Of_Suggestions := Nr_Of_Suggestions + 1;

            case Nr_Of_Suggestions is
               when 1      => Suggestion_1 := Node (Component_Elmt);
               when 2      => Suggestion_2 := Node (Component_Elmt);
               when others => null;
            end case;
         end if;

         Next_Elmt (Component_Elmt);
      end loop;

      --  Report at most two suggestions

      if Nr_Of_Suggestions = 1 then
         Error_Msg_NE -- CODEFIX
           ("\possible misspelling of&", Component, Suggestion_1);

      elsif Nr_Of_Suggestions = 2 then
         Error_Msg_Node_2 := Suggestion_2;
         Error_Msg_NE -- CODEFIX
           ("\possible misspelling of& or&", Component, Suggestion_1);
      end if;
   end Check_Misspelled_Component;

   ----------------------------------------
   -- Check_Expr_OK_In_Limited_Aggregate --
   ----------------------------------------

   procedure Check_Expr_OK_In_Limited_Aggregate (Expr : Node_Id) is
   begin
      if Is_Limited_Type (Etype (Expr))
         and then Comes_From_Source (Expr)
      then
         if In_Instance_Body or else In_Inlined_Body then
            null;

         elsif not OK_For_Limited_Init (Etype (Expr), Expr) then
            Error_Msg_N
              ("initialization not allowed for limited types", Expr);
            Explain_Limited_Type (Etype (Expr), Expr);
         end if;
      end if;
   end Check_Expr_OK_In_Limited_Aggregate;

   -------------------------
   -- Is_Others_Aggregate --
   -------------------------

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

   begin
      return No (Expressions (Aggr))
        and then Nkind (First (Choice_List (First (Assoc)))) = N_Others_Choice;
   end Is_Others_Aggregate;

   -------------------------
   -- Is_Single_Aggregate --
   -------------------------

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

   begin
      return No (Expressions (Aggr))
        and then No (Next (First (Assoc)))
        and then No (Next (First (Choice_List (First (Assoc)))));
   end Is_Single_Aggregate;

   --------------------------------
   -- Make_String_Into_Aggregate --
   --------------------------------

   procedure Make_String_Into_Aggregate (N : Node_Id) is
      Exprs  : constant List_Id    := New_List;
      Loc    : constant Source_Ptr := Sloc (N);
      Str    : constant String_Id  := Strval (N);
      Strlen : constant Nat        := String_Length (Str);
      C      : Char_Code;
      C_Node : Node_Id;
      New_N  : Node_Id;
      P      : Source_Ptr;

   begin
      P := Loc + 1;
      for J in  1 .. Strlen loop
         C := Get_String_Char (Str, J);
         Set_Character_Literal_Name (C);

         C_Node :=
           Make_Character_Literal (P,
             Chars              => Name_Find,
             Char_Literal_Value => UI_From_CC (C));
         Set_Etype (C_Node, Any_Character);
         Append_To (Exprs, C_Node);

         P := P + 1;
         --  Something special for wide strings???
      end loop;

      New_N := Make_Aggregate (Loc, Expressions => Exprs);
      Set_Analyzed (New_N);
      Set_Etype (New_N, Any_Composite);

      Rewrite (N, New_N);
   end Make_String_Into_Aggregate;

   -----------------------
   -- Resolve_Aggregate --
   -----------------------

   procedure Resolve_Aggregate (N : Node_Id; Typ : Entity_Id) is
      Loc : constant Source_Ptr := Sloc (N);

      Aggr_Subtyp : Entity_Id;
      --  The actual aggregate subtype. This is not necessarily the same as Typ
      --  which is the subtype of the context in which the aggregate was found.

      Others_Box : Boolean := False;
      --  Set to True if N represents a simple aggregate with only
      --  (others => <>), not nested as part of another aggregate.

      function Within_Aggregate (N : Node_Id) return Boolean;
      --  Return True if N is part of an N_Aggregate

      ----------------------
      -- Within_Aggregate --
      ----------------------

      function Within_Aggregate (N : Node_Id) return Boolean is
         P : Node_Id := Parent (N);
      begin
         while Present (P) loop
            if Nkind (P) = N_Aggregate then
               return True;
            end if;

            P := Parent (P);
         end loop;

         return False;
      end Within_Aggregate;

   --  Start of processing for Resolve_Aggregate

   begin
      --  Ignore junk empty aggregate resulting from parser error

      if No (Expressions (N))
        and then No (Component_Associations (N))
        and then not Null_Record_Present (N)
      then
         return;
      end if;

      --  If the aggregate has box-initialized components, its type must be
      --  frozen so that initialization procedures can properly be called
      --  in the resolution that follows. The replacement of boxes with
      --  initialization calls is properly an expansion activity but it must
      --  be done during resolution.

      if Expander_Active
        and then Present (Component_Associations (N))
      then
         declare
            Comp       : Node_Id;
            First_Comp : Boolean := True;

         begin
            Comp := First (Component_Associations (N));
            while Present (Comp) loop
               if Box_Present (Comp) then
                  if First_Comp
                    and then No (Expressions (N))
                    and then Nkind (First (Choices (Comp))) = N_Others_Choice
                    and then not Within_Aggregate (N)
                  then
                     Others_Box := True;
                  end if;

                  Insert_Actions (N, Freeze_Entity (Typ, N));
                  exit;
               end if;

               First_Comp := False;
               Next (Comp);
            end loop;
         end;
      end if;

      --  Check for aggregates not allowed in configurable run-time mode.
      --  We allow all cases of aggregates that do not come from source, since
      --  these are all assumed to be small (e.g. bounds of a string literal).
      --  We also allow aggregates of types we know to be small.

      if not Support_Aggregates_On_Target
        and then Comes_From_Source (N)
        and then (not Known_Static_Esize (Typ)
                   or else Esize (Typ) > System_Max_Integer_Size)
      then
         Error_Msg_CRT ("aggregate", N);
      end if;

      --  Ada 2005 (AI-287): Limited aggregates allowed

      --  In an instance, ignore aggregate subcomponents tnat may be limited,
      --  because they originate in view conflicts. If the original aggregate
      --  is legal and the actuals are legal, the aggregate itself is legal.

      if Is_Limited_Type (Typ)
        and then Ada_Version < Ada_2005
        and then not In_Instance
      then
         Error_Msg_N ("aggregate type cannot be limited", N);
         Explain_Limited_Type (Typ, N);

      elsif Is_Class_Wide_Type (Typ) then
         Error_Msg_N ("type of aggregate cannot be class-wide", N);

      elsif Typ = Any_String
        or else Typ = Any_Composite
      then
         Error_Msg_N ("no unique type for aggregate", N);
         Set_Etype (N, Any_Composite);

      elsif Is_Array_Type (Typ) and then Null_Record_Present (N) then
         Error_Msg_N ("null record forbidden in array aggregate", N);

      elsif Present (Find_Aspect (Typ, Aspect_Aggregate))
        and then Ekind (Typ) /= E_Record_Type
        and then Ada_Version >= Ada_2022
      then
         Resolve_Container_Aggregate (N, Typ);

      elsif Is_Record_Type (Typ) then
         Resolve_Record_Aggregate (N, Typ);

      elsif Is_Array_Type (Typ) then

         --  First a special test, for the case of a positional aggregate of
         --  characters which can be replaced by a string literal.

         --  Do not perform this transformation if this was a string literal
         --  to start with, whose components needed constraint checks, or if
         --  the component type is non-static, because it will require those
         --  checks and be transformed back into an aggregate. If the index
         --  type is not Integer the aggregate may represent a user-defined
         --  string type but the context might need the original type so we
         --  do not perform the transformation at this point.

         if Number_Dimensions (Typ) = 1
           and then Is_Standard_Character_Type (Component_Type (Typ))
           and then No (Component_Associations (N))
           and then not Is_Limited_Composite (Typ)
           and then not Is_Private_Composite (Typ)
           and then not Is_Bit_Packed_Array (Typ)
           and then Nkind (Original_Node (Parent (N))) /= N_String_Literal
           and then Is_OK_Static_Subtype (Component_Type (Typ))
           and then Base_Type (Etype (First_Index (Typ))) =
                      Base_Type (Standard_Integer)
         then
            declare
               Expr : Node_Id;

            begin
               Expr := First (Expressions (N));
               while Present (Expr) loop
                  exit when Nkind (Expr) /= N_Character_Literal;
                  Next (Expr);
               end loop;

               if No (Expr) then
                  Start_String;

                  Expr := First (Expressions (N));
                  while Present (Expr) loop
                     Store_String_Char (UI_To_CC (Char_Literal_Value (Expr)));
                     Next (Expr);
                  end loop;

                  Rewrite (N, Make_String_Literal (Loc, End_String));

                  Analyze_And_Resolve (N, Typ);
                  return;
               end if;
            end;
         end if;

         --  Here if we have a real aggregate to deal with

         Array_Aggregate : declare
            Aggr_Resolved : Boolean;

            Aggr_Typ : constant Entity_Id := Etype (Typ);
            --  This is the unconstrained array type, which is the type against
            --  which the aggregate is to be resolved. Typ itself is the array
            --  type of the context which may not be the same subtype as the
            --  subtype for the final aggregate.

         begin
            --  In the following we determine whether an OTHERS choice is
            --  allowed inside the array aggregate. The test checks the context
            --  in which the array aggregate occurs. If the context does not
            --  permit it, or the aggregate type is unconstrained, an OTHERS
            --  choice is not allowed (except that it is always allowed on the
            --  right-hand side of an assignment statement; in this case the
            --  constrainedness of the type doesn't matter, because an array
            --  object is always constrained).

            --  If expansion is disabled (generic context, or semantics-only
            --  mode) actual subtypes cannot be constructed, and the type of an
            --  object may be its unconstrained nominal type. However, if the
            --  context is an assignment statement, OTHERS is allowed, because
            --  the target of the assignment will have a constrained subtype
            --  when fully compiled. Ditto if the context is an initialization
            --  procedure where a component may have a predicate function that
            --  carries the base type.

            --  Note that there is no node for Explicit_Actual_Parameter.
            --  To test for this context we therefore have to test for node
            --  N_Parameter_Association which itself appears only if there is a
            --  formal parameter. Consequently we also need to test for
            --  N_Procedure_Call_Statement or N_Function_Call.

            --  The context may be an N_Reference node, created by expansion.
            --  Legality of the others clause was established in the source,
            --  so the context is legal.

            Set_Etype (N, Aggr_Typ);  --  May be overridden later on

            if Nkind (Parent (N)) = N_Assignment_Statement
              or else Inside_Init_Proc
              or else (Is_Constrained (Typ)
                        and then Nkind (Parent (N)) in
                                   N_Parameter_Association
                                 | N_Function_Call
                                 | N_Procedure_Call_Statement
                                 | N_Generic_Association
                                 | N_Formal_Object_Declaration
                                 | N_Simple_Return_Statement
                                 | N_Object_Declaration
                                 | N_Component_Declaration
                                 | N_Parameter_Specification
                                 | N_Qualified_Expression
                                 | N_Reference
                                 | N_Aggregate
                                 | N_Extension_Aggregate
                                 | N_Component_Association
                                 | N_Case_Expression_Alternative
                                 | N_If_Expression
                                 | N_Expression_With_Actions)
            then
               Aggr_Resolved :=
                 Resolve_Array_Aggregate
                   (N,
                    Index          => First_Index (Aggr_Typ),
                    Index_Constr   => First_Index (Typ),
                    Component_Typ  => Component_Type (Typ),
                    Others_Allowed => True);
            else
               Aggr_Resolved :=
                 Resolve_Array_Aggregate
                   (N,
                    Index          => First_Index (Aggr_Typ),
                    Index_Constr   => First_Index (Aggr_Typ),
                    Component_Typ  => Component_Type (Typ),
                    Others_Allowed => False);
            end if;

            if not Aggr_Resolved then

               --  A parenthesized expression may have been intended as an
               --  aggregate, leading to a type error when analyzing the
               --  component. This can also happen for a nested component
               --  (see Analyze_Aggr_Expr).

               if Paren_Count (N) > 0 then
                  Error_Msg_N
                    ("positional aggregate cannot have one component", N);
               end if;

               Aggr_Subtyp := Any_Composite;

            else
               Aggr_Subtyp := Array_Aggr_Subtype (N, Typ);
            end if;

            Set_Etype (N, Aggr_Subtyp);
         end Array_Aggregate;

      elsif Is_Private_Type (Typ)
        and then Present (Full_View (Typ))
        and then (In_Inlined_Body or In_Instance_Body)
        and then Is_Composite_Type (Full_View (Typ))
      then
         Resolve (N, Full_View (Typ));

      else
         Error_Msg_N ("illegal context for aggregate", N);
      end if;

      --  If we can determine statically that the evaluation of the aggregate
      --  raises Constraint_Error, then replace the aggregate with an
      --  N_Raise_Constraint_Error node, but set the Etype to the right
      --  aggregate subtype. Gigi needs this.

      if Raises_Constraint_Error (N) then
         Aggr_Subtyp := Etype (N);
         Rewrite (N,
           Make_Raise_Constraint_Error (Loc, Reason => CE_Range_Check_Failed));
         Set_Raises_Constraint_Error (N);
         Set_Etype (N, Aggr_Subtyp);
         Set_Analyzed (N);
      end if;

      if Warn_On_No_Value_Assigned
        and then Others_Box
        and then not Is_Fully_Initialized_Type (Etype (N))
      then
         Error_Msg_N ("?v?aggregate not fully initialized", N);
      end if;

      Check_Function_Writable_Actuals (N);
   end Resolve_Aggregate;

   -----------------------------
   -- Resolve_Array_Aggregate --
   -----------------------------

   function Resolve_Array_Aggregate
     (N              : Node_Id;
      Index          : Node_Id;
      Index_Constr   : Node_Id;
      Component_Typ  : Entity_Id;
      Others_Allowed : Boolean) return Boolean
   is
      Loc : constant Source_Ptr := Sloc (N);

      Failure : constant Boolean := False;
      Success : constant Boolean := True;

      Index_Typ      : constant Entity_Id := Etype (Index);
      Index_Typ_Low  : constant Node_Id   := Type_Low_Bound  (Index_Typ);
      Index_Typ_High : constant Node_Id   := Type_High_Bound (Index_Typ);
      --  The type of the index corresponding to the array sub-aggregate along
      --  with its low and upper bounds.

      Index_Base      : constant Entity_Id := Base_Type (Index_Typ);
      Index_Base_Low  : constant Node_Id   := Type_Low_Bound (Index_Base);
      Index_Base_High : constant Node_Id   := Type_High_Bound (Index_Base);
      --  Ditto for the base type

      Others_Present : Boolean := False;

      Nb_Choices : Nat := 0;
      --  Contains the overall number of named choices in this sub-aggregate

      function Add (Val : Uint; To : Node_Id) return Node_Id;
      --  Creates a new expression node where Val is added to expression To.
      --  Tries to constant fold whenever possible. To must be an already
      --  analyzed expression.

      procedure Check_Bound (BH : Node_Id; AH : in out Node_Id);
      --  Checks that AH (the upper bound of an array aggregate) is less than
      --  or equal to BH (the upper bound of the index base type). If the check
      --  fails, a warning is emitted, the Raises_Constraint_Error flag of N is
      --  set, and AH is replaced with a duplicate of BH.

      procedure Check_Bounds (L, H : Node_Id; AL, AH : Node_Id);
      --  Checks that range AL .. AH is compatible with range L .. H. Emits a
      --  warning if not and sets the Raises_Constraint_Error flag in N.

      procedure Check_Length (L, H : Node_Id; Len : Uint);
      --  Checks that range L .. H contains at least Len elements. Emits a
      --  warning if not and sets the Raises_Constraint_Error flag in N.

      function Dynamic_Or_Null_Range (L, H : Node_Id) return Boolean;
      --  Returns True if range L .. H is dynamic or null

      procedure Get (Value : out Uint; From : Node_Id; OK : out Boolean);
      --  Given expression node From, this routine sets OK to False if it
      --  cannot statically evaluate From. Otherwise it stores this static
      --  value into Value.

      function Resolve_Aggr_Expr
        (Expr        : Node_Id;
         Single_Elmt : Boolean) return Boolean;
      --  Resolves aggregate expression Expr. Returns False if resolution
      --  fails. If Single_Elmt is set to False, the expression Expr may be
      --  used to initialize several array aggregate elements (this can happen
      --  for discrete choices such as "L .. H => Expr" or the OTHERS choice).
      --  In this event we do not resolve Expr unless expansion is disabled.
      --  To know why, see the DELAYED COMPONENT RESOLUTION note above.
      --
      --  NOTE: In the case of "... => <>", we pass the in the
      --  N_Component_Association node as Expr, since there is no Expression in
      --  that case, and we need a Sloc for the error message.

      procedure Resolve_Iterated_Component_Association
        (N         : Node_Id;
         Index_Typ : Entity_Id);
      --  For AI12-061

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

      function Add (Val : Uint; To : Node_Id) return Node_Id is
         Expr_Pos : Node_Id;
         Expr     : Node_Id;
         To_Pos   : Node_Id;

      begin
         if Raises_Constraint_Error (To) then
            return To;
         end if;

         --  First test if we can do constant folding

         if Compile_Time_Known_Value (To)
           or else Nkind (To) = N_Integer_Literal
         then
            Expr_Pos := Make_Integer_Literal (Loc, Expr_Value (To) + Val);
            Set_Is_Static_Expression (Expr_Pos);
            Set_Etype (Expr_Pos, Etype (To));
            Set_Analyzed (Expr_Pos, Analyzed (To));

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

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

            else
               Expr :=
                 Make_Attribute_Reference
                   (Loc,
                    Prefix         => New_Occurrence_Of (Index_Typ, Loc),
                    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, Val));

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

         else
            To_Pos :=
              Make_Attribute_Reference
                (Loc,
                 Prefix         => New_Occurrence_Of (Index_Typ, Loc),
                 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, Val));

            Expr :=
              Make_Attribute_Reference
                (Loc,
                 Prefix         => New_Occurrence_Of (Index_Typ, Loc),
                 Attribute_Name => Name_Val,
                 Expressions    => New_List (Expr_Pos));

            --  If the index type has a non standard representation, the
            --  attributes 'Val and 'Pos expand into function calls and the
            --  resulting expression is considered non-safe for reevaluation
            --  by the backend. Relocate it into a constant temporary in order
            --  to make it safe for reevaluation.

            if Has_Non_Standard_Rep (Etype (N)) then
               declare
                  Def_Id : Entity_Id;

               begin
                  Def_Id := Make_Temporary (Loc, 'R', Expr);
                  Set_Etype (Def_Id, Index_Typ);
                  Insert_Action (N,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Def_Id,
                      Object_Definition   =>
                        New_Occurrence_Of (Index_Typ, Loc),
                      Constant_Present    => True,
                      Expression          => Relocate_Node (Expr)));

                  Expr := New_Occurrence_Of (Def_Id, Loc);
               end;
            end if;
         end if;

         return Expr;
      end Add;

      -----------------
      -- Check_Bound --
      -----------------

      procedure Check_Bound (BH : Node_Id; AH : in out Node_Id) is
         Val_BH : Uint;
         Val_AH : Uint;

         OK_BH : Boolean;
         OK_AH : Boolean;

      begin
         Get (Value => Val_BH, From => BH, OK => OK_BH);
         Get (Value => Val_AH, From => AH, OK => OK_AH);

         if OK_BH and then OK_AH and then Val_BH < Val_AH then
            Set_Raises_Constraint_Error (N);
            Error_Msg_Warn := SPARK_Mode /= On;
            Error_Msg_N ("upper bound out of range<<", AH);
            Error_Msg_N ("\Constraint_Error [<<", AH);

            --  You need to set AH to BH or else in the case of enumerations
            --  indexes we will not be able to resolve the aggregate bounds.

            AH := Duplicate_Subexpr (BH);
         end if;
      end Check_Bound;

      ------------------
      -- Check_Bounds --
      ------------------

      procedure Check_Bounds (L, H : Node_Id; AL, AH : Node_Id) is
         Val_L  : Uint;
         Val_H  : Uint;
         Val_AL : Uint;
         Val_AH : Uint;

         OK_L : Boolean;
         OK_H : Boolean;

         OK_AL : Boolean;
         OK_AH  : Boolean;
         pragma Warnings (Off, OK_AL);
         pragma Warnings (Off, OK_AH);

      begin
         if Raises_Constraint_Error (N)
           or else Dynamic_Or_Null_Range (AL, AH)
         then
            return;
         end if;

         Get (Value => Val_L, From => L, OK => OK_L);
         Get (Value => Val_H, From => H, OK => OK_H);

         Get (Value => Val_AL, From => AL, OK => OK_AL);
         Get (Value => Val_AH, From => AH, OK => OK_AH);

         if OK_L and then Val_L > Val_AL then
            Set_Raises_Constraint_Error (N);
            Error_Msg_Warn := SPARK_Mode /= On;
            Error_Msg_N ("lower bound of aggregate out of range<<", N);
            Error_Msg_N ("\Constraint_Error [<<", N);
         end if;

         if OK_H and then Val_H < Val_AH then
            Set_Raises_Constraint_Error (N);
            Error_Msg_Warn := SPARK_Mode /= On;
            Error_Msg_N ("upper bound of aggregate out of range<<", N);
            Error_Msg_N ("\Constraint_Error [<<", N);
         end if;
      end Check_Bounds;

      ------------------
      -- Check_Length --
      ------------------

      procedure Check_Length (L, H : Node_Id; Len : Uint) is
         Val_L  : Uint;
         Val_H  : Uint;

         OK_L  : Boolean;
         OK_H  : Boolean;

         Range_Len : Uint;

      begin
         if Raises_Constraint_Error (N) then
            return;
         end if;

         Get (Value => Val_L, From => L, OK => OK_L);
         Get (Value => Val_H, From => H, OK => OK_H);

         if not OK_L or else not OK_H then
            return;
         end if;

         --  If null range length is zero

         if Val_L > Val_H then
            Range_Len := Uint_0;
         else
            Range_Len := Val_H - Val_L + 1;
         end if;

         if Range_Len < Len then
            Set_Raises_Constraint_Error (N);
            Error_Msg_Warn := SPARK_Mode /= On;
            Error_Msg_N ("too many elements<<", N);
            Error_Msg_N ("\Constraint_Error [<<", N);
         end if;
      end Check_Length;

      ---------------------------
      -- Dynamic_Or_Null_Range --
      ---------------------------

      function Dynamic_Or_Null_Range (L, H : Node_Id) return Boolean is
         Val_L : Uint;
         Val_H : Uint;

         OK_L  : Boolean;
         OK_H  : Boolean;

      begin
         Get (Value => Val_L, From => L, OK => OK_L);
         Get (Value => Val_H, From => H, OK => OK_H);

         return not OK_L or else not OK_H
           or else not Is_OK_Static_Expression (L)
           or else not Is_OK_Static_Expression (H)
           or else Val_L > Val_H;
      end Dynamic_Or_Null_Range;

      ---------
      -- Get --
      ---------

      procedure Get (Value : out Uint; From : Node_Id; OK : out Boolean) is
      begin
         OK := True;

         if Compile_Time_Known_Value (From) then
            Value := Expr_Value (From);

         --  If expression From is something like Some_Type'Val (10) then
         --  Value = 10.

         elsif Nkind (From) = N_Attribute_Reference
           and then Attribute_Name (From) = Name_Val
           and then Compile_Time_Known_Value (First (Expressions (From)))
         then
            Value := Expr_Value (First (Expressions (From)));
         else
            Value := Uint_0;
            OK := False;
         end if;
      end Get;

      -----------------------
      -- Resolve_Aggr_Expr --
      -----------------------

      function Resolve_Aggr_Expr
        (Expr        : Node_Id;
         Single_Elmt : Boolean) return Boolean
      is
         Nxt_Ind        : constant Node_Id := Next_Index (Index);
         Nxt_Ind_Constr : constant Node_Id := Next_Index (Index_Constr);
         --  Index is the current index corresponding to the expression

         Resolution_OK : Boolean := True;
         --  Set to False if resolution of the expression failed

      begin
         --  Defend against previous errors

         if Nkind (Expr) = N_Error
           or else Error_Posted (Expr)
         then
            return True;
         end if;

         --  If the array type against which we are resolving the aggregate
         --  has several dimensions, the expressions nested inside the
         --  aggregate must be further aggregates (or strings).

         if Present (Nxt_Ind) then
            if Nkind (Expr) /= N_Aggregate then

               --  A string literal can appear where a one-dimensional array
               --  of characters is expected. If the literal looks like an
               --  operator, it is still an operator symbol, which will be
               --  transformed into a string when analyzed.

               if Is_Character_Type (Component_Typ)
                 and then No (Next_Index (Nxt_Ind))
                 and then Nkind (Expr) in N_String_Literal | N_Operator_Symbol
               then
                  --  A string literal used in a multidimensional array
                  --  aggregate in place of the final one-dimensional
                  --  aggregate must not be enclosed in parentheses.

                  if Paren_Count (Expr) /= 0 then
                     Error_Msg_N ("no parenthesis allowed here", Expr);
                  end if;

                  Make_String_Into_Aggregate (Expr);

               else
                  Error_Msg_N ("nested array aggregate expected", Expr);

                  --  If the expression is parenthesized, this may be
                  --  a missing component association for a 1-aggregate.

                  if Paren_Count (Expr) > 0 then
                     Error_Msg_N
                       ("\if single-component aggregate is intended, "
                        & "write e.g. (1 ='> ...)", Expr);
                  end if;

                  return Failure;
               end if;
            end if;

            --  If it's "... => <>", nothing to resolve

            if Nkind (Expr) = N_Component_Association then
               pragma Assert (Box_Present (Expr));
               return Success;
            end if;

            --  Ada 2005 (AI-231): Propagate the type to the nested aggregate.
            --  Required to check the null-exclusion attribute (if present).
            --  This value may be overridden later on.

            Set_Etype (Expr, Etype (N));

            Resolution_OK := Resolve_Array_Aggregate
              (Expr, Nxt_Ind, Nxt_Ind_Constr, Component_Typ, Others_Allowed);

         else
            --  If it's "... => <>", nothing to resolve

            if Nkind (Expr) = N_Component_Association then
               pragma Assert (Box_Present (Expr));
               return Success;
            end if;

            --  Do not resolve the expressions of discrete or others choices
            --  unless the expression covers a single component, or the
            --  expander is inactive.

            --  In SPARK mode, expressions that can perform side effects will
            --  be recognized by the gnat2why back-end, and the whole
            --  subprogram will be ignored. So semantic analysis can be
            --  performed safely.

            if Single_Elmt
              or else not Expander_Active
              or else In_Spec_Expression
            then
               Analyze_And_Resolve (Expr, Component_Typ);
               Check_Expr_OK_In_Limited_Aggregate (Expr);
               Check_Non_Static_Context (Expr);
               Aggregate_Constraint_Checks (Expr, Component_Typ);
               Check_Unset_Reference (Expr);
            end if;
         end if;

         --  If an aggregate component has a type with predicates, an explicit
         --  predicate check must be applied, as for an assignment statement,
         --  because the aggregate might not be expanded into individual
         --  component assignments. If the expression covers several components
         --  the analysis and the predicate check take place later.

         if Has_Predicates (Component_Typ)
           and then Analyzed (Expr)
         then
            Apply_Predicate_Check (Expr, Component_Typ);
         end if;

         if Raises_Constraint_Error (Expr)
           and then Nkind (Parent (Expr)) /= N_Component_Association
         then
            Set_Raises_Constraint_Error (N);
         end if;

         --  If the expression has been marked as requiring a range check,
         --  then generate it here. It's a bit odd to be generating such
         --  checks in the analyzer, but harmless since Generate_Range_Check
         --  does nothing (other than making sure Do_Range_Check is set) if
         --  the expander is not active.

         if Do_Range_Check (Expr) then
            Generate_Range_Check (Expr, Component_Typ, CE_Range_Check_Failed);
         end if;

         return Resolution_OK;
      end Resolve_Aggr_Expr;

      --------------------------------------------
      -- Resolve_Iterated_Component_Association --
      --------------------------------------------

      procedure Resolve_Iterated_Component_Association
        (N         : Node_Id;
         Index_Typ : Entity_Id)
      is
         Loc : constant Source_Ptr := Sloc (N);
         Id  : constant Entity_Id  := Defining_Identifier (N);

         Id_Typ : Entity_Id := Any_Type;

         -----------------------
         -- Remove_References --
         -----------------------

         function Remove_Ref (N : Node_Id) return Traverse_Result;
         --  Remove references to the entity Id after analysis, so it can be
         --  properly reanalyzed after construct is expanded into a loop.

         function Remove_Ref (N : Node_Id) return Traverse_Result is
         begin
            if Nkind (N) = N_Identifier
               and then Present (Entity (N))
               and then Entity (N) = Id
            then
               Set_Entity (N, Empty);
               Set_Etype (N, Empty);
            end if;
            Set_Analyzed (N, False);
            return OK;
         end Remove_Ref;

         procedure Remove_References is new Traverse_Proc (Remove_Ref);

         --  Local variables

         Choice : Node_Id;
         Dummy  : Boolean;
         Ent    : Entity_Id;
         Expr   : Node_Id;

      --  Start of processing for Resolve_Iterated_Component_Association

      begin
         Error_Msg_Ada_2022_Feature ("iterated component", Loc);

         if Present (Iterator_Specification (N)) then
            Analyze (Name (Iterator_Specification (N)));

            --  We assume that the domain of iteration cannot be overloaded.

            declare
               Domain : constant Node_Id := Name (Iterator_Specification (N));
               D_Type : constant Entity_Id := Etype (Domain);
               Elt    : Entity_Id;
            begin
               if Is_Array_Type (D_Type) then
                  Id_Typ := Component_Type (D_Type);

               else
                  if Has_Aspect (D_Type, Aspect_Iterable) then
                     Elt :=
                       Get_Iterable_Type_Primitive (D_Type, Name_Element);
                     if No (Elt) then
                        Error_Msg_N
                          ("missing Element primitive for iteration", Domain);
                     else
                        Id_Typ := Etype (Elt);
                     end if;
                  else
                     Error_Msg_N ("cannot iterate over", Domain);
                  end if;
               end if;
            end;

         else
            Id_Typ := Index_Typ;
            Choice := First (Discrete_Choices (N));

            while Present (Choice) loop
               if Nkind (Choice) = N_Others_Choice then
                  Others_Present := True;

               else
                  Analyze (Choice);

                  --  Choice can be a subtype name, a range, or an expression

                  if Is_Entity_Name (Choice)
                    and then Is_Type (Entity (Choice))
                    and then
                      Base_Type (Entity (Choice)) = Base_Type (Index_Typ)
                  then
                     null;

                  else
                     Analyze_And_Resolve (Choice, Index_Typ);
                  end if;
               end if;

               Next (Choice);
            end loop;
         end if;

         --  Create a scope in which to introduce an index, which is usually
         --  visible in the expression for the component, and needed for its
         --  analysis.

         Ent := New_Internal_Entity (E_Loop, Current_Scope, Loc, 'L');
         Set_Etype  (Ent, Standard_Void_Type);
         Set_Parent (Ent, Parent (N));
         Push_Scope (Ent);

         --  Insert and decorate the index variable in the current scope.
         --  The expression has to be analyzed once the index variable is
         --  directly visible.

         Enter_Name (Id);
         Set_Etype (Id, Id_Typ);
         Mutate_Ekind (Id, E_Variable);
         Set_Scope (Id, Ent);

         --  Analyze  expression without expansion, to verify legality.
         --  When generating code, we then remove references to the index
         --  variable, because the expression will be analyzed anew after
         --  rewritting as a loop with a new index variable; when not
         --  generating code we leave the analyzed expression as it is.

         Expr := Expression (N);

         Expander_Mode_Save_And_Set (False);
         Dummy := Resolve_Aggr_Expr (Expr, Single_Elmt => False);
         Expander_Mode_Restore;

         if Operating_Mode /= Check_Semantics then
            Remove_References (Expr);
         end if;

         --  An iterated_component_association may appear in a nested
         --  aggregate for a multidimensional structure: preserve the bounds
         --  computed for the expression, as well as the anonymous array
         --  type generated for it; both are needed during array expansion.

         if Nkind (Expr) = N_Aggregate then
            Set_Aggregate_Bounds (Expression (N), Aggregate_Bounds (Expr));
            Set_Etype (Expression (N), Etype (Expr));
         end if;

         End_Scope;
      end Resolve_Iterated_Component_Association;

      --  Local variables

      Assoc   : Node_Id;
      Choice  : Node_Id;
      Expr    : Node_Id;
      Discard : Node_Id;

      Aggr_Low  : Node_Id := Empty;
      Aggr_High : Node_Id := Empty;
      --  The actual low and high bounds of this sub-aggregate

      Case_Table_Size : Nat;
      --  Contains the size of the case table needed to sort aggregate choices

      Choices_Low  : Node_Id := Empty;
      Choices_High : Node_Id := Empty;
      --  The lowest and highest discrete choices values for a named aggregate

      Delete_Choice : Boolean;
      --  Used when replacing a subtype choice with predicate by a list

      Has_Iterator_Specifications : Boolean := False;
      --  Flag to indicate that all named associations are iterated component
      --  associations with iterator specifications, in which case the
      --  expansion will create two loops: one to evaluate the size and one
      --  to generate the elements (4.3.3 (20.2/5)).

      Nb_Elements : Uint := Uint_0;
      --  The number of elements in a positional aggregate

      Nb_Discrete_Choices : Nat := 0;
      --  The overall number of discrete choices (not counting others choice)

   --  Start of processing for Resolve_Array_Aggregate

   begin
      --  Ignore junk empty aggregate resulting from parser error

      if No (Expressions (N))
        and then No (Component_Associations (N))
        and then not Null_Record_Present (N)
      then
         return False;
      end if;

      --  STEP 1: make sure the aggregate is correctly formatted

      if Present (Component_Associations (N)) then

         --  Verify that all or none of the component associations
         --  include an iterator specification.

         Assoc := First (Component_Associations (N));
         if Nkind (Assoc) = N_Iterated_Component_Association
           and then Present (Iterator_Specification (Assoc))
         then
            --  All other component associations must have an iterator spec.

            Next (Assoc);
            while Present (Assoc) loop
               if Nkind (Assoc) /= N_Iterated_Component_Association
                 or else No (Iterator_Specification (Assoc))
               then
                  Error_Msg_N ("mixed iterated component association"
                   & " (RM 4.4.3 (17.1/5))",
                      Assoc);
                  return False;
               end if;

               Next (Assoc);
            end loop;

            Has_Iterator_Specifications := True;

         else
            --  or none of them do.

            Next (Assoc);
            while Present (Assoc) loop
               if Nkind (Assoc) = N_Iterated_Component_Association
                 and then Present (Iterator_Specification (Assoc))
               then
                  Error_Msg_N ("mixed iterated component association"
                    & " (RM 4.4.3 (17.1/5))",
                      Assoc);
                  return False;
               end if;

               Next (Assoc);
            end loop;

            while Present (Assoc) loop
               Next (Assoc);
            end loop;
         end if;

         Assoc := First (Component_Associations (N));
         while Present (Assoc) loop
            if Nkind (Assoc) = N_Iterated_Component_Association then
               Resolve_Iterated_Component_Association (Assoc, Index_Typ);
            end if;

            Choice := First (Choice_List (Assoc));
            Delete_Choice := False;
            while Present (Choice) loop
               if Nkind (Choice) = N_Others_Choice then
                  Others_Present := True;

                  if Choice /= First (Choice_List (Assoc))
                    or else Present (Next (Choice))
                  then
                     Error_Msg_N
                       ("OTHERS must appear alone in a choice list", Choice);
                     return Failure;
                  end if;

                  if Present (Next (Assoc)) then
                     Error_Msg_N
                       ("OTHERS must appear last in an aggregate", Choice);
                     return Failure;
                  end if;

                  if Ada_Version = Ada_83
                    and then Assoc /= First (Component_Associations (N))
                    and then Nkind (Parent (N)) in
                               N_Assignment_Statement | N_Object_Declaration
                  then
                     Error_Msg_N
                       ("(Ada 83) illegal context for OTHERS choice", N);
                  end if;

               elsif Is_Entity_Name (Choice) then
                  Analyze (Choice);

                  declare
                     E      : constant Entity_Id := Entity (Choice);
                     New_Cs : List_Id;
                     P      : Node_Id;
                     C      : Node_Id;

                  begin
                     if Is_Type (E) and then Has_Predicates (E) then
                        Freeze_Before (N, E);

                        if Has_Dynamic_Predicate_Aspect (E) then
                           Error_Msg_NE
                             ("subtype& has dynamic predicate, not allowed "
                              & "in aggregate choice", Choice, E);

                        elsif not Is_OK_Static_Subtype (E) then
                           Error_Msg_NE
                             ("non-static subtype& has predicate, not allowed "
                              & "in aggregate choice", Choice, E);
                        end if;

                        --  If the subtype has a static predicate, replace the
                        --  original choice with the list of individual values
                        --  covered by the predicate.
                        --  This should be deferred to expansion time ???

                        if Present (Static_Discrete_Predicate (E)) then
                           Delete_Choice := True;

                           New_Cs := New_List;
                           P := First (Static_Discrete_Predicate (E));
                           while Present (P) loop
                              C := New_Copy (P);
                              Set_Sloc (C, Sloc (Choice));
                              Append_To (New_Cs, C);
                              Next (P);
                           end loop;

                           Insert_List_After (Choice, New_Cs);
                        end if;
                     end if;
                  end;
               end if;

               Nb_Choices := Nb_Choices + 1;

               declare
                  C : constant Node_Id := Choice;

               begin
                  Next (Choice);

                  if Delete_Choice then
                     Remove (C);
                     Nb_Choices := Nb_Choices - 1;
                     Delete_Choice := False;
                  end if;
               end;
            end loop;

            Next (Assoc);
         end loop;
      end if;

      --  At this point we know that the others choice, if present, is by
      --  itself and appears last in the aggregate. Check if we have mixed
      --  positional and discrete associations (other than the others choice).

      if Present (Expressions (N))
        and then (Nb_Choices > 1
                   or else (Nb_Choices = 1 and then not Others_Present))
      then
         Error_Msg_N
           ("cannot mix named and positional associations in array aggregate",
            First (Choice_List (First (Component_Associations (N)))));
         return Failure;
      end if;

      --  Test for the validity of an others choice if present

      if Others_Present and then not Others_Allowed then
         declare
            Others_N : constant Node_Id :=
              First (Choice_List (First (Component_Associations (N))));
         begin
            Error_Msg_N ("OTHERS choice not allowed here", Others_N);
            Error_Msg_N ("\qualify the aggregate with a constrained subtype "
                         & "to provide bounds for it", Others_N);
            return Failure;
         end;
      end if;

      --  Protect against cascaded errors

      if Etype (Index_Typ) = Any_Type then
         return Failure;
      end if;

      --  STEP 2: Process named components

      if No (Expressions (N)) then
         if Others_Present then
            Case_Table_Size := Nb_Choices - 1;
         else
            Case_Table_Size := Nb_Choices;
         end if;

         Step_2 : declare
            function Empty_Range (A : Node_Id) return Boolean;
            --  If an association covers an empty range, some warnings on the
            --  expression of the association can be disabled.

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

            function Empty_Range (A : Node_Id) return Boolean is
               R : constant Node_Id := First (Choices (A));
            begin
               return No (Next (R))
                 and then Nkind (R) = N_Range
                 and then Compile_Time_Compare
                            (Low_Bound (R), High_Bound (R), False) = GT;
            end Empty_Range;

            --  Local variables

            Low  : Node_Id;
            High : Node_Id;
            --  Denote the lowest and highest values in an aggregate choice

            S_Low  : Node_Id := Empty;
            S_High : Node_Id := Empty;
            --  if a choice in an aggregate is a subtype indication these
            --  denote the lowest and highest values of the subtype

            Table : Case_Table_Type (1 .. Case_Table_Size);
            --  Used to sort all the different choice values

            Single_Choice : Boolean;
            --  Set to true every time there is a single discrete choice in a
            --  discrete association

            Prev_Nb_Discrete_Choices : Nat;
            --  Used to keep track of the number of discrete choices in the
            --  current association.

            Errors_Posted_On_Choices : Boolean := False;
            --  Keeps track of whether any choices have semantic errors

         --  Start of processing for Step_2

         begin
            --  STEP 2 (A): Check discrete choices validity
            --  No need if this is an element iteration.

            Assoc := First (Component_Associations (N));
            while Present (Assoc)
              and then Present (Choice_List (Assoc))
            loop
               Prev_Nb_Discrete_Choices := Nb_Discrete_Choices;
               Choice := First (Choice_List (Assoc));

               loop
                  Analyze (Choice);

                  if Nkind (Choice) = N_Others_Choice then
                     Single_Choice := False;
                     exit;

                  --  Test for subtype mark without constraint

                  elsif Is_Entity_Name (Choice) and then
                    Is_Type (Entity (Choice))
                  then
                     if Base_Type (Entity (Choice)) /= Index_Base then
                        Error_Msg_N
                          ("invalid subtype mark in aggregate choice",
                           Choice);
                        return Failure;
                     end if;

                  --  Case of subtype indication

                  elsif Nkind (Choice) = N_Subtype_Indication then
                     Resolve_Discrete_Subtype_Indication (Choice, Index_Base);

                     if Has_Dynamic_Predicate_Aspect
                       (Entity (Subtype_Mark (Choice)))
                     then
                        Error_Msg_NE
                          ("subtype& has dynamic predicate, "
                           & "not allowed in aggregate choice",
                           Choice, Entity (Subtype_Mark (Choice)));
                     end if;

                     --  Does the subtype indication evaluation raise CE?

                     Get_Index_Bounds (Subtype_Mark (Choice), S_Low, S_High);
                     Get_Index_Bounds (Choice, Low, High);
                     Check_Bounds (S_Low, S_High, Low, High);

                  --  Case of range or expression

                  else
                     Resolve (Choice, Index_Base);
                     Check_Unset_Reference (Choice);
                     Check_Non_Static_Context (Choice);

                     --  If semantic errors were posted on the choice, then
                     --  record that for possible early return from later
                     --  processing (see handling of enumeration choices).

                     if Error_Posted (Choice) then
                        Errors_Posted_On_Choices := True;
                     end if;

                     --  Do not range check a choice. This check is redundant
                     --  since this test is already done when we check that the
                     --  bounds of the array aggregate are within range.

                     Set_Do_Range_Check (Choice, False);
                  end if;

                  --  If we could not resolve the discrete choice stop here

                  if Etype (Choice) = Any_Type then
                     return Failure;

                  --  If the discrete choice raises CE get its original bounds

                  elsif Nkind (Choice) = N_Raise_Constraint_Error then
                     Set_Raises_Constraint_Error (N);
                     Get_Index_Bounds (Original_Node (Choice), Low, High);

                  --  Otherwise get its bounds as usual

                  else
                     Get_Index_Bounds (Choice, Low, High);
                  end if;

                  if (Dynamic_Or_Null_Range (Low, High)
                       or else (Nkind (Choice) = N_Subtype_Indication
                                 and then
                                   Dynamic_Or_Null_Range (S_Low, S_High)))
                    and then Nb_Choices /= 1
                  then
                     Error_Msg_N
                       ("dynamic or empty choice in aggregate "
                        & "must be the only choice", Choice);
                     return Failure;
                  end if;

                  if not (All_Composite_Constraints_Static (Low)
                            and then All_Composite_Constraints_Static (High)
                            and then All_Composite_Constraints_Static (S_Low)
                            and then All_Composite_Constraints_Static (S_High))
                  then
                     Check_Restriction (No_Dynamic_Sized_Objects, Choice);
                  end if;

                  Nb_Discrete_Choices := Nb_Discrete_Choices + 1;
                  Table (Nb_Discrete_Choices).Lo := Low;
                  Table (Nb_Discrete_Choices).Hi := High;
                  Table (Nb_Discrete_Choices).Choice := Choice;

                  Next (Choice);

                  if No (Choice) then

                     --  Check if we have a single discrete choice and whether
                     --  this discrete choice specifies a single value.

                     Single_Choice :=
                       (Nb_Discrete_Choices = Prev_Nb_Discrete_Choices + 1)
                         and then (Low = High);

                     exit;
                  end if;
               end loop;

               --  Ada 2005 (AI-231)

               if Ada_Version >= Ada_2005
                 and then Known_Null (Expression (Assoc))
                 and then not Empty_Range (Assoc)
               then
                  Check_Can_Never_Be_Null (Etype (N), Expression (Assoc));
               end if;

               --  Ada 2005 (AI-287): In case of default initialized component
               --  we delay the resolution to the expansion phase.

               if Box_Present (Assoc) then

                  --  Ada 2005 (AI-287): In case of default initialization of a
                  --  component the expander will generate calls to the
                  --  corresponding initialization subprogram. We need to call
                  --  Resolve_Aggr_Expr to check the rules about
                  --  dimensionality.

                  if not Resolve_Aggr_Expr
                           (Assoc, Single_Elmt => Single_Choice)
                  then
                     return Failure;
                  end if;

               --  ??? Checks for dynamically tagged expressions below will
               --  be only applied to iterated_component_association after
               --  expansion; in particular, errors might not be reported when
               --  -gnatc switch is used.

               elsif Nkind (Assoc) = N_Iterated_Component_Association then
                  null;   --  handled above, in a loop context

               elsif not Resolve_Aggr_Expr
                           (Expression (Assoc), Single_Elmt => Single_Choice)
               then
                  return Failure;

               --  Check incorrect use of dynamically tagged expression

               --  We differentiate here two cases because the expression may
               --  not be decorated. For example, the analysis and resolution
               --  of the expression associated with the others choice will be
               --  done later with the full aggregate. In such case we
               --  duplicate the expression tree to analyze the copy and
               --  perform the required check.

               elsif not Present (Etype (Expression (Assoc))) then
                  declare
                     Save_Analysis : constant Boolean := Full_Analysis;
                     Expr          : constant Node_Id :=
                                       New_Copy_Tree (Expression (Assoc));

                  begin
                     Expander_Mode_Save_And_Set (False);
                     Full_Analysis := False;

                     --  Analyze the expression, making sure it is properly
                     --  attached to the tree before we do the analysis.

                     Set_Parent (Expr, Parent (Expression (Assoc)));
                     Analyze (Expr);

                     --  Compute its dimensions now, rather than at the end of
                     --  resolution, because in the case of multidimensional
                     --  aggregates subsequent expansion may lead to spurious
                     --  errors.

                     Check_Expression_Dimensions (Expr, Component_Typ);

                     --  If the expression is a literal, propagate this info
                     --  to the expression in the association, to enable some
                     --  optimizations downstream.

                     if Is_Entity_Name (Expr)
                       and then Present (Entity (Expr))
                       and then Ekind (Entity (Expr)) = E_Enumeration_Literal
                     then
                        Analyze_And_Resolve
                          (Expression (Assoc), Component_Typ);
                     end if;

                     Full_Analysis := Save_Analysis;
                     Expander_Mode_Restore;

                     if Is_Tagged_Type (Etype (Expr)) then
                        Check_Dynamically_Tagged_Expression
                          (Expr => Expr,
                           Typ  => Component_Type (Etype (N)),
                           Related_Nod => N);
                     end if;
                  end;

               elsif Is_Tagged_Type (Etype (Expression (Assoc))) then
                  Check_Dynamically_Tagged_Expression
                    (Expr        => Expression (Assoc),
                     Typ         => Component_Type (Etype (N)),
                     Related_Nod => N);
               end if;

               Next (Assoc);
            end loop;

            --  If aggregate contains more than one choice then these must be
            --  static. Check for duplicate and missing values.

            --  Note: there is duplicated code here wrt Check_Choice_Set in
            --  the body of Sem_Case, and it is possible we could just reuse
            --  that procedure. To be checked ???

            if Nb_Discrete_Choices > 1 then
               Check_Choices : declare
                  Choice : Node_Id;
                  --  Location of choice for messages

                  Hi_Val : Uint;
                  Lo_Val : Uint;
                  --  High end of one range and Low end of the next. Should be
                  --  contiguous if there is no hole in the list of values.

                  Lo_Dup : Uint;
                  Hi_Dup : Uint;
                  --  End points of duplicated range

                  Missing_Or_Duplicates : Boolean := False;
                  --  Set True if missing or duplicate choices found

                  procedure Output_Bad_Choices (Lo, Hi : Uint; C : Node_Id);
                  --  Output continuation message with a representation of the
                  --  bounds (just Lo if Lo = Hi, else Lo .. Hi). C is the
                  --  choice node where the message is to be posted.

                  ------------------------
                  -- Output_Bad_Choices --
                  ------------------------

                  procedure Output_Bad_Choices (Lo, Hi : Uint; C : Node_Id) is
                  begin
                     --  Enumeration type case

                     if Is_Enumeration_Type (Index_Typ) then
                        Error_Msg_Name_1 :=
                          Chars (Get_Enum_Lit_From_Pos (Index_Typ, Lo, Loc));
                        Error_Msg_Name_2 :=
                          Chars (Get_Enum_Lit_From_Pos (Index_Typ, Hi, Loc));

                        if Lo = Hi then
                           Error_Msg_N ("\\  %!", C);
                        else
                           Error_Msg_N ("\\  % .. %!", C);
                        end if;

                        --  Integer types case

                     else
                        Error_Msg_Uint_1 := Lo;
                        Error_Msg_Uint_2 := Hi;

                        if Lo = Hi then
                           Error_Msg_N ("\\  ^!", C);
                        else
                           Error_Msg_N ("\\  ^ .. ^!", C);
                        end if;
                     end if;
                  end Output_Bad_Choices;

               --  Start of processing for Check_Choices

               begin
                  Sort_Case_Table (Table);

                  --  First we do a quick linear loop to find out if we have
                  --  any duplicates or missing entries (usually we have a
                  --  legal aggregate, so this will get us out quickly).

                  for J in 1 .. Nb_Discrete_Choices - 1 loop
                     Hi_Val := Expr_Value (Table (J).Hi);
                     Lo_Val := Expr_Value (Table (J + 1).Lo);

                     if Lo_Val <= Hi_Val
                       or else (Lo_Val > Hi_Val + 1
                                 and then not Others_Present)
                     then
                        Missing_Or_Duplicates := True;
                        exit;
                     end if;
                  end loop;

                  --  If we have missing or duplicate entries, first fill in
                  --  the Highest entries to make life easier in the following
                  --  loops to detect bad entries.

                  if Missing_Or_Duplicates then
                     Table (1).Highest := Expr_Value (Table (1).Hi);

                     for J in 2 .. Nb_Discrete_Choices loop
                        Table (J).Highest :=
                          UI_Max
                            (Table (J - 1).Highest, Expr_Value (Table (J).Hi));
                     end loop;

                     --  Loop through table entries to find duplicate indexes

                     for J in 2 .. Nb_Discrete_Choices loop
                        Lo_Val := Expr_Value (Table (J).Lo);
                        Hi_Val := Expr_Value (Table (J).Hi);

                        --  Case where we have duplicates (the lower bound of
                        --  this choice is less than or equal to the highest
                        --  high bound found so far).

                        if Lo_Val <= Table (J - 1).Highest then

                           --  We move backwards looking for duplicates. We can
                           --  abandon this loop as soon as we reach a choice
                           --  highest value that is less than Lo_Val.

                           for K in reverse 1 .. J - 1 loop
                              exit when Table (K).Highest < Lo_Val;

                              --  Here we may have duplicates between entries
                              --  for K and J. Get range of duplicates.

                              Lo_Dup :=
                                UI_Max (Lo_Val, Expr_Value (Table (K).Lo));
                              Hi_Dup :=
                                UI_Min (Hi_Val, Expr_Value (Table (K).Hi));

                              --  Nothing to do if duplicate range is null

                              if Lo_Dup > Hi_Dup then
                                 null;

                              --  Otherwise place proper message

                              else
                                 --  We place message on later choice, with a
                                 --  line reference to the earlier choice.

                                 if Sloc (Table (J).Choice) <
                                   Sloc (Table (K).Choice)
                                 then
                                    Choice := Table (K).Choice;
                                    Error_Msg_Sloc := Sloc (Table (J).Choice);
                                 else
                                    Choice := Table (J).Choice;
                                    Error_Msg_Sloc := Sloc (Table (K).Choice);
                                 end if;

                                 if Lo_Dup = Hi_Dup then
                                    Error_Msg_N
                                      ("index value in array aggregate "
                                       & "duplicates the one given#!", Choice);
                                 else
                                    Error_Msg_N
                                      ("index values in array aggregate "
                                       & "duplicate those given#!", Choice);
                                 end if;

                                 Output_Bad_Choices (Lo_Dup, Hi_Dup, Choice);
                              end if;
                           end loop;
                        end if;
                     end loop;

                     --  Loop through entries in table to find missing indexes.
                     --  Not needed if others, since missing impossible.

                     if not Others_Present then
                        for J in 2 .. Nb_Discrete_Choices loop
                           Lo_Val := Expr_Value (Table (J).Lo);
                           Hi_Val := Table (J - 1).Highest;

                           if Lo_Val > Hi_Val + 1 then

                              declare
                                 Error_Node : Node_Id;

                              begin
                                 --  If the choice is the bound of a range in
                                 --  a subtype indication, it is not in the
                                 --  source lists for the aggregate itself, so
                                 --  post the error on the aggregate. Otherwise
                                 --  post it on choice itself.

                                 Choice := Table (J).Choice;

                                 if Is_List_Member (Choice) then
                                    Error_Node := Choice;
                                 else
                                    Error_Node := N;
                                 end if;

                                 if Hi_Val + 1 = Lo_Val - 1 then
                                    Error_Msg_N
                                      ("missing index value "
                                       & "in array aggregate!", Error_Node);
                                 else
                                    Error_Msg_N
                                      ("missing index values "
                                       & "in array aggregate!", Error_Node);
                                 end if;

                                 Output_Bad_Choices
                                   (Hi_Val + 1, Lo_Val - 1, Error_Node);
                              end;
                           end if;
                        end loop;
                     end if;

                     --  If either missing or duplicate values, return failure

                     Set_Etype (N, Any_Composite);
                     return Failure;
                  end if;
               end Check_Choices;
            end if;

            if Has_Iterator_Specifications then
               --  Bounds will be determined dynamically.

               return Success;
            end if;

            --  STEP 2 (B): Compute aggregate bounds and min/max choices values

            if Nb_Discrete_Choices > 0 then
               Choices_Low  := Table (1).Lo;
               Choices_High := Table (Nb_Discrete_Choices).Hi;
            end if;

            --  If Others is present, then bounds of aggregate come from the
            --  index constraint (not the choices in the aggregate itself).

            if Others_Present then
               Get_Index_Bounds (Index_Constr, Aggr_Low, Aggr_High);

               --  Abandon processing if either bound is already signalled as
               --  an error (prevents junk cascaded messages and blow ups).

               if Nkind (Aggr_Low) = N_Error
                    or else
                  Nkind (Aggr_High) = N_Error
               then
                  return False;
               end if;

            --  No others clause present

            else
               --  Special processing if others allowed and not present. This
               --  means that the bounds of the aggregate come from the index
               --  constraint (and the length must match).

               if Others_Allowed then
                  Get_Index_Bounds (Index_Constr, Aggr_Low, Aggr_High);

                  --  Abandon processing if either bound is already signalled
                  --  as an error (stop junk cascaded messages and blow ups).

                  if Nkind (Aggr_Low) = N_Error
                       or else
                     Nkind (Aggr_High) = N_Error
                  then
                     return False;
                  end if;

                  --  If others allowed, and no others present, then the array
                  --  should cover all index values. If it does not, we will
                  --  get a length check warning, but there is two cases where
                  --  an additional warning is useful:

                  --  If we have no positional components, and the length is
                  --  wrong (which we can tell by others being allowed with
                  --  missing components), and the index type is an enumeration
                  --  type, then issue appropriate warnings about these missing
                  --  components. They are only warnings, since the aggregate
                  --  is fine, it's just the wrong length. We skip this check
                  --  for standard character types (since there are no literals
                  --  and it is too much trouble to concoct them), and also if
                  --  any of the bounds have values that are not known at
                  --  compile time.

                  --  Another case warranting a warning is when the length
                  --  is right, but as above we have an index type that is
                  --  an enumeration, and the bounds do not match. This is a
                  --  case where dubious sliding is allowed and we generate a
                  --  warning that the bounds do not match.

                  if No (Expressions (N))
                    and then Nkind (Index) = N_Range
                    and then Is_Enumeration_Type (Etype (Index))
                    and then not Is_Standard_Character_Type (Etype (Index))
                    and then Compile_Time_Known_Value (Aggr_Low)
                    and then Compile_Time_Known_Value (Aggr_High)
                    and then Compile_Time_Known_Value (Choices_Low)
                    and then Compile_Time_Known_Value (Choices_High)
                  then
                     --  If any of the expressions or range bounds in choices
                     --  have semantic errors, then do not attempt further
                     --  resolution, to prevent cascaded errors.

                     if Errors_Posted_On_Choices then
                        return Failure;
                     end if;

                     declare
                        ALo : constant Node_Id := Expr_Value_E (Aggr_Low);
                        AHi : constant Node_Id := Expr_Value_E (Aggr_High);
                        CLo : constant Node_Id := Expr_Value_E (Choices_Low);
                        CHi : constant Node_Id := Expr_Value_E (Choices_High);

                        Ent : Entity_Id;

                     begin
                        --  Warning case 1, missing values at start/end. Only
                        --  do the check if the number of entries is too small.

                        if (Enumeration_Pos (CHi) - Enumeration_Pos (CLo))
                              <
                           (Enumeration_Pos (AHi) - Enumeration_Pos (ALo))
                        then
                           Error_Msg_N
                             ("missing index value(s) in array aggregate??",
                              N);

                           --  Output missing value(s) at start

                           if Chars (ALo) /= Chars (CLo) then
                              Ent := Prev (CLo);

                              if Chars (ALo) = Chars (Ent) then
                                 Error_Msg_Name_1 := Chars (ALo);
                                 Error_Msg_N ("\  %??", N);
                              else
                                 Error_Msg_Name_1 := Chars (ALo);
                                 Error_Msg_Name_2 := Chars (Ent);
                                 Error_Msg_N ("\  % .. %??", N);
                              end if;
                           end if;

                           --  Output missing value(s) at end

                           if Chars (AHi) /= Chars (CHi) then
                              Ent := Next (CHi);

                              if Chars (AHi) = Chars (Ent) then
                                 Error_Msg_Name_1 := Chars (Ent);
                                 Error_Msg_N ("\  %??", N);
                              else
                                 Error_Msg_Name_1 := Chars (Ent);
                                 Error_Msg_Name_2 := Chars (AHi);
                                 Error_Msg_N ("\  % .. %??", N);
                              end if;
                           end if;

                        --  Warning case 2, dubious sliding. The First_Subtype
                        --  test distinguishes between a constrained type where
                        --  sliding is not allowed (so we will get a warning
                        --  later that Constraint_Error will be raised), and
                        --  the unconstrained case where sliding is permitted.

                        elsif (Enumeration_Pos (CHi) - Enumeration_Pos (CLo))
                                 =
                              (Enumeration_Pos (AHi) - Enumeration_Pos (ALo))
                          and then Chars (ALo) /= Chars (CLo)
                          and then
                            not Is_Constrained (First_Subtype (Etype (N)))
                        then
                           Error_Msg_N
                             ("bounds of aggregate do not match target??", N);
                        end if;
                     end;
                  end if;
               end if;

               --  If no others, aggregate bounds come from aggregate

               Aggr_Low  := Choices_Low;
               Aggr_High := Choices_High;
            end if;
         end Step_2;

      --  STEP 3: Process positional components

      else
         --  STEP 3 (A): Process positional elements

         Expr := First (Expressions (N));
         Nb_Elements := Uint_0;
         while Present (Expr) loop
            Nb_Elements := Nb_Elements + 1;

            --  Ada 2005 (AI-231)

            if Ada_Version >= Ada_2005 and then Known_Null (Expr) then
               Check_Can_Never_Be_Null (Etype (N), Expr);
            end if;

            if not Resolve_Aggr_Expr (Expr, Single_Elmt => True) then
               return Failure;
            end if;

            --  Check incorrect use of dynamically tagged expression

            if Is_Tagged_Type (Etype (Expr)) then
               Check_Dynamically_Tagged_Expression
                 (Expr => Expr,
                  Typ  => Component_Type (Etype (N)),
                  Related_Nod => N);
            end if;

            Next (Expr);
         end loop;

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

            --  Ada 2005 (AI-231)

            if Ada_Version >= Ada_2005 and then Known_Null (Assoc) then
               Check_Can_Never_Be_Null (Etype (N), Expression (Assoc));
            end if;

            --  Ada 2005 (AI-287): In case of default initialized component,
            --  we delay the resolution to the expansion phase.

            if Box_Present (Assoc) then

               --  Ada 2005 (AI-287): In case of default initialization of a
               --  component the expander will generate calls to the
               --  corresponding initialization subprogram. We need to call
               --  Resolve_Aggr_Expr to check the rules about
               --  dimensionality.

               if not Resolve_Aggr_Expr (Assoc, Single_Elmt => False) then
                  return Failure;
               end if;

            elsif not Resolve_Aggr_Expr (Expression (Assoc),
                                         Single_Elmt => False)
            then
               return Failure;

            --  Check incorrect use of dynamically tagged expression. The
            --  expression of the others choice has not been resolved yet.
            --  In order to diagnose the semantic error we create a duplicate
            --  tree to analyze it and perform the check.

            elsif Nkind (Assoc) /= N_Iterated_Component_Association then
               declare
                  Save_Analysis : constant Boolean := Full_Analysis;
                  Expr          : constant Node_Id :=
                                    New_Copy_Tree (Expression (Assoc));

               begin
                  Expander_Mode_Save_And_Set (False);
                  Full_Analysis := False;
                  Analyze (Expr);
                  Full_Analysis := Save_Analysis;
                  Expander_Mode_Restore;

                  if Is_Tagged_Type (Etype (Expr)) then
                     Check_Dynamically_Tagged_Expression
                       (Expr        => Expr,
                        Typ         => Component_Type (Etype (N)),
                        Related_Nod => N);
                  end if;
               end;
            end if;
         end if;

         --  STEP 3 (B): Compute the aggregate bounds

         if Others_Present then
            Get_Index_Bounds (Index_Constr, Aggr_Low, Aggr_High);

         else
            if Others_Allowed then
               Get_Index_Bounds (Index_Constr, Aggr_Low, Discard);
            else
               Aggr_Low := Index_Typ_Low;
            end if;

            Aggr_High := Add (Nb_Elements - 1, To => Aggr_Low);
            Check_Bound (Index_Base_High, Aggr_High);
         end if;
      end if;

      --  STEP 4: Perform static aggregate checks and save the bounds

      --  Check (A)

      Check_Bounds (Index_Typ_Low, Index_Typ_High, Aggr_Low, Aggr_High);
      Check_Bounds (Index_Base_Low, Index_Base_High, Aggr_Low, Aggr_High);

      --  Check (B)

      if Others_Present and then Nb_Discrete_Choices > 0 then
         Check_Bounds (Aggr_Low, Aggr_High, Choices_Low, Choices_High);
         Check_Bounds (Index_Typ_Low, Index_Typ_High,
                       Choices_Low, Choices_High);
         Check_Bounds (Index_Base_Low, Index_Base_High,
                       Choices_Low, Choices_High);

      --  Check (C)

      elsif Others_Present and then Nb_Elements > 0 then
         Check_Length (Aggr_Low, Aggr_High, Nb_Elements);
         Check_Length (Index_Typ_Low, Index_Typ_High, Nb_Elements);
         Check_Length (Index_Base_Low, Index_Base_High, Nb_Elements);
      end if;

      if Raises_Constraint_Error (Aggr_Low)
        or else Raises_Constraint_Error (Aggr_High)
      then
         Set_Raises_Constraint_Error (N);
      end if;

      Aggr_Low := Duplicate_Subexpr (Aggr_Low);

      --  Do not duplicate Aggr_High if Aggr_High = Aggr_Low + Nb_Elements
      --  since the addition node returned by Add is not yet analyzed. Attach
      --  to tree and analyze first. Reset analyzed flag to ensure it will get
      --  analyzed when it is a literal bound whose type must be properly set.

      if Others_Present or else Nb_Discrete_Choices > 0 then
         Aggr_High := Duplicate_Subexpr (Aggr_High);

         if Etype (Aggr_High) = Universal_Integer then
            Set_Analyzed (Aggr_High, False);
         end if;
      end if;

      --  If the aggregate already has bounds attached to it, it means this is
      --  a positional aggregate created as an optimization by
      --  Exp_Aggr.Convert_To_Positional, so we don't want to change those
      --  bounds.

      if Present (Aggregate_Bounds (N))
        and then not Others_Allowed
        and then not Comes_From_Source (N)
      then
         Aggr_Low  := Low_Bound  (Aggregate_Bounds (N));
         Aggr_High := High_Bound (Aggregate_Bounds (N));
      end if;

      Set_Aggregate_Bounds
        (N, Make_Range (Loc, Low_Bound => Aggr_Low, High_Bound => Aggr_High));

      --  The bounds may contain expressions that must be inserted upwards.
      --  Attach them fully to the tree. After analysis, remove side effects
      --  from upper bound, if still needed.

      Set_Parent (Aggregate_Bounds (N), N);
      Analyze_And_Resolve (Aggregate_Bounds (N), Index_Typ);
      Check_Unset_Reference (Aggregate_Bounds (N));

      if not Others_Present and then Nb_Discrete_Choices = 0 then
         Set_High_Bound
           (Aggregate_Bounds (N),
            Duplicate_Subexpr (High_Bound (Aggregate_Bounds (N))));
      end if;

      --  Check the dimensions of each component in the array aggregate

      Analyze_Dimension_Array_Aggregate (N, Component_Typ);

      return Success;
   end Resolve_Array_Aggregate;

   ---------------------------------
   -- Resolve_Container_Aggregate --
   ---------------------------------

   procedure Resolve_Container_Aggregate (N : Node_Id; Typ : Entity_Id) is
      procedure Resolve_Iterated_Association
       (Comp      : Node_Id;
        Key_Type  : Entity_Id;
        Elmt_Type : Entity_Id);
      --  Resolve choices and expression in an iterated component association
      --  or an iterated element association, which has a key_expression.
      --  This is similar but not identical to the handling of this construct
      --  in an array aggregate.
      --  For a named container, the type of each choice must be compatible
      --  with the key type. For a positional container, the choice must be
      --  a subtype indication or an iterator specification that determines
      --  an element type.

      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;

      ----------------------------------
      -- Resolve_Iterated_Association --
      ----------------------------------

      procedure Resolve_Iterated_Association
       (Comp      : Node_Id;
        Key_Type  : Entity_Id;
        Elmt_Type : Entity_Id)
      is
         Loc      : constant Source_Ptr := Sloc (N);
         Choice   : Node_Id;
         Ent      : Entity_Id;
         Expr     : Node_Id;
         Key_Expr : Node_Id;
         Id       : Entity_Id;
         Id_Name  : Name_Id;
         Iter     : Node_Id;
         Typ      : Entity_Id := Empty;

      begin
         Error_Msg_Ada_2022_Feature ("iterated component", Loc);

         --  If this is an Iterated_Element_Association then either a
         --  an Iterator_Specification or a Loop_Parameter specification
         --  is present. In both cases a Key_Expression is present.

         if Nkind (Comp) = N_Iterated_Element_Association then
            if Present (Loop_Parameter_Specification (Comp)) then
               Analyze_Loop_Parameter_Specification
                  (Loop_Parameter_Specification (Comp));
               Id_Name := Chars (Defining_Identifier
                            (Loop_Parameter_Specification (Comp)));
            else
               Iter := Copy_Separate_Tree (Iterator_Specification (Comp));
               Analyze (Iter);
               Typ := Etype (Defining_Identifier (Iter));
               Id_Name := Chars (Defining_Identifier
                            (Iterator_Specification (Comp)));
            end if;

            --  Key expression must have the type of the key. We analyze
            --  a copy of the original expression, because it will be
            --  reanalyzed and copied as needed during expansion of the
            --  corresponding loop.

            Key_Expr := Key_Expression (Comp);
            Analyze_And_Resolve (New_Copy_Tree (Key_Expr), Key_Type);

         elsif Present (Iterator_Specification (Comp)) then
            Iter    := Copy_Separate_Tree (Iterator_Specification (Comp));
            Id_Name := Chars (Defining_Identifier (Comp));
            Analyze (Iter);
            Typ := Etype (Defining_Identifier (Iter));

         else
            Choice := First (Discrete_Choices (Comp));

            while Present (Choice) loop
               Analyze (Choice);

               --  Choice can be a subtype name, a range, or an expression

               if Is_Entity_Name (Choice)
                 and then Is_Type (Entity (Choice))
                 and then Base_Type (Entity (Choice)) = Base_Type (Key_Type)
               then
                  null;

               elsif Present (Key_Type) then
                  Analyze_And_Resolve (Choice, Key_Type);

               else
                  Typ := Etype (Choice);  --  assume unique for now
               end if;

               Next (Choice);
            end loop;

            Id_Name := Chars (Defining_Identifier (Comp));
         end if;

         --  Create a scope in which to introduce an index, which is usually
         --  visible in the expression for the component, and needed for its
         --  analysis.

         Id := Make_Defining_Identifier (Sloc (Comp), Id_Name);
         Ent := New_Internal_Entity (E_Loop, Current_Scope, Sloc (Comp), 'L');
         Set_Etype  (Ent, Standard_Void_Type);
         Set_Parent (Ent, Parent (Comp));
         Push_Scope (Ent);

         --  Insert and decorate the loop variable in the current scope.
         --  The expression has to be analyzed once the loop variable is
         --  directly visible. Mark the variable as referenced to prevent
         --  spurious warnings, given that subsequent uses of its name in the
         --  expression will reference the internal (synonym) loop variable.

         Enter_Name (Id);

         if No (Key_Type) then
            pragma Assert (Present (Typ));
            Set_Etype (Id, Typ);
         else
            Set_Etype (Id, Key_Type);
         end if;

         Mutate_Ekind (Id, E_Variable);
         Set_Scope (Id, Ent);
         Set_Referenced (Id);

         --  Analyze a copy of the expression, to verify legality. We use
         --  a copy because the expression will be analyzed anew when the
         --  enclosing aggregate is expanded, and the construct is rewritten
         --  as a loop with a new index variable.

         Expr := New_Copy_Tree (Expression (Comp));
         Preanalyze_And_Resolve (Expr, Elmt_Type);
         End_Scope;

      end Resolve_Iterated_Association;

   begin
      pragma Assert (Nkind (Asp) = N_Aggregate);

      Set_Etype (N, Typ);
      Parse_Aspect_Aggregate (Asp,
        Empty_Subp, Add_Named_Subp, Add_Unnamed_Subp,
        New_Indexed_Subp, Assign_Indexed_Subp);

      if Present (Add_Unnamed_Subp)
        and then No (New_Indexed_Subp)
      then
         declare
            Elmt_Type : constant Entity_Id :=
              Etype (Next_Formal
                (First_Formal (Entity (Add_Unnamed_Subp))));
            Comp : Node_Id;

         begin
            if Present (Expressions (N)) then
               --  positional aggregate

               Comp := First (Expressions (N));
               while Present (Comp) loop
                  Analyze_And_Resolve (Comp, Elmt_Type);
                  Next (Comp);
               end loop;
            end if;

            --  Empty aggregate, to be replaced by Empty during
            --  expansion, or iterated component association.

            if Present (Component_Associations (N)) then
               declare
                  Comp : Node_Id := First (Component_Associations (N));
               begin
                  while Present (Comp) loop
                     if Nkind (Comp) /=
                       N_Iterated_Component_Association
                     then
                        Error_Msg_N ("illegal component association "
                          & "for unnamed container aggregate", Comp);
                        return;
                     else
                        Resolve_Iterated_Association
                          (Comp, Empty, Elmt_Type);
                     end if;

                     Next (Comp);
                  end loop;
               end;
            end if;
         end;

      elsif  Present (Add_Named_Subp) then
         declare
            --  Retrieves types of container, key, and element from the
            --  specified insertion procedure.

            Container : constant Entity_Id :=
              First_Formal (Entity (Add_Named_Subp));
            Key_Type  : constant Entity_Id := Etype (Next_Formal (Container));
            Elmt_Type : constant Entity_Id :=
                                 Etype (Next_Formal (Next_Formal (Container)));
            Comp   : Node_Id;
            Choice : Node_Id;

         begin
            Comp := First (Component_Associations (N));
            while Present (Comp) loop
               if Nkind (Comp) = N_Component_Association then
                  Choice := First (Choices (Comp));

                  while Present (Choice) loop
                     Analyze_And_Resolve (Choice, Key_Type);
                     if not Is_Static_Expression (Choice) then
                        Error_Msg_N ("choice must be static", Choice);
                     end if;

                     Next (Choice);
                  end loop;

                  Analyze_And_Resolve (Expression (Comp), Elmt_Type);

               elsif Nkind (Comp) in
                 N_Iterated_Component_Association |
                 N_Iterated_Element_Association
               then
                  Resolve_Iterated_Association
                    (Comp, Key_Type, Elmt_Type);
               end if;

               Next (Comp);
            end loop;
         end;

      else
         --  Indexed Aggregate. Positional or indexed component
         --  can be present, but not both. Choices must be static
         --  values or ranges with static bounds.

         declare
            Container : constant Entity_Id :=
              First_Formal (Entity (Assign_Indexed_Subp));
            Index_Type : constant Entity_Id := Etype (Next_Formal (Container));
            Comp_Type  : constant Entity_Id :=
                                 Etype (Next_Formal (Next_Formal (Container)));
            Comp        : Node_Id;
            Choice      : Node_Id;
            Num_Choices : Nat := 0;

            Hi_Val : Uint;
            Lo_Val : Uint;
         begin
            if Present (Expressions (N)) then
               Comp := First (Expressions (N));
               while Present (Comp) loop
                  Analyze_And_Resolve (Comp, Comp_Type);
                  Next (Comp);
               end loop;
            end if;

            if Present (Component_Associations (N)) then
               if Present (Expressions (N)) then
                  Error_Msg_N ("container aggregate cannot be "
                    & "both positional and named", N);
                  return;
               end if;

               Comp := First (Component_Associations (N));

               while Present (Comp) loop
                  if Nkind (Comp) = N_Component_Association then
                     Choice := First (Choices (Comp));

                     while Present (Choice) loop
                        Analyze_And_Resolve (Choice, Index_Type);
                        Num_Choices := Num_Choices + 1;
                        Next (Choice);
                     end loop;

                     Analyze_And_Resolve (Expression (Comp), Comp_Type);

                  elsif Nkind (Comp) in
                    N_Iterated_Component_Association |
                    N_Iterated_Element_Association
                  then
                     Resolve_Iterated_Association
                       (Comp, Index_Type, Comp_Type);
                     Num_Choices := Num_Choices + 1;
                  end if;

                  Next (Comp);
               end loop;

               --  The component associations in an indexed aggregate
               --  must denote a contiguous set of static values. We
               --  build a table of values/ranges and sort it, as is done
               --  elsewhere for case statements and array aggregates.
               --  If the aggregate has a single iterated association it
               --  is allowed to be nonstatic and there is nothing to check.

               if Num_Choices > 1 then
                  declare
                     Table     : Case_Table_Type (1 .. Num_Choices);
                     No_Choice : Pos := 1;
                     Lo, Hi    : Node_Id;

                  --  Traverse aggregate to determine size of needed table.
                  --  Verify that bounds are static and that loops have no
                  --  filters or key expressions.

                  begin
                     Comp := First (Component_Associations (N));
                     while Present (Comp) loop
                        if Nkind (Comp) = N_Iterated_Element_Association then
                           if Present
                             (Loop_Parameter_Specification (Comp))
                           then
                              if Present (Iterator_Filter
                                (Loop_Parameter_Specification (Comp)))
                              then
                                 Error_Msg_N
                                   ("iterator filter not allowed " &
                                     "in indexed aggregate", Comp);
                                 return;

                              elsif Present (Key_Expression
                                (Loop_Parameter_Specification (Comp)))
                              then
                                 Error_Msg_N
                                   ("key expression not allowed " &
                                     "in indexed aggregate", Comp);
                                 return;
                              end if;
                           end if;
                        else
                           Choice := First (Choices (Comp));

                           while Present (Choice) loop
                              Get_Index_Bounds (Choice, Lo, Hi);
                              Table (No_Choice).Choice := Choice;
                              Table (No_Choice).Lo := Lo;
                              Table (No_Choice).Hi := Hi;

                              --  Verify staticness of value or range

                              if not Is_Static_Expression (Lo)
                                or else not Is_Static_Expression (Hi)
                              then
                                 Error_Msg_N
                                   ("nonstatic expression for index " &
                                     "for indexed aggregate", Choice);
                                 return;
                              end if;

                              No_Choice := No_Choice + 1;
                              Next (Choice);
                           end loop;
                        end if;

                        Next (Comp);
                     end loop;

                     Sort_Case_Table (Table);

                     for J in 1 .. Num_Choices - 1 loop
                        Hi_Val := Expr_Value (Table (J).Hi);
                        Lo_Val := Expr_Value (Table (J + 1).Lo);

                        if Lo_Val = Hi_Val then
                           Error_Msg_N
                             ("duplicate index in indexed aggregate",
                               Table (J + 1).Choice);
                           exit;

                        elsif Lo_Val < Hi_Val then
                           Error_Msg_N
                             ("overlapping indices in indexed aggregate",
                               Table (J + 1).Choice);
                           exit;

                        elsif Lo_Val > Hi_Val + 1 then
                           Error_Msg_N
                             ("missing index values", Table (J + 1).Choice);
                           exit;
                        end if;
                     end loop;
                  end;
               end if;
            end if;
         end;
      end if;
   end Resolve_Container_Aggregate;

   -----------------------------
   -- Resolve_Delta_Aggregate --
   -----------------------------

   procedure Resolve_Delta_Aggregate (N : Node_Id; Typ : Entity_Id) is
      Base : constant Node_Id := Expression (N);

   begin
      Error_Msg_Ada_2022_Feature ("delta aggregate", Sloc (N));

      if not Is_Composite_Type (Typ) then
         Error_Msg_N ("not a composite type", N);
      end if;

      Analyze_And_Resolve (Base, Typ);

      if Is_Array_Type (Typ) then
         Resolve_Delta_Array_Aggregate (N, Typ);
      else
         Resolve_Delta_Record_Aggregate (N, Typ);
      end if;

      Set_Etype (N, Typ);
   end Resolve_Delta_Aggregate;

   -----------------------------------
   -- Resolve_Delta_Array_Aggregate --
   -----------------------------------

   procedure Resolve_Delta_Array_Aggregate (N : Node_Id; Typ : Entity_Id) is
      Deltas     : constant List_Id   := Component_Associations (N);
      Index_Type : constant Entity_Id := Etype (First_Index (Typ));

      Assoc  : Node_Id;
      Choice : Node_Id;
      Expr   : Node_Id;

   begin
      Assoc := First (Deltas);
      while Present (Assoc) loop
         if Nkind (Assoc) = N_Iterated_Component_Association then
            Choice := First (Choice_List (Assoc));
            while Present (Choice) loop
               if Nkind (Choice) = N_Others_Choice then
                  Error_Msg_N
                    ("OTHERS not allowed in delta aggregate", Choice);

               elsif Nkind (Choice) = N_Subtype_Indication then
                  Resolve_Discrete_Subtype_Indication
                    (Choice, Base_Type (Index_Type));

               else
                  Analyze_And_Resolve (Choice, Index_Type);
               end if;

               Next (Choice);
            end loop;

            declare
               Id  : constant Entity_Id := Defining_Identifier (Assoc);
               Ent : constant Entity_Id :=
                       New_Internal_Entity
                         (E_Loop, Current_Scope, Sloc (Assoc), 'L');

            begin
               Set_Etype  (Ent, Standard_Void_Type);
               Set_Parent (Ent, Assoc);
               Push_Scope (Ent);

               if No (Scope (Id)) then
                  Set_Etype (Id, Index_Type);
                  Mutate_Ekind (Id, E_Variable);
                  Set_Scope (Id, Ent);
               end if;
               Enter_Name (Id);

               --  Resolve a copy of the expression, after setting
               --  its parent properly to preserve its context.

               Expr := New_Copy_Tree (Expression (Assoc));
               Set_Parent (Expr, Assoc);
               Analyze_And_Resolve (Expr, Component_Type (Typ));
               End_Scope;
            end;

         else
            Choice := First (Choice_List (Assoc));
            while Present (Choice) loop
               Analyze (Choice);

               if Nkind (Choice) = N_Others_Choice then
                  Error_Msg_N
                    ("OTHERS not allowed in delta aggregate", Choice);

               elsif Is_Entity_Name (Choice)
                 and then Is_Type (Entity (Choice))
               then
                  --  Choice covers a range of values

                  if Base_Type (Entity (Choice)) /=
                     Base_Type (Index_Type)
                  then
                     Error_Msg_NE
                       ("choice does not match index type of &",
                        Choice, Typ);
                  end if;

               elsif Nkind (Choice) = N_Subtype_Indication then
                  Resolve_Discrete_Subtype_Indication
                    (Choice, Base_Type (Index_Type));

               else
                  Resolve (Choice, Index_Type);
               end if;

               Next (Choice);
            end loop;

            Analyze_And_Resolve (Expression (Assoc), Component_Type (Typ));
         end if;

         Next (Assoc);
      end loop;
   end Resolve_Delta_Array_Aggregate;

   ------------------------------------
   -- Resolve_Delta_Record_Aggregate --
   ------------------------------------

   procedure Resolve_Delta_Record_Aggregate (N : Node_Id; Typ : Entity_Id) is

      --  Variables used to verify that discriminant-dependent components
      --  appear in the same variant.

      Comp_Ref : Entity_Id := Empty; -- init to avoid warning
      Variant  : Node_Id;

      procedure Check_Variant (Id : Entity_Id);
      --  If a given component of the delta aggregate appears in a variant
      --  part, verify that it is within the same variant as that of previous
      --  specified variant components of the delta.

      function Get_Component (Nam : Node_Id) return Entity_Id;
      --  Locate component with a given name and return it. If none found then
      --  report error and return Empty.

      function Nested_In (V1 : Node_Id; V2 : Node_Id) return Boolean;
      --  Determine whether variant V1 is within variant V2

      function Variant_Depth (N : Node_Id) return Natural;
      --  Determine the distance of a variant to the enclosing type declaration

      --------------------
      --  Check_Variant --
      --------------------

      procedure Check_Variant (Id : Entity_Id) is
         Comp         : Entity_Id;
         Comp_Variant : Node_Id;

      begin
         if not Has_Discriminants (Typ) then
            return;
         end if;

         Comp := First_Entity (Typ);
         while Present (Comp) loop
            exit when Chars (Comp) = Chars (Id);
            Next_Component (Comp);
         end loop;

         --  Find the variant, if any, whose component list includes the
         --  component declaration.

         Comp_Variant := Parent (Parent (List_Containing (Parent (Comp))));
         if Nkind (Comp_Variant) = N_Variant then
            if No (Variant) then
               Variant  := Comp_Variant;
               Comp_Ref := Comp;

            elsif Variant /= Comp_Variant then
               declare
                  D1 : constant Integer := Variant_Depth (Variant);
                  D2 : constant Integer := Variant_Depth (Comp_Variant);

               begin
                  if D1 = D2
                    or else
                      (D1 > D2 and then not Nested_In (Variant, Comp_Variant))
                    or else
                      (D2 > D1 and then not Nested_In (Comp_Variant, Variant))
                  then
                     pragma Assert (Present (Comp_Ref));
                     Error_Msg_Node_2 := Comp_Ref;
                     Error_Msg_NE
                       ("& and & appear in different variants", Id, Comp);

                  --  Otherwise retain the deeper variant for subsequent tests

                  elsif D2 > D1 then
                     Variant := Comp_Variant;
                  end if;
               end;
            end if;
         end if;
      end Check_Variant;

      -------------------
      -- Get_Component --
      -------------------

      function Get_Component (Nam : Node_Id) return Entity_Id is
         Comp : Entity_Id;

      begin
         Comp := First_Entity (Typ);
         while Present (Comp) loop
            if Chars (Comp) = Chars (Nam) then
               if Ekind (Comp) = E_Discriminant then
                  Error_Msg_N ("delta cannot apply to discriminant", Nam);
               end if;

               return Comp;
            end if;

            Next_Entity (Comp);
         end loop;

         Error_Msg_NE ("type& has no component with this name", Nam, Typ);
         return Empty;
      end Get_Component;

      ---------------
      -- Nested_In --
      ---------------

      function Nested_In (V1, V2 : Node_Id) return Boolean is
         Par : Node_Id;

      begin
         Par := Parent (V1);
         while Nkind (Par) /= N_Full_Type_Declaration loop
            if Par = V2 then
               return True;
            end if;

            Par := Parent (Par);
         end loop;

         return False;
      end Nested_In;

      -------------------
      -- Variant_Depth --
      -------------------

      function Variant_Depth (N : Node_Id) return Natural is
         Depth : Natural;
         Par   : Node_Id;

      begin
         Depth := 0;
         Par   := Parent (N);
         while Nkind (Par) /= N_Full_Type_Declaration loop
            Depth := Depth + 1;
            Par   := Parent (Par);
         end loop;

         return Depth;
      end Variant_Depth;

      --  Local variables

      Deltas : constant List_Id := Component_Associations (N);

      Assoc     : Node_Id;
      Choice    : Node_Id;
      Comp      : Entity_Id;
      Comp_Type : Entity_Id := Empty; -- init to avoid warning

   --  Start of processing for Resolve_Delta_Record_Aggregate

   begin
      Variant := Empty;

      Assoc := First (Deltas);
      while Present (Assoc) loop
         Choice := First (Choice_List (Assoc));
         while Present (Choice) loop
            Comp := Get_Component (Choice);

            if Present (Comp) then
               Check_Variant (Choice);

               Comp_Type := Etype (Comp);

               --  Decorate the component reference by setting its entity and
               --  type, as otherwise backends like GNATprove would have to
               --  rediscover this information by themselves.

               Set_Entity (Choice, Comp);
               Set_Etype  (Choice, Comp_Type);
            else
               Comp_Type := Any_Type;
            end if;

            Next (Choice);
         end loop;

         pragma Assert (Present (Comp_Type));

         --  A record_component_association in record_delta_aggregate shall not
         --  use the box compound delimiter <> rather than an expression; see
         --  RM 4.3.1(17.3/5).

         pragma Assert (Present (Expression (Assoc)) xor Box_Present (Assoc));

         if Box_Present (Assoc) then
            Error_Msg_N
              ("'<'> in record delta aggregate is not allowed", Assoc);
         else
            Analyze_And_Resolve (Expression (Assoc), Comp_Type);
         end if;
         Next (Assoc);
      end loop;
   end Resolve_Delta_Record_Aggregate;

   ---------------------------------
   -- Resolve_Extension_Aggregate --
   ---------------------------------

   --  There are two cases to consider:

   --  a) If the ancestor part is a type mark, the components needed are the
   --  difference between the components of the expected type and the
   --  components of the given type mark.

   --  b) If the ancestor part is an expression, it must be unambiguous, and
   --  once we have its type we can also compute the needed components as in
   --  the previous case. In both cases, if the ancestor type is not the
   --  immediate ancestor, we have to build this ancestor recursively.

   --  In both cases, discriminants of the ancestor type do not play a role in
   --  the resolution of the needed components, because inherited discriminants
   --  cannot be used in a type extension. As a result we can compute
   --  independently the list of components of the ancestor type and of the
   --  expected type.

   procedure Resolve_Extension_Aggregate (N : Node_Id; Typ : Entity_Id) is
      A      : constant Node_Id := Ancestor_Part (N);
      A_Type : Entity_Id;
      I      : Interp_Index;
      It     : Interp;

      function Valid_Limited_Ancestor (Anc : Node_Id) return Boolean;
      --  If the type is limited, verify that the ancestor part is a legal
      --  expression (aggregate or function call, including 'Input)) that does
      --  not require a copy, as specified in 7.5(2).

      function Valid_Ancestor_Type return Boolean;
      --  Verify that the type of the ancestor part is a non-private ancestor
      --  of the expected type, which must be a type extension.

      procedure Transform_BIP_Assignment (Typ : Entity_Id);
      --  For an extension aggregate whose ancestor part is a build-in-place
      --  call returning a nonlimited type, this is used to transform the
      --  assignment to the ancestor part to use a temp.

      ----------------------------
      -- Valid_Limited_Ancestor --
      ----------------------------

      function Valid_Limited_Ancestor (Anc : Node_Id) return Boolean is
      begin
         if Is_Entity_Name (Anc) and then Is_Type (Entity (Anc)) then
            return True;

         --  The ancestor must be a call or an aggregate, but a call may
         --  have been expanded into a temporary, so check original node.

         elsif Nkind (Anc) in N_Aggregate
                            | N_Extension_Aggregate
                            | N_Function_Call
         then
            return True;

         elsif Nkind (Original_Node (Anc)) = N_Function_Call then
            return True;

         elsif Nkind (Anc) = N_Attribute_Reference
           and then Attribute_Name (Anc) = Name_Input
         then
            return True;

         elsif Nkind (Anc) = N_Qualified_Expression then
            return Valid_Limited_Ancestor (Expression (Anc));

         elsif Nkind (Anc) = N_Raise_Expression then
            return True;

         else
            return False;
         end if;
      end Valid_Limited_Ancestor;

      -------------------------
      -- Valid_Ancestor_Type --
      -------------------------

      function Valid_Ancestor_Type return Boolean is
         Imm_Type : Entity_Id;

      begin
         Imm_Type := Base_Type (Typ);
         while Is_Derived_Type (Imm_Type) loop
            if Etype (Imm_Type) = Base_Type (A_Type) then
               return True;

            --  The base type of the parent type may appear as a private
            --  extension if it is declared as such in a parent unit of the
            --  current one. For consistency of the subsequent analysis use
            --  the partial view for the ancestor part.

            elsif Is_Private_Type (Etype (Imm_Type))
              and then Present (Full_View (Etype (Imm_Type)))
              and then Base_Type (A_Type) = Full_View (Etype (Imm_Type))
            then
               A_Type := Etype (Imm_Type);
               return True;

            --  The parent type may be a private extension. The aggregate is
            --  legal if the type of the aggregate is an extension of it that
            --  is not a private extension.

            elsif Is_Private_Type (A_Type)
              and then not Is_Private_Type (Imm_Type)
              and then Present (Full_View (A_Type))
              and then Base_Type (Full_View (A_Type)) = Etype (Imm_Type)
            then
               return True;

            --  The parent type may be a raise expression (which is legal in
            --  any expression context).

            elsif A_Type = Raise_Type then
               A_Type := Etype (Imm_Type);
               return True;

            else
               Imm_Type := Etype (Base_Type (Imm_Type));
            end if;
         end loop;

         --  If previous loop did not find a proper ancestor, report error

         Error_Msg_NE ("expect ancestor type of &", A, Typ);
         return False;
      end Valid_Ancestor_Type;

      ------------------------------
      -- Transform_BIP_Assignment --
      ------------------------------

      procedure Transform_BIP_Assignment (Typ : Entity_Id) is
         Loc      : constant Source_Ptr := Sloc (N);
         Def_Id   : constant Entity_Id  := Make_Temporary (Loc, 'Y', A);
         Obj_Decl : constant Node_Id    :=
                      Make_Object_Declaration (Loc,
                        Defining_Identifier => Def_Id,
                        Constant_Present    => True,
                        Object_Definition   => New_Occurrence_Of (Typ, Loc),
                        Expression          => A,
                        Has_Init_Expression => True);
      begin
         Set_Etype (Def_Id, Typ);
         Set_Ancestor_Part (N, New_Occurrence_Of (Def_Id, Loc));
         Insert_Action (N, Obj_Decl);
      end Transform_BIP_Assignment;

   --  Start of processing for Resolve_Extension_Aggregate

   begin
      --  Analyze the ancestor part and account for the case where it is a
      --  parameterless function call.

      Analyze (A);
      Check_Parameterless_Call (A);

      if Is_Entity_Name (A) and then Is_Type (Entity (A)) then

         --  AI05-0115: If the ancestor part is a subtype mark, the ancestor
         --  must not have unknown discriminants. To catch cases where the
         --  aggregate occurs at a place where the full view of the ancestor
         --  type is visible and doesn't have unknown discriminants, but the
         --  aggregate type was derived from a partial view that has unknown
         --  discriminants, we check whether the aggregate type has unknown
         --  discriminants (unknown discriminants were inherited), along
         --  with checking that the partial view of the ancestor has unknown
         --  discriminants. (It might be sufficient to replace the entire
         --  condition with Has_Unknown_Discriminants (Typ), but that might
         --  miss some cases, not clear, and causes error changes in some tests
         --  such as class-wide cases, that aren't clearly improvements. ???)

         if Has_Unknown_Discriminants (Entity (A))
           or else (Has_Unknown_Discriminants (Typ)
                      and then Partial_View_Has_Unknown_Discr (Entity (A)))
         then
            Error_Msg_NE
              ("aggregate not available for type& whose ancestor "
                 & "has unknown discriminants", N, Typ);
         end if;
      end if;

      if not Is_Tagged_Type (Typ) then
         Error_Msg_N ("type of extension aggregate must be tagged", N);
         return;

      elsif Is_Limited_Type (Typ) then

         --  Ada 2005 (AI-287): Limited aggregates are allowed

         if Ada_Version < Ada_2005 then
            Error_Msg_N ("aggregate type cannot be limited", N);
            Explain_Limited_Type (Typ, N);
            return;

         elsif Valid_Limited_Ancestor (A) then
            null;

         else
            Error_Msg_N
              ("limited ancestor part must be aggregate or function call", A);
         end if;

      elsif Is_Class_Wide_Type (Typ) then
         Error_Msg_N ("aggregate cannot be of a class-wide type", N);
         return;
      end if;

      if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
         A_Type := Get_Full_View (Entity (A));

         if Valid_Ancestor_Type then
            Set_Entity (A, A_Type);
            Set_Etype  (A, A_Type);

            Validate_Ancestor_Part (N);
            Resolve_Record_Aggregate (N, Typ);
         end if;

      elsif Nkind (A) /= N_Aggregate then
         if Is_Overloaded (A) then
            A_Type := Any_Type;

            Get_First_Interp (A, I, It);
            while Present (It.Typ) loop

               --  Consider limited interpretations if Ada 2005 or higher

               if Is_Tagged_Type (It.Typ)
                 and then (Ada_Version >= Ada_2005
                            or else not Is_Limited_Type (It.Typ))
               then
                  if A_Type /= Any_Type then
                     Error_Msg_N ("cannot resolve expression", A);
                     return;
                  else
                     A_Type := It.Typ;
                  end if;
               end if;

               Get_Next_Interp (I, It);
            end loop;

            if A_Type = Any_Type then
               if Ada_Version >= Ada_2005 then
                  Error_Msg_N
                    ("ancestor part must be of a tagged type", A);
               else
                  Error_Msg_N
                    ("ancestor part must be of a nonlimited tagged type", A);
               end if;

               return;
            end if;

         else
            A_Type := Etype (A);
         end if;

         if Valid_Ancestor_Type then
            Resolve (A, A_Type);
            Check_Unset_Reference (A);
            Check_Non_Static_Context (A);

            --  The aggregate is illegal if the ancestor expression is a call
            --  to a function with a limited unconstrained result, unless the
            --  type of the aggregate is a null extension. This restriction
            --  was added in AI05-67 to simplify implementation.

            if Nkind (A) = N_Function_Call
              and then Is_Limited_Type (A_Type)
              and then not Is_Null_Extension (Typ)
              and then not Is_Constrained (A_Type)
            then
               Error_Msg_N
                 ("type of limited ancestor part must be constrained", A);

            --  Reject the use of CPP constructors that leave objects partially
            --  initialized. For example:

            --    type CPP_Root is tagged limited record ...
            --    pragma Import (CPP, CPP_Root);

            --    type CPP_DT is new CPP_Root and Iface ...
            --    pragma Import (CPP, CPP_DT);

            --    type Ada_DT is new CPP_DT with ...

            --    Obj : Ada_DT := Ada_DT'(New_CPP_Root with others => <>);

            --  Using the constructor of CPP_Root the slots of the dispatch
            --  table of CPP_DT cannot be set, and the secondary tag of
            --  CPP_DT is unknown.

            elsif Nkind (A) = N_Function_Call
              and then Is_CPP_Constructor_Call (A)
              and then Enclosing_CPP_Parent (Typ) /= A_Type
            then
               Error_Msg_NE
                 ("??must use 'C'P'P constructor for type &", A,
                  Enclosing_CPP_Parent (Typ));

               --  The following call is not needed if the previous warning
               --  is promoted to an error.

               Resolve_Record_Aggregate (N, Typ);

            elsif Is_Class_Wide_Type (Etype (A))
              and then Nkind (Original_Node (A)) = N_Function_Call
            then
               --  If the ancestor part is a dispatching call, it appears
               --  statically to be a legal ancestor, but it yields any member
               --  of the class, and it is not possible to determine whether
               --  it is an ancestor of the extension aggregate (much less
               --  which ancestor). It is not possible to determine the
               --  components of the extension part.

               --  This check implements AI-306, which in fact was motivated by
               --  an AdaCore query to the ARG after this test was added.

               Error_Msg_N ("ancestor part must be statically tagged", A);
            else
               --  We are using the build-in-place protocol, but we can't build
               --  in place, because we need to call the function before
               --  allocating the aggregate. Could do better for null
               --  extensions, and maybe for nondiscriminated types.
               --  This is wrong for limited, but those were wrong already.

               if not Is_Limited_View (A_Type)
                 and then Is_Build_In_Place_Function_Call (A)
               then
                  Transform_BIP_Assignment (A_Type);
               end if;

               Resolve_Record_Aggregate (N, Typ);
            end if;
         end if;

      else
         Error_Msg_N ("no unique type for this aggregate", A);
      end if;

      Check_Function_Writable_Actuals (N);
   end Resolve_Extension_Aggregate;

   ------------------------------
   -- Resolve_Record_Aggregate --
   ------------------------------

   procedure Resolve_Record_Aggregate (N : Node_Id; Typ : Entity_Id) is
      New_Assoc_List : constant List_Id := New_List;
      --  New_Assoc_List is the newly built list of N_Component_Association
      --  nodes.

      Others_Etype : Entity_Id := Empty;
      --  This variable is used to save the Etype of the last record component
      --  that takes its value from the others choice. Its purpose is:
      --
      --    (a) make sure the others choice is useful
      --
      --    (b) make sure the type of all the components whose value is
      --        subsumed by the others choice are the same.
      --
      --  This variable is updated as a side effect of function Get_Value.

      Box_Node               : Node_Id := Empty;
      Is_Box_Present         : Boolean := False;
      Is_Box_Init_By_Default : Boolean := False;
      Others_Box             : Natural := 0;
      --  Ada 2005 (AI-287): Variables used in case of default initialization
      --  to provide a functionality similar to Others_Etype. Box_Present
      --  indicates that the component takes its default initialization;
      --  Others_Box counts the number of components of the current aggregate
      --  (which may be a sub-aggregate of a larger one) that are default-
      --  initialized. A value of One indicates that an others_box is present.
      --  Any larger value indicates that the others_box is not redundant.
      --  These variables, similar to Others_Etype, are also updated as a side
      --  effect of function Get_Value. Box_Node is used to place a warning on
      --  a redundant others_box.

      procedure Add_Association
        (Component      : Entity_Id;
         Expr           : Node_Id;
         Assoc_List     : List_Id;
         Is_Box_Present : Boolean := False);
      --  Builds a new N_Component_Association node which associates Component
      --  to expression Expr and adds it to the association list being built,
      --  either New_Assoc_List, or the association being built for an inner
      --  aggregate.

      procedure Add_Discriminant_Values
        (New_Aggr   : Node_Id;
         Assoc_List : List_Id);
      --  The constraint to a component may be given by a discriminant of the
      --  enclosing type, in which case we have to retrieve its value, which is
      --  part of the enclosing aggregate. Assoc_List provides the discriminant
      --  associations of the current type or of some enclosing record.

      function Discriminant_Present (Input_Discr : Entity_Id) return Boolean;
      --  If aggregate N is a regular aggregate this routine will return True.
      --  Otherwise, if N is an extension aggregate, then Input_Discr denotes
      --  a discriminant whose value may already have been specified by N's
      --  ancestor part. This routine checks whether this is indeed the case
      --  and if so returns False, signaling that no value for Input_Discr
      --  should appear in N's aggregate part. Also, in this case, the routine
      --  appends to New_Assoc_List the discriminant value specified in the
      --  ancestor part.
      --
      --  If the aggregate is in a context with expansion delayed, it will be
      --  reanalyzed. The inherited discriminant values must not be reinserted
      --  in the component list to prevent spurious errors, but they must be
      --  present on first analysis to build the proper subtype indications.
      --  The flag Inherited_Discriminant is used to prevent the re-insertion.

      function Find_Private_Ancestor (Typ : Entity_Id) return Entity_Id;
      --  AI05-0115: Find earlier ancestor in the derivation chain that is
      --  derived from private view Typ. Whether the aggregate is legal depends
      --  on the current visibility of the type as well as that of the parent
      --  of the ancestor.

      function Get_Value
        (Compon                 : Entity_Id;
         From                   : List_Id;
         Consider_Others_Choice : Boolean := False) return Node_Id;
      --  Given a record component stored in parameter Compon, this function
      --  returns its value as it appears in the list From, which is a list
      --  of N_Component_Association nodes.
      --
      --  If no component association has a choice for the searched component,
      --  the value provided by the others choice is returned, if there is one,
      --  and Consider_Others_Choice is set to true. Otherwise Empty is
      --  returned. If there is more than one component association giving a
      --  value for the searched record component, an error message is emitted
      --  and the first found value is returned.
      --
      --  If Consider_Others_Choice is set and the returned expression comes
      --  from the others choice, then Others_Etype is set as a side effect.
      --  An error message is emitted if the components taking their value from
      --  the others choice do not have same type.

      procedure Propagate_Discriminants
        (Aggr       : Node_Id;
         Assoc_List : List_Id);
      --  Nested components may themselves be discriminated types constrained
      --  by outer discriminants, whose values must be captured before the
      --  aggregate is expanded into assignments.

      procedure Resolve_Aggr_Expr (Expr : Node_Id; Component : Entity_Id);
      --  Analyzes and resolves expression Expr against the Etype of the
      --  Component. This routine also applies all appropriate checks to Expr.
      --  It finally saves a Expr in the newly created association list that
      --  will be attached to the final record aggregate. Note that if the
      --  Parent pointer of Expr is not set then Expr was produced with a
      --  New_Copy_Tree or some such.

      procedure Rewrite_Range (Root_Type : Entity_Id; Rge : Node_Id);
      --  Rewrite a range node Rge when its bounds refer to non-stored
      --  discriminants from Root_Type, to replace them with the stored
      --  discriminant values. This is required in GNATprove mode, and is
      --  adopted in all modes to avoid special-casing GNATprove mode.

      ---------------------
      -- Add_Association --
      ---------------------

      procedure Add_Association
        (Component      : Entity_Id;
         Expr           : Node_Id;
         Assoc_List     : List_Id;
         Is_Box_Present : Boolean := False)
      is
         Choice_List : constant List_Id := New_List;
         Loc         : Source_Ptr;

      begin
         --  If this is a box association the expression is missing, so use the
         --  Sloc of the aggregate itself for the new association.

         pragma Assert (Present (Expr) xor Is_Box_Present);

         if Present (Expr) then
            Loc := Sloc (Expr);
         else
            Loc := Sloc (N);
         end if;

         Append_To (Choice_List, New_Occurrence_Of (Component, Loc));

         Append_To (Assoc_List,
           Make_Component_Association (Loc,
             Choices     => Choice_List,
             Expression  => Expr,
             Box_Present => Is_Box_Present));

         --  If this association has a box for a component that is initialized
         --  by default, then set flag on the new association to indicate that
         --  the original association was for such a box-initialized component.

         if Is_Box_Init_By_Default then
            Set_Was_Default_Init_Box_Association (Last (Assoc_List));
         end if;
      end Add_Association;

      -----------------------------
      -- Add_Discriminant_Values --
      -----------------------------

      procedure Add_Discriminant_Values
        (New_Aggr   : Node_Id;
         Assoc_List : List_Id)
      is
         Assoc      : Node_Id;
         Discr      : Entity_Id;
         Discr_Elmt : Elmt_Id;
         Discr_Val  : Node_Id;
         Val        : Entity_Id;

      begin
         Discr      := First_Discriminant (Etype (New_Aggr));
         Discr_Elmt := First_Elmt (Discriminant_Constraint (Etype (New_Aggr)));
         while Present (Discr_Elmt) loop
            Discr_Val := Node (Discr_Elmt);

            --  If the constraint is given by a discriminant then it is a
            --  discriminant of an enclosing record, and its value has already
            --  been placed in the association list.

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

               Assoc := First (Assoc_List);
               while Present (Assoc) loop
                  if Present (Entity (First (Choices (Assoc))))
                    and then Entity (First (Choices (Assoc))) = Val
                  then
                     Discr_Val := Expression (Assoc);
                     exit;
                  end if;

                  Next (Assoc);
               end loop;
            end if;

            Add_Association
              (Discr, New_Copy_Tree (Discr_Val),
               Component_Associations (New_Aggr));

            --  If the discriminant constraint is a current instance, mark the
            --  current aggregate so that the self-reference can be expanded
            --  later. The constraint may refer to the subtype of aggregate, so
            --  use base type for comparison.

            if Nkind (Discr_Val) = N_Attribute_Reference
              and then Is_Entity_Name (Prefix (Discr_Val))
              and then Is_Type (Entity (Prefix (Discr_Val)))
              and then Base_Type (Etype (N)) = Entity (Prefix (Discr_Val))
            then
               Set_Has_Self_Reference (N);
            end if;

            Next_Elmt (Discr_Elmt);
            Next_Discriminant (Discr);
         end loop;
      end Add_Discriminant_Values;

      --------------------------
      -- Discriminant_Present --
      --------------------------

      function Discriminant_Present (Input_Discr : Entity_Id) return Boolean is
         Regular_Aggr : constant Boolean := Nkind (N) /= N_Extension_Aggregate;

         Ancestor_Is_Subtyp : Boolean;

         Loc : Source_Ptr;

         Ancestor     : Node_Id;
         Ancestor_Typ : Entity_Id;
         Comp_Assoc   : Node_Id;
         Discr        : Entity_Id;
         Discr_Expr   : Node_Id;
         Discr_Val    : Elmt_Id := No_Elmt;
         Orig_Discr   : Entity_Id;

      begin
         if Regular_Aggr then
            return True;
         end if;

         --  Check whether inherited discriminant values have already been
         --  inserted in the aggregate. This will be the case if we are
         --  re-analyzing an aggregate whose expansion was delayed.

         if Present (Component_Associations (N)) then
            Comp_Assoc := First (Component_Associations (N));
            while Present (Comp_Assoc) loop
               if Inherited_Discriminant (Comp_Assoc) then
                  return True;
               end if;

               Next (Comp_Assoc);
            end loop;
         end if;

         Ancestor     := Ancestor_Part (N);
         Ancestor_Typ := Etype (Ancestor);
         Loc          := Sloc (Ancestor);

         --  For a private type with unknown discriminants, use the underlying
         --  record view if it is available.

         if Has_Unknown_Discriminants (Ancestor_Typ)
           and then Present (Full_View (Ancestor_Typ))
           and then Present (Underlying_Record_View (Full_View (Ancestor_Typ)))
         then
            Ancestor_Typ := Underlying_Record_View (Full_View (Ancestor_Typ));
         end if;

         Ancestor_Is_Subtyp :=
           Is_Entity_Name (Ancestor) and then Is_Type (Entity (Ancestor));

         --  If the ancestor part has no discriminants clearly N's aggregate
         --  part must provide a value for Discr.

         if not Has_Discriminants (Ancestor_Typ) then
            return True;

         --  If the ancestor part is an unconstrained subtype mark then the
         --  Discr must be present in N's aggregate part.

         elsif Ancestor_Is_Subtyp
           and then not Is_Constrained (Entity (Ancestor))
         then
            return True;
         end if;

         --  Now look to see if Discr was specified in the ancestor part

         if Ancestor_Is_Subtyp then
            Discr_Val :=
              First_Elmt (Discriminant_Constraint (Entity (Ancestor)));
         end if;

         Orig_Discr := Original_Record_Component (Input_Discr);

         Discr := First_Discriminant (Ancestor_Typ);
         while Present (Discr) loop

            --  If Ancestor has already specified Disc value then insert its
            --  value in the final aggregate.

            if Original_Record_Component (Discr) = Orig_Discr then
               if Ancestor_Is_Subtyp then
                  Discr_Expr := New_Copy_Tree (Node (Discr_Val));
               else
                  Discr_Expr :=
                    Make_Selected_Component (Loc,
                      Prefix        => Duplicate_Subexpr (Ancestor),
                      Selector_Name => New_Occurrence_Of (Input_Discr, Loc));
               end if;

               Resolve_Aggr_Expr (Discr_Expr, Input_Discr);
               Set_Inherited_Discriminant (Last (New_Assoc_List));
               return False;
            end if;

            Next_Discriminant (Discr);

            if Ancestor_Is_Subtyp then
               Next_Elmt (Discr_Val);
            end if;
         end loop;

         return True;
      end Discriminant_Present;

      ---------------------------
      -- Find_Private_Ancestor --
      ---------------------------

      function Find_Private_Ancestor (Typ : Entity_Id) return Entity_Id is
         Par : Entity_Id;

      begin
         Par := Typ;
         loop
            if Has_Private_Ancestor (Par)
              and then not Has_Private_Ancestor (Etype (Base_Type (Par)))
            then
               return Par;

            elsif not Is_Derived_Type (Par) then
               return Empty;

            else
               Par := Etype (Base_Type (Par));
            end if;
         end loop;
      end Find_Private_Ancestor;

      ---------------
      -- Get_Value --
      ---------------

      function Get_Value
        (Compon                 : Entity_Id;
         From                   : List_Id;
         Consider_Others_Choice : Boolean := False) return Node_Id
      is
         Typ           : constant Entity_Id := Etype (Compon);
         Assoc         : Node_Id;
         Expr          : Node_Id := Empty;
         Selector_Name : Node_Id;

      begin
         Is_Box_Present := False;
         Is_Box_Init_By_Default := False;

         if No (From) then
            return Empty;
         end if;

         Assoc := First (From);
         while Present (Assoc) loop
            Selector_Name := First (Choices (Assoc));
            while Present (Selector_Name) loop
               if Nkind (Selector_Name) = N_Others_Choice then
                  if Consider_Others_Choice and then No (Expr) then

                     --  We need to duplicate the expression for each
                     --  successive component covered by the others choice.
                     --  This is redundant if the others_choice covers only
                     --  one component (small optimization possible???), but
                     --  indispensable otherwise, because each one must be
                     --  expanded individually to preserve side effects.

                     --  Ada 2005 (AI-287): In case of default initialization
                     --  of components, we duplicate the corresponding default
                     --  expression (from the record type declaration). The
                     --  copy must carry the sloc of the association (not the
                     --  original expression) to prevent spurious elaboration
                     --  checks when the default includes function calls.

                     if Box_Present (Assoc) then
                        Others_Box     := Others_Box + 1;
                        Is_Box_Present := True;

                        if Expander_Active then
                           return
                             New_Copy_Tree_And_Copy_Dimensions
                               (Expression (Parent (Compon)),
                                New_Sloc => Sloc (Assoc));
                        else
                           return Expression (Parent (Compon));
                        end if;

                     else
                        if Present (Others_Etype)
                          and then Base_Type (Others_Etype) /= Base_Type (Typ)
                        then
                           --  If the components are of an anonymous access
                           --  type they are distinct, but this is legal in
                           --  Ada 2012 as long as designated types match.

                           if (Ekind (Typ) = E_Anonymous_Access_Type
                                or else Ekind (Typ) =
                                            E_Anonymous_Access_Subprogram_Type)
                             and then Designated_Type (Typ) =
                                            Designated_Type (Others_Etype)
                           then
                              null;
                           else
                              Error_Msg_N
                                ("components in OTHERS choice must have same "
                                 & "type", Selector_Name);
                           end if;
                        end if;

                        Others_Etype := Typ;

                        --  Copy the expression so that it is resolved
                        --  independently for each component, This is needed
                        --  for accessibility checks on components of anonymous
                        --  access types, even in compile_only mode.

                        if not Inside_A_Generic then
                           return
                             New_Copy_Tree_And_Copy_Dimensions
                               (Expression (Assoc));
                        else
                           return Expression (Assoc);
                        end if;
                     end if;
                  end if;

               elsif Chars (Compon) = Chars (Selector_Name) then
                  if No (Expr) then

                     --  Ada 2005 (AI-231)

                     if Ada_Version >= Ada_2005
                       and then Known_Null (Expression (Assoc))
                     then
                        Check_Can_Never_Be_Null (Compon, Expression (Assoc));
                     end if;

                     --  We need to duplicate the expression when several
                     --  components are grouped together with a "|" choice.
                     --  For instance "filed1 | filed2 => Expr"

                     --  Ada 2005 (AI-287)

                     if Box_Present (Assoc) then
                        Is_Box_Present := True;

                        --  Duplicate the default expression of the component
                        --  from the record type declaration, so a new copy
                        --  can be attached to the association.

                        --  Note that we always copy the default expression,
                        --  even when the association has a single choice, in
                        --  order to create a proper association for the
                        --  expanded aggregate.

                        --  Component may have no default, in which case the
                        --  expression is empty and the component is default-
                        --  initialized, but an association for the component
                        --  exists, and it is not covered by an others clause.

                        --  Scalar and private types have no initialization
                        --  procedure, so they remain uninitialized. If the
                        --  target of the aggregate is a constant this
                        --  deserves a warning.

                        if No (Expression (Parent (Compon)))
                          and then not Has_Non_Null_Base_Init_Proc (Typ)
                          and then not Has_Aspect (Typ, Aspect_Default_Value)
                          and then not Is_Concurrent_Type (Typ)
                          and then Nkind (Parent (N)) = N_Object_Declaration
                          and then Constant_Present (Parent (N))
                        then
                           Error_Msg_Node_2 := Typ;
                           Error_Msg_NE
                             ("component&? of type& is uninitialized",
                              Assoc, Selector_Name);

                           --  An additional reminder if the component type
                           --  is a generic formal.

                           if Is_Generic_Type (Base_Type (Typ)) then
                              Error_Msg_NE
                                ("\instance should provide actual type with "
                                 & "initialization for&", Assoc, Typ);
                           end if;
                        end if;

                        return
                          New_Copy_Tree_And_Copy_Dimensions
                            (Expression (Parent (Compon)));

                     else
                        if Present (Next (Selector_Name)) then
                           Expr := New_Copy_Tree_And_Copy_Dimensions
                                     (Expression (Assoc));
                        else
                           Expr := Expression (Assoc);
                        end if;
                     end if;

                     Generate_Reference (Compon, Selector_Name, 'm');

                  else
                     Error_Msg_NE
                       ("more than one value supplied for &",
                        Selector_Name, Compon);

                  end if;
               end if;

               Next (Selector_Name);
            end loop;

            Next (Assoc);
         end loop;

         return Expr;
      end Get_Value;

      -----------------------------
      -- Propagate_Discriminants --
      -----------------------------

      procedure Propagate_Discriminants
        (Aggr       : Node_Id;
         Assoc_List : List_Id)
      is
         Loc : constant Source_Ptr := Sloc (N);

         procedure Process_Component (Comp : Entity_Id);
         --  Add one component with a box association to the inner aggregate,
         --  and recurse if component is itself composite.

         -----------------------
         -- Process_Component --
         -----------------------

         procedure Process_Component (Comp : Entity_Id) is
            T        : constant Entity_Id := Etype (Comp);
            New_Aggr : Node_Id;

         begin
            if Is_Record_Type (T) and then Has_Discriminants (T) then
               New_Aggr := Make_Aggregate (Loc, No_List, New_List);
               Set_Etype (New_Aggr, T);

               Add_Association
                 (Comp, New_Aggr, Component_Associations (Aggr));

               --  Collect discriminant values and recurse

               Add_Discriminant_Values (New_Aggr, Assoc_List);
               Propagate_Discriminants (New_Aggr, Assoc_List);

               Build_Constrained_Itype
                 (New_Aggr, T, Component_Associations (New_Aggr));
            else
               Add_Association
                 (Comp, Empty, Component_Associations (Aggr),
                  Is_Box_Present => True);
            end if;
         end Process_Component;

         --  Local variables

         Aggr_Type  : constant Entity_Id := Base_Type (Etype (Aggr));
         Components : constant Elist_Id  := New_Elmt_List;
         Def_Node   : constant Node_Id   :=
                       Type_Definition (Declaration_Node (Aggr_Type));

         Comp      : Node_Id;
         Comp_Elmt : Elmt_Id;
         Errors    : Boolean;

      --  Start of processing for Propagate_Discriminants

      begin
         --  The component type may be a variant type. Collect the components
         --  that are ruled by the known values of the discriminants. Their
         --  values have already been inserted into the component list of the
         --  current aggregate.

         if Nkind (Def_Node) = N_Record_Definition
           and then Present (Component_List (Def_Node))
           and then Present (Variant_Part (Component_List (Def_Node)))
         then
            Gather_Components (Aggr_Type,
              Component_List (Def_Node),
              Governed_By   => Component_Associations (Aggr),
              Into          => Components,
              Report_Errors => Errors);

            Comp_Elmt := First_Elmt (Components);
            while Present (Comp_Elmt) loop
               if Ekind (Node (Comp_Elmt)) /= E_Discriminant then
                  Process_Component (Node (Comp_Elmt));
               end if;

               Next_Elmt (Comp_Elmt);
            end loop;

            --  No variant part, iterate over all components

         else
            Comp := First_Component (Etype (Aggr));
            while Present (Comp) loop
               Process_Component (Comp);
               Next_Component (Comp);
            end loop;
         end if;
      end Propagate_Discriminants;

      -----------------------
      -- Resolve_Aggr_Expr --
      -----------------------

      procedure Resolve_Aggr_Expr (Expr : Node_Id; Component : Entity_Id) is
         function Has_Expansion_Delayed (Expr : Node_Id) return Boolean;
         --  If the expression is an aggregate (possibly qualified) then its
         --  expansion is delayed until the enclosing aggregate is expanded
         --  into assignments. In that case, do not generate checks on the
         --  expression, because they will be generated later, and will other-
         --  wise force a copy (to remove side effects) that would leave a
         --  dynamic-sized aggregate in the code, something that gigi cannot
         --  handle.

         ---------------------------
         -- Has_Expansion_Delayed --
         ---------------------------

         function Has_Expansion_Delayed (Expr : Node_Id) return Boolean is
         begin
            return
               (Nkind (Expr) in N_Aggregate | N_Extension_Aggregate
                 and then Present (Etype (Expr))
                 and then Is_Record_Type (Etype (Expr))
                 and then Expansion_Delayed (Expr))
              or else
                (Nkind (Expr) = N_Qualified_Expression
                  and then Has_Expansion_Delayed (Expression (Expr)));
         end Has_Expansion_Delayed;

         --  Local variables

         Expr_Type : Entity_Id := Empty;
         New_C     : Entity_Id := Component;
         New_Expr  : Node_Id;

         Relocate : Boolean;
         --  Set to True if the resolved Expr node needs to be relocated when
         --  attached to the newly created association list. This node need not
         --  be relocated if its parent pointer is not set. In fact in this
         --  case Expr is the output of a New_Copy_Tree call. If Relocate is
         --  True then we have analyzed the expression node in the original
         --  aggregate and hence it needs to be relocated when moved over to
         --  the new association list.

      --  Start of processing for Resolve_Aggr_Expr

      begin
         --  If the type of the component is elementary or the type of the
         --  aggregate does not contain discriminants, use the type of the
         --  component to resolve Expr.

         if Is_Elementary_Type (Etype (Component))
           or else not Has_Discriminants (Etype (N))
         then
            Expr_Type := Etype (Component);

         --  Otherwise we have to pick up the new type of the component from
         --  the new constrained subtype of the aggregate. In fact components
         --  which are of a composite type might be constrained by a
         --  discriminant, and we want to resolve Expr against the subtype were
         --  all discriminant occurrences are replaced with their actual value.

         else
            New_C := First_Component (Etype (N));
            while Present (New_C) loop
               if Chars (New_C) = Chars (Component) then
                  Expr_Type := Etype (New_C);
                  exit;
               end if;

               Next_Component (New_C);
            end loop;

            pragma Assert (Present (Expr_Type));

            --  For each range in an array type where a discriminant has been
            --  replaced with the constraint, check that this range is within
            --  the range of the base type. This checks is done in the init
            --  proc for regular objects, but has to be done here for
            --  aggregates since no init proc is called for them.

            if Is_Array_Type (Expr_Type) then
               declare
                  Index : Node_Id;
                  --  Range of the current constrained index in the array

                  Orig_Index : Node_Id := First_Index (Etype (Component));
                  --  Range corresponding to the range Index above in the
                  --  original unconstrained record type. The bounds of this
                  --  range may be governed by discriminants.

                  Unconstr_Index : Node_Id := First_Index (Etype (Expr_Type));
                  --  Range corresponding to the range Index above for the
                  --  unconstrained array type. This range is needed to apply
                  --  range checks.

               begin
                  Index := First_Index (Expr_Type);
                  while Present (Index) loop
                     if Depends_On_Discriminant (Orig_Index) then
                        Apply_Range_Check (Index, Etype (Unconstr_Index));
                     end if;

                     Next_Index (Index);
                     Next_Index (Orig_Index);
                     Next_Index (Unconstr_Index);
                  end loop;
               end;
            end if;
         end if;

         --  If the Parent pointer of Expr is not set, Expr is an expression
         --  duplicated by New_Tree_Copy (this happens for record aggregates
         --  that look like (Field1 | Filed2 => Expr) or (others => Expr)).
         --  Such a duplicated expression must be attached to the tree
         --  before analysis and resolution to enforce the rule that a tree
         --  fragment should never be analyzed or resolved unless it is
         --  attached to the current compilation unit.

         if No (Parent (Expr)) then
            Set_Parent (Expr, N);
            Relocate := False;
         else
            Relocate := True;
         end if;

         Analyze_And_Resolve (Expr, Expr_Type);
         Check_Expr_OK_In_Limited_Aggregate (Expr);
         Check_Non_Static_Context (Expr);
         Check_Unset_Reference (Expr);

         --  Check wrong use of class-wide types

         if Is_Class_Wide_Type (Etype (Expr)) then
            Error_Msg_N ("dynamically tagged expression not allowed", Expr);
         end if;

         if not Has_Expansion_Delayed (Expr) then
            Aggregate_Constraint_Checks (Expr, Expr_Type);
         end if;

         --  If an aggregate component has a type with predicates, an explicit
         --  predicate check must be applied, as for an assignment statement,
         --  because the aggregate might not be expanded into individual
         --  component assignments.

         if Has_Predicates (Expr_Type)
           and then Analyzed (Expr)
         then
            Apply_Predicate_Check (Expr, Expr_Type);
         end if;

         if Raises_Constraint_Error (Expr) then
            Set_Raises_Constraint_Error (N);
         end if;

         --  If the expression has been marked as requiring a range check, then
         --  generate it here. It's a bit odd to be generating such checks in
         --  the analyzer, but harmless since Generate_Range_Check does nothing
         --  (other than making sure Do_Range_Check is set) if the expander is
         --  not active.

         if Do_Range_Check (Expr) then
            Generate_Range_Check (Expr, Expr_Type, CE_Range_Check_Failed);
         end if;

         --  Add association Component => Expr if the caller requests it

         if Relocate then
            New_Expr := Relocate_Node (Expr);

            --  Since New_Expr is not gonna be analyzed later on, we need to
            --  propagate here the dimensions form Expr to New_Expr.

            Copy_Dimensions (Expr, New_Expr);

         else
            New_Expr := Expr;
         end if;

         Add_Association (New_C, New_Expr, New_Assoc_List);
      end Resolve_Aggr_Expr;

      -------------------
      -- Rewrite_Range --
      -------------------

      procedure Rewrite_Range (Root_Type : Entity_Id; Rge : Node_Id) is
         procedure Rewrite_Bound
           (Bound     : Node_Id;
            Disc      : Entity_Id;
            Expr_Disc : Node_Id);
         --  Rewrite a bound of the range Bound, when it is equal to the
         --  non-stored discriminant Disc, into the stored discriminant
         --  value Expr_Disc.

         -------------------
         -- Rewrite_Bound --
         -------------------

         procedure Rewrite_Bound
           (Bound     : Node_Id;
            Disc      : Entity_Id;
            Expr_Disc : Node_Id)
         is
         begin
            if Nkind (Bound) /= N_Identifier then
               return;
            end if;

            --  We expect either the discriminant or the discriminal

            if Entity (Bound) = Disc
              or else (Ekind (Entity (Bound)) = E_In_Parameter
                        and then Discriminal_Link (Entity (Bound)) = Disc)
            then
               Rewrite (Bound, New_Copy_Tree (Expr_Disc));
            end if;
         end Rewrite_Bound;

         --  Local variables

         Low, High : Node_Id;
         Disc      : Entity_Id;
         Expr_Disc : Elmt_Id;

      --  Start of processing for Rewrite_Range

      begin
         if Has_Discriminants (Root_Type) and then Nkind (Rge) = N_Range then
            Low := Low_Bound (Rge);
            High := High_Bound (Rge);

            Disc      := First_Discriminant (Root_Type);
            Expr_Disc := First_Elmt (Stored_Constraint (Etype (N)));
            while Present (Disc) loop
               Rewrite_Bound (Low, Disc, Node (Expr_Disc));
               Rewrite_Bound (High, Disc, Node (Expr_Disc));
               Next_Discriminant (Disc);
               Next_Elmt (Expr_Disc);
            end loop;
         end if;
      end Rewrite_Range;

      --  Local variables

      Components : constant Elist_Id := New_Elmt_List;
      --  Components is the list of the record components whose value must be
      --  provided in the aggregate. This list does include discriminants.

      Component       : Entity_Id;
      Component_Elmt  : Elmt_Id;
      Expr            : Node_Id;
      Positional_Expr : Node_Id;

   --  Start of processing for Resolve_Record_Aggregate

   begin
      --  A record aggregate is restricted in SPARK:

      --    Each named association can have only a single choice.
      --    OTHERS cannot be used.
      --    Positional and named associations cannot be mixed.

      if Present (Component_Associations (N))
        and then Present (First (Component_Associations (N)))
      then
         declare
            Assoc : Node_Id;

         begin
            Assoc := First (Component_Associations (N));
            while Present (Assoc) loop
               if Nkind (Assoc) = N_Iterated_Component_Association then
                  Error_Msg_N
                    ("iterated component association can only appear in an "
                     & "array aggregate", N);
                  raise Unrecoverable_Error;
               end if;

               Next (Assoc);
            end loop;
         end;
      end if;

      --  We may end up calling Duplicate_Subexpr on expressions that are
      --  attached to New_Assoc_List. For this reason we need to attach it
      --  to the tree by setting its parent pointer to N. This parent point
      --  will change in STEP 8 below.

      Set_Parent (New_Assoc_List, N);

      --  STEP 1: abstract type and null record verification

      if Is_Abstract_Type (Typ) then
         Error_Msg_N ("type of aggregate cannot be abstract",  N);
      end if;

      if No (First_Entity (Typ)) and then Null_Record_Present (N) then
         Set_Etype (N, Typ);
         return;

      elsif Present (First_Entity (Typ))
        and then Null_Record_Present (N)
        and then not Is_Tagged_Type (Typ)
      then
         Error_Msg_N ("record aggregate cannot be null", N);
         return;

      --  If the type has no components, then the aggregate should either
      --  have "null record", or in Ada 2005 it could instead have a single
      --  component association given by "others => <>". For Ada 95 we flag an
      --  error at this point, but for Ada 2005 we proceed with checking the
      --  associations below, which will catch the case where it's not an
      --  aggregate with "others => <>". Note that the legality of a <>
      --  aggregate for a null record type was established by AI05-016.

      elsif No (First_Entity (Typ))
         and then Ada_Version < Ada_2005
      then
         Error_Msg_N ("record aggregate must be null", N);
         return;
      end if;

      --  STEP 2: Verify aggregate structure

      Step_2 : declare
         Assoc         : Node_Id;
         Bad_Aggregate : Boolean := False;
         Selector_Name : Node_Id;

      begin
         if Present (Component_Associations (N)) then
            Assoc := First (Component_Associations (N));
         else
            Assoc := Empty;
         end if;

         while Present (Assoc) loop
            Selector_Name := First (Choices (Assoc));
            while Present (Selector_Name) loop
               if Nkind (Selector_Name) = N_Identifier then
                  null;

               elsif Nkind (Selector_Name) = N_Others_Choice then
                  if Selector_Name /= First (Choices (Assoc))
                    or else Present (Next (Selector_Name))
                  then
                     Error_Msg_N
                       ("OTHERS must appear alone in a choice list",
                        Selector_Name);
                     return;

                  elsif Present (Next (Assoc)) then
                     Error_Msg_N
                       ("OTHERS must appear last in an aggregate",
                        Selector_Name);
                     return;

                  --  (Ada 2005): If this is an association with a box,
                  --  indicate that the association need not represent
                  --  any component.

                  elsif Box_Present (Assoc) then
                     Others_Box := 1;
                     Box_Node   := Assoc;
                  end if;

               else
                  Error_Msg_N
                    ("selector name should be identifier or OTHERS",
                     Selector_Name);
                  Bad_Aggregate := True;
               end if;

               Next (Selector_Name);
            end loop;

            Next (Assoc);
         end loop;

         if Bad_Aggregate then
            return;
         end if;
      end Step_2;

      --  STEP 3: Find discriminant Values

      Step_3 : declare
         Discrim               : Entity_Id;
         Missing_Discriminants : Boolean := False;

      begin
         if Present (Expressions (N)) then
            Positional_Expr := First (Expressions (N));
         else
            Positional_Expr := Empty;
         end if;

         --  AI05-0115: if the ancestor part is a subtype mark, the ancestor
         --  must not have unknown discriminants.
         --  ??? We are not checking any subtype mark here and this code is not
         --  exercised by any test, so it's likely wrong (in particular
         --  we should not use Root_Type here but the subtype mark, if any),
         --  and possibly not needed.

         if Is_Derived_Type (Typ)
           and then Has_Unknown_Discriminants (Root_Type (Typ))
           and then Nkind (N) /= N_Extension_Aggregate
         then
            Error_Msg_NE
              ("aggregate not available for type& whose ancestor "
               & "has unknown discriminants", N, Typ);
         end if;

         if Has_Unknown_Discriminants (Typ)
           and then Present (Underlying_Record_View (Typ))
         then
            Discrim := First_Discriminant (Underlying_Record_View (Typ));
         elsif Has_Discriminants (Typ) then
            Discrim := First_Discriminant (Typ);
         else
            Discrim := Empty;
         end if;

         --  First find the discriminant values in the positional components

         while Present (Discrim) and then Present (Positional_Expr) loop
            if Discriminant_Present (Discrim) then
               Resolve_Aggr_Expr (Positional_Expr, Discrim);

               --  Ada 2005 (AI-231)

               if Ada_Version >= Ada_2005
                 and then Known_Null (Positional_Expr)
               then
                  Check_Can_Never_Be_Null (Discrim, Positional_Expr);
               end if;

               Next (Positional_Expr);
            end if;

            if Present (Get_Value (Discrim, Component_Associations (N))) then
               Error_Msg_NE
                 ("more than one value supplied for discriminant&",
                  N, Discrim);
            end if;

            Next_Discriminant (Discrim);
         end loop;

         --  Find remaining discriminant values if any among named components

         while Present (Discrim) loop
            Expr := Get_Value (Discrim, Component_Associations (N), True);

            if not Discriminant_Present (Discrim) then
               if Present (Expr) then
                  Error_Msg_NE
                    ("more than one value supplied for discriminant &",
                     N, Discrim);
               end if;

            elsif No (Expr) then
               Error_Msg_NE
                 ("no value supplied for discriminant &", N, Discrim);
               Missing_Discriminants := True;

            else
               Resolve_Aggr_Expr (Expr, Discrim);
            end if;

            Next_Discriminant (Discrim);
         end loop;

         if Missing_Discriminants then
            return;
         end if;

         --  At this point and until the beginning of STEP 6, New_Assoc_List
         --  contains only the discriminants and their values.

      end Step_3;

      --  STEP 4: Set the Etype of the record aggregate

      if Has_Discriminants (Typ)
        or else (Has_Unknown_Discriminants (Typ)
                  and then Present (Underlying_Record_View (Typ)))
      then
         Build_Constrained_Itype (N, Typ, New_Assoc_List);
      else
         Set_Etype (N, Typ);
      end if;

      --  STEP 5: Get remaining components according to discriminant values

      Step_5 : declare
         Dnode           : Node_Id;
         Errors_Found    : Boolean := False;
         Record_Def      : Node_Id;
         Parent_Typ      : Entity_Id;
         Parent_Typ_List : Elist_Id;
         Parent_Elmt     : Elmt_Id;
         Root_Typ        : Entity_Id;

      begin
         if Is_Derived_Type (Typ) and then Is_Tagged_Type (Typ) then
            Parent_Typ_List := New_Elmt_List;

            --  If this is an extension aggregate, the component list must
            --  include all components that are not in the given ancestor type.
            --  Otherwise, the component list must include components of all
            --  ancestors, starting with the root.

            if Nkind (N) = N_Extension_Aggregate then
               Root_Typ := Base_Type (Etype (Ancestor_Part (N)));

            else
               --  AI05-0115: check legality of aggregate for type with a
               --  private ancestor.

               Root_Typ := Root_Type (Typ);
               if Has_Private_Ancestor (Typ) then
                  declare
                     Ancestor      : constant Entity_Id :=
                                       Find_Private_Ancestor (Typ);
                     Ancestor_Unit : constant Entity_Id :=
                                       Cunit_Entity
                                         (Get_Source_Unit (Ancestor));
                     Parent_Unit   : constant Entity_Id :=
                                       Cunit_Entity (Get_Source_Unit
                                         (Base_Type (Etype (Ancestor))));
                  begin
                     --  Check whether we are in a scope that has full view
                     --  over the private ancestor and its parent. This can
                     --  only happen if the derivation takes place in a child
                     --  unit of the unit that declares the parent, and we are
                     --  in the private part or body of that child unit, else
                     --  the aggregate is illegal.

                     if Is_Child_Unit (Ancestor_Unit)
                       and then Scope (Ancestor_Unit) = Parent_Unit
                       and then In_Open_Scopes (Scope (Ancestor))
                       and then
                        (In_Private_Part (Scope (Ancestor))
                          or else In_Package_Body (Scope (Ancestor)))
                     then
                        null;

                     else
                        Error_Msg_NE
                          ("type of aggregate has private ancestor&!",
                           N, Root_Typ);
                        Error_Msg_N ("must use extension aggregate!", N);
                        return;
                     end if;
                  end;
               end if;

               Dnode := Declaration_Node (Base_Type (Root_Typ));

               --  If we don't get a full declaration, then we have some error
               --  which will get signalled later so skip this part. Otherwise
               --  gather components of root that apply to the aggregate type.
               --  We use the base type in case there is an applicable stored
               --  constraint that renames the discriminants of the root.

               if Nkind (Dnode) = N_Full_Type_Declaration then
                  Record_Def := Type_Definition (Dnode);
                  Gather_Components
                    (Base_Type (Typ),
                     Component_List (Record_Def),
                     Governed_By   => New_Assoc_List,
                     Into          => Components,
                     Report_Errors => Errors_Found);

                  if Errors_Found then
                     Error_Msg_N
                       ("discriminant controlling variant part is not static",
                        N);
                     return;
                  end if;
               end if;
            end if;

            Parent_Typ := Base_Type (Typ);
            while Parent_Typ /= Root_Typ loop
               Prepend_Elmt (Parent_Typ, To => Parent_Typ_List);
               Parent_Typ := Etype (Parent_Typ);

               --  Check whether a private parent requires the use of
               --  an extension aggregate. This test does not apply in
               --  an instantiation: if the generic unit is legal so is
               --  the instance.

               if Nkind (Parent (Base_Type (Parent_Typ))) =
                                        N_Private_Type_Declaration
                 or else Nkind (Parent (Base_Type (Parent_Typ))) =
                                        N_Private_Extension_Declaration
               then
                  if Nkind (N) /= N_Extension_Aggregate
                    and then not In_Instance
                  then
                     Error_Msg_NE
                       ("type of aggregate has private ancestor&!",
                        N, Parent_Typ);
                     Error_Msg_N  ("must use extension aggregate!", N);
                     return;

                  elsif Parent_Typ /= Root_Typ then
                     Error_Msg_NE
                       ("ancestor part of aggregate must be private type&",
                         Ancestor_Part (N), Parent_Typ);
                     return;
                  end if;

               --  The current view of ancestor part may be a private type,
               --  while the context type is always non-private.

               elsif Is_Private_Type (Root_Typ)
                 and then Present (Full_View (Root_Typ))
                 and then Nkind (N) = N_Extension_Aggregate
               then
                  exit when Base_Type (Full_View (Root_Typ)) = Parent_Typ;
               end if;
            end loop;

            --  Now collect components from all other ancestors, beginning
            --  with the current type. If the type has unknown discriminants
            --  use the component list of the Underlying_Record_View, which
            --  needs to be used for the subsequent expansion of the aggregate
            --  into assignments.

            Parent_Elmt := First_Elmt (Parent_Typ_List);
            while Present (Parent_Elmt) loop
               Parent_Typ := Node (Parent_Elmt);

               if Has_Unknown_Discriminants (Parent_Typ)
                 and then Present (Underlying_Record_View (Typ))
               then
                  Parent_Typ := Underlying_Record_View (Parent_Typ);
               end if;

               Record_Def := Type_Definition (Parent (Base_Type (Parent_Typ)));
               Gather_Components (Empty,
                 Component_List (Record_Extension_Part (Record_Def)),
                 Governed_By   => New_Assoc_List,
                 Into          => Components,
                 Report_Errors => Errors_Found);

               Next_Elmt (Parent_Elmt);
            end loop;

         --  Typ is not a derived tagged type

         else
            Record_Def := Type_Definition (Parent (Base_Type (Typ)));

            if Null_Present (Record_Def) then
               null;

            elsif not Has_Unknown_Discriminants (Typ) then
               Gather_Components
                 (Base_Type (Typ),
                  Component_List (Record_Def),
                  Governed_By   => New_Assoc_List,
                  Into          => Components,
                  Report_Errors => Errors_Found);

            else
               Gather_Components
                 (Base_Type (Underlying_Record_View (Typ)),
                  Component_List (Record_Def),
                  Governed_By   => New_Assoc_List,
                  Into          => Components,
                  Report_Errors => Errors_Found);
            end if;
         end if;

         if Errors_Found then
            return;
         end if;
      end Step_5;

      --  STEP 6: Find component Values

      Component := Empty;
      Component_Elmt := First_Elmt (Components);

      --  First scan the remaining positional associations in the aggregate.
      --  Remember that at this point Positional_Expr contains the current
      --  positional association if any is left after looking for discriminant
      --  values in step 3.

      while Present (Positional_Expr) and then Present (Component_Elmt) loop
         Component := Node (Component_Elmt);
         Resolve_Aggr_Expr (Positional_Expr, Component);

         --  Ada 2005 (AI-231)

         if Ada_Version >= Ada_2005 and then Known_Null (Positional_Expr) then
            Check_Can_Never_Be_Null (Component, Positional_Expr);
         end if;

         if Present (Get_Value (Component, Component_Associations (N))) then
            Error_Msg_NE
              ("more than one value supplied for component &", N, Component);
         end if;

         Next (Positional_Expr);
         Next_Elmt (Component_Elmt);
      end loop;

      if Present (Positional_Expr) then
         Error_Msg_N
           ("too many components for record aggregate", Positional_Expr);
      end if;

      --  Now scan for the named arguments of the aggregate

      while Present (Component_Elmt) loop
         Component := Node (Component_Elmt);
         Expr := Get_Value (Component, Component_Associations (N), True);

         --  Note: The previous call to Get_Value sets the value of the
         --  variable Is_Box_Present.

         --  Ada 2005 (AI-287): Handle components with default initialization.
         --  Note: This feature was originally added to Ada 2005 for limited
         --  but it was finally allowed with any type.

         if Is_Box_Present then
            Check_Box_Component : declare
               Ctyp : constant Entity_Id := Etype (Component);

            begin
               --  Initially assume that the box is for a default-initialized
               --  component and reset to False in cases where that's not true.

               Is_Box_Init_By_Default := True;

               --  If there is a default expression for the aggregate, copy
               --  it into a new association. This copy must modify the scopes
               --  of internal types that may be attached to the expression
               --  (e.g. index subtypes of arrays) because in general the type
               --  declaration and the aggregate appear in different scopes,
               --  and the backend requires the scope of the type to match the
               --  point at which it is elaborated.

               --  If the component has an initialization procedure (IP) we
               --  pass the component to the expander, which will generate
               --  the call to such IP.

               --  If the component has discriminants, their values must
               --  be taken from their subtype. This is indispensable for
               --  constraints that are given by the current instance of an
               --  enclosing type, to allow the expansion of the aggregate to
               --  replace the reference to the current instance by the target
               --  object of the aggregate.

               if Is_Case_Choice_Pattern (N) then

                  --  Do not transform box component values in a case-choice
                  --  aggregate.

                  Add_Association
                   (Component      => Component,
                    Expr           => Empty,
                    Assoc_List     => New_Assoc_List,
                    Is_Box_Present => True);

               elsif Present (Parent (Component))
                 and then Nkind (Parent (Component)) = N_Component_Declaration
                 and then Present (Expression (Parent (Component)))
               then
                  --  If component declaration has an initialization expression
                  --  then this is not a case of default initialization.

                  Is_Box_Init_By_Default := False;

                  Expr :=
                    New_Copy_Tree_And_Copy_Dimensions
                      (Expression (Parent (Component)),
                       New_Scope => Current_Scope,
                       New_Sloc  => Sloc (N));

                  --  As the type of the copied default expression may refer
                  --  to discriminants of the record type declaration, these
                  --  non-stored discriminants need to be rewritten into stored
                  --  discriminant values for the aggregate. This is required
                  --  in GNATprove mode, and is adopted in all modes to avoid
                  --  special-casing GNATprove mode.

                  if Is_Array_Type (Etype (Expr)) then
                     declare
                        Rec_Typ : constant Entity_Id := Scope (Component);
                        --  Root record type whose discriminants may be used as
                        --  bounds in range nodes.

                        Assoc  : Node_Id;
                        Choice : Node_Id;
                        Index  : Node_Id;

                     begin
                        --  Rewrite the range nodes occurring in the indexes
                        --  and their types.

                        Index := First_Index (Etype (Expr));
                        while Present (Index) loop
                           Rewrite_Range (Rec_Typ, Index);
                           Rewrite_Range
                             (Rec_Typ, Scalar_Range (Etype (Index)));

                           Next_Index (Index);
                        end loop;

                        --  Rewrite the range nodes occurring as aggregate
                        --  bounds and component associations.

                        if Nkind (Expr) = N_Aggregate then
                           if Present (Aggregate_Bounds (Expr)) then
                              Rewrite_Range (Rec_Typ, Aggregate_Bounds (Expr));
                           end if;

                           if Present (Component_Associations (Expr)) then
                              Assoc := First (Component_Associations (Expr));
                              while Present (Assoc) loop
                                 Choice := First (Choices (Assoc));
                                 while Present (Choice) loop
                                    Rewrite_Range (Rec_Typ, Choice);

                                    Next (Choice);
                                 end loop;

                                 Next (Assoc);
                              end loop;
                           end if;
                        end if;
                     end;
                  end if;

                  Add_Association
                    (Component  => Component,
                     Expr       => Expr,
                     Assoc_List => New_Assoc_List);
                  Set_Has_Self_Reference (N);

               elsif Needs_Simple_Initialization (Ctyp) then
                  Add_Association
                    (Component      => Component,
                     Expr           => Empty,
                     Assoc_List     => New_Assoc_List,
                     Is_Box_Present => True);

               elsif Has_Non_Null_Base_Init_Proc (Ctyp)
                 or else not Expander_Active
               then
                  if Is_Record_Type (Ctyp)
                    and then Has_Discriminants (Ctyp)
                    and then not Is_Private_Type (Ctyp)
                  then
                     --  We build a partially initialized aggregate with the
                     --  values of the discriminants and box initialization
                     --  for the rest, if other components are present.

                     --  The type of the aggregate is the known subtype of
                     --  the component. The capture of discriminants must be
                     --  recursive because subcomponents may be constrained
                     --  (transitively) by discriminants of enclosing types.
                     --  For a private type with discriminants, a call to the
                     --  initialization procedure will be generated, and no
                     --  subaggregate is needed.

                     Capture_Discriminants : declare
                        Loc  : constant Source_Ptr := Sloc (N);
                        Expr : Node_Id;

                     begin
                        Expr := Make_Aggregate (Loc, No_List, New_List);
                        Set_Etype (Expr, Ctyp);

                        --  If the enclosing type has discriminants, they have
                        --  been collected in the aggregate earlier, and they
                        --  may appear as constraints of subcomponents.

                        --  Similarly if this component has discriminants, they
                        --  might in turn be propagated to their components.

                        if Has_Discriminants (Typ) then
                           Add_Discriminant_Values (Expr, New_Assoc_List);
                           Propagate_Discriminants (Expr, New_Assoc_List);

                        elsif Has_Discriminants (Ctyp) then
                           Add_Discriminant_Values
                             (Expr, Component_Associations (Expr));
                           Propagate_Discriminants
                             (Expr, Component_Associations (Expr));

                           Build_Constrained_Itype
                             (Expr, Ctyp, Component_Associations (Expr));

                        else
                           declare
                              Comp : Entity_Id;

                           begin
                              --  If the type has additional components, create
                              --  an OTHERS box association for them.

                              Comp := First_Component (Ctyp);
                              while Present (Comp) loop
                                 if Ekind (Comp) = E_Component then
                                    if not Is_Record_Type (Etype (Comp)) then
                                       Append_To
                                         (Component_Associations (Expr),
                                          Make_Component_Association (Loc,
                                            Choices     =>
                                              New_List (
                                                Make_Others_Choice (Loc)),
                                            Expression  => Empty,
                                            Box_Present => True));
                                    end if;

                                    exit;
                                 end if;

                                 Next_Component (Comp);
                              end loop;
                           end;
                        end if;

                        Add_Association
                          (Component  => Component,
                           Expr       => Expr,
                           Assoc_List => New_Assoc_List);
                     end Capture_Discriminants;

                  --  Otherwise the component type is not a record, or it has
                  --  not discriminants, or it is private.

                  else
                     Add_Association
                       (Component      => Component,
                        Expr           => Empty,
                        Assoc_List     => New_Assoc_List,
                        Is_Box_Present => True);
                  end if;

               --  Otherwise we only need to resolve the expression if the
               --  component has partially initialized values (required to
               --  expand the corresponding assignments and run-time checks).

               elsif Present (Expr)
                 and then Is_Partially_Initialized_Type (Ctyp)
               then
                  Resolve_Aggr_Expr (Expr, Component);
               end if;
            end Check_Box_Component;

         elsif No (Expr) then

            --  Ignore hidden components associated with the position of the
            --  interface tags: these are initialized dynamically.

            if not Present (Related_Type (Component)) then
               Error_Msg_NE
                 ("no value supplied for component &!", N, Component);
            end if;

         else
            Resolve_Aggr_Expr (Expr, Component);
         end if;

         Next_Elmt (Component_Elmt);
      end loop;

      --  STEP 7: check for invalid components + check type in choice list

      Step_7 : declare
         Assoc     : Node_Id;
         New_Assoc : Node_Id;

         Selectr : Node_Id;
         --  Selector name

         Typech : Entity_Id;
         --  Type of first component in choice list

      begin
         if Present (Component_Associations (N)) then
            Assoc := First (Component_Associations (N));
         else
            Assoc := Empty;
         end if;

         Verification : while Present (Assoc) loop
            Selectr := First (Choices (Assoc));
            Typech := Empty;

            if Nkind (Selectr) = N_Others_Choice then

               --  Ada 2005 (AI-287): others choice may have expression or box

               if No (Others_Etype) and then Others_Box = 0 then
                  Error_Msg_N
                    ("OTHERS must represent at least one component", Selectr);

               elsif Others_Box = 1 and then Warn_On_Redundant_Constructs then
                  Error_Msg_N ("OTHERS choice is redundant?", Box_Node);
                  Error_Msg_N
                    ("\previous choices cover all components?", Box_Node);
               end if;

               exit Verification;
            end if;

            while Present (Selectr) loop
               New_Assoc := First (New_Assoc_List);
               while Present (New_Assoc) loop
                  Component := First (Choices (New_Assoc));

                  if Chars (Selectr) = Chars (Component) then
                     if Style_Check then
                        Check_Identifier (Selectr, Entity (Component));
                     end if;

                     exit;
                  end if;

                  Next (New_Assoc);
               end loop;

               --  If no association, this is not a legal component of the type
               --  in question, unless its association is provided with a box.

               if No (New_Assoc) then
                  if Box_Present (Parent (Selectr)) then

                     --  This may still be a bogus component with a box. Scan
                     --  list of components to verify that a component with
                     --  that name exists.

                     declare
                        C : Entity_Id;

                     begin
                        C := First_Component (Typ);
                        while Present (C) loop
                           if Chars (C) = Chars (Selectr) then

                              --  If the context is an extension aggregate,
                              --  the component must not be inherited from
                              --  the ancestor part of the aggregate.

                              if Nkind (N) /= N_Extension_Aggregate
                                or else
                                  Scope (Original_Record_Component (C)) /=
                                    Etype (Ancestor_Part (N))
                              then
                                 exit;
                              end if;
                           end if;

                           Next_Component (C);
                        end loop;

                        if No (C) then
                           Error_Msg_Node_2 := Typ;
                           Error_Msg_N ("& is not a component of}", Selectr);
                        end if;
                     end;

                  elsif Chars (Selectr) /= Name_uTag
                    and then Chars (Selectr) /= Name_uParent
                  then
                     if not Has_Discriminants (Typ) then
                        Error_Msg_Node_2 := Typ;
                        Error_Msg_N ("& is not a component of}", Selectr);
                     else
                        Error_Msg_N
                          ("& is not a component of the aggregate subtype",
                            Selectr);
                     end if;

                     Check_Misspelled_Component (Components, Selectr);
                  end if;

               elsif No (Typech) then
                  Typech := Base_Type (Etype (Component));

               --  AI05-0199: In Ada 2012, several components of anonymous
               --  access types can appear in a choice list, as long as the
               --  designated types match.

               elsif Typech /= Base_Type (Etype (Component)) then
                  if Ada_Version >= Ada_2012
                    and then Ekind (Typech) = E_Anonymous_Access_Type
                    and then
                       Ekind (Etype (Component)) = E_Anonymous_Access_Type
                    and then Base_Type (Designated_Type (Typech)) =
                             Base_Type (Designated_Type (Etype (Component)))
                    and then
                      Subtypes_Statically_Match (Typech, (Etype (Component)))
                  then
                     null;

                  elsif not Box_Present (Parent (Selectr)) then
                     Error_Msg_N
                       ("components in choice list must have same type",
                        Selectr);
                  end if;
               end if;

               Next (Selectr);
            end loop;

            Next (Assoc);
         end loop Verification;
      end Step_7;

      --  STEP 8: replace the original aggregate

      Step_8 : declare
         New_Aggregate : constant Node_Id := New_Copy (N);

      begin
         Set_Expressions            (New_Aggregate, No_List);
         Set_Etype                  (New_Aggregate, Etype (N));
         Set_Component_Associations (New_Aggregate, New_Assoc_List);
         Set_Check_Actuals          (New_Aggregate, Check_Actuals (N));

         Rewrite (N, New_Aggregate);
      end Step_8;

      --  Check the dimensions of the components in the record aggregate

      Analyze_Dimension_Extension_Or_Record_Aggregate (N);
   end Resolve_Record_Aggregate;

   -----------------------------
   -- Check_Can_Never_Be_Null --
   -----------------------------

   procedure Check_Can_Never_Be_Null (Typ : Entity_Id; Expr : Node_Id) is
      Comp_Typ : Entity_Id;

   begin
      pragma Assert
        (Ada_Version >= Ada_2005
          and then Present (Expr)
          and then Known_Null (Expr));

      case Ekind (Typ) is
         when E_Array_Type  =>
            Comp_Typ := Component_Type (Typ);

         when E_Component
            | E_Discriminant
         =>
            Comp_Typ := Etype (Typ);

         when others =>
            return;
      end case;

      if Can_Never_Be_Null (Comp_Typ) then

         --  Here we know we have a constraint error. Note that we do not use
         --  Apply_Compile_Time_Constraint_Error here to the Expr, which might
         --  seem the more natural approach. That's because in some cases the
         --  components are rewritten, and the replacement would be missed.
         --  We do not mark the whole aggregate as raising a constraint error,
         --  because the association may be a null array range.

         Error_Msg_N
           ("(Ada 2005) NULL not allowed in null-excluding component??", Expr);
         Error_Msg_N
           ("\Constraint_Error will be raised at run time??", Expr);

         Rewrite (Expr,
           Make_Raise_Constraint_Error
             (Sloc (Expr), Reason => CE_Access_Check_Failed));
         Set_Etype    (Expr, Comp_Typ);
         Set_Analyzed (Expr);
      end if;
   end Check_Can_Never_Be_Null;

   ---------------------
   -- Sort_Case_Table --
   ---------------------

   procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
      U : constant Int := Case_Table'Last;
      K : Int;
      J : Int;
      T : Case_Bounds;

   begin
      K := 1;
      while K < U loop
         T := Case_Table (K + 1);

         J := K + 1;
         while J > 1
           and then Expr_Value (Case_Table (J - 1).Lo) > Expr_Value (T.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;

end Sem_Aggr;
