------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              E X P _ C H 3                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2026, 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 Accessibility;  use Accessibility;
with Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
with Contracts;      use Contracts;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Exp_Aggr;       use Exp_Aggr;
with Exp_Atag;       use Exp_Atag;
with Exp_Ch4;        use Exp_Ch4;
with Exp_Ch6;        use Exp_Ch6;
with Exp_Ch7;        use Exp_Ch7;
with Exp_Ch9;        use Exp_Ch9;
with Exp_Disp;       use Exp_Disp;
with Exp_Dist;       use Exp_Dist;
with Exp_Put_Image;
with Exp_Smem;       use Exp_Smem;
with Exp_Strm;       use Exp_Strm;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Ghost;          use Ghost;
with Lib;            use Lib;
with Mutably_Tagged; use Mutably_Tagged;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Attr;       use Sem_Attr;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Disp;       use Sem_Disp;
with Sem_Eval;       use Sem_Eval;
with Sem_Mech;       use Sem_Mech;
with Sem_Res;        use Sem_Res;
with Sem_SCIL;       use Sem_SCIL;
with Sem_Type;       use Sem_Type;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Stand;          use Stand;
with Snames;         use Snames;
with Ttypes;         use Ttypes;
with Validsw;        use Validsw;
with Warnsw;         use Warnsw;

package body Exp_Ch3 is

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

   procedure Adjust_Discriminants (Rtype : Entity_Id);
   --  This is used when freezing a record type. It attempts to construct
   --  more restrictive subtypes for discriminants so that the max size of
   --  the record can be calculated more accurately. See the body of this
   --  procedure for details.

   procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id);
   --  Build initialization procedure for given array type. Nod is a node
   --  used for attachment of any actions required in its construction.
   --  It also supplies the source location used for the procedure.

   procedure Build_Implicit_Copy_Constructor (N : Node_Id; Typ : Entity_Id);
   --  Build default copy constructor. N is the type declaration node, and Typ
   --  is the corresponding entity for the record type.

   function Build_Discriminant_Formals
     (Rec_Id : Entity_Id;
      Use_Dl : Boolean) return List_Id;
   --  This function uses the discriminants of a type to build a list of
   --  formal parameters, used in Build_Init_Procedure among other places.
   --  If the flag Use_Dl is set, the list is built using the already
   --  defined discriminals of the type, as is the case for concurrent
   --  types with discriminants. Otherwise new identifiers are created,
   --  with the source names of the discriminants.

   procedure Build_Discr_Checking_Funcs (N : Node_Id);
   --  For each variant component, builds a function which checks whether
   --  the component name is consistent with the current discriminants
   --  and sets the component's Dcheck_Function attribute to refer to it.
   --  N is the full type declaration node; the discriminant checking
   --  functions are inserted after this node.

   function Build_Equivalent_Array_Aggregate (T : Entity_Id) return Node_Id;
   --  This function builds a static aggregate that can serve as the initial
   --  value for an array type whose bounds are static, and whose component
   --  type is a composite type that has a static equivalent aggregate.
   --  The equivalent array aggregate is used both for object initialization
   --  and for component initialization, when used in the following function.

   function Build_Equivalent_Record_Aggregate (T : Entity_Id) return Node_Id;
   --  This function builds a static aggregate that can serve as the initial
   --  value for a record type whose components are scalar and initialized
   --  with compile-time values, or arrays with similar initialization or
   --  defaults. When possible, initialization of an object of the type can
   --  be achieved by using a copy of the aggregate as an initial value, thus
   --  removing the implicit call that would otherwise constitute elaboration
   --  code.

   procedure Build_Record_Init_Proc (N : Node_Id; Rec_Ent : Entity_Id);
   --  Build record initialization procedure. N is the type declaration
   --  node, and Rec_Ent is the corresponding entity for the record type.

   procedure Build_Slice_Assignment (Typ : Entity_Id);
   --  Build assignment procedure for one-dimensional arrays of controlled
   --  types. Other array and slice assignments are expanded in-line, but
   --  the code expansion for controlled components (when control actions
   --  are active) can lead to very large blocks that GCC handles poorly.

   procedure Build_Untagged_Record_Equality (Typ : Entity_Id);
   --  AI05-0123: Equality on untagged records composes. This procedure
   --  builds the equality routine for an untagged record that has components
   --  of a record type that has user-defined primitive equality operations.
   --  The resulting operation is a TSS subprogram.

   procedure Check_Stream_Attributes (Typ : Entity_Id);
   --  Check that if a limited extension has a parent with user-defined stream
   --  attributes, and does not itself have user-defined stream-attributes,
   --  then any limited component of the extension also has the corresponding
   --  user-defined stream attributes.

   procedure Clean_Task_Names
     (Typ     : Entity_Id;
      Proc_Id : Entity_Id);
   --  If an initialization procedure includes calls to generate names
   --  for task subcomponents, indicate that secondary stack cleanup is
   --  needed after an initialization. Typ is the component type, and Proc_Id
   --  the initialization procedure for the enclosing composite type.

   procedure Copy_Discr_Checking_Funcs (N : Node_Id);
   --  For a derived untagged type, copy the attributes that were set
   --  for the components of the parent type onto the components of the
   --  derived type. No new subprograms are constructed.
   --  N is the full type declaration node, as for Build_Discr_Checking_Funcs.

   procedure Expand_Freeze_Array_Type (N : Node_Id);
   --  Freeze an array type. Deals with building the initialization procedure,
   --  creating the packed array type for a packed array and also with the
   --  creation of the controlling procedures for the controlled case. The
   --  argument N is the N_Freeze_Entity node for the type.

   procedure Expand_Freeze_Class_Wide_Type (N : Node_Id);
   --  Freeze a class-wide type. Build routine Finalize_Address for the purpose
   --  of finalizing controlled derivations from the class-wide's root type.

   procedure Expand_Freeze_Enumeration_Type (N : Node_Id);
   --  Freeze enumeration type with non-standard representation. Builds the
   --  array and function needed to convert between enumeration pos and
   --  enumeration representation values. N is the N_Freeze_Entity node
   --  for the type.

   procedure Expand_Freeze_Record_Type (N : Node_Id);
   --  Freeze record type. Builds all necessary discriminant checking
   --  and other ancillary functions, and builds dispatch tables where
   --  needed. The argument N is the N_Freeze_Entity node. This processing
   --  applies only to E_Record_Type entities, not to class wide types,
   --  record subtypes, or private types.

   procedure Expand_Tagged_Root (T : Entity_Id);
   --  Add a field _Tag at the beginning of the record. This field carries
   --  the value of the access to the Dispatch table. This procedure is only
   --  called on root type, the _Tag field being inherited by the descendants.

   procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id);
   --  Treat user-defined stream operations as renaming_as_body if the
   --  subprogram they rename is not frozen when the type is frozen.

   package Initialization_Control is

      function Requires_Late_Init
        (Decl : Node_Id; Rec_Type : Entity_Id) return Boolean;
      --  Return True iff the given component declaration requires late
      --  initialization, as defined by 3.3.1 (8.1/5).

      function Has_Late_Init_Component
        (Tagged_Rec_Type : Entity_Id) return Boolean;
      --  Return True iff the given tagged record type has at least one
      --  component that requires late initialization; this includes
      --  components of ancestor types.

      function Tag_Init_Condition
        (Loc : Source_Ptr;
         Init_Control_Formal : Entity_Id) return Node_Id;
      function Early_Init_Condition
        (Loc : Source_Ptr;
         Init_Control_Formal : Entity_Id) return Node_Id;
      function Late_Init_Condition
        (Loc : Source_Ptr;
         Init_Control_Formal : Entity_Id) return Node_Id;
      --  These three functions each return a Boolean expression that
      --  can be used to determine whether a given call to the initialization
      --  expression for a tagged type should initialize (respectively)
      --  the Tag component, the non-Tag components that do not require late
      --  initialization, and the components that do require late
      --  initialization.

   end Initialization_Control;

   procedure Initialization_Warning (E : Entity_Id);
   --  If static elaboration of the package is requested, indicate
   --  when a type does meet the conditions for static initialization. If
   --  E is a type, it has components that have no static initialization.
   --  if E is an entity, its initial expression is not compile-time known.

   function Init_Formals (Typ : Entity_Id; Proc_Id : Entity_Id) return List_Id;
   --  This function builds the list of formals for an initialization routine.
   --  The first formal is always _Init with the given type. For task value
   --  record types and types containing tasks, three additional formals are
   --  added and Proc_Id is decorated with attribute Has_Master_Entity:
   --
   --    _Master    : Master_Id
   --    _Chain     : in out Activation_Chain
   --    _Task_Name : String
   --
   --  The caller must append additional entries for discriminants if required.

   function Inline_Init_Proc (Typ : Entity_Id) return Boolean;
   --  Returns true if the initialization procedure of Typ should be inlined

   function In_Runtime (E : Entity_Id) return Boolean;
   --  Check if E is defined in the RTL (in a child of Ada or System). Used
   --  to avoid to bring in the overhead of _Input, _Output for tagged types.

   function Is_Null_Statement_List (Stmts : List_Id) return Boolean;
   --  Returns true if Stmts is made of null statements only, possibly wrapped
   --  in a case statement, recursively. This latter pattern may occur for the
   --  initialization procedure of an unchecked union.

   function Make_Eq_Body
     (Typ     : Entity_Id;
      Eq_Name : Name_Id) return Node_Id;
   --  Build the body of a primitive equality operation for a tagged record
   --  type, or in Ada 2012 for any record type that has components with a
   --  user-defined equality. Factored out of Predefined_Primitive_Bodies.

   function Make_Eq_Case
     (E      : Entity_Id;
      CL     : Node_Id;
      Discrs : Elist_Id := New_Elmt_List) return List_Id;
   --  Building block for variant record equality. Defined to share the code
   --  between the tagged and untagged case. Given a Component_List node CL,
   --  it generates an 'if' followed by a 'case' statement that compares all
   --  components of local temporaries named X and Y (that are declared as
   --  formals at some upper level). E provides the Sloc to be used for the
   --  generated code.
   --
   --  IF E is an unchecked_union,  Discrs is the list of formals created for
   --  the inferred discriminants of one operand. These formals are used in
   --  the generated case statements for each variant of the unchecked union.

   function Make_Eq_If
     (E : Entity_Id;
      L : List_Id) return Node_Id;
   --  Building block for variant record equality. Defined to share the code
   --  between the tagged and untagged case. Given the list of components
   --  (or discriminants) L, it generates a return statement that compares all
   --  components of local temporaries named X and Y (that are declared as
   --  formals at some upper level). E provides the Sloc to be used for the
   --  generated code.

   function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id;
   --  Search for a renaming of the inequality dispatching primitive of
   --  this tagged type. If found then build and return the corresponding
   --  rename-as-body inequality subprogram; otherwise return Empty.

   procedure Make_Predefined_Primitive_Specs
     (Tag_Typ     : Entity_Id;
      Predef_List : out List_Id;
      Renamed_Eq  : out Entity_Id);
   --  Create a list with the specs of the predefined primitive operations.
   --  For tagged types that are interfaces all these primitives are defined
   --  abstract.
   --
   --  The following entries are present for all tagged types, and provide
   --  the results of the corresponding attribute applied to the object.
   --  Dispatching is required in general, since the result of the attribute
   --  will vary with the actual object subtype.
   --
   --     _size          provides result of 'Size attribute
   --     typSR          provides result of 'Read attribute
   --     typSW          provides result of 'Write attribute
   --     typSI          provides result of 'Input attribute
   --     typSO          provides result of 'Output attribute
   --     typPI          provides result of 'Put_Image attribute
   --
   --  The following entries implement additional dispatching operations for
   --  predefined operations. Deep finalization is present on all tagged types;
   --  the others only on nonlimited tagged types:
   --
   --     _equality      implements "=" operator
   --     _assign        implements assignment operation
   --     typDF          implements deep finalization
   --     typDA          implements deep adjust
   --
   --  The latter two are empty procedures unless the type contains some
   --  controlled components that require finalization actions (the deep
   --  in the name refers to the fact that the action applies to components).
   --
   --  The list of specs is returned in Predef_List

   function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean;
   --  Returns True if there are representation clauses for type T that are not
   --  inherited. If the result is false, the init_proc and the discriminant
   --  checking functions of the parent can be reused by a derived type.

   function Make_Null_Procedure_Specs (Tag_Typ : Entity_Id) return List_Id;
   --  Ada 2005 (AI-251): Makes specs for null procedures associated with any
   --  null procedures inherited from an interface type that have not been
   --  overridden. Only one null procedure will be created for a given set of
   --  inherited null procedures with homographic profiles.

   function Predef_Spec_Or_Body
     (Loc      : Source_Ptr;
      Tag_Typ  : Entity_Id;
      Name     : Name_Id;
      Profile  : List_Id;
      Ret_Type : Entity_Id := Empty;
      For_Body : Boolean   := False) return Node_Id;
   --  This function generates the appropriate expansion for a predefined
   --  primitive operation specified by its name, parameter profile and
   --  return type (Empty means this is a procedure). If For_Body is false,
   --  then the returned node is a subprogram declaration. If For_Body is
   --  true, then the returned node is a empty subprogram body containing
   --  no declarations and no statements.

   function Predef_Stream_Attr_Spec
     (Loc     : Source_Ptr;
      Tag_Typ : Entity_Id;
      Name    : TSS_Name_Type) return Node_Id;
   --  Specialized version of Predef_Spec_Or_Body that apply to read, write,
   --  input and output attribute whose specs are constructed in Exp_Strm.

   function Predef_Deep_Spec
     (Loc      : Source_Ptr;
      Tag_Typ  : Entity_Id;
      Name     : TSS_Name_Type;
      For_Body : Boolean := False) return Node_Id;
   --  Specialized version of Predef_Spec_Or_Body that apply to _deep_adjust
   --  and _deep_finalize

   function Predefined_Primitive_Bodies
     (Tag_Typ    : Entity_Id;
      Renamed_Eq : Entity_Id) return List_Id;
   --  Create the bodies of the predefined primitives that are described in
   --  Make_Predefined_Primitive_Specs. When not empty, Renamed_Eq must denote
   --  the defining unit name of the type's predefined equality as returned
   --  by Make_Predefined_Primitive_Specs.

   function Predefined_Primitive_Freeze (Tag_Typ : Entity_Id) return List_Id;
   --  Freeze entities of all predefined primitive operations. This is needed
   --  because the bodies of these operations do not normally do any freezing.

   function Constructor_Freeze (Typ : Entity_Id) return List_Id;
   --  Freeze all constructors of the type Tag_Typ. Otherwise, constructors
   --  would not be available at freeze point.

   --------------------------
   -- Adjust_Discriminants --
   --------------------------

   --  This procedure attempts to define subtypes for discriminants that are
   --  more restrictive than those declared. Such a replacement is possible if
   --  we can demonstrate that values outside the restricted range would cause
   --  constraint errors in any case. The advantage of restricting the
   --  discriminant types in this way is that the maximum size of the variant
   --  record can be calculated more conservatively.

   --  An example of a situation in which we can perform this type of
   --  restriction is the following:

   --    subtype B is range 1 .. 10;
   --    type Q is array (B range <>) of Integer;

   --    type V (N : Natural) is record
   --       C : Q (1 .. N);
   --    end record;

   --  In this situation, we can restrict the upper bound of N to 10, since
   --  any larger value would cause a constraint error in any case.

   --  There are many situations in which such restriction is possible, but
   --  for now, we just look for cases like the above, where the component
   --  in question is a one dimensional array whose upper bound is one of
   --  the record discriminants. Also the component must not be part of
   --  any variant part, since then the component does not always exist.

   procedure Adjust_Discriminants (Rtype : Entity_Id) is
      Loc   : constant Source_Ptr := Sloc (Rtype);
      Comp  : Entity_Id;
      Ctyp  : Entity_Id;
      Ityp  : Entity_Id;
      Lo    : Node_Id;
      Hi    : Node_Id;
      P     : Node_Id;
      Loval : Uint;
      Discr : Entity_Id;
      Dtyp  : Entity_Id;
      Dhi   : Node_Id;
      Dhiv  : Uint;
      Ahi   : Node_Id;
      Ahiv  : Uint;
      Tnn   : Entity_Id;

   begin
      Comp := First_Component (Rtype);
      while Present (Comp) loop

         --  If our parent is a variant, quit, we do not look at components
         --  that are in variant parts, because they may not always exist.

         P := Parent (Comp);   -- component declaration
         P := Parent (P);      -- component list

         exit when Nkind (Parent (P)) = N_Variant;

         --  We are looking for a one dimensional array type

         Ctyp := Etype (Comp);

         if not Is_Array_Type (Ctyp) or else Number_Dimensions (Ctyp) > 1 then
            goto Continue;
         end if;

         --  The lower bound must be constant, and the upper bound is a
         --  discriminant (which is a discriminant of the current record).

         Ityp := Etype (First_Index (Ctyp));
         Lo := Type_Low_Bound (Ityp);
         Hi := Type_High_Bound (Ityp);

         if not Compile_Time_Known_Value (Lo)
           or else Nkind (Hi) /= N_Identifier
           or else No (Entity (Hi))
           or else Ekind (Entity (Hi)) /= E_Discriminant
         then
            goto Continue;
         end if;

         --  We have an array with appropriate bounds

         Loval := Expr_Value (Lo);
         Discr := Entity (Hi);
         Dtyp  := Etype (Discr);

         --  See if the discriminant has a known upper bound

         Dhi := Type_High_Bound (Dtyp);

         if not Compile_Time_Known_Value (Dhi) then
            goto Continue;
         end if;

         Dhiv := Expr_Value (Dhi);

         --  See if base type of component array has known upper bound

         Ahi := Type_High_Bound (Etype (First_Index (Base_Type (Ctyp))));

         if not Compile_Time_Known_Value (Ahi) then
            goto Continue;
         end if;

         Ahiv := Expr_Value (Ahi);

         --  The condition for doing the restriction is that the high bound
         --  of the discriminant is greater than the low bound of the array,
         --  and is also greater than the high bound of the base type index.

         if Dhiv > Loval and then Dhiv > Ahiv then

            --  We can reset the upper bound of the discriminant type to
            --  whichever is larger, the low bound of the component, or
            --  the high bound of the base type array index.

            --  We build a subtype that is declared as

            --     subtype Tnn is discr_type range discr_type'First .. max;

            --  And insert this declaration into the tree. The type of the
            --  discriminant is then reset to this more restricted subtype.

            Tnn := Make_Temporary (Loc, 'T');

            Insert_Action (Declaration_Node (Rtype),
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => Tnn,
                Subtype_Indication =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark => New_Occurrence_Of (Dtyp, Loc),
                    Constraint   =>
                      Make_Range_Constraint (Loc,
                        Range_Expression =>
                          Make_Range (Loc,
                            Low_Bound =>
                              Make_Attribute_Reference (Loc,
                                Attribute_Name => Name_First,
                                Prefix => New_Occurrence_Of (Dtyp, Loc)),
                            High_Bound =>
                              Make_Integer_Literal (Loc,
                                Intval => UI_Max (Loval, Ahiv)))))));

            Set_Etype (Discr, Tnn);
         end if;

      <<Continue>>
         Next_Component (Comp);
      end loop;
   end Adjust_Discriminants;

   ------------------------------------------
   -- Build_Access_Subprogram_Wrapper_Body --
   ------------------------------------------

   procedure Build_Access_Subprogram_Wrapper_Body
     (Decl     : Node_Id;
      New_Decl : Node_Id)
   is
      Loc       : constant Source_Ptr := Sloc (Decl);
      Actuals   : constant List_Id    := New_List;
      Type_Def  : constant Node_Id    := Type_Definition (Decl);
      Type_Id   : constant Entity_Id  := Defining_Identifier (Decl);
      Spec_Node : constant Node_Id    :=
                    Copy_Subprogram_Spec (Specification (New_Decl));
      --  This copy creates new identifiers for formals and subprogram.

      Act       : Node_Id;
      Body_Node : Node_Id;
      Call_Stmt : Node_Id;
      Ptr       : Entity_Id;

   begin
      --  Create List of actuals for indirect call. The last parameter of the
      --  subprogram declaration is the access value for the indirect call.

      Act := First (Parameter_Specifications (Spec_Node));

      while Present (Act) loop
         exit when Act = Last (Parameter_Specifications (Spec_Node));
         Append_To (Actuals,
           Make_Identifier (Loc, Chars (Defining_Identifier (Act))));
         Next (Act);
      end loop;

      Ptr :=
        Defining_Identifier
          (Last (Parameter_Specifications (Specification (New_Decl))));

      if Nkind (Type_Def) = N_Access_Procedure_Definition then
         Call_Stmt := Make_Procedure_Call_Statement (Loc,
           Name =>
              Make_Explicit_Dereference
                (Loc, New_Occurrence_Of (Ptr, Loc)),
           Parameter_Associations => Actuals);
      else
         Call_Stmt := Make_Simple_Return_Statement (Loc,
           Expression =>
             Make_Function_Call (Loc,
           Name => Make_Explicit_Dereference
                    (Loc, New_Occurrence_Of (Ptr, Loc)),
           Parameter_Associations => Actuals));
      end if;

      Body_Node := Make_Subprogram_Body (Loc,
        Specification => Spec_Node,
        Declarations  => New_List,
        Handled_Statement_Sequence =>
          Make_Handled_Sequence_Of_Statements (Loc,
            Statements    => New_List (Call_Stmt)));

      --  Place body in list of freeze actions for the type.

      Append_Freeze_Action (Type_Id, Body_Node);
   end Build_Access_Subprogram_Wrapper_Body;

   ---------------------------
   -- Build_Array_Init_Proc --
   ---------------------------

   procedure Build_Array_Init_Proc (A_Type : Entity_Id; Nod : Node_Id) is
      --  Obtain the corresponding mutably tagged type's parent subtype to
      --  handle default initialization.

      Comp_Type : constant Entity_Id :=
        Get_Corresponding_Tagged_Type_If_Present (Component_Type (A_Type));

      Comp_Simple_Init : constant Boolean :=
        Needs_Simple_Initialization
          (Typ         => Comp_Type,
           Consider_IS =>
             not (Validity_Check_Copies and Is_Bit_Packed_Array (A_Type)));
      --  True if the component needs simple initialization, based on its type,
      --  plus the fact that we do not do simple initialization for components
      --  of bit-packed arrays when validity checks are enabled, because the
      --  initialization with deliberately out-of-range values would raise
      --  Constraint_Error.

      Body_Stmts       : List_Id;
      Has_Default_Init : Boolean;
      Index_List       : List_Id;
      Loc              : Source_Ptr;
      Parameters       : List_Id;
      Proc_Id          : Entity_Id;

      function Init_Component return List_Id;
      --  Create one statement to initialize one array component, designated
      --  by a full set of indexes.

      function Init_One_Dimension (N : Int) return List_Id;
      --  Create loop to initialize one dimension of the array. The single
      --  statement in the loop body initializes the inner dimensions if any,
      --  or else the single component. Note that this procedure is called
      --  recursively, with N being the dimension to be initialized. A call
      --  with N greater than the number of dimensions simply generates the
      --  component initialization, terminating the recursion.

      --------------------
      -- Init_Component --
      --------------------

      function Init_Component return List_Id is
         Comp   : Node_Id;
         Result : List_Id;

      begin
         Comp :=
           Make_Indexed_Component (Loc,
             Prefix      => Make_Identifier (Loc, Name_uInit),
             Expressions => Index_List);

         if Has_Default_Aspect (A_Type) then
            Set_Assignment_OK (Comp);
            Result := New_List (
              Make_Assignment_Statement (Loc,
                Name       => Comp,
                Expression =>
                  Convert_To (Comp_Type,
                    Default_Aspect_Component_Value (First_Subtype (A_Type)))));

         elsif Comp_Simple_Init then
            Set_Assignment_OK (Comp);
            Result := New_List (
              Make_Assignment_Statement (Loc,
                Name       => Comp,
                Expression =>
                  Get_Simple_Init_Val
                    (Typ  => Comp_Type,
                     N    => Nod,
                     Size => Component_Size (A_Type))));

         else
            Clean_Task_Names (Comp_Type, Proc_Id);
            Result :=
              Build_Initialization_Call
                (N            => Nod,
                 Id_Ref       => Comp,
                 Typ          => Comp_Type,
                 In_Init_Proc => True,
                 Enclos_Type  => A_Type);
         end if;

         --  Raise Program_Error in the init procedure of arrays when the type
         --  of their components is a mutably tagged abstract class-wide type.

         if Is_Class_Wide_Equivalent_Type (Component_Type (A_Type))
           and then Is_Abstract_Type (Comp_Type)
         then
            Append_To (Result,
              Make_Raise_Program_Error (Loc,
                Reason => PE_Abstract_Type_Component));
         end if;

         return Result;
      end Init_Component;

      ------------------------
      -- Init_One_Dimension --
      ------------------------

      function Init_One_Dimension (N : Int) return List_Id is
         Index       : Entity_Id;
         DIC_Call    : Node_Id;
         Result_List : List_Id;

         function Possible_DIC_Call return Node_Id;
         --  If the component type has Default_Initial_Conditions and a DIC
         --  procedure that is not an empty body, then builds a call to the
         --  DIC procedure and returns it.

         -----------------------
         -- Possible_DIC_Call --
         -----------------------

         function Possible_DIC_Call return Node_Id is
         begin
            --  When the component's type has a Default_Initial_Condition, then
            --  create a call for the DIC check.

            if Has_DIC (Comp_Type)
              --  In GNATprove mode, the component DICs are checked by other
              --  means. They should not be added to the record type DIC
              --  procedure, so that the procedure can be used to check the
              --  record type invariants or DICs if any.

              and then not GNATprove_Mode

              --  DIC checks for components of controlled types are done later
              --  (see Exp_Ch7.Make_Deep_Array_Body).

              and then not Is_Controlled (Comp_Type)

              and then Present (DIC_Procedure (Comp_Type))

              and then not Has_Null_Body (DIC_Procedure (Comp_Type))
            then
               return
                 Build_DIC_Call (Loc,
                   Make_Indexed_Component (Loc,
                     Prefix      => Make_Identifier (Loc, Name_uInit),
                     Expressions => Index_List),
                   Comp_Type);
            else
               return Empty;
            end if;
         end Possible_DIC_Call;

      --  Start of processing for Init_One_Dimension

      begin
         --  If the component does not need initializing, then there is nothing
         --  to do here, so we return a null body. This occurs when generating
         --  the dummy Init_Proc needed for Initialize_Scalars processing.
         --  An exception is if component type has a Default_Initial_Condition,
         --  in which case we generate a call to the type's DIC procedure.

         if not Has_Non_Null_Base_Init_Proc (Comp_Type)
           and then not Comp_Simple_Init
           and then not Has_Task (Comp_Type)
           and then not Has_Default_Aspect (A_Type)
           and then (not Has_DIC (Comp_Type)
                      or else N > Number_Dimensions (A_Type))
         then
            DIC_Call := Possible_DIC_Call;

            if Present (DIC_Call) then
               return New_List (DIC_Call);
            else
               return New_List (Make_Null_Statement (Loc));
            end if;

         --  If all dimensions dealt with, we simply initialize the component
         --  and append a call to component type's DIC procedure when needed.

         elsif N > Number_Dimensions (A_Type) then
            DIC_Call := Possible_DIC_Call;

            if Present (DIC_Call) then
               Result_List := Init_Component;
               Append (DIC_Call, Result_List);
               return Result_List;

            else
               return Init_Component;
            end if;

         --  Here we generate the required loop

         else
            Index :=
              Make_Defining_Identifier (Loc, New_External_Name ('J', N));

            Append (New_Occurrence_Of (Index, Loc), Index_List);

            return New_List (
              Make_Implicit_Loop_Statement (Nod,
                Identifier       => Empty,
                Iteration_Scheme =>
                  Make_Iteration_Scheme (Loc,
                    Loop_Parameter_Specification =>
                      Make_Loop_Parameter_Specification (Loc,
                        Defining_Identifier         => Index,
                        Discrete_Subtype_Definition =>
                          Make_Attribute_Reference (Loc,
                            Prefix          =>
                              Make_Identifier (Loc, Name_uInit),
                            Attribute_Name  => Name_Range,
                            Expressions     => New_List (
                              Make_Integer_Literal (Loc, N))))),
                Statements       => Init_One_Dimension (N + 1)));
         end if;
      end Init_One_Dimension;

   --  Start of processing for Build_Array_Init_Proc

   begin
      --  The init proc is created when analyzing the freeze node for the type,
      --  but it properly belongs with the array type declaration. However, if
      --  the freeze node is for a subtype of a type declared in another unit
      --  it seems preferable to use the freeze node as the source location of
      --  the init proc. In any case this is preferable for gcov usage, and
      --  the Sloc is not otherwise used by the compiler.

      if In_Open_Scopes (Scope (A_Type)) then
         Loc := Sloc (A_Type);
      else
         Loc := Sloc (Nod);
      end if;

      --  Nothing to generate in the following cases:

      --    1. Initialization is suppressed for the type
      --    2. An initialization already exists for the base type

      if Initialization_Suppressed (A_Type)
        or else Present (Base_Init_Proc (A_Type))
      then
         return;
      end if;

      Index_List := New_List;

      --  We need an initialization procedure if any of the following is true:

      --    1. The component type has an initialization procedure
      --    2. The component type needs simple initialization
      --    3. Tasks are present
      --    4. The type is marked as a public entity
      --    5. The array type has a Default_Component_Value aspect
      --    6. The array component type has a Default_Initialization_Condition

      --  The reason for the public entity test is to deal properly with the
      --  Initialize_Scalars pragma. This pragma can be set in the client and
      --  not in the declaring package, this means the client will make a call
      --  to the initialization procedure (because one of conditions 1-3 must
      --  apply in this case), and we must generate a procedure (even if it is
      --  null) to satisfy the call in this case.

      --  Exception: do not build an array init_proc for a type whose root
      --  type is Standard.String or Standard.Wide_[Wide_]String, since there
      --  is no place to put the code, and in any case we handle initialization
      --  of such types (in the Initialize_Scalars case, that's the only time
      --  the issue arises) in a special manner anyway which does not need an
      --  init_proc.

      Has_Default_Init := Has_Non_Null_Base_Init_Proc (Comp_Type)
                            or else Comp_Simple_Init
                            or else Has_Task (Comp_Type)
                            or else Has_Default_Aspect (A_Type)
                            or else Has_DIC (Comp_Type);

      if Has_Default_Init
        or else (not Restriction_Active (No_Initialize_Scalars)
                  and then Is_Public (A_Type)
                  and then not Is_Standard_String_Type (A_Type))
      then
         Proc_Id :=
           Make_Defining_Identifier (Loc,
             Chars => Make_Init_Proc_Name (A_Type));

         --  If No_Default_Initialization restriction is active, then we don't
         --  want to build an init_proc, but we need to mark that an init_proc
         --  would be needed if this restriction was not active (so that we can
         --  detect attempts to call it), so set a dummy init_proc in place.
         --  This is only done though when actual default initialization is
         --  needed (and not done when only Is_Public is True), since otherwise
         --  objects such as arrays of scalars could be wrongly flagged as
         --  violating the restriction.

         if Restriction_Active (No_Default_Initialization) then
            if Has_Default_Init then
               Set_Init_Proc (A_Type, Proc_Id);
            end if;

            return;
         end if;

         Body_Stmts := Init_One_Dimension (1);
         Parameters := Init_Formals (A_Type, Proc_Id);

         Discard_Node (
           Make_Subprogram_Body (Loc,
             Specification =>
               Make_Procedure_Specification (Loc,
                 Defining_Unit_Name => Proc_Id,
                 Parameter_Specifications => Parameters),
             Declarations => New_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Body_Stmts)));

         Mutate_Ekind         (Proc_Id, E_Procedure);
         Set_Is_Public        (Proc_Id, Is_Public (A_Type));
         Set_Is_Internal      (Proc_Id);
         Set_Has_Completion   (Proc_Id);
         Freeze_Extra_Formals (Proc_Id);

         if not Debug_Generated_Code then
            Set_Debug_Info_Off (Proc_Id);
         end if;

         --  Set Inlined on Init_Proc if it is set on the Init_Proc of the
         --  component type itself (see also Build_Record_Init_Proc).

         Set_Is_Inlined (Proc_Id, Inline_Init_Proc (Comp_Type));

         --  Associate Init_Proc with type, and determine if the procedure
         --  is null (happens because of the Initialize_Scalars pragma case,
         --  where we have to generate a null procedure in case it is called
         --  by a client with Initialize_Scalars set). Such procedures have
         --  to be generated, but do not have to be called, so we mark them
         --  as null to suppress the call. Kill also warnings for the _Init
         --  out parameter, which is left entirely uninitialized.

         Set_Init_Proc (A_Type, Proc_Id);

         if Is_Null_Statement_List (Body_Stmts) then
            Set_Is_Null_Init_Proc (Proc_Id);
            Set_Warnings_Off (Defining_Identifier (First (Parameters)));

         else
            --  Try to build a static aggregate to statically initialize
            --  objects of the type. This can only be done for constrained
            --  one-dimensional arrays with static bounds.

            Set_Static_Initialization
              (Proc_Id,
               Build_Equivalent_Array_Aggregate (First_Subtype (A_Type)));
         end if;
      end if;
   end Build_Array_Init_Proc;

   ----------------------------------
   -- Build_Default_Initialization --
   ----------------------------------

   function Build_Default_Initialization
     (N          : Node_Id;
      Typ        : Entity_Id;
      Obj_Id     : Entity_Id;
      For_CW     : Boolean := False;
      Target_Ref : Node_Id := Empty) return List_Id
   is
      Exceptions_OK : constant Boolean :=
                        not Restriction_Active (No_Exception_Propagation);
      Loc           : constant Source_Ptr := Sloc (N);

      function New_Object_Reference return Node_Id;
      --  Return either a reference to Obj_Id or a dereference of Obj_Id

      --------------------------
      -- New_Object_Reference --
      --------------------------

      function New_Object_Reference return Node_Id is
         Obj_Ref : Node_Id := New_Occurrence_Of (Obj_Id, Loc);

      begin
         if Nkind (N) = N_Object_Declaration then
            --  The call to the type init proc or [Deep_]Finalize must not
            --  freeze the object since the call is internally generated.
            --  This prevents representation clauses from being rejected.
            --  Note that the initialization call may be removed if pragma
            --  Import is encountered or moved to the freeze actions of
            --  the object if an address clause is encountered.

            Set_Assignment_OK   (Obj_Ref);
            Set_Must_Not_Freeze (Obj_Ref);

         else pragma Assert (Nkind (N) = N_Allocator);
            Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref);

            --  If the designated subtype is unconstrained and the allocator
            --  specifies a constrained subtype, or such a subtype has been
            --  created, associate that subtype with the dereference of the
            --  allocator's access value. This is needed by the expander for
            --  cases where the access type has a Designated_Storage_Model
            --  in order to support allocation of a host object of the right
            --  size for passing to the initialization procedure.

            if not Is_Constrained (Designated_Type (Etype (N)))
              and then Is_Constrained (Typ)
            then
               Set_Actual_Designated_Subtype (Obj_Ref, Typ);
            end if;

            --  The initialization procedure expects a specific type so.
            --  if the context is access to class-wide, indicate that the
            --  object being initialized has the right specific type.

            if For_CW then
               Obj_Ref := Unchecked_Convert_To (Typ, Obj_Ref);
            end if;
         end if;

         return Obj_Ref;
      end New_Object_Reference;

      --  Local variables

      Comp_Init  : List_Id := No_List;
      Fin_Block  : Node_Id;
      Fin_Call   : Node_Id;
      Init_Stmts : List_Id := No_List;
      Obj_Init   : Node_Id := Empty;
      Obj_Ref    : Node_Id;

   --  Start of processing for Build_Default_Initialization

   begin
      --  The expansion performed by this routine is as follows:

      --    begin
      --       Abort_Defer;
      --       Type_Init_Proc (Obj);

      --       begin
      --          [Deep_]Initialize (Obj);

      --       exception
      --          when others =>
      --             [Deep_]Finalize (Obj, Self => False);
      --             raise;
      --       end;
      --    at end
      --       Abort_Undefer_Direct;
      --    end;

      --  Initialize the components of the object

      if Has_Non_Null_Base_Init_Proc (Typ)
        and then not Initialization_Suppressed (Typ)
      then
         --  Do not initialize the components if No_Default_Initialization
         --  applies as the actual restriction check will occur later when
         --  the object is frozen as it is not known yet whether the object
         --  is imported or not.

         if not Restriction_Active (No_Default_Initialization) then

            --  Invoke the type init proc, generate:
            --    Type_Init_Proc (Obj);

            Obj_Ref := New_Object_Reference;

            if Comes_From_Source (Obj_Id) then
               Initialization_Warning (Obj_Ref);
            end if;

            Comp_Init :=
              Build_Initialization_Call (N,
                Obj_Ref, Typ, Target_Ref => Target_Ref);
         end if;
      end if;

      --  Initialize the object, generate:
      --    [Deep_]Initialize (Obj);

      if Needs_Finalization (Typ) then
         Obj_Init :=
           Make_Init_Call
             (Obj_Ref => New_Object_Reference,
              Typ     => Typ);
      end if;

      --  Build a special finalization block when both the object and its
      --  controlled components are to be initialized. The block finalizes
      --  the components if the object initialization fails. Generate:

      --    begin
      --       <Obj_Init>

      --    exception
      --       when others =>
      --          <Fin_Call>
      --          raise;
      --    end;

      if Has_Controlled_Component (Typ)
        and then Present (Comp_Init)
        and then Present (Obj_Init)
        and then Exceptions_OK
      then
         Init_Stmts := Comp_Init;

         Fin_Call :=
           Make_Final_Call
             (Obj_Ref   => New_Object_Reference,
              Typ       => Typ,
              Skip_Self => True);

         if Present (Fin_Call) then

            --  Do not emit warnings related to the elaboration order when a
            --  controlled object is declared before the body of Finalize is
            --  seen.

            if Legacy_Elaboration_Checks then
               Set_No_Elaboration_Check (Fin_Call);
            end if;

            Fin_Block :=
              Make_Block_Statement (Loc,
                Declarations               => No_List,

                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements         => New_List (Obj_Init),

                    Exception_Handlers => New_List (
                      Make_Exception_Handler (Loc,
                        Exception_Choices => New_List (
                          Make_Others_Choice (Loc)),

                        Statements        => New_List (
                          Fin_Call,
                          Make_Raise_Statement (Loc))))));

            --  Signal the ABE mechanism that the block carries out
            --  initialization actions.

            Set_Is_Initialization_Block (Fin_Block);

            Append_To (Init_Stmts, Fin_Block);
         end if;

      --  Otherwise finalization is not required, the initialization calls
      --  are passed to the abort block building circuitry, generate:

      --    Type_Init_Proc (Obj);
      --    [Deep_]Initialize (Obj);

      else
         if Present (Comp_Init) then
            Init_Stmts := Comp_Init;
         end if;

         if Present (Obj_Init) then
            if No (Init_Stmts) then
               Init_Stmts := New_List;
            end if;

            Append_To (Init_Stmts, Obj_Init);
         end if;
      end if;

      --  Build an abort block to protect the initialization calls, except for
      --  a finalization collection, which does not need any protection.

      if Abort_Allowed
        and then Present (Comp_Init)
        and then Present (Obj_Init)
        and then not Is_RTE (Typ, RE_Finalization_Collection)
      then
         --  Generate:
         --    Abort_Defer;

         Prepend_To (Init_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));

         --  When exceptions are propagated, abort deferral must take place
         --  in the presence of initialization or finalization exceptions.
         --  Generate:

         --    begin
         --       Abort_Defer;
         --       <Init_Stmts>
         --    at end
         --       Abort_Undefer_Direct;
         --    end;

         if Exceptions_OK then
            Init_Stmts := New_List (
              Build_Abort_Undefer_Block (Loc,
                Stmts   => Init_Stmts,
                Context => N));

         --  Otherwise exceptions are not propagated. Generate:

         --    Abort_Defer;
         --    <Init_Stmts>
         --    Abort_Undefer;

         else
            Append_To (Init_Stmts,
              Build_Runtime_Call (Loc, RE_Abort_Undefer));
         end if;
      end if;

      return Init_Stmts;
   end Build_Default_Initialization;

   -----------------------------------------
   -- Build_Default_Simple_Initialization --
   -----------------------------------------

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

      function Build_Equivalent_Aggregate return Node_Id;
      --  If the object has a constrained discriminated type and no initial
      --  value, it may be possible to build an equivalent aggregate instead,
      --  and prevent an actual call to the initialization procedure.

      function Simple_Initialization_OK (Typ : Entity_Id) return Boolean;
      --  Determine whether object declaration N with entity Obj_Id if set, or
      --  object allocation N if Obj_Id is empty, needs simple initialization,
      --  assuming that it is of type Typ.

      --------------------------------
      -- Build_Equivalent_Aggregate --
      --------------------------------

      function Build_Equivalent_Aggregate return Node_Id is
         Aggr     : Node_Id;
         Comp     : Entity_Id;
         Discr    : Elmt_Id;
         Full_Typ : Entity_Id;

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

         --  Only do this transformation for a package entity of a constrained
         --  record type and if Elaboration_Code is forbidden or undesirable.

         --  If Initialize_Scalars might be active this transformation cannot
         --  be performed either, because it will lead to different semantics
         --  or because elaboration code will in fact be created.

         if Ekind (Full_Typ) /= E_Record_Subtype
           or else not Has_Discriminants (Full_Typ)
           or else not Is_Constrained (Full_Typ)
           or else Is_Controlled (Full_Typ)
           or else Is_Limited_Type (Full_Typ)
           or else Ekind (Current_Scope) /= E_Package
           or else not (Is_Preelaborated (Current_Scope)
                         or else Restriction_Active (No_Elaboration_Code))
           or else not Restriction_Active (No_Initialize_Scalars)
         then
            return Empty;
         end if;

         --  Building a static aggregate is possible if the discriminants
         --  have static values and the other components have static
         --  defaults or none.

         Discr := First_Elmt (Discriminant_Constraint (Full_Typ));
         while Present (Discr) loop
            if not Is_OK_Static_Expression (Node (Discr)) then
               return Empty;
            end if;

            Next_Elmt (Discr);
         end loop;

         --  Check that initialized components are OK, and that non-
         --  initialized components do not require a call to their own
         --  initialization procedure.

         Comp := First_Component (Full_Typ);
         while Present (Comp) loop
            if Present (Expression (Parent (Comp)))
              and then not Is_OK_Static_Expression (Expression (Parent (Comp)))
            then
               return Empty;

            elsif Has_Non_Null_Base_Init_Proc (Etype (Comp)) then
               return Empty;

            end if;

            Next_Component (Comp);
         end loop;

         --  Everything is static, assemble the aggregate, discriminant
         --  values first.

         Aggr :=
            Make_Aggregate (Loc,
             Expressions            => New_List,
              Component_Associations => New_List);
         Set_Parent (Aggr, N);

         Discr := First_Elmt (Discriminant_Constraint (Full_Typ));
         while Present (Discr) loop
            Append_To (Expressions (Aggr), New_Copy (Node (Discr)));
            Next_Elmt (Discr);
         end loop;

         --  Now collect values of initialized components

         Comp := First_Component (Full_Typ);
         while Present (Comp) loop
            if Present (Expression (Parent (Comp))) then
               Append_To (Component_Associations (Aggr),
                 Make_Component_Association (Loc,
                   Choices    => New_List (New_Occurrence_Of (Comp, Loc)),
                   Expression => New_Copy_Tree
                                   (Expression (Parent (Comp)))));
            end if;

            Next_Component (Comp);
         end loop;

         --  Finally, box-initialize remaining components

         Append_To (Component_Associations (Aggr),
           Make_Component_Association (Loc,
             Choices     => New_List (Make_Others_Choice (Loc)),
             Box_Present => True));

         if Typ /= Full_Typ then
            Analyze_And_Resolve (Aggr, Full_View (Base_Type (Full_Typ)));
            Rewrite (Aggr, Unchecked_Convert_To (Typ, Aggr));
         end if;

         return Aggr;
      end Build_Equivalent_Aggregate;

      ------------------------------
      -- Simple_Initialization_OK --
      ------------------------------

      function Simple_Initialization_OK (Typ : Entity_Id) return Boolean is
      begin
         --  Skip internal entities as specified in Einfo

         return
           not (Present (Obj_Id) and then Is_Internal (Obj_Id))
             and then not Is_Mutably_Tagged_CW_Equivalent_Type (Typ)
             and then
               Needs_Simple_Initialization
                 (Typ         => Typ,
                  Consider_IS =>
                    Initialize_Scalars
                      and then (No (Obj_Id)
                                 or else No (Following_Address_Clause (N))));
      end Simple_Initialization_OK;

      --  Local variables

      Aggr_Init  : Node_Id;

   --  Start of processing for Build_Default_Simple_Initialization

   begin
      if Has_Non_Null_Base_Init_Proc (Typ)
        and then not Is_Dispatching_Operation (Base_Init_Proc (Typ))
        and then not Initialization_Suppressed (Typ)
      then
         --  Do not initialize the components if No_Default_Initialization
         --  applies as the actual restriction check will occur later when
         --  the object is frozen as it is not known yet whether the object
         --  is imported or not.

         if not Restriction_Active (No_Default_Initialization) then
            --  If the type requires construction and the object being
            --  initialized is an allocator that comes from source, then use
            --  the parameterless constructor.

            if Nkind (N) = N_Allocator
              and then Comes_From_Source (N)
              and then Needs_Construction (Typ)
            then
               return
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Occurrence_Of (Typ, Loc),
                   Attribute_Name => Name_Make);
            end if;

            --  If the values of the components are compile-time known, use
            --  their prebuilt aggregate form directly.

            Aggr_Init := Static_Initialization (Base_Init_Proc (Typ));
            if Present (Aggr_Init) then
               return New_Copy_Tree (Aggr_Init, New_Scope => Current_Scope);
            end if;

            --  If type has discriminants, try to build an equivalent
            --  aggregate using discriminant values from the declaration.
            --  This is a useful optimization, in particular if restriction
            --  No_Elaboration_Code is active.

            Aggr_Init := Build_Equivalent_Aggregate;
            if Present (Aggr_Init) then
               return Aggr_Init;
            end if;

            --  Optimize the default initialization of an array object when
            --  pragma Initialize_Scalars or Normalize_Scalars is in effect.
            --  Construct an in-place initialization aggregate which may be
            --  convert into a fast memset by the backend.

            if Init_Or_Norm_Scalars
              and then Is_Array_Type (Typ)

              --  The array must lack atomic components because they are
              --  treated as non-static, and as a result the backend will
              --  not initialize the memory in one go.

              and then not Has_Atomic_Components (Typ)

              --  The array must not be packed because the invalid values
              --  in System.Scalar_Values are multiples of Storage_Unit.

              and then not Is_Packed (Typ)

              --  The array must have static non-empty ranges, otherwise
              --  the backend cannot initialize the memory in one go.

              and then Has_Static_Non_Empty_Array_Bounds (Typ)

              --  The optimization is only relevant for arrays of scalar
              --  types.

              and then Is_Scalar_Type (Component_Type (Typ))

              --  Similar to regular array initialization using a type
              --  init proc, predicate checks are not performed because the
              --  initialization values are intentionally invalid, and may
              --  violate the predicate.

              and then not Has_Predicates (Component_Type (Typ))

              --  Array default component value takes precedence over
              --  Init_Or_Norm_Scalars.

              and then No (Find_Aspect (Typ, Aspect_Default_Component_Value))

              --  The component type must have a single initialization value

              and then Simple_Initialization_OK (Component_Type (Typ))
            then
               return
                 Get_Simple_Init_Val
                   (Typ  => Typ,
                    N    => N,
                    Size => (if Known_Esize (Typ)
                             then Esize (Typ)
                             else Uint_0));
            end if;
         end if;

      --  Provide a default value if the object needs simple initialization

      elsif Simple_Initialization_OK (Typ) then
         return
           Get_Simple_Init_Val
             (Typ  => Typ,
              N    => N,
              Size => (if Known_Esize (Typ)
                       then Esize (Typ)
                       else Uint_0));
      end if;

      return Empty;
   end Build_Default_Simple_Initialization;

   --------------------------------
   -- Build_Discr_Checking_Funcs --
   --------------------------------

   procedure Build_Discr_Checking_Funcs (N : Node_Id) is
      Rec_Id            : Entity_Id;
      Loc               : Source_Ptr;
      Enclosing_Func_Id : Entity_Id;
      Sequence          : Nat := 1;
      Type_Def          : Node_Id;
      V                 : Node_Id;

      function Build_Case_Statement
        (Case_Id : Entity_Id;
         Variant : Node_Id) return Node_Id;
      --  Build a case statement containing only two alternatives. The first
      --  alternative corresponds to the discrete choices given on the variant
      --  that contains the components that we are generating the checks
      --  for. If the discriminant is one of these return False. The second
      --  alternative is an OTHERS choice that returns True indicating the
      --  discriminant did not match.

      function Build_Dcheck_Function
        (Case_Id : Entity_Id;
         Variant : Node_Id) return Entity_Id;
      --  Build the discriminant checking function for a given variant

      procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id);
      --  Builds the discriminant checking function for each variant of the
      --  given variant part of the record type.

      --------------------------
      -- Build_Case_Statement --
      --------------------------

      function Build_Case_Statement
        (Case_Id : Entity_Id;
         Variant : Node_Id) return Node_Id
      is
         Alt_List       : constant List_Id := New_List;
         Actuals_List   : List_Id;
         Case_Node      : Node_Id;
         Case_Alt_Node  : Node_Id;
         Choice         : Node_Id;
         Choice_List    : List_Id;
         D              : Entity_Id;
         Return_Node    : Node_Id;

      begin
         Case_Node := New_Node (N_Case_Statement, Loc);
         Set_End_Span (Case_Node, Uint_0);

         --  Replace the discriminant which controls the variant with the name
         --  of the formal of the checking function.

         Set_Expression (Case_Node, Make_Identifier (Loc, Chars (Case_Id)));

         Choice := First (Discrete_Choices (Variant));

         if Nkind (Choice) = N_Others_Choice then
            Choice_List := New_Copy_List (Others_Discrete_Choices (Choice));
         else
            Choice_List := New_Copy_List (Discrete_Choices (Variant));
         end if;

         if not Is_Empty_List (Choice_List) then
            Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
            Set_Discrete_Choices (Case_Alt_Node, Choice_List);

            --  In case this is a nested variant, we need to return the result
            --  of the discriminant checking function for the immediately
            --  enclosing variant.

            if Present (Enclosing_Func_Id) then
               Actuals_List := New_List;

               D := First_Discriminant (Rec_Id);
               while Present (D) loop
                  Append (Make_Identifier (Loc, Chars (D)), Actuals_List);
                  Next_Discriminant (D);
               end loop;

               Return_Node :=
                 Make_Simple_Return_Statement (Loc,
                   Expression =>
                     Make_Function_Call (Loc,
                       Name =>
                         New_Occurrence_Of (Enclosing_Func_Id,  Loc),
                       Parameter_Associations =>
                         Actuals_List));

            else
               Return_Node :=
                 Make_Simple_Return_Statement (Loc,
                   Expression =>
                     New_Occurrence_Of (Standard_False, Loc));
            end if;

            Set_Statements (Case_Alt_Node, New_List (Return_Node));
            Append (Case_Alt_Node, Alt_List);
         end if;

         Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Loc);
         Choice_List := New_List (New_Node (N_Others_Choice, Loc));
         Set_Discrete_Choices (Case_Alt_Node, Choice_List);

         Return_Node :=
           Make_Simple_Return_Statement (Loc,
             Expression =>
               New_Occurrence_Of (Standard_True, Loc));

         Set_Statements (Case_Alt_Node, New_List (Return_Node));
         Append (Case_Alt_Node, Alt_List);

         Set_Alternatives (Case_Node, Alt_List);
         return Case_Node;
      end Build_Case_Statement;

      ---------------------------
      -- Build_Dcheck_Function --
      ---------------------------

      function Build_Dcheck_Function
        (Case_Id : Entity_Id;
         Variant : Node_Id) return Entity_Id
      is
         Body_Node      : Node_Id;
         Func_Id        : Entity_Id;
         Parameter_List : List_Id;
         Spec_Node      : Node_Id;

      begin
         Body_Node := New_Node (N_Subprogram_Body, Loc);
         Sequence := Sequence + 1;

         Func_Id :=
           Make_Defining_Identifier (Loc,
             Chars => New_External_Name (Chars (Rec_Id), 'D', Sequence));
         Set_Is_Discriminant_Check_Function (Func_Id);

         Spec_Node := New_Node (N_Function_Specification, Loc);
         Set_Defining_Unit_Name (Spec_Node, Func_Id);

         Parameter_List := Build_Discriminant_Formals (Rec_Id, False);

         Set_Parameter_Specifications (Spec_Node, Parameter_List);
         Set_Result_Definition (Spec_Node,
                                New_Occurrence_Of (Standard_Boolean,  Loc));
         Set_Specification (Body_Node, Spec_Node);
         Set_Declarations (Body_Node, New_List);

         Set_Handled_Statement_Sequence (Body_Node,
           Make_Handled_Sequence_Of_Statements (Loc,
             Statements => New_List (
               Build_Case_Statement (Case_Id, Variant))));

         Mutate_Ekind    (Func_Id, E_Function);
         Set_Mechanism   (Func_Id, Default_Mechanism);
         Set_Is_Inlined  (Func_Id, True);
         Set_Is_Pure     (Func_Id, True);
         Set_Is_Public   (Func_Id, Is_Public (Rec_Id));
         Set_Is_Internal (Func_Id, True);

         if not Debug_Generated_Code then
            Set_Debug_Info_Off (Func_Id);
         end if;

         Analyze (Body_Node);

         Append_Freeze_Action (Rec_Id, Body_Node);
         Set_Dcheck_Function (Variant, Func_Id);
         return Func_Id;
      end Build_Dcheck_Function;

      ----------------------------
      -- Build_Dcheck_Functions --
      ----------------------------

      procedure Build_Dcheck_Functions (Variant_Part_Node : Node_Id) is
         Component_List_Node : Node_Id;
         Decl                : Entity_Id;
         Discr_Name          : Entity_Id;
         Func_Id             : Entity_Id;
         Variant             : Node_Id;
         Saved_Enclosing_Func_Id : Entity_Id;

      begin
         --  Build the discriminant-checking function for each variant, and
         --  label all components of that variant with the function's name.
         --  We only Generate a discriminant-checking function when the
         --  variant is not empty, to prevent the creation of dead code.

         Discr_Name := Entity (Name (Variant_Part_Node));
         Variant := First_Non_Pragma (Variants (Variant_Part_Node));

         while Present (Variant) loop
            Component_List_Node := Component_List (Variant);

            if not Null_Present (Component_List_Node) then
               Func_Id := Build_Dcheck_Function (Discr_Name, Variant);

               Decl :=
                 First_Non_Pragma (Component_Items (Component_List_Node));
               while Present (Decl) loop
                  Set_Discriminant_Checking_Func
                    (Defining_Identifier (Decl), Func_Id);
                  Next_Non_Pragma (Decl);
               end loop;

               if Present (Variant_Part (Component_List_Node)) then
                  Saved_Enclosing_Func_Id := Enclosing_Func_Id;
                  Enclosing_Func_Id := Func_Id;
                  Build_Dcheck_Functions (Variant_Part (Component_List_Node));
                  Enclosing_Func_Id := Saved_Enclosing_Func_Id;
               end if;
            end if;

            Next_Non_Pragma (Variant);
         end loop;
      end Build_Dcheck_Functions;

   --  Start of processing for Build_Discr_Checking_Funcs

   begin
      --  Only build if not done already

      if not Discr_Check_Funcs_Built (N) then
         Type_Def := Type_Definition (N);

         if Nkind (Type_Def) = N_Record_Definition then
            if No (Component_List (Type_Def)) then   -- null record.
               return;
            else
               V := Variant_Part (Component_List (Type_Def));
            end if;

         else pragma Assert (Nkind (Type_Def) = N_Derived_Type_Definition);
            if No (Component_List (Record_Extension_Part (Type_Def))) then
               return;
            else
               V := Variant_Part
                      (Component_List (Record_Extension_Part (Type_Def)));
            end if;
         end if;

         Rec_Id := Defining_Identifier (N);

         if Present (V) and then not Is_Unchecked_Union (Rec_Id) then
            Loc := Sloc (N);
            Enclosing_Func_Id := Empty;
            Build_Dcheck_Functions (V);
         end if;

         Set_Discr_Check_Funcs_Built (N);
      end if;
   end Build_Discr_Checking_Funcs;

   ----------------------------------------
   -- Build_Or_Copy_Discr_Checking_Funcs --
   ----------------------------------------

   procedure Build_Or_Copy_Discr_Checking_Funcs (N : Node_Id) is
      Typ : constant Entity_Id := Defining_Identifier (N);
   begin
      if Is_Unchecked_Union (Typ) or else not Has_Discriminants (Typ) then
         null;
      elsif not Is_Derived_Type (Typ)
        or else Has_New_Non_Standard_Rep (Typ)
        or else Is_Tagged_Type (Typ)
      then
         Build_Discr_Checking_Funcs (N);
      else
         Copy_Discr_Checking_Funcs (N);
      end if;
   end Build_Or_Copy_Discr_Checking_Funcs;

   -------------------------------------
   -- Build_Implicit_Copy_Constructor --
   -------------------------------------

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

      Comp_List, Comp_Decl : Node_Id;
      Comp_Id, Comp_Typ    : Entity_Id;

      Body_Stmts, Parameters, Aspect_Specs : List_Id;
      Spec_Node, Stmt                      : Node_Id;
      Self, From                           : Entity_Id;
   begin
      --  Only build copy constructor for user-defined non-limited tagged
      --  record types that needs construction without having declared a copy
      --  constructor already, or without having it explicitly removed. This
      --  implicit copy needs to call first the parent's copy constructor (if
      --  derived), second to copy field-by-field the components, and third to
      --  call their respective copy constructors if necessary.

      if not Comes_From_Source (N)
        or else Is_Limited_Type (Typ)
        or else not Is_Tagged_Type (Typ)
        or else not Needs_Construction (Typ)
        or else Has_Copy_Constructor (Typ, Allow_Removed => True)
      then
         return;
      end if;

      if Is_Derived_Type (Typ) then
         Comp_List :=
           Component_List (Record_Extension_Part (Type_Definition (N)));
      else
         Comp_List := Component_List (Type_Definition (N));
      end if;

      --  Here, there is still a possibility that an implicit copy constructor
      --  is actually not needed.

      declare
         Found : Boolean := False;
      begin
         if Present (Comp_List) then
            Comp_Decl := First_Non_Pragma (Component_Items (Comp_List));
            while not Found and then Present (Comp_Decl) loop
               Comp_Id := Defining_Identifier (Comp_Decl);
               Comp_Typ := Etype (Comp_Id);
               if Has_Copy_Constructor (Comp_Typ) then
                  Found := True;
               end if;
               Next_Non_Pragma (Comp_Decl);
            end loop;
         end if;

         --  If Found is false, then there is no component in the current type
         --  with a copy constructor. If also the type is either not derived or
         --  its parent has no copy constructor, then there is no need for a
         --  copy constructor for the current type as its behavior would be
         --  identical to the byte-wise copy provided by assignment.

         if not Found
           and then (if Is_Derived_Type (Typ)
                      then not Has_Copy_Constructor (Parent_Subtype (Typ)))
         then
            return;
         end if;
      end;

      Copy_Id :=
        Make_Defining_Identifier (Loc,
          Direct_Attribute_Definition_Name (Typ, Name_Constructor));
      Mutate_Ekind (Copy_Id, E_Procedure);

      if not Debug_Generated_Code then
         Set_Debug_Info_Off (Copy_Id);
      end if;

      --  The copy constructor has the following profile:
      --    procedure T'Constructor (Self : in out T; From : T);

      Self := Make_Defining_Identifier (Loc, Name_Self);
      From := Make_Defining_Identifier (Loc, Name_From);

      Parameters := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Self,
          In_Present          => True,
          Out_Present         => True,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)),
        Make_Parameter_Specification (Loc,
          Defining_Identifier => From,
          In_Present          => True,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));

      --  The first thing to do in the implicit copy constructor is to copy
      --  components field-by-field, the parent copy constructor call is
      --  prepended later via the 'Super aspect.

      Body_Stmts := New_List;
      if Present (Comp_List) then
         Comp_Decl := First_Non_Pragma (Component_Items (Comp_List));
         while Present (Comp_Decl) loop
            Comp_Id := Defining_Identifier (Comp_Decl);
            Comp_Typ := Etype (Comp_Id);

            if Chars (Comp_Id) not in Name_uParent | Name_uTag then
               Stmt :=
                 Make_Assignment_Statement (Loc,
                   Name       =>
                     Make_Selected_Component (Loc,
                       Prefix        => New_Occurrence_Of (Self, Loc),
                       Selector_Name => New_Occurrence_Of (Comp_Id, Loc)),
                   Expression =>
                     Make_Selected_Component (Loc,
                       Prefix        => New_Occurrence_Of (From, Loc),
                       Selector_Name => New_Occurrence_Of (Comp_Id, Loc)));
               Set_Assignment_OK (Name (Stmt));
               Set_No_Ctrl_Actions (Stmt);
               Append_To (Body_Stmts, Stmt);
            end if;

            Next_Non_Pragma (Comp_Decl);
         end loop;

         --  Then, call the copy constructor for each component that needs
         --  construction and has a copy constructor.

         Comp_Decl := First_Non_Pragma (Component_Items (Comp_List));
         while Present (Comp_Decl) loop
            Comp_Id := Defining_Identifier (Comp_Decl);
            Comp_Typ := Etype (Comp_Id);

            --  For each component that has a copy constructor, generate:
            --    Self.Comp_Id := Comp_Typ'Make (From.Comp_Id);

            if Chars (Comp_Id) /= Name_uParent
              and then Needs_Construction (Comp_Typ)
              and then Has_Copy_Constructor (Comp_Typ)
            then
               Stmt :=
                 Make_Assignment_Statement (Loc,
                   Name       =>
                     Make_Selected_Component (Loc,
                       Prefix        => New_Occurrence_Of (Self, Loc),
                       Selector_Name => New_Occurrence_Of (Comp_Id, Loc)),
                   Expression =>
                     Make_Attribute_Reference (Loc,
                       Prefix         => New_Occurrence_Of (Comp_Typ, Loc),
                       Attribute_Name => Name_Make,
                       Expressions    => New_List (
                         Make_Selected_Component (Loc,
                           Prefix        => New_Occurrence_Of (From, Loc),
                           Selector_Name =>
                             New_Occurrence_Of (Comp_Id, Loc)))));
               Set_Assignment_OK (Name (Stmt));
               Append_To (Body_Stmts, Stmt);
            end if;

            --  Components that do not need construction or lack a copy
            --  constructor are simply skipped since the expansion of a
            --  constructor also takes care of default copies/initializations.

            Next_Non_Pragma (Comp_Decl);
         end loop;
      end if;

      --  Prepend the call to the parent's copy constructor if derived

      if Is_Derived_Type (Typ)
        and then Has_Copy_Constructor (Parent_Subtype (Typ))
      then
         Aspect_Specs := New_List
           (Make_Aspect_Specification (Loc,
              Identifier => Make_Identifier (Loc, Name_Super),
              Expression =>
                Make_Aggregate (Loc,
                  Expressions => New_List (
                    Make_Type_Conversion (Loc,
                      Subtype_Mark =>
                        New_Occurrence_Of (Parent_Subtype (Typ), Loc),
                      Expression   => New_Occurrence_Of (From, Loc))),
                  Is_Parenthesis_Aggregate => True,
                  Is_Homogeneous_Aggregate => True)));
      else
         Aspect_Specs := No_List;
      end if;

      Spec_Node := New_Node (N_Procedure_Specification, Loc);
      Set_Defining_Unit_Name (Spec_Node, Copy_Id);
      Set_Parameter_Specifications (Spec_Node, Parameters);
      Freeze_Extra_Formals (Copy_Id);

      declare
         Ignore : Node_Id;
      begin
         Ignore :=
           Make_Subprogram_Body (Loc,
             Specification => Spec_Node,
             Aspect_Specifications => Aspect_Specs,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc, Body_Stmts));
      end;

      Set_Is_Public (Copy_Id, Is_Public (Typ));
      Set_Is_Internal (Copy_Id);
      Set_Is_Constructor (Copy_Id);
      Set_Init_Proc (Typ, Copy_Id);
   end Build_Implicit_Copy_Constructor;

   --------------------------------
   -- Build_Discriminant_Formals --
   --------------------------------

   function Build_Discriminant_Formals
     (Rec_Id : Entity_Id;
      Use_Dl : Boolean) return List_Id
   is
      Loc             : Source_Ptr       := Sloc (Rec_Id);
      Parameter_List  : constant List_Id := New_List;
      D               : Entity_Id;
      Formal          : Entity_Id;
      Formal_Type     : Entity_Id;
      Param_Spec_Node : Node_Id;

   begin
      if Has_Discriminants (Rec_Id) then
         D := First_Discriminant (Rec_Id);
         while Present (D) loop
            Loc := Sloc (D);

            if Use_Dl then
               Formal := Discriminal (D);
               Formal_Type := Etype (Formal);
            else
               Formal := Make_Defining_Identifier (Loc, Chars (D));
               Formal_Type := Etype (D);
            end if;

            Param_Spec_Node :=
              Make_Parameter_Specification (Loc,
                  Defining_Identifier => Formal,
                Parameter_Type =>
                  New_Occurrence_Of (Formal_Type, Loc));
            Append (Param_Spec_Node, Parameter_List);
            Next_Discriminant (D);
         end loop;
      end if;

      return Parameter_List;
   end Build_Discriminant_Formals;

   --------------------------------------
   -- Build_Equivalent_Array_Aggregate --
   --------------------------------------

   function Build_Equivalent_Array_Aggregate (T : Entity_Id) return Node_Id is
      Loc        : constant Source_Ptr := Sloc (T);
      Comp_Type  : constant Entity_Id := Component_Type (T);
      Index_Type : constant Entity_Id := Etype (First_Index (T));
      Proc       : constant Entity_Id := Base_Init_Proc (T);
      Lo, Hi     : Node_Id;
      Aggr       : Node_Id;
      Expr       : Node_Id;

   begin
      if not Is_Constrained (T)
        or else Number_Dimensions (T) > 1
        or else No (Proc)
      then
         Initialization_Warning (T);
         return Empty;
      end if;

      Lo := Type_Low_Bound  (Index_Type);
      Hi := Type_High_Bound (Index_Type);

      if not Compile_Time_Known_Value (Lo)
        or else not Compile_Time_Known_Value (Hi)
      then
         Initialization_Warning (T);
         return Empty;
      end if;

      if Is_Record_Type (Comp_Type)
        and then Present (Base_Init_Proc (Comp_Type))
      then
         Expr := Static_Initialization (Base_Init_Proc (Comp_Type));

         if No (Expr) then
            Initialization_Warning (T);
            return Empty;
         end if;

      else
         Initialization_Warning (T);
         return Empty;
      end if;

      Aggr := Make_Aggregate (Loc, No_List, New_List);
      Set_Etype (Aggr, T);
      Set_Aggregate_Bounds (Aggr,
        Make_Range (Loc,
          Low_Bound  => New_Copy (Lo),
          High_Bound => New_Copy (Hi)));
      Set_Parent (Aggr, Parent (Proc));

      Append_To (Component_Associations (Aggr),
         Make_Component_Association (Loc,
              Choices =>
                 New_List (
                   Make_Range (Loc,
                     Low_Bound  => New_Copy (Lo),
                     High_Bound => New_Copy (Hi))),
              Expression => Expr));

      if Static_Array_Aggregate (Aggr) then
         return Aggr;
      else
         Initialization_Warning (T);
         return Empty;
      end if;
   end Build_Equivalent_Array_Aggregate;

   ---------------------------------------
   -- Build_Equivalent_Record_Aggregate --
   ---------------------------------------

   function Build_Equivalent_Record_Aggregate (T : Entity_Id) return Node_Id is
      Agg       : Node_Id;
      Comp      : Entity_Id;
      Comp_Type : Entity_Id;

   begin
      if not Is_Record_Type (T)
        or else Has_Discriminants (T)
        or else Is_Limited_Type (T)
        or else Has_Non_Standard_Rep (T)
        or else Needs_Finalization (T)
      then
         Initialization_Warning (T);
         return Empty;
      end if;

      Comp := First_Component (T);

      --  A null record needs no warning

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

      while Present (Comp) loop

         --  Array components are acceptable if initialized by a positional
         --  aggregate with static components.

         if Is_Array_Type (Etype (Comp)) then
            Comp_Type := Component_Type (Etype (Comp));

            if Nkind (Parent (Comp)) /= N_Component_Declaration
              or else No (Expression (Parent (Comp)))
              or else Nkind (Expression (Parent (Comp))) /= N_Aggregate
            then
               Initialization_Warning (T);
               return Empty;

            elsif Is_Scalar_Type (Component_Type (Etype (Comp)))
               and then
                 (not Compile_Time_Known_Value (Type_Low_Bound  (Comp_Type))
                   or else
                  not Compile_Time_Known_Value (Type_High_Bound (Comp_Type)))
            then
               Initialization_Warning (T);
               return Empty;

            elsif
              not Static_Array_Aggregate (Expression (Parent (Comp)))
            then
               Initialization_Warning (T);
               return Empty;

               --  We need to return empty if the type has predicates because
               --  this would otherwise duplicate calls to the predicate
               --  function. If the type hasn't been frozen before being
               --  referenced in the current record, the extraneous call to
               --  the predicate function would be inserted somewhere before
               --  the predicate function is elaborated, which would result in
               --  an invalid tree.

            elsif Has_Predicates (Etype (Comp)) then
               return Empty;
            end if;

         elsif Is_Scalar_Type (Etype (Comp)) then
            Comp_Type := Etype (Comp);

            if Nkind (Parent (Comp)) /= N_Component_Declaration
              or else No (Expression (Parent (Comp)))
              or else not Compile_Time_Known_Value (Expression (Parent (Comp)))
              or else not Compile_Time_Known_Value (Type_Low_Bound (Comp_Type))
              or else not
                Compile_Time_Known_Value (Type_High_Bound (Comp_Type))
              or else Has_Predicates (Etype (Comp))
            then
               Initialization_Warning (T);
               return Empty;
            end if;

         --  For now, other types are excluded

         else
            Initialization_Warning (T);
            return Empty;
         end if;

         Next_Component (Comp);
      end loop;

      --  All components have static initialization. Build positional aggregate
      --  from the given expressions or defaults.

      Agg := Make_Aggregate (Sloc (T), New_List, New_List);
      Set_Parent (Agg, Parent (T));

      Comp := First_Component (T);
      while Present (Comp) loop
         Append
           (New_Copy_Tree (Expression (Parent (Comp))), Expressions (Agg));
         Next_Component (Comp);
      end loop;

      Analyze_And_Resolve (Agg, T);
      return Agg;
   end Build_Equivalent_Record_Aggregate;

   -------------------------------
   -- Build_Initialization_Call --
   -------------------------------

   --  References to a discriminant inside the record type declaration can
   --  appear either in the subtype_indication to constrain a record or an
   --  array, or as part of a larger expression given for the initial value
   --  of a component. In both of these cases N appears in the record
   --  initialization procedure and needs to be replaced by the formal
   --  parameter of the initialization procedure which corresponds to that
   --  discriminant.

   --  In the example below, references to discriminants D1 and D2 in proc_1
   --  are replaced by references to formals with the same name
   --  (discriminals)

   --  A similar replacement is done for calls to any record initialization
   --  procedure for any components that are themselves of a record type.

   --  type R (D1, D2 : Integer) is record
   --     X : Integer := F * D1;
   --     Y : Integer := F * D2;
   --  end record;

   --  procedure proc_1 (Out_2 : out R; D1 : Integer; D2 : Integer) is
   --  begin
   --     Out_2.D1 := D1;
   --     Out_2.D2 := D2;
   --     Out_2.X := F * D1;
   --     Out_2.Y := F * D2;
   --  end;

   function Build_Initialization_Call
     (N                   : Node_Id;
      Id_Ref              : Node_Id;
      Typ                 : Entity_Id;
      In_Init_Proc        : Boolean   := False;
      Enclos_Type         : Entity_Id := Empty;
      Target_Ref          : Node_Id   := Empty;
      Discr_Map           : Elist_Id  := New_Elmt_List;
      With_Default_Init   : Boolean   := False;
      Constructor_Ref     : Node_Id   := Empty;
      Init_Control_Actual : Entity_Id := Empty) return List_Id
   is
      Loc : constant Source_Ptr := Sloc (N);
      Res : constant List_Id    := New_List;

      Full_Type : Entity_Id;

      procedure Check_Predicated_Discriminant
        (Val   : Node_Id;
         Discr : Entity_Id);
      --  Discriminants whose subtypes have predicates are checked in two
      --  cases:
      --    a) When an object is default-initialized and assertions are enabled
      --       we check that the value of the discriminant obeys the predicate.

      --    b) In all cases, if the discriminant controls a variant and the
      --       variant has no others_choice, Constraint_Error must be raised if
      --       the predicate is violated, because there is no variant covered
      --       by the illegal discriminant value.

      -----------------------------------
      -- Check_Predicated_Discriminant --
      -----------------------------------

      procedure Check_Predicated_Discriminant
        (Val   : Node_Id;
         Discr : Entity_Id)
      is
         Typ : constant Entity_Id := Etype (Discr);

         procedure Check_Missing_Others (V : Node_Id);
         --  Check that a given variant and its nested variants have an others
         --  choice, and generate a constraint error raise when it does not.

         --------------------------
         -- Check_Missing_Others --
         --------------------------

         procedure Check_Missing_Others (V : Node_Id) is
            Alt      : Node_Id;
            Choice   : Node_Id;
            Last_Var : Node_Id;

         begin
            Last_Var := Last_Non_Pragma (Variants (V));
            Choice   := First (Discrete_Choices (Last_Var));

            --  An others_choice is added during expansion for gcc use, but
            --  does not cover the illegality.

            if Entity (Name (V)) = Discr then
               if Present (Choice)
                 and then (Nkind (Choice) /= N_Others_Choice
                            or else not Comes_From_Source (Choice))
               then
                  Check_Expression_Against_Static_Predicate (Val, Typ);

                  if not Is_Static_Expression (Val) then
                     Prepend_To (Res,
                        Make_Raise_Constraint_Error (Loc,
                          Condition =>
                            Make_Op_Not (Loc,
                              Right_Opnd => Make_Predicate_Call (Typ, Val)),
                          Reason    => CE_Invalid_Data));
                  end if;
               end if;
            end if;

            --  Check whether some nested variant is ruled by the predicated
            --  discriminant.

            Alt := First (Variants (V));
            while Present (Alt) loop
               if Nkind (Alt) = N_Variant
                 and then Present (Variant_Part (Component_List (Alt)))
               then
                  Check_Missing_Others
                    (Variant_Part (Component_List (Alt)));
               end if;

               Next (Alt);
            end loop;
         end Check_Missing_Others;

         --  Local variables

         Def : Node_Id;

      --  Start of processing for Check_Predicated_Discriminant

      begin
         if Ekind (Base_Type (Full_Type)) = E_Record_Type then
            Def := Type_Definition (Parent (Base_Type (Full_Type)));
         else
            return;
         end if;

         if Policy_In_Effect (Name_Assert) = Name_Check
           and then not Predicates_Ignored_In_Codegen (Etype (Discr))
         then
            Prepend_To (Res, Make_Predicate_Check (Typ, Val));
         end if;

         --  If discriminant controls a variant, verify that predicate is
         --  obeyed or else an Others_Choice is present.

         if Nkind (Def) = N_Record_Definition
           and then Present (Variant_Part (Component_List (Def)))
           and then Policy_In_Effect (Name_Assert) = Name_Ignore
         then
            Check_Missing_Others (Variant_Part (Component_List (Def)));
         end if;
      end Check_Predicated_Discriminant;

      --  Local variables

      A_Type         : Entity_Id;
      Arg            : Node_Id;
      Args           : List_Id;
      Decls          : List_Id;
      Decl           : Node_Id;
      Discr          : Entity_Id;
      First_Arg      : Node_Id;
      Full_Init_Type : Entity_Id;
      Init_Call      : Node_Id;
      Init_Type      : Entity_Id;
      Proc           : Entity_Id;

   --  Start of processing for Build_Initialization_Call

   begin
      pragma Assert (Constructor_Ref = Empty
        or else Is_CPP_Constructor_Call (Constructor_Ref));

      if No (Constructor_Ref) then
         Proc := Base_Init_Proc (Typ);
      else
         Proc := Base_Init_Proc (Typ, Entity (Name (Constructor_Ref)));
      end if;

      pragma Assert (Present (Proc));
      Init_Type      := Etype (First_Formal (Proc));
      Full_Init_Type := Underlying_Type (Init_Type);

      --  Nothing to do if the Init_Proc is null, unless Initialize_Scalars
      --  is active (in which case we make the call anyway, since in the
      --  actual compiled client it may be non null).

      if Is_Null_Init_Proc (Proc) and then not Init_Or_Norm_Scalars then
         return Empty_List;

      --  Nothing to do for an array of controlled components that have only
      --  the inherited Initialize primitive. This is a useful optimization
      --  for CodePeer.

      elsif Is_Trivial_Subprogram (Proc)
        and then Is_Array_Type (Full_Init_Type)
      then
         return New_List (Make_Null_Statement (Loc));
      end if;

      --  Use the [underlying] full view when dealing with a private type. This
      --  may require several steps depending on derivations.

      Full_Type := Typ;
      loop
         if Is_Private_Type (Full_Type) then
            if Present (Full_View (Full_Type)) then
               Full_Type := Full_View (Full_Type);

            elsif Present (Underlying_Full_View (Full_Type)) then
               Full_Type := Underlying_Full_View (Full_Type);

            --  When a private type acts as a generic actual and lacks a full
            --  view, use the base type.

            elsif Is_Generic_Actual_Type (Full_Type) then
               Full_Type := Base_Type (Full_Type);

            elsif Ekind (Full_Type) = E_Private_Subtype
              and then (not Has_Discriminants (Full_Type)
                         or else No (Discriminant_Constraint (Full_Type)))
            then
               Full_Type := Etype (Full_Type);

            --  The loop has recovered the [underlying] full view, stop the
            --  traversal.

            else
               exit;
            end if;

         --  The type is not private, nothing to do

         else
            exit;
         end if;
      end loop;

      --  If Typ is derived, the procedure is the initialization procedure for
      --  the root type. Wrap the argument in an conversion to make it type
      --  honest. Actually it isn't quite type honest, because there can be
      --  conflicts of views in the private type case. That is why we set
      --  Conversion_OK in the conversion node.

      if (Is_Record_Type (Typ)
           or else Is_Array_Type (Typ)
           or else Is_Private_Type (Typ))
        and then Init_Type /= Base_Type (Typ)
      then
         First_Arg := OK_Convert_To (Etype (Init_Type), Id_Ref);
         Set_Etype (First_Arg, Init_Type);

      else
         First_Arg := Id_Ref;
      end if;

      Args := New_List (Convert_Concurrent (First_Arg, Typ));

      --  In the tasks case, add _Master as the value of the _Master parameter
      --  and _Chain as the value of the _Chain parameter. At the outer level,
      --  these will be variables holding the corresponding values obtained
      --  from GNARL. At inner levels, they will be the parameters passed down
      --  through the outer routines.

      if Has_Task (Full_Type) then
         if Restriction_Active (No_Task_Hierarchy) then
            Append_To (Args, Make_Integer_Literal (Loc, Library_Task_Level));
         elsif Present (Target_Ref) then
            Append_To (Args,
              New_Occurrence_Of
                (Master_Id (Base_Type (Root_Type (Etype (Target_Ref)))), Loc));
         else
            Append_To (Args, Make_Identifier (Loc, Name_uMaster));
         end if;

         --  Add _Chain (not done for sequential elaboration policy, see
         --  comment for Create_Restricted_Task_Sequential in s-tarest.ads).

         if Partition_Elaboration_Policy /= 'S' then
            Append_To (Args, Make_Identifier (Loc, Name_uChain));
         end if;

         --  Ada 2005 (AI-287): In case of default initialized components
         --  with tasks, we generate a null string actual parameter.
         --  This is just a workaround that must be improved later???

         if With_Default_Init then
            Append_To (Args, Make_String_Literal (Loc, Strval => ""));

         else
            if Present (Enclos_Type) then
               A_Type := Enclos_Type;

            elsif Present (Target_Ref)
              and then Nkind (Target_Ref) in N_Indexed_Component
                                           | N_Selected_Component
            then
               A_Type := Etype (Prefix (Target_Ref));

            else
               A_Type := Full_Type;
            end if;

            Decls :=
              Build_Task_Image_Decls (Loc,
                (if Present (Target_Ref) then Target_Ref else Id_Ref),
                A_Type,
                In_Init_Proc);
            Decl  := Last (Decls);

            Append_To (Args,
              New_Occurrence_Of (Defining_Identifier (Decl), Loc));
            Append_List (Decls, Res);
         end if;

      else
         Decls := No_List;
         Decl  := Empty;
      end if;

      --  Handle the optionally generated formal *_skip_null_excluding_checks

      --  Look at the associated node for the object we are referencing and
      --  verify that we are expanding a call to an Init_Proc for an internally
      --  generated object declaration before passing True and skipping the
      --  relevant checks.

      if Needs_Conditional_Null_Excluding_Check (Full_Init_Type)
        and then Nkind (Id_Ref) in N_Has_Entity
        and then (Comes_From_Source (Id_Ref)
                   or else (Present (Associated_Node (Id_Ref))
                             and then Comes_From_Source
                                        (Associated_Node (Id_Ref))))
      then
         Append_To (Args, New_Occurrence_Of (Standard_True, Loc));
      end if;

      --  Add discriminant values if discriminants are present

      if Has_Discriminants (Full_Init_Type) then
         --  If an allocated object will be constrained by the default
         --  values for discriminants, then build a subtype with those
         --  defaults, and change the allocated subtype to that. Note
         --  that this happens in fewer cases in Ada 2005 (AI95-0363).

         if Nkind (N) = N_Allocator
           and then not Is_Constrained (Full_Type)
           and then
             Present
               (Discriminant_Default_Value (First_Discriminant (Full_Type)))
           and then (Ada_Version < Ada_2005
                      or else not Object_Type_Has_Constrained_Partial_View
                                    (Full_Type, Current_Scope))
         then
            Full_Type := Build_Default_Subtype (Full_Type, N);
            Set_Expression (N, New_Occurrence_Of (Full_Type, Loc));
         end if;

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

            --  If this is a discriminated concurrent type, the init_proc
            --  for the corresponding record is being called. Use that type
            --  directly to find the discriminant value, to handle properly
            --  intervening renamed discriminants.

            declare
               T : Entity_Id := Full_Type;

            begin
               if Is_Protected_Type (T) then
                  T := Corresponding_Record_Type (T);
               end if;

               Arg :=
                 Get_Discriminant_Value (
                   Discr,
                   T,
                   Discriminant_Constraint (Full_Type));
            end;

            --  If the target has access discriminants, and is constrained by
            --  an access to the enclosing construct, i.e. a current instance,
            --  replace the reference to the type by a reference to the object.

            if Nkind (Arg) = N_Attribute_Reference
              and then Is_Access_Type (Etype (Arg))
              and then Is_Entity_Name (Prefix (Arg))
              and then Is_Type (Entity (Prefix (Arg)))
            then
               Arg :=
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Copy (Prefix (Id_Ref)),
                   Attribute_Name => Name_Unrestricted_Access);

            elsif In_Init_Proc then

               --  Replace any possible references to the discriminant in the
               --  call to the record initialization procedure with references
               --  to the appropriate formal parameter.

               if Nkind (Arg) = N_Identifier
                 and then Ekind (Entity (Arg)) = E_Discriminant
               then
                  Arg := New_Occurrence_Of (Discriminal (Entity (Arg)), Loc);

               --  Otherwise make a copy of the default expression. Note that
               --  we use the current Sloc for this, because we do not want the
               --  call to appear to be at the declaration point. Within the
               --  expression, replace discriminants with their discriminals.

               else
                  Arg :=
                    New_Copy_Tree (Arg, Map => Discr_Map, New_Sloc => Loc);
               end if;

            else
               if Is_Constrained (Full_Type) then
                  Arg := Duplicate_Subexpr_No_Checks (Arg);
               else
                  --  The constraints come from the discriminant default exps,
                  --  they must be reevaluated, so we use New_Copy_Tree but we
                  --  ensure the proper Sloc (for any embedded calls).
                  --  In addition, if a predicate check is needed on the value
                  --  of the discriminant, insert it ahead of the call.

                  Arg := New_Copy_Tree (Arg, New_Sloc => Loc);
               end if;

               if Has_Predicates (Etype (Discr)) then
                  Check_Predicated_Discriminant (Arg, Discr);
               end if;
            end if;

            --  Ada 2005 (AI-287): In case of default initialized components,
            --  if the component is constrained with a discriminant of the
            --  enclosing type, we need to generate the corresponding selected
            --  component node to access the discriminant value. In other cases
            --  this is not required, either  because we are inside the init
            --  proc and we use the corresponding formal, or else because the
            --  component is constrained by an expression.

            if With_Default_Init
              and then Nkind (Id_Ref) = N_Selected_Component
              and then Nkind (Arg) = N_Identifier
              and then Ekind (Entity (Arg)) = E_Discriminant
            then
               Append_To (Args,
                 Make_Selected_Component (Loc,
                   Prefix        => New_Copy_Tree (Prefix (Id_Ref)),
                   Selector_Name => Arg));
            else
               Append_To (Args, Arg);
            end if;

            Next_Discriminant (Discr);
         end loop;
      end if;

      --  If this is a call to initialize the parent component of a derived
      --  tagged type, indicate that the tag should not be set in the parent.
      --  This is done via the actual parameter value for the Init_Control
      --  formal parameter, which is also used to deal with late initialization
      --  requirements.
      --
      --  We pass in Full_Init_Except_Tag unless the caller tells us to do
      --  otherwise (by passing in a nonempty Init_Control_Actual parameter).

      if Is_Tagged_Type (Full_Init_Type)
        and then not Is_CPP_Class (Full_Init_Type)
        and then Nkind (Id_Ref) = N_Selected_Component
        and then Chars (Selector_Name (Id_Ref)) = Name_uParent
      then
         Append_To (Args,
           (if Present (Init_Control_Actual)
            then Init_Control_Actual
            else Make_Mode_Literal (Loc, Full_Init_Except_Tag)));
      elsif Present (Constructor_Ref) then
         Append_List_To (Args,
           New_Copy_List (Parameter_Associations (Constructor_Ref)));
      end if;

      --  Pass the extra accessibility level parameter associated with the
      --  level of the object being initialized when required.

      if Is_Entity_Name (Id_Ref)
        and then Present (Init_Proc_Level_Formal (Proc))
      then
         Append_To (Args,
           Make_Parameter_Association (Loc,
             Selector_Name             =>
               Make_Identifier (Loc, Name_uInit_Level),
             Explicit_Actual_Parameter =>
               Accessibility_Level (Id_Ref, Dynamic_Level)));
      end if;

      Append_To (Res,
        Make_Procedure_Call_Statement (Loc,
          Name                   => New_Occurrence_Of (Proc, Loc),
          Parameter_Associations => Args));

      if Needs_Finalization (Typ)
        and then Nkind (Id_Ref) = N_Selected_Component
      then
         if Chars (Selector_Name (Id_Ref)) /= Name_uParent then
            Init_Call :=
              Make_Init_Call
                (Obj_Ref => New_Copy_Tree (First_Arg),
                 Typ     => Typ);

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

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

      return Res;

   exception
      when RE_Not_Available =>
         return Empty_List;
   end Build_Initialization_Call;

   ----------------------------
   -- Build_Record_Init_Proc --
   ----------------------------

   procedure Build_Record_Init_Proc (N : Node_Id; Rec_Ent : Entity_Id) is
      Decls     : constant List_Id  := New_List;
      Discr_Map : constant Elist_Id := New_Elmt_List;
      Loc       : constant Source_Ptr := Sloc (Rec_Ent);
      Counter   : Nat := 0;
      Proc_Id   : Entity_Id;
      Rec_Type  : Entity_Id;

      Init_Control_Formal : Entity_Id := Empty; -- set in Build_Init_Statements
      Has_Late_Init_Comp  : Boolean := False;   -- set in Build_Init_Statements

      function Build_Assignment
        (Id      : Entity_Id;
         Default : Node_Id) return List_Id;
      --  Build an assignment statement that assigns the default expression to
      --  its corresponding record component if defined. The left-hand side of
      --  the assignment is marked Assignment_OK so that initialization of
      --  limited private records works correctly. This routine may also build
      --  an adjustment call if the component is controlled.

      procedure Build_Discriminant_Assignments (Statement_List : List_Id);
      --  If the record has discriminants, add assignment statements to
      --  Statement_List to initialize the discriminant values from the
      --  arguments of the initialization procedure.

      function Build_Init_Statements (Comp_List : Node_Id) return List_Id;
      --  Build a list representing a sequence of statements which initialize
      --  components of the given component list. This may involve building
      --  case statements for the variant parts. Append any locally declared
      --  objects on list Decls.

      function Build_Init_Call_Thru (Parameters : List_Id) return List_Id;
      --  Given an untagged type-derivation that declares discriminants, e.g.
      --
      --     type R (R1, R2 : Integer) is record ... end record;
      --     type D (D1 : Integer) is new R (1, D1);
      --
      --  we make the _init_proc of D be
      --
      --       procedure _init_proc (X : D; D1 : Integer) is
      --       begin
      --          _init_proc (R (X), 1, D1);
      --       end _init_proc;
      --
      --  This function builds the call statement in this _init_proc.

      procedure Build_CPP_Init_Procedure;
      --  Build the tree corresponding to the procedure specification and body
      --  of the IC procedure that initializes the C++ part of the dispatch
      --  table of an Ada tagged type that is a derivation of a CPP type.
      --  Install it as the CPP_Init TSS.

      procedure Build_Init_Procedure;
      --  Build the tree corresponding to the procedure specification and body
      --  of the initialization procedure and install it as the _init TSS.

      procedure Build_Offset_To_Top_Functions;
      --  Ada 2005 (AI-251): Build the tree corresponding to the procedure spec
      --  and body of Offset_To_Top, a function used in conjuction with types
      --  having secondary dispatch tables.

      procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id);
      --  Add range checks to components of discriminated records. S is a
      --  subtype indication of a record component. Check_List is a list
      --  to which the check actions are appended.

      function Component_Needs_Simple_Initialization
        (T : Entity_Id) return Boolean;
      --  Determine if a component needs simple initialization, given its type
      --  T. This routine is the same as Needs_Simple_Initialization except for
      --  components of type Tag and Interface_Tag. These two access types do
      --  not require initialization since they are explicitly initialized by
      --  other means.

      function Parent_Subtype_Renaming_Discrims return Boolean;
      --  Returns True for base types N that rename discriminants, else False

      function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean;
      --  Determine whether a record initialization procedure needs to be
      --  generated for the given record type.

      ----------------------
      -- Build_Assignment --
      ----------------------

      function Build_Assignment
        (Id      : Entity_Id;
         Default : Node_Id) return List_Id
      is
         Default_Loc : constant Source_Ptr := Sloc (Default);
         Typ         : constant Entity_Id  := Underlying_Type (Etype (Id));

         Exp   : Node_Id;
         Exp_Q : Node_Id;
         Lhs   : Node_Id;
         Res   : List_Id;

      begin
         Lhs :=
           Make_Selected_Component (Default_Loc,
             Prefix        => Make_Identifier (Loc, Name_uInit),
             Selector_Name => New_Occurrence_Of (Id, Default_Loc));
         Set_Assignment_OK (Lhs);

         --  Take copy of Default to ensure that later copies of this component
         --  declaration in derived types see the original tree, not a node
         --  rewritten during expansion of the init_proc. If the copy contains
         --  itypes, the scope of the new itypes is the init_proc being built.

         declare
            Map : Elist_Id := No_Elist;

         begin
            if Has_Late_Init_Comp then
               --  Map the type to the _Init parameter in order to
               --  handle "current instance" references.

               Map := New_Elmt_List
                        (Elmt1 => Rec_Type,
                         Elmt2 => Defining_Identifier (First
                                   (Parameter_Specifications
                                      (Parent (Proc_Id)))));

               --  If the type has an incomplete view, a current instance
               --  may have an incomplete type. In that case, it must also be
               --  replaced by the formal of the Init_Proc.

               if Present (Incomplete_View (Rec_Type)) then
                  Append_Elmt (
                    N  => Incomplete_View (Rec_Type),
                    To => Map);
                  Append_Elmt (
                    N  => Defining_Identifier
                            (First
                              (Parameter_Specifications
                                (Parent (Proc_Id)))),
                    To => Map);
               end if;
            end if;

            Exp := New_Copy_Tree (Default, New_Scope => Proc_Id, Map => Map);
         end;

         Res := New_List (
           Make_Assignment_Statement (Loc,
             Name       => Lhs,
             Expression => Exp));

         Exp_Q := Unqualify (Exp);

         --  Adjust the component if controlled, except if the expression is an
         --  aggregate that will be expanded inline (but note that the case of
         --  container aggregates does require component adjustment), or else
         --  a function call whose result is adjusted in the called function.
         --  Note that, when we don't inhibit component adjustment, the tag
         --  will be automatically inserted by Make_Tag_Ctrl_Assignment in the
         --  tagged case. Otherwise, we have to generate a tag assignment here.

         if Needs_Finalization (Typ)
           and then (Nkind (Exp_Q) not in N_Aggregate | N_Extension_Aggregate
                      or else Is_Container_Aggregate (Exp_Q))
           and then not Is_Build_In_Place_Function_Call (Exp)
           and then not (Back_End_Return_Slot
                          and then Nkind (Exp) = N_Function_Call)
         then
            Set_No_Finalize_Actions (First (Res));

         else
            Set_No_Ctrl_Actions (First (Res));

            --  Adjust the tag if tagged because of possible view conversions

            if Is_Tagged_Type (Typ)
              and then Tagged_Type_Expansion
              and then Nkind (Exp_Q) /= N_Raise_Expression
            then
               declare
                  Utyp : Entity_Id := Underlying_Type (Typ);

               begin
                  --  Get the relevant type for Make_Tag_Assignment_From_Type,
                  --  which, for concurrent types is the corresponding record.

                  if Ekind (Utyp) in E_Protected_Type | E_Task_Type then
                     Utyp := Corresponding_Record_Type (Utyp);
                  end if;

                  Append_To (Res,
                    Make_Tag_Assignment_From_Type (Default_Loc,
                      New_Copy_Tree (Lhs, New_Scope => Proc_Id),
                      Utyp));
               end;
            end if;
         end if;

         return Res;

      exception
         when RE_Not_Available =>
            return Empty_List;
      end Build_Assignment;

      ------------------------------------
      -- Build_Discriminant_Assignments --
      ------------------------------------

      procedure Build_Discriminant_Assignments (Statement_List : List_Id) is
         Is_Tagged : constant Boolean := Is_Tagged_Type (Rec_Type);
         D         : Entity_Id;
         D_Loc     : Source_Ptr;

      begin
         if Has_Discriminants (Rec_Type)
           and then not Is_Unchecked_Union (Rec_Type)
         then
            D := First_Discriminant (Rec_Type);
            while Present (D) loop

               --  Don't generate the assignment for discriminants in derived
               --  tagged types if the discriminant is a renaming of some
               --  ancestor discriminant. This initialization will be done
               --  when initializing the _parent field of the derived record.

               if Is_Tagged
                 and then Present (Corresponding_Discriminant (D))
               then
                  null;

               else
                  D_Loc := Sloc (D);
                  Append_List_To (Statement_List,
                    Build_Assignment (D,
                      New_Occurrence_Of (Discriminal (D), D_Loc)));
               end if;

               Next_Discriminant (D);
            end loop;
         end if;
      end Build_Discriminant_Assignments;

      --------------------------
      -- Build_Init_Call_Thru --
      --------------------------

      function Build_Init_Call_Thru (Parameters : List_Id) return List_Id is
         Parent_Proc : constant Entity_Id :=
                         Base_Init_Proc (Etype (Rec_Type));

         Parent_Type : constant Entity_Id :=
                         Etype (First_Formal (Parent_Proc));

         Uparent_Type : constant Entity_Id :=
                          Underlying_Type (Parent_Type);

         First_Discr_Param : Node_Id;

         Arg          : Node_Id;
         Args         : List_Id;
         First_Arg    : Node_Id;
         Parent_Discr : Entity_Id;
         Res          : List_Id;

      begin
         --  First argument (_Init) is the object to be initialized.
         --  ??? not sure where to get a reasonable Loc for First_Arg

         First_Arg :=
           OK_Convert_To (Parent_Type,
             New_Occurrence_Of
               (Defining_Identifier (First (Parameters)), Loc));

         Set_Etype (First_Arg, Parent_Type);

         Args := New_List (Convert_Concurrent (First_Arg, Rec_Type));

         --  In the tasks case,
         --    add _Master as the value of the _Master parameter
         --    add _Chain as the value of the _Chain parameter.
         --    add _Task_Name as the value of the _Task_Name parameter.
         --  At the outer level, these will be variables holding the
         --  corresponding values obtained from GNARL or the expander.
         --
         --  At inner levels, they will be the parameters passed down through
         --  the outer routines.

         First_Discr_Param := Next (First (Parameters));

         if Has_Task (Rec_Type) then
            if Restriction_Active (No_Task_Hierarchy) then
               Append_To
                 (Args, Make_Integer_Literal (Loc, Library_Task_Level));
            else
               Append_To (Args, Make_Identifier (Loc, Name_uMaster));
            end if;

            --  Add _Chain (not done for sequential elaboration policy, see
            --  comment for Create_Restricted_Task_Sequential in s-tarest.ads).

            if Partition_Elaboration_Policy /= 'S' then
               Append_To (Args, Make_Identifier (Loc, Name_uChain));
            end if;

            Append_To (Args, Make_Identifier (Loc, Name_uTask_Name));
            First_Discr_Param := Next (Next (Next (First_Discr_Param)));
         end if;

         --  Append discriminant values

         if Has_Discriminants (Uparent_Type) then
            pragma Assert (not Is_Tagged_Type (Uparent_Type));

            Parent_Discr := First_Discriminant (Uparent_Type);
            while Present (Parent_Discr) loop

               --  Get the initial value for this discriminant
               --  ??? needs to be cleaned up to use parent_Discr_Constr
               --  directly.

               declare
                  Discr       : Entity_Id :=
                                  First_Stored_Discriminant (Uparent_Type);

                  Discr_Value : Elmt_Id :=
                                  First_Elmt (Stored_Constraint (Rec_Type));

               begin
                  while Original_Record_Component (Parent_Discr) /= Discr loop
                     Next_Stored_Discriminant (Discr);
                     Next_Elmt (Discr_Value);
                  end loop;

                  Arg := Node (Discr_Value);
               end;

               --  Append it to the list

               if Nkind (Arg) = N_Identifier
                 and then Ekind (Entity (Arg)) = E_Discriminant
               then
                  Append_To (Args,
                    New_Occurrence_Of (Discriminal (Entity (Arg)), Loc));

               --  Case of access discriminants. We replace the reference
               --  to the type by a reference to the actual object.

               --  Is above comment right??? Use of New_Copy below seems mighty
               --  suspicious ???

               else
                  Append_To (Args, New_Copy (Arg));
               end if;

               Next_Discriminant (Parent_Discr);
            end loop;
         end if;

         Res :=
           New_List (
             Make_Procedure_Call_Statement (Loc,
               Name                   =>
                 New_Occurrence_Of (Parent_Proc, Loc),
               Parameter_Associations => Args));

         return Res;
      end Build_Init_Call_Thru;

      -----------------------------------
      -- Build_Offset_To_Top_Functions --
      -----------------------------------

      procedure Build_Offset_To_Top_Functions is

         procedure Build_Offset_To_Top_Function (Iface_Comp : Entity_Id);
         --  Generate:
         --    function Fxx (O : Address) return Storage_Offset is
         --       type Acc is access all <Typ>;
         --    begin
         --       return Acc!(O).Iface_Comp'Position;
         --    end Fxx;

         ----------------------------------
         -- Build_Offset_To_Top_Function --
         ----------------------------------

         procedure Build_Offset_To_Top_Function (Iface_Comp : Entity_Id) is
            Body_Node : Node_Id;
            Func_Id   : Entity_Id;
            Spec_Node : Node_Id;
            Acc_Type  : Entity_Id;

         begin
            Func_Id := Make_Temporary (Loc, 'F');
            Set_DT_Offset_To_Top_Func (Iface_Comp, Func_Id);

            --  Generate
            --    function Fxx (O : in Rec_Typ) return Storage_Offset;

            Spec_Node := New_Node (N_Function_Specification, Loc);
            Set_Defining_Unit_Name (Spec_Node, Func_Id);
            Set_Parameter_Specifications (Spec_Node, New_List (
              Make_Parameter_Specification (Loc,
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uO),
                In_Present          => True,
                Parameter_Type      =>
                  New_Occurrence_Of (RTE (RE_Address), Loc))));
            Set_Result_Definition (Spec_Node,
              New_Occurrence_Of (RTE (RE_Storage_Offset), Loc));

            --  Generate
            --    function Fxx (O : in Rec_Typ) return Storage_Offset is
            --    begin
            --       return -O.Iface_Comp'Position;
            --    end Fxx;

            Body_Node := New_Node (N_Subprogram_Body, Loc);
            Set_Specification (Body_Node, Spec_Node);

            Acc_Type := Make_Temporary (Loc, 'T');
            Set_Declarations (Body_Node, New_List (
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Acc_Type,
                Type_Definition     =>
                  Make_Access_To_Object_Definition (Loc,
                    All_Present        => True,
                    Subtype_Indication =>
                      New_Occurrence_Of (Rec_Type, Loc)))));

            Set_Handled_Statement_Sequence (Body_Node,
              Make_Handled_Sequence_Of_Statements (Loc,
                Statements     => New_List (
                  Make_Simple_Return_Statement (Loc,
                    Expression =>
                      Make_Op_Minus (Loc,
                        Make_Attribute_Reference (Loc,
                          Prefix         =>
                            Make_Selected_Component (Loc,
                              Prefix        =>
                                Make_Explicit_Dereference (Loc,
                                  Unchecked_Convert_To (Acc_Type,
                                    Make_Identifier (Loc, Name_uO))),
                              Selector_Name =>
                                New_Occurrence_Of (Iface_Comp, Loc)),
                          Attribute_Name => Name_Position))))));

            Mutate_Ekind    (Func_Id, E_Function);
            Set_Mechanism   (Func_Id, Default_Mechanism);
            Set_Is_Internal (Func_Id, True);

            if not Debug_Generated_Code then
               Set_Debug_Info_Off (Func_Id);
            end if;

            Analyze (Body_Node);

            Append_Freeze_Action (Rec_Type, Body_Node);
         end Build_Offset_To_Top_Function;

         --  Local variables

         Iface_Comp       : Node_Id;
         Iface_Comp_Elmt  : Elmt_Id;
         Ifaces_Comp_List : Elist_Id;

      --  Start of processing for Build_Offset_To_Top_Functions

      begin
         --  Offset_To_Top_Functions are built only for derivations of types
         --  with discriminants that cover interface types.
         --  Nothing is needed either in case of virtual targets, since
         --  interfaces are handled directly by the target.

         if not Is_Tagged_Type (Rec_Type)
           or else Etype (Rec_Type) = Rec_Type
           or else not Has_Discriminants (Etype (Rec_Type))
           or else not Tagged_Type_Expansion
         then
            return;
         end if;

         Collect_Interface_Components (Rec_Type, Ifaces_Comp_List);

         --  For each interface type with secondary dispatch table we generate
         --  the Offset_To_Top_Functions (required to displace the pointer in
         --  interface conversions)

         Iface_Comp_Elmt := First_Elmt (Ifaces_Comp_List);
         while Present (Iface_Comp_Elmt) loop
            Iface_Comp := Node (Iface_Comp_Elmt);
            pragma Assert (Is_Interface (Related_Type (Iface_Comp)));

            --  If the interface is a parent of Rec_Type it shares the primary
            --  dispatch table and hence there is no need to build the function

            if not Is_Ancestor (Related_Type (Iface_Comp), Rec_Type,
                                Use_Full_View => True)
            then
               Build_Offset_To_Top_Function (Iface_Comp);
            end if;

            Next_Elmt (Iface_Comp_Elmt);
         end loop;
      end Build_Offset_To_Top_Functions;

      ------------------------------
      -- Build_CPP_Init_Procedure --
      ------------------------------

      procedure Build_CPP_Init_Procedure is
         Body_Node         : Node_Id;
         Body_Stmts        : List_Id;
         Flag_Id           : Entity_Id;
         Handled_Stmt_Node : Node_Id;
         Init_Tags_List    : List_Id;
         Proc_Id           : Entity_Id;
         Proc_Spec_Node    : Node_Id;

      begin
         --  Check cases requiring no IC routine

         if not Is_CPP_Class (Root_Type (Rec_Type))
           or else Is_CPP_Class (Rec_Type)
           or else CPP_Num_Prims (Rec_Type) = 0
           or else not Tagged_Type_Expansion
           or else No_Run_Time_Mode
         then
            return;
         end if;

         --  Generate:

         --     Flag : Boolean := False;
         --
         --     procedure Typ_IC is
         --     begin
         --        if not Flag then
         --           Copy C++ dispatch table slots from parent
         --           Update C++ slots of overridden primitives
         --        end if;
         --     end;

         Flag_Id := Make_Temporary (Loc, 'F');

         Append_Freeze_Action (Rec_Type,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Flag_Id,
             Object_Definition =>
               New_Occurrence_Of (Standard_Boolean, Loc),
             Expression =>
               New_Occurrence_Of (Standard_True, Loc)));

         Body_Stmts := New_List;
         Body_Node  := New_Node (N_Subprogram_Body, Loc);

         Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);

         Proc_Id :=
           Make_Defining_Identifier (Loc,
             Chars => Make_TSS_Name (Rec_Type, TSS_CPP_Init_Proc));

         Mutate_Ekind    (Proc_Id, E_Procedure);
         Set_Is_Internal (Proc_Id);

         Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);

         Set_Parameter_Specifications (Proc_Spec_Node, New_List);
         Set_Specification (Body_Node, Proc_Spec_Node);
         Set_Declarations  (Body_Node, New_List);

         Init_Tags_List := Build_Inherit_CPP_Prims (Rec_Type);

         Append_To (Init_Tags_List,
           Make_Assignment_Statement (Loc,
             Name =>
               New_Occurrence_Of (Flag_Id, Loc),
             Expression =>
               New_Occurrence_Of (Standard_False, Loc)));

         Append_To (Body_Stmts,
           Make_If_Statement (Loc,
             Condition => New_Occurrence_Of (Flag_Id, Loc),
             Then_Statements => Init_Tags_List));

         Handled_Stmt_Node :=
           New_Node (N_Handled_Sequence_Of_Statements, Loc);
         Set_Statements (Handled_Stmt_Node, Body_Stmts);
         Set_Exception_Handlers (Handled_Stmt_Node, No_List);
         Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);

         if not Debug_Generated_Code then
            Set_Debug_Info_Off (Proc_Id);
         end if;

         --  Associate CPP_Init_Proc with type

         Set_Init_Proc (Rec_Type, Proc_Id);
      end Build_CPP_Init_Procedure;

      --------------------------
      -- Build_Init_Procedure --
      --------------------------

      procedure Build_Init_Procedure is
         Body_Stmts            : List_Id;
         Body_Node             : Node_Id;
         Handled_Stmt_Node     : Node_Id;
         Init_Tags_List        : List_Id;
         Parameters            : List_Id;
         Proc_Spec_Node        : Node_Id;
         Record_Extension_Node : Node_Id;

         use Initialization_Control;
      begin
         Body_Stmts := New_List;
         Body_Node := New_Node (N_Subprogram_Body, Loc);
         Mutate_Ekind (Proc_Id, E_Procedure);

         Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
         Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);

         Parameters := Init_Formals (Rec_Type, Proc_Id);
         Append_List_To (Parameters,
           Build_Discriminant_Formals (Rec_Type, True));

         --  For tagged types, we add a parameter to indicate what
         --  portion of the object's initialization is to be performed.
         --  This is used for two purposes:
         --   1)  When a type extension's initialization procedure calls
         --       the initialization procedure of the parent type, we do
         --       not want the parent to initialize the Tag component;
         --       it has been set already.
         --   2)  If an ancestor type has at least one component that requires
         --       late initialization, then we need to be able to initialize
         --       those components separately after initializing any other
         --       components.

         if Is_Tagged_Type (Rec_Type) then
            Init_Control_Formal := Make_Temporary (Loc, 'P');

            Append_To (Parameters,
              Make_Parameter_Specification (Loc,
                Defining_Identifier => Init_Control_Formal,
                Parameter_Type =>
                  New_Occurrence_Of (Standard_Natural, Loc),
                Expression => Make_Mode_Literal (Loc, Full_Init)));
         end if;

         --  Create an extra accessibility parameter to capture the level of
         --  the object being initialized when its type is a limited record.

         if Is_Limited_Record (Rec_Type) then
            Append_To (Parameters,
              Make_Parameter_Specification (Loc,
                Defining_Identifier => Make_Defining_Identifier
                                         (Loc, Name_uInit_Level),
                Parameter_Type      =>
                  New_Occurrence_Of (Standard_Natural, Loc),
                Expression          =>
                  Make_Integer_Literal
                    (Loc, Scope_Depth (Standard_Standard))));
         end if;

         Set_Parameter_Specifications (Proc_Spec_Node, Parameters);
         Freeze_Extra_Formals (Proc_Id);
         Set_Specification (Body_Node, Proc_Spec_Node);
         Set_Declarations (Body_Node, Decls);

         --  N is a Derived_Type_Definition that renames the parameters of the
         --  ancestor type. We initialize it by expanding our discriminants and
         --  call the ancestor _init_proc with a type-converted object.

         if Parent_Subtype_Renaming_Discrims then
            Append_List_To (Body_Stmts, Build_Init_Call_Thru (Parameters));

         elsif Nkind (Type_Definition (N)) = N_Record_Definition then
            Build_Discriminant_Assignments (Body_Stmts);

            if not Null_Present (Type_Definition (N)) then
               Append_List_To (Body_Stmts,
                 Build_Init_Statements (Component_List (Type_Definition (N))));
            end if;

         --  N is a Derived_Type_Definition with a possible non-empty
         --  extension. The initialization of a type extension consists in the
         --  initialization of the components in the extension.

         else
            Build_Discriminant_Assignments (Body_Stmts);

            Record_Extension_Node :=
              Record_Extension_Part (Type_Definition (N));

            if not Null_Present (Record_Extension_Node) then
               declare
                  Stmts : constant List_Id :=
                            Build_Init_Statements (
                              Component_List (Record_Extension_Node));

               begin
                  --  The parent field must be initialized first because the
                  --  offset of the new discriminants may depend on it. This is
                  --  not needed if the parent is an interface type because in
                  --  such case the initialization of the _parent field was not
                  --  generated.

                  if not Is_Interface (Etype (Rec_Ent)) then
                     declare
                        Parent_IP : constant Name_Id :=
                                      Make_Init_Proc_Name (Etype (Rec_Ent));
                        Stmt      : Node_Id := First (Stmts);
                        IP_Call   : Node_Id := Empty;
                     begin
                        --  Look for a call to the parent IP associated with
                        --  the record extension.
                        --  The call will be inside not one but two
                        --  if-statements (with the same condition). Testing
                        --  the same Early_Init condition twice might seem
                        --  redundant. However, as soon as we exit this loop,
                        --  we are going to hoist the inner if-statement out
                        --  of the outer one; the "redundant" test was built
                        --  in anticipation of this hoisting.

                        while Present (Stmt) loop
                           if Nkind (Stmt) = N_If_Statement then
                              declare
                                 Then_Stmt1 : Node_Id :=
                                   First (Then_Statements (Stmt));
                                 Then_Stmt2 : Node_Id;
                              begin
                                 while Present (Then_Stmt1) loop
                                    if Nkind (Then_Stmt1) = N_If_Statement then
                                       Then_Stmt2 :=
                                         First (Then_Statements (Then_Stmt1));

                                       if Nkind (Then_Stmt2) =
                                            N_Procedure_Call_Statement
                                         and then Chars (Name (Then_Stmt2)) =
                                           Parent_IP
                                       then
                                          --  IP_Call is a call wrapped in an
                                          --  if statement.
                                          IP_Call := Then_Stmt1;
                                          exit;
                                       end if;
                                    end if;
                                    Next (Then_Stmt1);
                                 end loop;
                              end;
                           end if;

                           Next (Stmt);
                        end loop;

                        --  If found then move it to the beginning of the
                        --  statements of this IP routine

                        if Present (IP_Call) then
                           Remove (IP_Call);
                           Prepend_List_To (Body_Stmts, New_List (IP_Call));
                        end if;
                     end;
                  end if;

                  Append_List_To (Body_Stmts, Stmts);
               end;
            end if;
         end if;

         --  Add here the assignment to initialize the Tag

         --  The assignment corresponds to the code:

         --     _Init._Tag := Typ'Tag;

         --  Suppress the tag assignment when not Tagged_Type_Expansion because
         --  tags are represented implicitly in objects. It is also suppressed
         --  in case of CPP_Class types because in this case the tag is
         --  initialized in the C++ side.

         if Is_Tagged_Type (Rec_Type)
           and then Tagged_Type_Expansion
           and then not No_Run_Time_Mode
         then
            --  Case 1: Ada tagged types with no CPP ancestor. Set the tags of
            --  the actual object and invoke the IP of the parent (in this
            --  order). The tag must be initialized before the call to the IP
            --  of the parent and the assignments to other components because
            --  the initial value of the components may depend on the tag (eg.
            --  through a dispatching operation on an access to the current
            --  type). The tag assignment is not done when initializing the
            --  parent component of a type extension, because in that case the
            --  tag is set in the extension.

            if not Is_CPP_Class (Root_Type (Rec_Type)) then

               --  Initialize the primary tag component

               Init_Tags_List := New_List (
                 Make_Tag_Assignment_From_Type
                   (Loc, Make_Identifier (Loc, Name_uInit), Rec_Type));

               --  Ensure that Program_Error is raised if a mutably class-wide
               --  abstract tagged type is initialized by default.

               if Is_Abstract_Type (Rec_Type)
                 and then Is_Mutably_Tagged_Type (Class_Wide_Type (Rec_Type))
               then
                  Append_To (Init_Tags_List,
                    Make_Raise_Program_Error (Loc,
                      Reason => PE_Abstract_Type_Component));
               end if;

               --  Ada 2005 (AI-251): Initialize the secondary tags components
               --  located at fixed positions (tags whose position depends on
               --  variable size components are initialized later ---see below)

               if Ada_Version >= Ada_2005
                 and then not Is_Interface (Rec_Type)
                 and then Has_Interfaces (Rec_Type)
               then
                  declare
                     Elab_Sec_DT_Stmts_List : constant List_Id := New_List;
                     Elab_List              : List_Id          := New_List;

                  begin
                     Init_Secondary_Tags
                       (Typ            => Rec_Type,
                        Target         => Make_Identifier (Loc, Name_uInit),
                        Init_Tags_List => Init_Tags_List,
                        Stmts_List     => Elab_Sec_DT_Stmts_List,
                        Fixed_Comps    => True,
                        Variable_Comps => False);

                     Elab_List := New_List (
                       Make_If_Statement (Loc,
                         Condition       =>
                           Tag_Init_Condition (Loc, Init_Control_Formal),
                         Then_Statements => Init_Tags_List));

                     if Elab_Flag_Needed (Rec_Type) then
                        Append_To (Elab_Sec_DT_Stmts_List,
                          Make_Assignment_Statement (Loc,
                            Name       =>
                              New_Occurrence_Of
                                (Access_Disp_Table_Elab_Flag (Rec_Type),
                                 Loc),
                            Expression =>
                              New_Occurrence_Of (Standard_False, Loc)));

                        Append_To (Elab_List,
                          Make_If_Statement (Loc,
                            Condition       =>
                              New_Occurrence_Of
                                (Access_Disp_Table_Elab_Flag (Rec_Type), Loc),
                            Then_Statements => Elab_Sec_DT_Stmts_List));
                     end if;

                     Prepend_List_To (Body_Stmts, Elab_List);
                  end;
               else
                  Prepend_To (Body_Stmts,
                    Make_If_Statement (Loc,
                      Condition =>
                        Tag_Init_Condition (Loc, Init_Control_Formal),
                      Then_Statements => Init_Tags_List));
               end if;

            --  Case 2: CPP type. The imported C++ constructor takes care of
            --  tags initialization. No action needed here because the IP
            --  is built by Set_CPP_Constructors; in this case the IP is a
            --  wrapper that invokes the C++ constructor and copies the C++
            --  tags locally. Done to inherit the C++ slots in Ada derivations
            --  (see case 3).

            elsif Is_CPP_Class (Rec_Type) then
               pragma Assert (False);
               null;

            --  Case 3: Combined hierarchy containing C++ types and Ada tagged
            --  type derivations. Derivations of imported C++ classes add a
            --  complication, because we cannot inhibit tag setting in the
            --  constructor for the parent. Hence we initialize the tag after
            --  the call to the parent IP (that is, in reverse order compared
            --  with pure Ada hierarchies ---see comment on case 1).

            else
               --  Initialize the primary tag

               Init_Tags_List := New_List (
                 Make_Tag_Assignment_From_Type
                   (Loc, Make_Identifier (Loc, Name_uInit), Rec_Type));

               --  Ada 2005 (AI-251): Initialize the secondary tags components
               --  located at fixed positions (tags whose position depends on
               --  variable size components are initialized later ---see below)

               if Ada_Version >= Ada_2005
                 and then not Is_Interface (Rec_Type)
                 and then Has_Interfaces (Rec_Type)
               then
                  Init_Secondary_Tags
                    (Typ            => Rec_Type,
                     Target         => Make_Identifier (Loc, Name_uInit),
                     Init_Tags_List => Init_Tags_List,
                     Stmts_List     => Init_Tags_List,
                     Fixed_Comps    => True,
                     Variable_Comps => False);
               end if;

               --  Initialize the tag component after invocation of parent IP.

               --  Generate:
               --     parent_IP(_init.parent); // Invokes the C++ constructor
               --     [ typIC; ]               // Inherit C++ slots from parent
               --     init_tags

               declare
                  Ins_Nod : Node_Id;

               begin
                  --  Search for the call to the IP of the parent. We assume
                  --  that the first init_proc call is for the parent.
                  --  It is wrapped in an "if Early_Init_Condition"
                  --  if-statement.

                  Ins_Nod := First (Body_Stmts);
                  while Present (Next (Ins_Nod))
                    and then
                      (Nkind (Ins_Nod) /= N_If_Statement
                        or else Nkind (First (Then_Statements (Ins_Nod)))
                                  /= N_Procedure_Call_Statement
                        or else not Is_Init_Proc
                                      (Name (First (Then_Statements
                                         (Ins_Nod)))))
                  loop
                     Next (Ins_Nod);
                  end loop;

                  --  The IC routine copies the inherited slots of the C+ part
                  --  of the dispatch table from the parent and updates the
                  --  overridden C++ slots.

                  if CPP_Num_Prims (Rec_Type) > 0 then
                     declare
                        Init_DT : Entity_Id;
                        New_Nod : Node_Id;

                     begin
                        Init_DT := CPP_Init_Proc (Rec_Type);
                        pragma Assert (Present (Init_DT));

                        New_Nod :=
                          Make_Procedure_Call_Statement (Loc,
                            New_Occurrence_Of (Init_DT, Loc));
                        Insert_After (Ins_Nod, New_Nod);

                        --  Update location of init tag statements

                        Ins_Nod := New_Nod;
                     end;
                  end if;

                  Insert_List_After (Ins_Nod, Init_Tags_List);
               end;
            end if;

            --  Ada 2005 (AI-251): Initialize the secondary tag components
            --  located at variable positions. We delay the generation of this
            --  code until here because the value of the attribute 'Position
            --  applied to variable size components of the parent type that
            --  depend on discriminants is only safely read at runtime after
            --  the parent components have been initialized.

            if Ada_Version >= Ada_2005
              and then not Is_Interface (Rec_Type)
              and then Has_Interfaces (Rec_Type)
              and then Has_Discriminants (Etype (Rec_Type))
              and then Is_Variable_Size_Record (Etype (Rec_Type))
            then
               Init_Tags_List := New_List;

               Init_Secondary_Tags
                 (Typ            => Rec_Type,
                  Target         => Make_Identifier (Loc, Name_uInit),
                  Init_Tags_List => Init_Tags_List,
                  Stmts_List     => Init_Tags_List,
                  Fixed_Comps    => False,
                  Variable_Comps => True);

               Append_List_To (Body_Stmts, Init_Tags_List);
            end if;
         end if;

         Handled_Stmt_Node := New_Node (N_Handled_Sequence_Of_Statements, Loc);
         Set_Statements (Handled_Stmt_Node, Body_Stmts);

         --  Generate:
         --    Deep_Finalize (_init, C1, ..., CN);
         --    raise;

         if Counter > 0
           and then Needs_Finalization (Rec_Type)
           and then not Is_Abstract_Type (Rec_Type)
           and then not Restriction_Active (No_Exception_Propagation)
         then
            declare
               DF_Call : Node_Id;
               DF_Id   : Entity_Id;

            begin
               --  Create a local version of Deep_Finalize which has indication
               --  of partial initialization state.

               DF_Id :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Name_uFinalizer));
               Set_Is_Finalizer (DF_Id);

               Append_To (Decls, Make_Local_Deep_Finalize (Rec_Type, DF_Id));

               DF_Call :=
                 Make_Procedure_Call_Statement (Loc,
                   Name                   => New_Occurrence_Of (DF_Id, Loc),
                   Parameter_Associations => New_List (
                     Make_Identifier (Loc, Name_uInit),
                     New_Occurrence_Of (Standard_False, Loc)));

               --  Do not emit warnings related to the elaboration order when a
               --  controlled object is declared before the body of Finalize is
               --  seen.

               if Legacy_Elaboration_Checks then
                  Set_No_Elaboration_Check (DF_Call);
               end if;

               Set_Exception_Handlers (Handled_Stmt_Node, New_List (
                 Make_Exception_Handler (Loc,
                   Exception_Choices => New_List (
                     Make_Others_Choice (Loc)),
                   Statements        => New_List (
                     DF_Call,
                     Make_Raise_Statement (Loc)))));
            end;
         else
            Set_Exception_Handlers (Handled_Stmt_Node, No_List);
         end if;

         Set_Handled_Statement_Sequence (Body_Node, Handled_Stmt_Node);

         if not Debug_Generated_Code then
            Set_Debug_Info_Off (Proc_Id);
         end if;

         --  Associate Init_Proc with type, and determine if the procedure
         --  is null (happens because of the Initialize_Scalars pragma case,
         --  where we have to generate a null procedure in case it is called
         --  by a client with Initialize_Scalars set). Such procedures have
         --  to be generated, but do not have to be called, so we mark them
         --  as null to suppress the call. Kill also warnings for the _Init
         --  out parameter, which is left entirely uninitialized.

         Set_Init_Proc (Rec_Type, Proc_Id);

         if Is_Null_Statement_List (Body_Stmts) then
            Set_Is_Null_Init_Proc (Proc_Id);
            Set_Warnings_Off (Defining_Identifier (First (Parameters)));
         end if;
      end Build_Init_Procedure;

      ---------------------------
      -- Build_Init_Statements --
      ---------------------------

      function Build_Init_Statements (Comp_List : Node_Id) return List_Id is
         Checks             : constant List_Id := New_List;
         Actions            : List_Id          := No_List;
         Counter_Id         : Entity_Id        := Empty;
         Comp_Loc           : Source_Ptr;
         Decl               : Node_Id;
         Id                 : Entity_Id;
         Parent_Stmts       : List_Id;
         Parent_Id          : Entity_Id := Empty;
         Stmts, Late_Stmts  : List_Id := Empty_List;
         Typ                : Entity_Id;

         procedure Increment_Counter
           (Loc  : Source_Ptr; Late : Boolean := False);
         --  Generate an "increment by one" statement for the current counter
         --  and append it to the appropriate statement list.

         procedure Make_Counter (Loc : Source_Ptr);
         --  Create a new counter for the current component list. The routine
         --  creates a new defining Id, adds an object declaration and sets
         --  the Id generator for the next variant.

         -----------------------
         -- Increment_Counter --
         -----------------------

         procedure Increment_Counter
           (Loc  : Source_Ptr; Late : Boolean := False) is
         begin
            --  Generate:
            --    Counter := Counter + 1;

            Append_To ((if Late then Late_Stmts else Stmts),
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (Counter_Id, Loc),
                Expression =>
                  Make_Op_Add (Loc,
                    Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
                    Right_Opnd => Make_Integer_Literal (Loc, 1))));
         end Increment_Counter;

         ------------------
         -- Make_Counter --
         ------------------

         procedure Make_Counter (Loc : Source_Ptr) is
         begin
            --  Increment the Id generator

            Counter := Counter + 1;

            --  Create the entity and declaration

            Counter_Id :=
              Make_Defining_Identifier (Loc,
                Chars => New_External_Name ('C', Counter));

            --  Generate:
            --    Cnn : Integer := 0;

            Append_To (Decls,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Counter_Id,
                Object_Definition   =>
                  New_Occurrence_Of (Standard_Integer, Loc),
                Expression          =>
                  Make_Integer_Literal (Loc, 0)));
         end Make_Counter;

      --  Start of processing for Build_Init_Statements

      begin
         if Null_Present (Comp_List) then
            return New_List (Make_Null_Statement (Loc));
         end if;

         Parent_Stmts := New_List;
         Stmts := New_List;

         --  Loop through visible declarations of task types and protected
         --  types moving any expanded code from the spec to the body of the
         --  init procedure.

         if Is_Concurrent_Record_Type (Rec_Type) then
            declare
               Decl : constant Node_Id :=
                        Parent (Corresponding_Concurrent_Type (Rec_Type));
               Def  : Node_Id;
               N1   : Node_Id;
               N2   : Node_Id;

            begin
               if Is_Task_Record_Type (Rec_Type) then
                  Def := Task_Definition (Decl);
               else
                  Def := Protected_Definition (Decl);
               end if;

               if Present (Def) then
                  N1 := First (Visible_Declarations (Def));
                  while Present (N1) loop
                     N2 := N1;
                     N1 := Next (N1);

                     if Nkind (N2) in N_Statement_Other_Than_Procedure_Call
                       or else Nkind (N2) in N_Raise_xxx_Error
                       or else Nkind (N2) = N_Procedure_Call_Statement
                     then
                        Append_To (Stmts,
                          New_Copy_Tree (N2, New_Scope => Proc_Id));
                        Rewrite (N2, Make_Null_Statement (Sloc (N2)));
                        Analyze (N2);
                     end if;
                  end loop;
               end if;
            end;
         end if;

         --  Loop through components, skipping pragmas, in 2 steps. The first
         --  step deals with regular components. The second step deals with
         --  components that require late initialization.

         --  First pass : regular components

         Decl := First_Non_Pragma (Component_Items (Comp_List));
         while Present (Decl) loop
            Comp_Loc := Sloc (Decl);
            Build_Record_Checks
              (Subtype_Indication (Component_Definition (Decl)), Checks);

            Id  := Defining_Identifier (Decl);

            --  Obtain the corresponding mutably tagged type's parent subtype
            --  to handle default initialization.

            Typ := Get_Corresponding_Tagged_Type_If_Present (Etype (Id));

            --  Leave any processing of component requiring late initialization
            --  for the second pass.

            if Initialization_Control.Requires_Late_Init (Decl, Rec_Type) then
               if not Has_Late_Init_Comp then
                  Late_Stmts := New_List;
               end if;
               Has_Late_Init_Comp := True;

            --  Regular component cases

            else
               --  In the context of the init proc, references to discriminants
               --  resolve to denote the discriminals: this is where we can
               --  freeze discriminant dependent component subtypes.

               if not Is_Frozen (Typ) then
                  Append_List_To (Stmts, Freeze_Entity (Typ, N));
               end if;

               --  Explicit initialization

               if Present (Expression (Decl)) then

                  --  Ensure that the type of the expression initializing a
                  --  mutably tagged class-wide type component is frozen.

                  if Nkind (Expression (Decl)) = N_Qualified_Expression
                    and then Is_Class_Wide_Equivalent_Type (Etype (Id))
                  then
                     Freeze_Before (N, Etype (Expression (Decl)));
                  end if;

                  if Is_CPP_Constructor_Call (Expression (Decl)) then
                     Actions :=
                       Build_Initialization_Call
                         (Decl,
                          Id_Ref          =>
                            Make_Selected_Component (Comp_Loc,
                              Prefix        =>
                                Make_Identifier (Comp_Loc, Name_uInit),
                              Selector_Name =>
                                New_Occurrence_Of (Id, Comp_Loc)),
                          Typ             => Typ,
                          In_Init_Proc    => True,
                          Enclos_Type     => Rec_Type,
                          Discr_Map       => Discr_Map,
                          Constructor_Ref => Expression (Decl));
                  else
                     Actions := Build_Assignment (Id, Expression (Decl));
                  end if;

               --  Expand components with constructors to have the 'Make
               --  attribute.

               elsif Needs_Construction (Typ)
                 and then Has_Parameterless_Constructor (Typ)
               then
                  Set_Expression (Decl,
                    Make_Attribute_Reference (Loc,
                      Attribute_Name => Name_Make,
                      Prefix         =>
                        Subtype_Indication
                          (Component_Definition (Decl))));
                  Analyze (Expression (Decl));
                  Actions := Build_Assignment (Id, Expression (Decl));

               --  CPU, Dispatching_Domain, Priority, and Secondary_Stack_Size
               --  components are filled in with the corresponding rep-item
               --  expression of the concurrent type (if any).

               elsif Ekind (Scope (Id)) = E_Record_Type
                 and then Present (Corresponding_Concurrent_Type (Scope (Id)))
                 and then Chars (Id) in Name_uCPU
                                      | Name_uDispatching_Domain
                                      | Name_uPriority
                                      | Name_uSecondary_Stack_Size
               then
                  declare
                     Exp   : Node_Id;
                     Nam   : Name_Id;
                     pragma Warnings (Off, Nam);
                     Ritem : Node_Id;

                  begin
                     if Chars (Id) = Name_uCPU then
                        Nam := Name_CPU;

                     elsif Chars (Id) = Name_uDispatching_Domain then
                        Nam := Name_Dispatching_Domain;

                     elsif Chars (Id) = Name_uPriority then
                        Nam := Name_Priority;

                     elsif Chars (Id) = Name_uSecondary_Stack_Size then
                        Nam := Name_Secondary_Stack_Size;
                     end if;

                     --  Get the Rep Item (aspect specification, attribute
                     --  definition clause or pragma) of the corresponding
                     --  concurrent type.

                     Ritem :=
                       Get_Rep_Item
                         (Corresponding_Concurrent_Type (Scope (Id)),
                          Nam,
                          Check_Parents => False);

                     if Present (Ritem) then

                        --  Pragma case

                        if Nkind (Ritem) = N_Pragma then
                           Exp :=
                             Get_Pragma_Arg
                               (First (Pragma_Argument_Associations (Ritem)));

                           --  Conversion for Priority expression

                           if Nam = Name_Priority then
                              if Pragma_Name (Ritem) = Name_Priority
                                and then not GNAT_Mode
                              then
                                 Exp := Convert_To (RTE (RE_Priority), Exp);
                              else
                                 Exp :=
                                   Convert_To (RTE (RE_Any_Priority), Exp);
                              end if;
                           end if;

                        --  Aspect/Attribute definition clause case

                        else
                           Exp := Expression (Ritem);

                           --  Conversion for Priority expression

                           if Nam = Name_Priority then
                              if Chars (Ritem) = Name_Priority
                                and then not GNAT_Mode
                              then
                                 Exp := Convert_To (RTE (RE_Priority), Exp);
                              else
                                 Exp :=
                                   Convert_To (RTE (RE_Any_Priority), Exp);
                              end if;
                           end if;
                        end if;

                        --  Conversion for Dispatching_Domain value

                        if Nam = Name_Dispatching_Domain then
                           Exp :=
                             Unchecked_Convert_To
                               (RTE (RE_Dispatching_Domain_Access), Exp);

                        --  Conversion for Secondary_Stack_Size value

                        elsif Nam = Name_Secondary_Stack_Size then
                           Exp := Convert_To (RTE (RE_Size_Type), Exp);
                        end if;

                        Actions := Build_Assignment (Id, Exp);

                     --  Nothing needed if no Rep Item

                     else
                        Actions := No_List;
                     end if;
                  end;

               --  Composite component with its own Init_Proc

               elsif not Is_Interface (Typ)
                 and then Has_Non_Null_Base_Init_Proc (Typ)
               then
                  declare
                     use Initialization_Control;
                     Init_Control_Actual : Node_Id := Empty;
                     Is_Parent : constant Boolean := Chars (Id) = Name_uParent;
                     Init_Call_Stmts : List_Id;
                  begin
                     if Is_Parent and then Has_Late_Init_Component (Etype (Id))
                     then
                        Init_Control_Actual :=
                          Make_Mode_Literal (Comp_Loc, Early_Init_Only);
                        --  Parent_Id used later in second call to parent's
                        --  init proc to initialize late-init components.
                        Parent_Id := Id;
                     end if;

                     Init_Call_Stmts :=
                       Build_Initialization_Call
                         (Decl,
                          Make_Selected_Component (Comp_Loc,
                            Prefix        =>
                              Make_Identifier (Comp_Loc, Name_uInit),
                            Selector_Name => New_Occurrence_Of (Id, Comp_Loc)),
                          Typ,
                          In_Init_Proc        => True,
                          Enclos_Type         => Rec_Type,
                          Discr_Map           => Discr_Map,
                          Init_Control_Actual => Init_Control_Actual);

                     if Is_Mutably_Tagged_CW_Equivalent_Type (Etype (Id))
                       and then not Is_Parent
                       and then Is_Abstract_Type (Typ)
                     then
                        Append_To (Init_Call_Stmts,
                          Make_Raise_Program_Error (Comp_Loc,
                            Reason => PE_Abstract_Type_Component));
                     end if;

                     if Is_Parent then
                        --  This is tricky. At first it looks like
                        --  we are going to end up with nested
                        --  if-statements with the same condition:
                        --    if Early_Init_Condition then
                        --       if Early_Init_Condition then
                        --          Parent_TypeIP (...);
                        --       end if;
                        --    end if;
                        --  But later we will hoist the inner if-statement
                        --  out of the outer one; we do this  because the
                        --  init-proc call for the _Parent component of a type
                        --  extension has to precede any other initialization.
                        Actions :=
                          New_List (Make_If_Statement (Loc,
                            Condition =>
                              Early_Init_Condition (Loc, Init_Control_Formal),
                            Then_Statements => Init_Call_Stmts));
                     else
                        Actions := Init_Call_Stmts;
                     end if;
                  end;

                  Clean_Task_Names (Typ, Proc_Id);

               --  Simple initialization. If the Esize is not yet set, we pass
               --  Uint_0 as expected by Get_Simple_Init_Val.

               elsif Component_Needs_Simple_Initialization (Typ) then
                  Actions :=
                    Build_Assignment
                      (Id      => Id,
                       Default =>
                         Get_Simple_Init_Val
                           (Typ  => Typ,
                            N    => N,
                            Size =>
                              (if Known_Esize (Id) then Esize (Id)
                               else Uint_0)));

               --  Nothing needed for this case

               else
                  Actions := No_List;
               end if;

               --  When the component's type has a Default_Initial_Condition,
               --  and the component is default initialized, then check the
               --  DIC here.

               if Has_DIC (Typ)
                 and then No (Expression (Decl))
                 and then Present (DIC_Procedure (Typ))
                 and then not Has_Null_Body (DIC_Procedure (Typ))

                 --  The DICs of ancestors are checked as part of the type's
                 --  DIC procedure.

                 and then Chars (Id) /= Name_uParent

                 --  In GNATprove mode, the component DICs are checked by other
                 --  means. They should not be added to the record type DIC
                 --  procedure, so that the procedure can be used to check the
                 --  record type invariants or DICs if any.

                 and then not GNATprove_Mode
               then
                  Append_New_To (Actions,
                     Build_DIC_Call
                       (Comp_Loc,
                        Make_Selected_Component (Comp_Loc,
                          Prefix        =>
                            Make_Identifier (Comp_Loc, Name_uInit),
                          Selector_Name =>
                            New_Occurrence_Of (Id, Comp_Loc)),
                        Typ));
               end if;

               if Present (Checks) then
                  if Chars (Id) = Name_uParent then
                     Append_List_To (Parent_Stmts, Checks);
                  else
                     Append_List_To (Stmts, Checks);
                  end if;
               end if;

               if Present (Actions) then
                  if Chars (Id) = Name_uParent then
                     Append_List_To (Parent_Stmts, Actions);
                  else
                     Append_List_To (Stmts, Actions);

                     --  Preserve initialization state in the current counter

                     if Needs_Finalization (Typ) then
                        if No (Counter_Id) then
                           Make_Counter (Comp_Loc);
                        end if;

                        Increment_Counter (Comp_Loc);
                     end if;
                  end if;
               end if;
            end if;

            Next_Non_Pragma (Decl);
         end loop;

         --  The parent field must be initialized first because variable
         --  size components of the parent affect the location of all the
         --  new components.

         Prepend_List_To (Stmts, Parent_Stmts);

         --  Set up tasks and protected object support. This needs to be done
         --  before any component with a per-object access discriminant
         --  constraint, or any variant part (which may contain such
         --  components) is initialized, because the initialization of these
         --  components may reference the enclosing concurrent object.

         --  For a task record type, add the task create call and calls to bind
         --  any interrupt (signal) entries.

         if Is_Task_Record_Type (Rec_Type) then

            --  In the case of the restricted run time the ATCB has already
            --  been preallocated.

            if Restricted_Profile then
               Append_To (Stmts,
                 Make_Assignment_Statement (Loc,
                   Name       =>
                     Make_Selected_Component (Loc,
                       Prefix        => Make_Identifier (Loc, Name_uInit),
                       Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),
                   Expression =>
                     Make_Attribute_Reference (Loc,
                       Prefix         =>
                         Make_Selected_Component (Loc,
                           Prefix        => Make_Identifier (Loc, Name_uInit),
                           Selector_Name => Make_Identifier (Loc, Name_uATCB)),
                       Attribute_Name => Name_Unchecked_Access)));
            end if;

            Append_To (Stmts, Make_Task_Create_Call (Rec_Type));

            declare
               Task_Type : constant Entity_Id :=
                             Corresponding_Concurrent_Type (Rec_Type);
               Task_Decl : constant Node_Id := Parent (Task_Type);
               Task_Def  : constant Node_Id := Task_Definition (Task_Decl);
               Decl_Loc  : Source_Ptr;
               Ent       : Entity_Id;
               Vis_Decl  : Node_Id;

            begin
               if Present (Task_Def) then
                  Vis_Decl := First (Visible_Declarations (Task_Def));
                  while Present (Vis_Decl) loop
                     Decl_Loc := Sloc (Vis_Decl);

                     if Nkind (Vis_Decl) = N_Attribute_Definition_Clause then
                        if Get_Attribute_Id (Chars (Vis_Decl)) =
                                                       Attribute_Address
                        then
                           Ent := Entity (Name (Vis_Decl));

                           if Ekind (Ent) = E_Entry then
                              Append_To (Stmts,
                                Make_Procedure_Call_Statement (Decl_Loc,
                                  Name =>
                                    New_Occurrence_Of (RTE (
                                      RE_Bind_Interrupt_To_Entry), Decl_Loc),
                                  Parameter_Associations => New_List (
                                    Make_Selected_Component (Decl_Loc,
                                      Prefix        =>
                                        Make_Identifier (Decl_Loc, Name_uInit),
                                      Selector_Name =>
                                        Make_Identifier
                                         (Decl_Loc, Name_uTask_Id)),
                                    Entry_Index_Expression
                                      (Decl_Loc, Ent, Empty, Task_Type),
                                    Expression (Vis_Decl))));
                           end if;
                        end if;
                     end if;

                     Next (Vis_Decl);
                  end loop;
               end if;
            end;

         --  For a protected type, add statements generated by
         --  Make_Initialize_Protection.

         elsif Is_Protected_Record_Type (Rec_Type) then
            Append_List_To (Stmts,
              Make_Initialize_Protection (Rec_Type));
         end if;

         --  Second pass: components that require late initialization

         if Present (Parent_Id) then
            declare
               Parent_Loc : constant Source_Ptr := Sloc (Parent (Parent_Id));
            begin
               --  We are building the init proc for a type extension.
               --  Call the parent type's init proc a second time, this
               --  time to initialize the parent's components that require
               --  late initialization.

               Append_List_To (Late_Stmts,
                 Build_Initialization_Call
                   (N                    => Parent (Parent_Id),
                    Id_Ref               =>
                      Make_Selected_Component (Parent_Loc,
                        Prefix        => Make_Identifier
                                           (Parent_Loc, Name_uInit),
                        Selector_Name => New_Occurrence_Of (Parent_Id,
                                                            Parent_Loc)),
                    Typ                 => Etype (Parent_Id),
                    In_Init_Proc        => True,
                    Enclos_Type         => Rec_Type,
                    Discr_Map           => Discr_Map,
                    Init_Control_Actual => Make_Mode_Literal
                                             (Parent_Loc, Late_Init_Only)));
            end;
         end if;

         if Has_Late_Init_Comp then
            Decl := First_Non_Pragma (Component_Items (Comp_List));
            while Present (Decl) loop
               Comp_Loc := Sloc (Decl);
               Id := Defining_Identifier (Decl);

               --  Obtain the corresponding mutably tagged type's parent
               --  subtype to handle default initialization.

               Typ := Get_Corresponding_Tagged_Type_If_Present (Etype (Id));

               if Initialization_Control.Requires_Late_Init (Decl, Rec_Type)
               then
                  if Present (Expression (Decl)) then
                     Append_List_To (Late_Stmts,
                       Build_Assignment (Id, Expression (Decl)));

                  elsif Has_Non_Null_Base_Init_Proc (Typ) then
                     Append_List_To (Late_Stmts,
                       Build_Initialization_Call (Decl,
                         Make_Selected_Component (Comp_Loc,
                           Prefix        =>
                             Make_Identifier (Comp_Loc, Name_uInit),
                           Selector_Name => New_Occurrence_Of (Id, Comp_Loc)),
                         Typ,
                         In_Init_Proc => True,
                         Enclos_Type  => Rec_Type,
                         Discr_Map    => Discr_Map));

                     Clean_Task_Names (Typ, Proc_Id);

                     --  Preserve initialization state in the current counter

                     if Needs_Finalization (Typ) then
                        if No (Counter_Id) then
                           Make_Counter (Comp_Loc);
                        end if;

                        Increment_Counter (Comp_Loc, Late => True);
                     end if;
                  elsif Component_Needs_Simple_Initialization (Typ) then
                     Append_List_To (Late_Stmts,
                       Build_Assignment
                         (Id      => Id,
                          Default =>
                            Get_Simple_Init_Val
                              (Typ  => Typ,
                               N    => N,
                               Size => Esize (Id))));
                  end if;
               end if;

               Next_Non_Pragma (Decl);
            end loop;
         end if;

         --  Process the variant part (incorrectly ignoring late
         --  initialization requirements for components therein).

         if Present (Variant_Part (Comp_List)) then
            declare
               Variant_Alts : constant List_Id := New_List;
               Var_Loc      : Source_Ptr := No_Location;
               Variant      : Node_Id;

            begin
               Variant :=
                 First_Non_Pragma (Variants (Variant_Part (Comp_List)));
               while Present (Variant) loop
                  Var_Loc := Sloc (Variant);
                  Append_To (Variant_Alts,
                    Make_Case_Statement_Alternative (Var_Loc,
                      Discrete_Choices =>
                        New_Copy_List (Discrete_Choices (Variant)),
                      Statements =>
                        Build_Init_Statements (Component_List (Variant))));
                  Next_Non_Pragma (Variant);
               end loop;

               --  The expression of the case statement which is a reference
               --  to one of the discriminants is replaced by the appropriate
               --  formal parameter of the initialization procedure.

               Append_To (Stmts,
                 Make_Case_Statement (Var_Loc,
                   Expression =>
                     New_Occurrence_Of (Discriminal (
                       Entity (Name (Variant_Part (Comp_List)))), Var_Loc),
                   Alternatives => Variant_Alts));
            end;
         end if;

         if No (Init_Control_Formal) then
            Append_List_To (Stmts, Late_Stmts);

            --  If no initializations were generated for component declarations
            --  and included in Stmts, then append a null statement to Stmts
            --  to make it a valid Ada tree.

            if Is_Empty_List (Stmts) then
               Append (Make_Null_Statement (Loc), Stmts);
            end if;

            return Stmts;
         else
            declare
               use Initialization_Control;

               If_Early : constant Node_Id :=
                  (if Is_Empty_List (Stmts) then
                      Make_Null_Statement (Loc)
                   else
                      Make_If_Statement (Loc,
                        Condition =>
                          Early_Init_Condition (Loc, Init_Control_Formal),
                        Then_Statements => Stmts));
               If_Late : constant Node_Id :=
                  (if Is_Empty_List (Late_Stmts) then
                      Make_Null_Statement (Loc)
                   else
                      Make_If_Statement (Loc,
                        Condition =>
                          Late_Init_Condition (Loc, Init_Control_Formal),
                        Then_Statements => Late_Stmts));
            begin
               return New_List (If_Early, If_Late);
            end;
         end if;
      exception
         when RE_Not_Available =>
            return Empty_List;
      end Build_Init_Statements;

      -------------------------
      -- Build_Record_Checks --
      -------------------------

      procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id) is
         Subtype_Mark_Id : Entity_Id;

         procedure Constrain_Array
           (SI         : Node_Id;
            Check_List : List_Id);
         --  Apply a list of index constraints to an unconstrained array type.
         --  The first parameter is the entity for the resulting subtype.
         --  Check_List is a list to which the check actions are appended.

         ---------------------
         -- Constrain_Array --
         ---------------------

         procedure Constrain_Array
           (SI         : Node_Id;
            Check_List : List_Id)
         is
            C     : constant Node_Id := Constraint (SI);
            Index : Node_Id;
            S, T  : Entity_Id;

            procedure Constrain_Index
              (Index      : Node_Id;
               S          : Node_Id;
               Check_List : List_Id);
            --  Process an index constraint in a constrained array declaration.
            --  The constraint can be either a subtype name or a range with or
            --  without an explicit subtype mark. Index is the corresponding
            --  index of the unconstrained array. S is the range expression.
            --  Check_List is a list to which the check actions are appended.

            ---------------------
            -- Constrain_Index --
            ---------------------

            procedure Constrain_Index
              (Index        : Node_Id;
               S            : Node_Id;
               Check_List   : List_Id)
            is
               T : constant Entity_Id := Etype (Index);

            begin
               if Nkind (S) = N_Range then
                  Process_Range_Expr_In_Decl (S, T, Check_List => Check_List);
               end if;
            end Constrain_Index;

         --  Start of processing for Constrain_Array

         begin
            T := Entity (Subtype_Mark (SI));

            if Is_Access_Type (T) then
               T := Designated_Type (T);
            end if;

            --  In either case, the index constraint must provide a discrete
            --  range for each index of the array type and the type of each
            --  discrete range must be the same as that of the corresponding
            --  index. (RM 3.6.1)

            S := First (Constraints (C));
            Index := First_Index (T);
            Analyze (Index);

            --  Apply constraints to each index type

            while Present (S) loop
               Constrain_Index (Index, S, Check_List);
               Next (Index);
               Next (S);
            end loop;
         end Constrain_Array;

      --  Start of processing for Build_Record_Checks

      begin
         if Nkind (S) = N_Subtype_Indication then
            Find_Type (Subtype_Mark (S));
            Subtype_Mark_Id := Entity (Subtype_Mark (S));

            --  Remaining processing depends on type

            case Ekind (Subtype_Mark_Id) is
               when Array_Kind =>
                  Constrain_Array (S, Check_List);

               when others =>
                  null;
            end case;
         end if;
      end Build_Record_Checks;

      -------------------------------------------
      -- Component_Needs_Simple_Initialization --
      -------------------------------------------

      function Component_Needs_Simple_Initialization
        (T : Entity_Id) return Boolean
      is
      begin
         return
           Needs_Simple_Initialization (T)
             and then not Is_RTE (T, RE_Tag)

             --  Ada 2005 (AI-251): Check also the tag of abstract interfaces

             and then not Is_RTE (T, RE_Interface_Tag);
      end Component_Needs_Simple_Initialization;

      --------------------------------------
      -- Parent_Subtype_Renaming_Discrims --
      --------------------------------------

      function Parent_Subtype_Renaming_Discrims return Boolean is
         De : Entity_Id;
         Dp : Entity_Id;

      begin
         if Base_Type (Rec_Ent) /= Rec_Ent then
            return False;
         end if;

         if Etype (Rec_Ent) = Rec_Ent
           or else not Has_Discriminants (Rec_Ent)
           or else Is_Constrained (Rec_Ent)
           or else Is_Tagged_Type (Rec_Ent)
         then
            return False;
         end if;

         --  If there are no explicit stored discriminants we have inherited
         --  the root type discriminants so far, so no renamings occurred.

         if First_Discriminant (Rec_Ent) =
              First_Stored_Discriminant (Rec_Ent)
         then
            return False;
         end if;

         --  Check if we have done some trivial renaming of the parent
         --  discriminants, i.e. something like
         --
         --    type DT (X1, X2: int) is new PT (X1, X2);

         De := First_Discriminant (Rec_Ent);
         Dp := First_Discriminant (Etype (Rec_Ent));
         while Present (De) loop
            pragma Assert (Present (Dp));

            if Corresponding_Discriminant (De) /= Dp then
               return True;
            end if;

            Next_Discriminant (De);
            Next_Discriminant (Dp);
         end loop;

         return Present (Dp);
      end Parent_Subtype_Renaming_Discrims;

      ------------------------
      -- Requires_Init_Proc --
      ------------------------

      function Requires_Init_Proc (Rec_Id : Entity_Id) return Boolean is
         Comp_Decl : Node_Id;
         Id        : Entity_Id;
         Typ       : Entity_Id;

      begin
         --  Definitely do not need one if specifically suppressed

         if Initialization_Suppressed (Rec_Id) then
            return False;
         end if;

         --  If it is a type derived from a type with unknown discriminants,
         --  we cannot build an initialization procedure for it.

         if Has_Unknown_Discriminants (Rec_Id)
           or else Has_Unknown_Discriminants (Etype (Rec_Id))
         then
            return False;
         end if;

         --  Otherwise we need to generate an initialization procedure if
         --  Is_CPP_Class is False and at least one of the following applies:

         --  1. Discriminants are present, since they need to be initialized
         --     with the appropriate discriminant constraint expressions.
         --     However, the discriminant of an unchecked union does not
         --     count, since the discriminant is not present.

         --  2. The type is a tagged type, since the implicit Tag component
         --     needs to be initialized with a pointer to the dispatch table.

         --  3. The type contains tasks

         --  4. One or more components has an initial value

         --  5. One or more components is for a type which itself requires
         --     an initialization procedure.

         --  6. One or more components is a type that requires simple
         --     initialization (see Needs_Simple_Initialization), except
         --     that types Tag and Interface_Tag are excluded, since fields
         --     of these types are initialized by other means.

         --  7. The type is the record type built for a task type (since at
         --     the very least, Create_Task must be called)

         --  8. The type is the record type built for a protected type (since
         --     at least Initialize_Protection must be called)

         --  9. The type is marked as a public entity. The reason we add this
         --     case (even if none of the above apply) is to properly handle
         --     Initialize_Scalars. If a package is compiled without an IS
         --     pragma, and the client is compiled with an IS pragma, then
         --     the client will think an initialization procedure is present
         --     and call it, when in fact no such procedure is required, but
         --     since the call is generated, there had better be a routine
         --     at the other end of the call, even if it does nothing).

         --  10. The type needs construction with constructors.

         --  Note: the reason we exclude the CPP_Class case is because in this
         --  case the initialization is performed by the C++ constructors, and
         --  the IP is built by Set_CPP_Constructors.

         if Is_CPP_Class (Rec_Id) then
            return False;

         elsif Is_Interface (Rec_Id) then
            return False;

         elsif (Has_Discriminants (Rec_Id)
                 and then not Is_Unchecked_Union (Rec_Id))
           or else Is_Tagged_Type (Rec_Id)
           or else Is_Concurrent_Record_Type (Rec_Id)
           or else Has_Task (Rec_Id)
           or else Needs_Construction (Rec_Id)
         then
            return True;
         end if;

         Id := First_Component (Rec_Id);
         while Present (Id) loop
            Comp_Decl := Parent (Id);
            Typ := Etype (Id);

            if Present (Expression (Comp_Decl))
              or else Has_Non_Null_Base_Init_Proc (Typ)
              or else Component_Needs_Simple_Initialization (Typ)

               --  Mutably tagged class-wide types require the init-proc since
               --  it takes care of their default initialization.

              or else Is_Mutably_Tagged_CW_Equivalent_Type (Typ)
            then
               return True;
            end if;

            Next_Component (Id);
         end loop;

         --  As explained above, a record initialization procedure is needed
         --  for public types in case Initialize_Scalars applies to a client.
         --  However, such a procedure is not needed in the case where either
         --  of restrictions No_Initialize_Scalars or No_Default_Initialization
         --  applies. No_Initialize_Scalars excludes the possibility of using
         --  Initialize_Scalars in any partition, and No_Default_Initialization
         --  implies that no initialization should ever be done for objects of
         --  the type, so is incompatible with Initialize_Scalars.

         if not Restriction_Active (No_Initialize_Scalars)
           and then not Restriction_Active (No_Default_Initialization)
           and then Is_Public (Rec_Id)
         then
            return True;
         end if;

         return False;
      end Requires_Init_Proc;

   --  Start of processing for Build_Record_Init_Proc

   begin
      Rec_Type := Defining_Identifier (N);

      --  This may be full declaration of a private type, in which case
      --  the visible entity is a record, and the private entity has been
      --  exchanged with it in the private part of the current package.
      --  The initialization procedure is built for the record type, which
      --  is retrievable from the private entity.

      if Is_Incomplete_Or_Private_Type (Rec_Type) then
         Rec_Type := Underlying_Type (Rec_Type);
      end if;

      --  If we have a variant record with restriction No_Implicit_Conditionals
      --  in effect, then we skip building the procedure. This is safe because
      --  if we can see the restriction, so can any caller, calls to initialize
      --  such records are not allowed for variant records if this restriction
      --  is active.

      if Has_Variant_Part (Rec_Type)
        and then Restriction_Active (No_Implicit_Conditionals)
      then
         return;
      end if;

      --  If there are discriminants, build the discriminant map to replace
      --  discriminants by their discriminals in complex bound expressions.
      --  These only arise for the corresponding records of synchronized types.

      if Is_Concurrent_Record_Type (Rec_Type)
        and then Has_Discriminants (Rec_Type)
      then
         declare
            Disc : Entity_Id;
         begin
            Disc := First_Discriminant (Rec_Type);
            while Present (Disc) loop
               Append_Elmt (Disc, Discr_Map);
               Append_Elmt (Discriminal (Disc), Discr_Map);
               Next_Discriminant (Disc);
            end loop;
         end;
      end if;

      --  Derived types that have no type extension can use the initialization
      --  procedure of their parent and do not need a procedure of their own.
      --  This is only correct if there are no representation clauses for the
      --  type or its parent, and if the parent has in fact been frozen so
      --  that its initialization procedure exists.

      if Is_Derived_Type (Rec_Type)
        and then not Is_Tagged_Type (Rec_Type)
        and then not Is_Unchecked_Union (Rec_Type)
        and then not Has_New_Non_Standard_Rep (Rec_Type)
        and then not Parent_Subtype_Renaming_Discrims
        and then Present (Base_Init_Proc (Etype (Rec_Type)))
      then
         Copy_TSS (Base_Init_Proc (Etype (Rec_Type)), Rec_Type);

      --  Otherwise if we need an initialization procedure, then build one,
      --  mark it as public and inlinable and as having a completion.

      elsif Requires_Init_Proc (Rec_Type)
        or else Is_Unchecked_Union (Rec_Type)
      then
         Proc_Id :=
           Make_Defining_Identifier (Loc,
             Chars => Make_Init_Proc_Name (Rec_Type));

         --  If No_Default_Initialization restriction is active, then we don't
         --  want to build an init_proc, but we need to mark that an init_proc
         --  would be needed if this restriction was not active (so that we can
         --  detect attempts to call it), so set a dummy init_proc in place.

         if Restriction_Active (No_Default_Initialization) then
            Set_Init_Proc (Rec_Type, Proc_Id);
            return;
         end if;

         Build_Offset_To_Top_Functions;
         Build_CPP_Init_Procedure;
         Build_Init_Procedure;

         Set_Is_Public      (Proc_Id, Is_Public (Rec_Ent));
         Set_Is_Internal    (Proc_Id);
         Set_Has_Completion (Proc_Id);

         if not Debug_Generated_Code then
            Set_Debug_Info_Off (Proc_Id);
         end if;

         Set_Is_Inlined (Proc_Id, Inline_Init_Proc (Rec_Type));

         declare
            Agg : constant Node_Id :=
                    Build_Equivalent_Record_Aggregate (Rec_Type);

            procedure Collect_Itypes (Comp : Node_Id);
            --  Generate references to itypes in the aggregate, because
            --  the first use of the aggregate may be in a nested scope.

            --------------------
            -- Collect_Itypes --
            --------------------

            procedure Collect_Itypes (Comp : Node_Id) is
               Ref      : Node_Id;
               Sub_Aggr : Node_Id;
               Typ      : constant Entity_Id := Etype (Comp);

            begin
               if Is_Array_Type (Typ) and then Is_Itype (Typ) then
                  Ref := Make_Itype_Reference (Loc);
                  Set_Itype (Ref, Typ);
                  Append_Freeze_Action (Rec_Type, Ref);

                  Ref := Make_Itype_Reference (Loc);
                  Set_Itype (Ref, Etype (First_Index (Typ)));
                  Append_Freeze_Action (Rec_Type, Ref);

                  --  Recurse on nested arrays

                  Sub_Aggr := First (Expressions (Comp));
                  while Present (Sub_Aggr) loop
                     Collect_Itypes (Sub_Aggr);
                     Next (Sub_Aggr);
                  end loop;
               end if;
            end Collect_Itypes;

         begin
            --  If there is a static initialization aggregate for the type,
            --  generate itype references for the types of its (sub)components,
            --  to prevent out-of-scope errors in the resulting tree.
            --  The aggregate may have been rewritten as a Raise node, in which
            --  case there are no relevant itypes.

            if Present (Agg) and then Nkind (Agg) = N_Aggregate then
               Set_Static_Initialization (Proc_Id, Agg);

               declare
                  Comp : Node_Id;
               begin
                  Comp := First (Component_Associations (Agg));
                  while Present (Comp) loop
                     Collect_Itypes (Expression (Comp));
                     Next (Comp);
                  end loop;
               end;
            end if;
         end;
      end if;
   end Build_Record_Init_Proc;

   ----------------------------
   -- Build_Slice_Assignment --
   ----------------------------

   --  Generates the following subprogram:

   --    procedure array_typeSA
   --     (Source,  Target    : Array_Type,
   --      Left_Lo, Left_Hi   : Index;
   --      Right_Lo, Right_Hi : Index;
   --      Rev                : Boolean)
   --    is
   --       Li1 : Index;
   --       Ri1 : Index;

   --    begin
   --       if Left_Hi < Left_Lo then
   --          return;
   --       end if;

   --       if Rev then
   --          Li1 := Left_Hi;
   --          Ri1 := Right_Hi;
   --       else
   --          Li1 := Left_Lo;
   --          Ri1 := Right_Lo;
   --       end if;

   --       loop
   --          Target (Li1) := Source (Ri1);

   --          if Rev then
   --             exit when Li1 = Left_Lo;
   --             Li1 := Index'pred (Li1);
   --             Ri1 := Index'pred (Ri1);
   --          else
   --             exit when Li1 = Left_Hi;
   --             Li1 := Index'succ (Li1);
   --             Ri1 := Index'succ (Ri1);
   --          end if;
   --       end loop;
   --    end array_typeSA;

   procedure Build_Slice_Assignment (Typ : Entity_Id) is
      Loc   : constant Source_Ptr := Sloc (Typ);
      Index : constant Entity_Id  := Base_Type (Etype (First_Index (Typ)));

      Larray    : constant Entity_Id := Make_Temporary (Loc, 'A');
      Rarray    : constant Entity_Id := Make_Temporary (Loc, 'R');
      Left_Lo   : constant Entity_Id := Make_Temporary (Loc, 'L');
      Left_Hi   : constant Entity_Id := Make_Temporary (Loc, 'L');
      Right_Lo  : constant Entity_Id := Make_Temporary (Loc, 'R');
      Right_Hi  : constant Entity_Id := Make_Temporary (Loc, 'R');
      Rev       : constant Entity_Id := Make_Temporary (Loc, 'D');
      --  Formal parameters of procedure

      Proc_Name : constant Entity_Id :=
                    Make_Defining_Identifier (Loc,
                      Chars => Make_TSS_Name (Typ, TSS_Slice_Assign));

      Lnn : constant Entity_Id := Make_Temporary (Loc, 'L');
      Rnn : constant Entity_Id := Make_Temporary (Loc, 'R');
      --  Subscripts for left and right sides

      Decls : List_Id;
      Loops : Node_Id;
      Stats : List_Id;

   begin
      --  Build declarations for indexes

      Decls := New_List;

      Append_To (Decls,
         Make_Object_Declaration (Loc,
           Defining_Identifier => Lnn,
           Object_Definition  =>
             New_Occurrence_Of (Index, Loc)));

      Append_To (Decls,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Rnn,
          Object_Definition  =>
            New_Occurrence_Of (Index, Loc)));

      Stats := New_List;

      --  Build test for empty slice case

      Append_To (Stats,
        Make_If_Statement (Loc,
          Condition =>
             Make_Op_Lt (Loc,
               Left_Opnd  => New_Occurrence_Of (Left_Hi, Loc),
               Right_Opnd => New_Occurrence_Of (Left_Lo, Loc)),
          Then_Statements => New_List (Make_Simple_Return_Statement (Loc))));

      --  Build initializations for indexes

      declare
         F_Init : constant List_Id := New_List;
         B_Init : constant List_Id := New_List;

      begin
         Append_To (F_Init,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Lnn, Loc),
             Expression => New_Occurrence_Of (Left_Lo, Loc)));

         Append_To (F_Init,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Rnn, Loc),
             Expression => New_Occurrence_Of (Right_Lo, Loc)));

         Append_To (B_Init,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Lnn, Loc),
             Expression => New_Occurrence_Of (Left_Hi, Loc)));

         Append_To (B_Init,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Rnn, Loc),
             Expression => New_Occurrence_Of (Right_Hi, Loc)));

         Append_To (Stats,
           Make_If_Statement (Loc,
             Condition => New_Occurrence_Of (Rev, Loc),
             Then_Statements => B_Init,
             Else_Statements => F_Init));
      end;

      --  Now construct the assignment statement

      Loops :=
        Make_Loop_Statement (Loc,
          Statements => New_List (
            Make_Assignment_Statement (Loc,
              Name =>
                Make_Indexed_Component (Loc,
                  Prefix => New_Occurrence_Of (Larray, Loc),
                  Expressions => New_List (New_Occurrence_Of (Lnn, Loc))),
              Expression =>
                Make_Indexed_Component (Loc,
                  Prefix => New_Occurrence_Of (Rarray, Loc),
                  Expressions => New_List (New_Occurrence_Of (Rnn, Loc))))),
          End_Label  => Empty);

      --  Build the exit condition and increment/decrement statements

      declare
         F_Ass : constant List_Id := New_List;
         B_Ass : constant List_Id := New_List;

      begin
         Append_To (F_Ass,
           Make_Exit_Statement (Loc,
             Condition =>
               Make_Op_Eq (Loc,
                 Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
                 Right_Opnd => New_Occurrence_Of (Left_Hi, Loc))));

         Append_To (F_Ass,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Lnn, Loc),
             Expression =>
               Make_Attribute_Reference (Loc,
                 Prefix =>
                   New_Occurrence_Of (Index, Loc),
                 Attribute_Name => Name_Succ,
                 Expressions => New_List (
                   New_Occurrence_Of (Lnn, Loc)))));

         Append_To (F_Ass,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Rnn, Loc),
             Expression =>
               Make_Attribute_Reference (Loc,
                 Prefix =>
                   New_Occurrence_Of (Index, Loc),
                 Attribute_Name => Name_Succ,
                 Expressions => New_List (
                   New_Occurrence_Of (Rnn, Loc)))));

         Append_To (B_Ass,
           Make_Exit_Statement (Loc,
             Condition =>
               Make_Op_Eq (Loc,
                 Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
                 Right_Opnd => New_Occurrence_Of (Left_Lo, Loc))));

         Append_To (B_Ass,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Lnn, Loc),
             Expression =>
               Make_Attribute_Reference (Loc,
                 Prefix =>
                   New_Occurrence_Of (Index, Loc),
                 Attribute_Name => Name_Pred,
                   Expressions => New_List (
                     New_Occurrence_Of (Lnn, Loc)))));

         Append_To (B_Ass,
           Make_Assignment_Statement (Loc,
             Name => New_Occurrence_Of (Rnn, Loc),
             Expression =>
               Make_Attribute_Reference (Loc,
                 Prefix =>
                   New_Occurrence_Of (Index, Loc),
                 Attribute_Name => Name_Pred,
                 Expressions => New_List (
                   New_Occurrence_Of (Rnn, Loc)))));

         Append_To (Statements (Loops),
           Make_If_Statement (Loc,
             Condition => New_Occurrence_Of (Rev, Loc),
             Then_Statements => B_Ass,
             Else_Statements => F_Ass));
      end;

      Append_To (Stats, Loops);

      declare
         Spec    : Node_Id;
         Formals : List_Id;

      begin
         Formals := New_List (
           Make_Parameter_Specification (Loc,
             Defining_Identifier => Larray,
             Out_Present => True,
             Parameter_Type =>
               New_Occurrence_Of (Base_Type (Typ), Loc)),

           Make_Parameter_Specification (Loc,
             Defining_Identifier => Rarray,
             Parameter_Type =>
               New_Occurrence_Of (Base_Type (Typ), Loc)),

           Make_Parameter_Specification (Loc,
             Defining_Identifier => Left_Lo,
             Parameter_Type =>
               New_Occurrence_Of (Index, Loc)),

           Make_Parameter_Specification (Loc,
             Defining_Identifier => Left_Hi,
             Parameter_Type =>
               New_Occurrence_Of (Index, Loc)),

           Make_Parameter_Specification (Loc,
             Defining_Identifier => Right_Lo,
             Parameter_Type =>
               New_Occurrence_Of (Index, Loc)),

           Make_Parameter_Specification (Loc,
             Defining_Identifier => Right_Hi,
             Parameter_Type =>
               New_Occurrence_Of (Index, Loc)));

         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier => Rev,
             Parameter_Type =>
               New_Occurrence_Of (Standard_Boolean, Loc)));

         Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       => Proc_Name,
             Parameter_Specifications => Formals);

         Discard_Node (
           Make_Subprogram_Body (Loc,
             Specification              => Spec,
             Declarations               => Decls,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Stats)));
      end;

      Set_TSS (Typ, Proc_Name);
      Set_Is_Pure (Proc_Name);
   end Build_Slice_Assignment;

   ------------------------------------
   -- Build_Untagged_Record_Equality --
   ------------------------------------

   procedure Build_Untagged_Record_Equality (Typ : Entity_Id) is
      Build_Eq : Boolean;
      Comp     : Entity_Id;
      Decl     : Node_Id;
      Op       : Entity_Id;
      Eq_Op    : Entity_Id;

      function User_Defined_Eq (T : Entity_Id) return Entity_Id;
      --  Check whether the type T has a user-defined primitive equality. If so
      --  return it, else return Empty. If true for a component of Typ, we have
      --  to build the primitive equality for it.

      ---------------------
      -- User_Defined_Eq --
      ---------------------

      function User_Defined_Eq (T : Entity_Id) return Entity_Id is
         Op : constant Entity_Id := TSS (T, TSS_Composite_Equality);

      begin
         if Present (Op) then
            return Op;
         else
            return Get_User_Defined_Equality (T);
         end if;
      end User_Defined_Eq;

   --  Start of processing for Build_Untagged_Record_Equality

   begin
      --  If a record component has a primitive equality operation, we must
      --  build the corresponding one for the current type.

      Build_Eq := False;
      Comp := First_Component (Typ);
      while Present (Comp) loop
         if Is_Record_Type (Etype (Comp))
           and then Present (User_Defined_Eq (Etype (Comp)))
         then
            Build_Eq := True;
            exit;
         end if;

         Next_Component (Comp);
      end loop;

      --  If there is a user-defined equality for the type, we do not create
      --  the implicit one.

      Eq_Op := Get_User_Defined_Equality (Typ);
      if Present (Eq_Op) then
         if Comes_From_Source (Eq_Op) then
            Build_Eq := False;
         else
            Eq_Op := Empty;
         end if;
      end if;

      --  If the type is derived, inherit the operation, if present, from the
      --  parent type. It may have been declared after the type derivation. If
      --  the parent type itself is derived, it may have inherited an operation
      --  that has itself been overridden, so update its alias and related
      --  flags. Ditto for inequality.

      if No (Eq_Op) and then Is_Derived_Type (Typ) then
         Eq_Op := Get_User_Defined_Equality (Etype (Typ));
         if Present (Eq_Op) then
            Copy_TSS (Eq_Op, Typ);
            Build_Eq := False;

            declare
               Op    : constant Entity_Id := User_Defined_Eq (Typ);
               NE_Op : constant Entity_Id := Next_Entity (Eq_Op);

            begin
               if Present (Op) then
                  Set_Alias (Op, Eq_Op);
                  Set_Is_Abstract_Subprogram
                    (Op, Is_Abstract_Subprogram (Eq_Op));

                  if Chars (Next_Entity (Op)) = Name_Op_Ne then
                     Set_Is_Abstract_Subprogram
                       (Next_Entity (Op), Is_Abstract_Subprogram (NE_Op));
                  end if;
               end if;
            end;
         end if;
      end if;

      --  If not inherited and not user-defined, build body as for a type with
      --  components of record type (i.e. a type for which "=" composes when
      --  used as a component in an outer composite type).

      if Build_Eq then
         Decl :=
           Make_Eq_Body (Typ, Make_TSS_Name (Typ, TSS_Composite_Equality));
         Op := Defining_Entity (Decl);
         Set_TSS (Typ, Op);
         Set_Is_Pure (Op);

         if Is_Library_Level_Entity (Typ) then
            Set_Is_Public (Op);
         end if;

      --  Otherwise, the result is defined in terms of the primitive equals
      --  operator (RM 4.5.2 (24/3)). Report a warning if some component of
      --  the untagged record has defined a user-defined "=", because it can
      --  be surprising that the predefined "=" takes precedence over it.
      --  This warning is not reported when Build_Eq is True because the
      --  expansion of the built body will call Expand_Composite_Equality
      --  that will report it if necessary.

      elsif Warn_On_Ignored_Equality then
         Comp := First_Component (Typ);

         while Present (Comp) loop
            if Present (User_Defined_Eq (Etype (Comp)))
              and then not Is_Record_Type (Underlying_Type (Etype (Comp)))
              and then not Is_Intrinsic_Subprogram
                             (User_Defined_Eq (Etype (Comp)))
            then
               Warn_On_Ignored_Equality_Operator
                 (Typ      => Typ,
                  Comp_Typ => Etype (Comp),
                  Loc      => Sloc (User_Defined_Eq (Etype (Comp))));
            end if;

            Next_Component (Comp);
         end loop;
      end if;
   end Build_Untagged_Record_Equality;

   -----------------------------------
   -- Build_Variant_Record_Equality --
   -----------------------------------

   --  Generates:

   --    function <<Body_Id>> (Left, Right : T) return Boolean is
   --       [ X : T renames Left;  ]
   --       [ Y : T renames Right; ]
   --       --  The above renamings are generated only if the parameters of
   --       --  this built function (which are passed by the caller) are not
   --       --  named 'X' and 'Y'; these names are required to reuse several
   --       --  expander routines when generating this body.

   --    begin
   --       --  Compare discriminants

   --       if X.D1 /= Y.D1 or else X.D2 /= Y.D2 or else ... then
   --          return False;
   --       end if;

   --       --  Compare components

   --       if X.C1 /= Y.C1 or else X.C2 /= Y.C2 or else ... then
   --          return False;
   --       end if;

   --       --  Compare variant part

   --       case X.D1 is
   --          when V1 =>
   --             if X.C2 /= Y.C2 or else X.C3 /= Y.C3 or else ... then
   --                return False;
   --             end if;
   --          ...
   --          when Vn =>
   --             if X.Cn /= Y.Cn or else ... then
   --                return False;
   --             end if;
   --       end case;

   --       return True;
   --    end _Equality;

   function Build_Variant_Record_Equality
     (Typ         : Entity_Id;
      Spec_Id     : Entity_Id;
      Body_Id     : Entity_Id;
      Param_Specs : List_Id) return Node_Id
   is
      Loc   : constant Source_Ptr := Sloc (Typ);
      Def   : constant Node_Id    := Parent (Typ);
      Comps : constant Node_Id    := Component_List (Type_Definition (Def));
      Left  : constant Entity_Id  := Defining_Identifier (First (Param_Specs));
      Right : constant Entity_Id  :=
                    Defining_Identifier (Next (First (Param_Specs)));
      Decls : constant List_Id    := New_List;
      Stmts : constant List_Id    := New_List;

      Subp_Body : Node_Id;

   begin
      pragma Assert (not Is_Tagged_Type (Typ));

      --  In order to reuse the expander routines Make_Eq_If and Make_Eq_Case
      --  the name of the formals must be X and Y; otherwise we generate two
      --  renaming declarations for such purpose.

      if Chars (Left) /= Name_X then
         Append_To (Decls,
           Make_Object_Renaming_Declaration (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
             Subtype_Mark        => New_Occurrence_Of (Typ, Loc),
             Name                => Make_Identifier (Loc, Chars (Left))));
      end if;

      if Chars (Right) /= Name_Y then
         Append_To (Decls,
           Make_Object_Renaming_Declaration (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
             Subtype_Mark        => New_Occurrence_Of (Typ, Loc),
             Name                => Make_Identifier (Loc, Chars (Right))));
      end if;

      --  Unchecked_Unions require additional machinery to support equality.
      --  Two extra parameters (A and B) are added to the equality function
      --  parameter list for each discriminant of the type, in order to
      --  capture the inferred values of the discriminants in equality calls.
      --  The names of the parameters match the names of the corresponding
      --  discriminant, with an added suffix.

      if Is_Unchecked_Union (Typ) then
         declare
            Right_Formal : constant Entity_Id :=
              (if Present (Spec_Id) then Last_Formal (Spec_Id) else Right);
            Scop : constant Entity_Id :=
              (if Present (Spec_Id) then Spec_Id else Body_Id);

            procedure Decorate_Extra_Formal (F, F_Typ : Entity_Id);
            --  Decorate extra formal F with type F_Typ

            ---------------------------
            -- Decorate_Extra_Formal --
            ---------------------------

            procedure Decorate_Extra_Formal (F, F_Typ : Entity_Id) is
            begin
               Mutate_Ekind  (F, E_In_Parameter);
               Set_Etype     (F, F_Typ);
               Set_Scope     (F, Scop);
               Set_Mechanism (F, By_Copy);
            end Decorate_Extra_Formal;

            A          : Entity_Id;
            B          : Entity_Id;
            Discr      : Entity_Id;
            Discr_Type : Entity_Id;
            Last_Extra : Entity_Id := Empty;
            New_Discrs : Elist_Id;

         begin
            Mutate_Ekind (Body_Id, E_Subprogram_Body);
            New_Discrs := New_Elmt_List;

            Discr := First_Discriminant (Typ);
            while Present (Discr) loop
               Discr_Type := Etype (Discr);

               --  Add the new parameters as extra formals

               A :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Chars (Discr), 'A'));

               Decorate_Extra_Formal (A, Discr_Type);

               if Present (Last_Extra) then
                  Set_Extra_Formal (Last_Extra, A);
               else
                  Set_Extra_Formal (Right_Formal, A);
                  Set_Extra_Formals (Scop, A);
               end if;

               Append_Elmt (A, New_Discrs);

               B :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Chars (Discr), 'B'));

               Decorate_Extra_Formal (B, Discr_Type);

               Set_Extra_Formal (A, B);
               Last_Extra := B;

               --  Generate the following code to compare each of the inferred
               --  discriminants:

               --  if a /= b then
               --     return False;
               --  end if;

               Append_To (Stmts,
                 Make_If_Statement (Loc,
                   Condition       =>
                     Make_Op_Ne (Loc,
                       Left_Opnd  => New_Occurrence_Of (A, Loc),
                       Right_Opnd => New_Occurrence_Of (B, Loc)),
                   Then_Statements => New_List (
                     Make_Simple_Return_Statement (Loc,
                       Expression =>
                         New_Occurrence_Of (Standard_False, Loc)))));

               Next_Discriminant (Discr);
            end loop;

            --  Generate component-by-component comparison. Note that we must
            --  propagate the inferred discriminants formals to act as the case
            --  statement switch. Their value is added when an equality call on
            --  unchecked unions is expanded.

            Append_List_To (Stmts, Make_Eq_Case (Typ, Comps, New_Discrs));
         end;

      --  Normal case (not unchecked union)

      else
         Append_To (Stmts,
           Make_Eq_If (Typ, Discriminant_Specifications (Def)));
         Append_List_To (Stmts, Make_Eq_Case (Typ, Comps));
      end if;

      Append_To (Stmts,
        Make_Simple_Return_Statement (Loc,
          Expression => New_Occurrence_Of (Standard_True, Loc)));

      Subp_Body :=
        Make_Subprogram_Body (Loc,
          Specification              =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name       => Body_Id,
              Parameter_Specifications => Param_Specs,
              Result_Definition        =>
                New_Occurrence_Of (Standard_Boolean, Loc)),
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Stmts));

      return Subp_Body;
   end Build_Variant_Record_Equality;

   -----------------------------
   -- Check_Stream_Attributes --
   -----------------------------

   procedure Check_Stream_Attributes (Typ : Entity_Id) is
      Comp      : Entity_Id;
      Par_Read  : constant Boolean :=
                    Stream_Attribute_Available (Typ, TSS_Stream_Read)
                      and then not Has_Specified_Stream_Read (Typ);
      Par_Write : constant Boolean :=
                    Stream_Attribute_Available (Typ, TSS_Stream_Write)
                      and then not Has_Specified_Stream_Write (Typ);

      procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type);
      --  Check that Comp has a user-specified Nam stream attribute

      ----------------
      -- Check_Attr --
      ----------------

      procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type) is
      begin
         --  Move this check to sem???

         if not Stream_Attribute_Available (Etype (Comp), TSS_Nam) then
            Error_Msg_Name_1 := Nam;
            Error_Msg_N
              ("|component& in limited extension must have% attribute", Comp);
         end if;
      end Check_Attr;

   --  Start of processing for Check_Stream_Attributes

   begin
      if Par_Read or else Par_Write then
         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Comes_From_Source (Comp)
              and then Original_Record_Component (Comp) = Comp
              and then Is_Limited_Type (Etype (Comp))
            then
               if Par_Read then
                  Check_Attr (Name_Read, TSS_Stream_Read);
               end if;

               if Par_Write then
                  Check_Attr (Name_Write, TSS_Stream_Write);
               end if;
            end if;

            Next_Component (Comp);
         end loop;
      end if;
   end Check_Stream_Attributes;

   ----------------------
   -- Clean_Task_Names --
   ----------------------

   procedure Clean_Task_Names
     (Typ     : Entity_Id;
      Proc_Id : Entity_Id)
   is
   begin
      if Has_Task (Typ)
        and then not Restriction_Active (No_Implicit_Heap_Allocations)
        and then not Global_Discard_Names
        and then Tagged_Type_Expansion
      then
         Set_Uses_Sec_Stack (Proc_Id);
      end if;
   end Clean_Task_Names;

   -------------------------------
   -- Copy_Discr_Checking_Funcs --
   -------------------------------

   procedure Copy_Discr_Checking_Funcs (N : Node_Id) is
      Typ      : constant Entity_Id := Defining_Identifier (N);
      Comp     : Entity_Id := First_Component (Typ);
      Old_Comp : Entity_Id := First_Component
                                (Base_Type (Underlying_Type (Etype (Typ))));
   begin
      while Present (Comp) loop
         if Chars (Comp) = Chars (Old_Comp) then
            Set_Discriminant_Checking_Func
              (Comp, Discriminant_Checking_Func (Old_Comp));
         end if;

         Next_Component (Old_Comp);
         Next_Component (Comp);
      end loop;
   end Copy_Discr_Checking_Funcs;

   ------------------------------
   -- Expand_Freeze_Array_Type --
   ------------------------------

   procedure Expand_Freeze_Array_Type (N : Node_Id) is
      Typ      : constant Entity_Id := Entity (N);
      Base     : constant Entity_Id := Base_Type (Typ);

      --  Obtain the corresponding mutably tagged type if necessary

      Comp_Typ : constant Entity_Id :=
        Get_Corresponding_Mutably_Tagged_Type_If_Present
          (Component_Type (Typ));

   begin
      --  First, the nonpacked case

      if not Is_Bit_Packed_Array (Typ) then
         if No (Init_Proc (Base)) then

            --  If this is an anonymous array built for an object declaration
            --  with an initial value, its Init_Proc will never be called. The
            --  initial value itself may have been expanded into assignments,
            --  in which case the declaration has the No_Initialization flag.

            if Is_Itype (Base)
              and then Nkind (Associated_Node_For_Itype (Base)) =
                                                    N_Object_Declaration
              and then
                (Present (Expression (Associated_Node_For_Itype (Base)))
                  or else No_Initialization (Associated_Node_For_Itype (Base)))
            then
               null;

            --  We do not need an init proc for string or wide [wide] string,
            --  since the only time these need initialization in normalize or
            --  initialize scalars mode, and these types are treated specially
            --  and do not need initialization procedures.

            elsif Is_Standard_String_Type (Base)
              and then not Has_Default_Aspect (Base)
            then
               null;

            --  Otherwise we have to build an init proc for the subtype

            else
               Build_Array_Init_Proc (Base, N);
            end if;
         end if;

         if Typ = Base and then Has_Controlled_Component (Base) then
            Build_Controlling_Procs (Base);

            if not Is_Limited_Type (Comp_Typ)
              and then Number_Dimensions (Typ) = 1
            then
               Build_Slice_Assignment (Typ);
            end if;
         end if;

      --  For the packed case, no initialization, except if the component type
      --  has an initialization procedure, or Initialize/Normalize_Scalars is
      --  active, or there is a Default_Component_Value aspect, or the type is
      --  public, because a client might specify Initialize_Scalars and there
      --  better be a public Init_Proc for it.

      elsif Present (Init_Proc (Component_Type (Base)))
        or else Init_Or_Norm_Scalars
        or else Has_Default_Aspect (Base)
        or else Is_Public (Typ)
      then
         if No (Init_Proc (Base)) then
            Build_Array_Init_Proc (Base, N);
         end if;
      end if;
   end Expand_Freeze_Array_Type;

   -----------------------------------
   -- Expand_Freeze_Class_Wide_Type --
   -----------------------------------

   procedure Expand_Freeze_Class_Wide_Type (N : Node_Id) is
      function Is_C_Derivation (Typ : Entity_Id) return Boolean;
      --  Given a type, determine whether it is derived from a C or C++ root

      ---------------------
      -- Is_C_Derivation --
      ---------------------

      function Is_C_Derivation (Typ : Entity_Id) return Boolean is
         T : Entity_Id;

      begin
         T := Typ;
         loop
            if Is_CPP_Class (T)
              or else Convention (T) = Convention_C
              or else Convention (T) = Convention_CPP
            then
               return True;
            end if;

            exit when T = Etype (T);

            T := Etype (T);
         end loop;

         return False;
      end Is_C_Derivation;

      --  Local variables

      Typ  : constant Entity_Id := Entity (N);
      Root : constant Entity_Id := Root_Type (Typ);

   --  Start of processing for Expand_Freeze_Class_Wide_Type

   begin
      --  Certain run-time configurations and targets do not provide support
      --  for controlled types.

      if Restriction_Active (No_Finalization) then
         return;

      --  Do not create TSS routine Finalize_Address when dispatching calls are
      --  disabled since the core of the routine is a dispatching call.

      elsif Restriction_Active (No_Dispatching_Calls) then
         return;

      --  Do not create TSS routine Finalize_Address for concurrent class-wide
      --  types. Ignore C, C++, CIL and Java types since it is assumed that the
      --  non-Ada side will handle their destruction.
      --
      --  Concurrent Ada types are functionally represented by an associated
      --  "corresponding record type" (typenameV), which owns the actual TSS
      --  finalize bodies for the type (and technically class-wide type).

      elsif Is_Concurrent_Type (Root)
        or else Is_C_Derivation (Root)
        or else Convention (Typ) = Convention_CPP
      then
         return;

      --  Do not create TSS routine Finalize_Address when compiling in CodePeer
      --  mode since the routine contains an Unchecked_Conversion.

      elsif CodePeer_Mode then
         return;
      end if;

      --  Create the body of TSS primitive Finalize_Address. This automatically
      --  sets the TSS entry for the class-wide type.

      if No (Finalize_Address (Typ)) then
         Make_Finalize_Address_Body (Typ);
      end if;
   end Expand_Freeze_Class_Wide_Type;

   ------------------------------------
   -- Expand_Freeze_Enumeration_Type --
   ------------------------------------

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

      Arr           : Entity_Id;
      Ent           : Entity_Id;
      Fent          : Entity_Id;
      Is_Contiguous : Boolean;
      Index_Typ     : Entity_Id;
      Ityp          : Entity_Id;
      Last_Repval   : Uint;
      Lst           : List_Id;
      Num           : Nat;
      Pos_Expr      : Node_Id;

      Func : Entity_Id;
      pragma Warnings (Off, Func);

   begin
      --  Various optimizations possible if given representation is contiguous

      Is_Contiguous := True;

      Ent := First_Literal (Typ);
      Last_Repval := Enumeration_Rep (Ent);
      Num := 1;
      Next_Literal (Ent);

      while Present (Ent) loop
         if Enumeration_Rep (Ent) - Last_Repval /= 1 then
            Is_Contiguous := False;
         else
            Last_Repval := Enumeration_Rep (Ent);
         end if;

         Num := Num + 1;
         Next_Literal (Ent);
      end loop;

      if Is_Contiguous then
         Set_Has_Contiguous_Rep (Typ);

         --  Now build a subtype declaration

         --    subtype typI is new Natural range 0 .. num - 1

         Index_Typ :=
           Make_Defining_Identifier (Loc,
             Chars => New_External_Name (Chars (Typ), 'I'));

         Append_Freeze_Action (Typ,
           Make_Subtype_Declaration (Loc,
             Defining_Identifier => Index_Typ,
             Subtype_Indication =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark =>
                   New_Occurrence_Of (Standard_Natural,  Loc),
                 Constraint  =>
                   Make_Range_Constraint (Loc,
                     Range_Expression =>
                       Make_Range (Loc,
                         Low_Bound  =>
                           Make_Integer_Literal (Loc, 0),
                         High_Bound =>
                           Make_Integer_Literal (Loc, Num - 1))))));

         Set_Enum_Pos_To_Rep (Typ, Index_Typ);

      else
         --  Build list of literal references

         Lst := New_List;
         Ent := First_Literal (Typ);
         while Present (Ent) loop
            Append_To (Lst, New_Occurrence_Of (Ent, Sloc (Ent)));
            Next_Literal (Ent);
         end loop;

         --  Now build an array declaration

         --    typA : constant array (Natural range 0 .. num - 1) of typ :=
         --             (v, v, v, v, v, ....)

         Arr :=
           Make_Defining_Identifier (Loc,
             Chars => New_External_Name (Chars (Typ), 'A'));

         Append_Freeze_Action (Typ,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Arr,
             Constant_Present    => True,

             Object_Definition   =>
               Make_Constrained_Array_Definition (Loc,
                 Discrete_Subtype_Definitions => New_List (
                   Make_Subtype_Indication (Loc,
                     Subtype_Mark =>
                       New_Occurrence_Of (Standard_Natural, Loc),
                     Constraint   =>
                       Make_Range_Constraint (Loc,
                         Range_Expression =>
                           Make_Range (Loc,
                             Low_Bound  =>
                               Make_Integer_Literal (Loc, 0),
                             High_Bound =>
                               Make_Integer_Literal (Loc, Num - 1))))),

                 Component_Definition =>
                   Make_Component_Definition (Loc,
                     Subtype_Indication => New_Occurrence_Of (Typ, Loc))),

             Expression =>
               Make_Aggregate (Loc,
                 Expressions => Lst)));

         Set_Enum_Pos_To_Rep (Typ, Arr);
      end if;

      --  Now we build the function that converts representation values to
      --  position values. This function has the form:

      --    function _Rep_To_Pos (A : etype; F : Boolean) return Integer is
      --    begin
      --       case ityp!(A) is
      --         when enum-lit'Enum_Rep => return posval;
      --         when enum-lit'Enum_Rep => return posval;
      --         ...
      --         when others   =>
      --           [raise Constraint_Error when F "invalid data"]
      --           return -1;
      --       end case;
      --    end;

      --  Note: the F parameter determines whether the others case (no valid
      --  representation) raises Constraint_Error or returns a unique value
      --  of minus one. The latter case is used, e.g. in 'Valid code.

      --  Note: the reason we use Enum_Rep values in the case here is to avoid
      --  the code generator making inappropriate assumptions about the range
      --  of the values in the case where the value is invalid. ityp is a
      --  signed or unsigned integer type of appropriate width.

      --  Note: if exceptions are not supported, then we suppress the raise
      --  and return -1 unconditionally (this is an erroneous program in any
      --  case and there is no obligation to raise Constraint_Error here). We
      --  also do this if pragma Restrictions (No_Exceptions) is active.

      --  Is this right??? What about No_Exception_Propagation???

      --  The underlying type is signed. Reset the Is_Unsigned_Type explicitly
      --  because it might have been inherited from the parent type.

      if Enumeration_Rep (First_Literal (Typ)) < 0 then
         Set_Is_Unsigned_Type (Typ, False);
      end if;

      Ityp := Integer_Type_For (Esize (Typ), Is_Unsigned_Type (Typ));

      --  The body of the function is a case statement. First collect case
      --  alternatives, or optimize the contiguous case.

      Lst := New_List;

      --  If representation is contiguous, Pos is computed by subtracting
      --  the representation of the first literal.

      if Is_Contiguous then
         Ent := First_Literal (Typ);

         if Enumeration_Rep (Ent) = Last_Repval then

            --  Another special case: for a single literal, Pos is zero

            Pos_Expr := Make_Integer_Literal (Loc, Uint_0);

         else
            Pos_Expr :=
              Convert_To (Standard_Integer,
                Make_Op_Subtract (Loc,
                  Left_Opnd  =>
                    Unchecked_Convert_To
                     (Ityp, Make_Identifier (Loc, Name_uA)),
                  Right_Opnd =>
                    Make_Integer_Literal (Loc,
                      Intval => Enumeration_Rep (First_Literal (Typ)))));
         end if;

         Append_To (Lst,
           Make_Case_Statement_Alternative (Loc,
             Discrete_Choices => New_List (
               Make_Range (Sloc (Enumeration_Rep_Expr (Ent)),
                 Low_Bound =>
                   Make_Integer_Literal (Loc,
                    Intval => Enumeration_Rep (Ent)),
                 High_Bound =>
                   Make_Integer_Literal (Loc, Intval => Last_Repval))),

             Statements => New_List (
               Make_Simple_Return_Statement (Loc,
                 Expression => Pos_Expr))));

      else
         Ent := First_Literal (Typ);
         while Present (Ent) loop
            Append_To (Lst,
              Make_Case_Statement_Alternative (Loc,
                Discrete_Choices => New_List (
                  Make_Integer_Literal (Sloc (Enumeration_Rep_Expr (Ent)),
                    Intval => Enumeration_Rep (Ent))),

                Statements => New_List (
                  Make_Simple_Return_Statement (Loc,
                    Expression =>
                      Make_Integer_Literal (Loc,
                        Intval => Enumeration_Pos (Ent))))));

            Next_Literal (Ent);
         end loop;
      end if;

      --  In normal mode, add the others clause with the test.
      --  If Predicates_Ignored is True, validity checks do not apply to
      --  the subtype.

      if not No_Exception_Handlers_Set
        and then not Predicates_Ignored_In_Codegen (Typ)
      then
         Append_To (Lst,
           Make_Case_Statement_Alternative (Loc,
             Discrete_Choices => New_List (Make_Others_Choice (Loc)),
             Statements       => New_List (
               Make_Raise_Constraint_Error (Loc,
                 Condition => Make_Identifier (Loc, Name_uF),
                 Reason    => CE_Invalid_Data),
               Make_Simple_Return_Statement (Loc,
                 Expression => Make_Integer_Literal (Loc, -1)))));

      --  If either of the restrictions No_Exceptions_Handlers/Propagation is
      --  active then return -1 (we cannot usefully raise Constraint_Error in
      --  this case). See description above for further details.

      else
         Append_To (Lst,
           Make_Case_Statement_Alternative (Loc,
             Discrete_Choices => New_List (Make_Others_Choice (Loc)),
             Statements       => New_List (
               Make_Simple_Return_Statement (Loc,
                 Expression => Make_Integer_Literal (Loc, -1)))));
      end if;

      --  Now we can build the function body

      Fent :=
        Make_Defining_Identifier (Loc, Make_TSS_Name (Typ, TSS_Rep_To_Pos));

      Func :=
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name       => Fent,
              Parameter_Specifications => New_List (
                Make_Parameter_Specification (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc, Name_uA),
                  Parameter_Type => New_Occurrence_Of (Typ, Loc)),
                Make_Parameter_Specification (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc, Name_uF),
                  Parameter_Type =>
                    New_Occurrence_Of (Standard_Boolean, Loc))),

              Result_Definition => New_Occurrence_Of (Standard_Integer, Loc)),

            Declarations => Empty_List,

            Handled_Statement_Sequence =>
              Make_Handled_Sequence_Of_Statements (Loc,
                Statements => New_List (
                  Make_Case_Statement (Loc,
                    Expression =>
                      Unchecked_Convert_To
                        (Ityp, Make_Identifier (Loc, Name_uA)),
                    Alternatives => Lst))));

      Set_TSS (Typ, Fent);

      --  Set Pure flag (it will be reset if the current context is not Pure).
      --  We also pretend there was a pragma Pure_Function so that for purposes
      --  of optimization and constant-folding, we will consider the function
      --  Pure even if we are not in a Pure context).

      Set_Is_Pure (Fent);
      Set_Has_Pragma_Pure_Function (Fent);

      --  Unless we are in -gnatD mode, where we are debugging generated code,
      --  this is an internal entity for which we don't need debug info.

      if not Debug_Generated_Code then
         Set_Debug_Info_Off (Fent);
      end if;

      Set_Is_Inlined (Fent);

   exception
      when RE_Not_Available =>
         null;
   end Expand_Freeze_Enumeration_Type;

   -------------------------------
   -- Expand_Freeze_Record_Type --
   -------------------------------

   procedure Expand_Freeze_Record_Type (N : Node_Id) is

      procedure Build_Class_Condition_Subprograms (Typ : Entity_Id);
      --  Create internal subprograms of Typ primitives that have class-wide
      --  preconditions or postconditions; they are invoked by the caller to
      --  evaluate the conditions.

      procedure Build_Variant_Record_Equality (Typ  : Entity_Id);
      --  Create an equality function for the untagged variant record Typ and
      --  attach it to the TSS list.

      procedure Register_Dispatch_Table_Wrappers (Typ : Entity_Id);
      --  Register dispatch-table wrappers in the dispatch table of Typ

      procedure Validate_Tagged_Type_Extra_Formals (Typ : Entity_Id);
      --  Check extra formals of dispatching primitives of tagged type Typ.
      --  Used in pragma Debug.

      ---------------------------------------
      -- Build_Class_Condition_Subprograms --
      ---------------------------------------

      procedure Build_Class_Condition_Subprograms (Typ : Entity_Id) is
         Prim_List : constant Elist_Id := Primitive_Operations (Typ);
         Prim_Elmt : Elmt_Id           := First_Elmt (Prim_List);
         Prim      : Entity_Id;

      begin
         while Present (Prim_Elmt) loop
            Prim := Node (Prim_Elmt);

            --  Primitive with class-wide preconditions

            if Comes_From_Source (Prim)
              and then Has_Significant_Contract (Prim)
              and then
                (Present (Class_Preconditions (Prim))
                   or else Present (Ignored_Class_Preconditions (Prim)))
            then
               if Expander_Active then
                  Make_Class_Precondition_Subps (Prim);
               end if;

            --  Wrapper of a primitive that has or inherits class-wide
            --  preconditions.

            elsif Is_Primitive_Wrapper (Prim)
              and then
                (Present (Nearest_Class_Condition_Subprogram
                           (Spec_Id => Prim,
                            Kind    => Class_Precondition))
                   or else
                 Present (Nearest_Class_Condition_Subprogram
                           (Spec_Id => Prim,
                            Kind    => Ignored_Class_Precondition)))
            then
               if Expander_Active then
                  Make_Class_Precondition_Subps (Prim);
               end if;
            end if;

            Next_Elmt (Prim_Elmt);
         end loop;
      end Build_Class_Condition_Subprograms;

      -----------------------------------
      -- Build_Variant_Record_Equality --
      -----------------------------------

      procedure Build_Variant_Record_Equality (Typ : Entity_Id) is
         Loc : constant Source_Ptr := Sloc (Typ);
         F   : constant Entity_Id  :=
                 Make_Defining_Identifier (Loc,
                   Chars => Make_TSS_Name (Typ, TSS_Composite_Equality));
      begin
         --  For a variant record with restriction No_Implicit_Conditionals
         --  in effect we skip building the procedure. This is safe because
         --  if we can see the restriction, so can any caller, and calls to
         --  equality test routines are not allowed for variant records if
         --  this restriction is active.

         if Restriction_Active (No_Implicit_Conditionals) then
            return;
         end if;

         --  Derived Unchecked_Union types no longer inherit the equality
         --  function of their parent.

         if Is_Derived_Type (Typ)
           and then not Is_Unchecked_Union (Typ)
           and then not Has_New_Non_Standard_Rep (Typ)
         then
            declare
               Parent_Eq : constant Entity_Id :=
                             TSS (Root_Type (Typ), TSS_Composite_Equality);
            begin
               if Present (Parent_Eq) then
                  Copy_TSS (Parent_Eq, Typ);
                  return;
               end if;
            end;
         end if;

         Discard_Node (
           Build_Variant_Record_Equality
             (Typ         => Typ,
              Spec_Id     => Empty,
              Body_Id     => F,
              Param_Specs => New_List (
                Make_Parameter_Specification (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc, Name_X),
                  Parameter_Type      => New_Occurrence_Of (Typ, Loc)),

                Make_Parameter_Specification (Loc,
                  Defining_Identifier =>
                    Make_Defining_Identifier (Loc, Name_Y),
                  Parameter_Type      => New_Occurrence_Of (Typ, Loc)))));

         Set_TSS (Typ, F);
         Set_Is_Pure (F);

         if not Debug_Generated_Code then
            Set_Debug_Info_Off (F);
         end if;
      end Build_Variant_Record_Equality;

      --------------------------------------
      -- Register_Dispatch_Table_Wrappers --
      --------------------------------------

      procedure Register_Dispatch_Table_Wrappers (Typ : Entity_Id) is
         Elmt : Elmt_Id := First_Elmt (Primitive_Operations (Typ));
         Subp : Entity_Id;

      begin
         while Present (Elmt) loop
            Subp := Node (Elmt);

            if Is_Dispatch_Table_Wrapper (Subp) then
               Append_Freeze_Actions (Typ,
                 Register_Primitive (Sloc (Subp), Subp));
            end if;

            Next_Elmt (Elmt);
         end loop;
      end Register_Dispatch_Table_Wrappers;

      ----------------------------------------
      -- Validate_Tagged_Type_Extra_Formals --
      ----------------------------------------

      procedure Validate_Tagged_Type_Extra_Formals (Typ : Entity_Id) is
         Ovr_Subp : Entity_Id;
         Elmt     : Elmt_Id;
         Subp     : Entity_Id;

      begin
         pragma Assert (not Is_Class_Wide_Type (Typ));

         --  No check required if expansion is not active since we never
         --  generate extra formals in such case.

         if not Expander_Active then
            return;
         end if;

         Elmt := First_Elmt (Primitive_Operations (Typ));
         while Present (Elmt) loop
            Subp := Node (Elmt);

            --  Extra formals of a dispatching primitive must match:

            --  1) The extra formals of its covered interface primitive

            if Present (Interface_Alias (Subp)) then
               pragma Assert
                 (Extra_Formals_Match_OK
                   (E     => Interface_Alias (Subp),
                    Ref_E => Alias (Subp)));
            end if;

            --  2) The extra formals of its renamed primitive

            if Present (Alias (Subp)) then
               pragma Assert
                 (Extra_Formals_Match_OK
                   (E     => Subp,
                    Ref_E => Ultimate_Alias (Subp)));
            end if;

            --  3) The extra formals of its overridden primitive

            if Present (Overridden_Operation (Subp)) then
               Ovr_Subp := Overridden_Operation (Subp);

               --  Handle controlling function wrapper

               if Is_Wrapper (Subp)
                 and then Ultimate_Alias (Ovr_Subp) = Subp
               then
                  if Present (Overridden_Operation (Ovr_Subp)) then
                     pragma Assert
                       (Extra_Formals_Match_OK
                         (E     => Subp,
                          Ref_E => Overridden_Operation (Ovr_Subp)));
                  end if;

               else
                  pragma Assert
                    (Extra_Formals_Match_OK (E => Subp, Ref_E => Ovr_Subp));
               end if;
            end if;

            Next_Elmt (Elmt);
         end loop;
      end Validate_Tagged_Type_Extra_Formals;

      --  Local variables

      Typ      : constant Node_Id := Entity (N);
      Typ_Decl : constant Node_Id := Parent (Typ);

      Predef_List : List_Id;

      Wrapper_Decl_List : List_Id;
      Wrapper_Body_List : List_Id := No_List;

      Renamed_Eq : Node_Id := Empty;
      --  Defining unit name for the predefined equality function in the case
      --  where the type has a primitive operation that is a renaming of
      --  predefined equality (but only if there is also an overriding
      --  user-defined equality function). Used to pass this entity from
      --  Make_Predefined_Primitive_Specs to Predefined_Primitive_Bodies.

   --  Start of processing for Expand_Freeze_Record_Type

   begin
      --  Build discriminant checking functions if not a derived type (for
      --  derived types that are not tagged types, always use the discriminant
      --  checking functions of the parent type). However, for untagged types
      --  the derivation may have taken place before the parent was frozen, so
      --  we copy explicitly the discriminant checking functions from the
      --  parent into the components of the derived type.

      Build_Or_Copy_Discr_Checking_Funcs (Typ_Decl);

      if Is_Derived_Type (Typ)
        and then Is_Limited_Type (Typ)
        and then Is_Tagged_Type (Typ)
      then
         Check_Stream_Attributes (Typ);
      end if;

      --  Handle constructors of untagged CPP_Class types

      if not Is_Tagged_Type (Typ) and then Is_CPP_Class (Typ) then
         Set_CPP_Constructors (Typ);
      end if;

      --  Creation of the Dispatch Table. Note that a Dispatch Table is built
      --  for regular tagged types as well as for Ada types deriving from a C++
      --  Class, but not for tagged types directly corresponding to C++ classes
      --  In the later case we assume that it is created in the C++ side and we
      --  just use it.

      if Is_Tagged_Type (Typ) then

         --  Add the _Tag component

         if Underlying_Type (Etype (Typ)) = Typ then
            Expand_Tagged_Root (Typ);
         end if;

         if Is_CPP_Class (Typ) then
            Set_All_DT_Position (Typ);

            --  Create the tag entities with a minimum decoration

            if Tagged_Type_Expansion then
               Append_Freeze_Actions (Typ, Make_Tags (Typ));
            end if;

            Set_CPP_Constructors (Typ);

         else
            if not Building_Static_DT (Typ) then

               --  Usually inherited primitives are not delayed but the first
               --  Ada extension of a CPP_Class is an exception since the
               --  address of the inherited subprogram has to be inserted in
               --  the new Ada Dispatch Table and this is a freezing action.

               --  Similarly, if this is an inherited operation whose parent is
               --  not frozen yet, it is not in the DT of the parent, and we
               --  generate an explicit freeze node for the inherited operation
               --  so it is properly inserted in the DT of the current type.

               declare
                  Elmt : Elmt_Id;
                  Subp : Entity_Id;

               begin
                  Elmt := First_Elmt (Primitive_Operations (Typ));
                  while Present (Elmt) loop
                     Subp := Node (Elmt);

                     if Present (Alias (Subp)) then
                        if Is_CPP_Class (Etype (Typ)) then
                           Set_Has_Delayed_Freeze (Subp);

                        elsif Has_Delayed_Freeze (Alias (Subp))
                          and then not Is_Frozen (Alias (Subp))
                        then
                           Set_Is_Frozen (Subp, False);
                           Set_Has_Delayed_Freeze (Subp);
                        end if;
                     end if;

                     Next_Elmt (Elmt);
                  end loop;
               end;
            end if;

            --  Unfreeze momentarily the type to add the predefined primitives
            --  operations. The reason we unfreeze is so that these predefined
            --  operations will indeed end up as primitive operations (which
            --  must be before the freeze point).

            Set_Is_Frozen (Typ, False);

            --  Do not add the spec of predefined primitives in case of
            --  CPP tagged type derivations that have convention CPP.

            if Is_CPP_Class (Root_Type (Typ))
              and then Convention (Typ) = Convention_CPP
            then
               null;

            --  Do not add the spec of the predefined primitives if we are
            --  compiling under restriction No_Dispatching_Calls.

            elsif not Restriction_Active (No_Dispatching_Calls) then
               Make_Predefined_Primitive_Specs (Typ, Predef_List, Renamed_Eq);
               Insert_List_Before_And_Analyze (N, Predef_List);
            end if;

            --  Ada 2005 (AI-391): For a nonabstract null extension, create
            --  wrapper functions for each nonoverridden inherited function
            --  with a controlling result of the type. The wrapper for such
            --  a function returns an extension aggregate that invokes the
            --  parent function.

            if Ada_Version >= Ada_2005
              and then not Is_Abstract_Type (Typ)
              and then Is_Null_Extension (Typ)
            then
               Make_Controlling_Function_Wrappers
                 (Typ, Wrapper_Decl_List, Wrapper_Body_List);
               Insert_List_Before_And_Analyze (N, Wrapper_Decl_List);
            end if;

            --  Ada 2005 (AI-251): For a nonabstract type extension, build
            --  null procedure declarations for each set of homographic null
            --  procedures that are inherited from interface types but not
            --  overridden. This is done to ensure that the dispatch table
            --  entry associated with such null primitives are properly filled.

            if Ada_Version >= Ada_2005
              and then Etype (Typ) /= Typ
              and then not Is_Abstract_Type (Typ)
              and then Has_Interfaces (Typ)
            then
               Insert_Actions (N, Make_Null_Procedure_Specs (Typ));
            end if;

            Set_Is_Frozen (Typ);

            if not Is_Derived_Type (Typ)
              or else Is_Tagged_Type (Etype (Typ))
            then
               Set_All_DT_Position (Typ);

            --  If this is a type derived from an untagged private type whose
            --  full view is tagged, the type is marked tagged for layout
            --  reasons, but it has no dispatch table.

            elsif Is_Derived_Type (Typ)
              and then Is_Private_Type (Etype (Typ))
              and then not Is_Tagged_Type (Etype (Typ))
            then
               return;
            end if;

            --  Create and decorate the tags. Suppress their creation when
            --  not Tagged_Type_Expansion because the dispatching mechanism is
            --  handled internally by the virtual target.

            if Tagged_Type_Expansion then
               Append_Freeze_Actions (Typ, Make_Tags (Typ));

               --  Generate dispatch table of locally defined tagged type.
               --  Dispatch tables of library level tagged types are built
               --  later (see Build_Static_Dispatch_Tables).

               if not Building_Static_DT (Typ) then
                  Append_Freeze_Actions (Typ, Make_DT (Typ));

                  --  Register dispatch table wrappers in the dispatch table.
                  --  It could not be done when these wrappers were built
                  --  because, at that stage, the dispatch table was not
                  --  available.

                  Register_Dispatch_Table_Wrappers (Typ);
               end if;
            end if;

            --  If the type has unknown discriminants, propagate dispatching
            --  information to its underlying record view, which does not get
            --  its own dispatch table.

            if Is_Derived_Type (Typ)
              and then Has_Unknown_Discriminants (Typ)
              and then Present (Underlying_Record_View (Typ))
            then
               declare
                  Rep : constant Entity_Id := Underlying_Record_View (Typ);
               begin
                  Set_Access_Disp_Table
                    (Rep, Access_Disp_Table           (Typ));
                  Set_Dispatch_Table_Wrappers
                    (Rep, Dispatch_Table_Wrappers     (Typ));
                  Set_Direct_Primitive_Operations
                    (Rep, Direct_Primitive_Operations (Typ));
               end;
            end if;

            --  Make sure that the primitives Initialize, Adjust and Finalize
            --  are Frozen before other TSS subprograms. We don't want them
            --  frozen inside.

            if Is_Controlled (Typ) then
               declare
                  Prim : Entity_Id;

               begin
                  Prim := Find_Controlled_Prim_Op (Typ, Name_Initialize);
                  if Present (Prim) then
                     Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
                  end if;

                  if not Is_Limited_Type (Typ) then
                     Prim := Find_Controlled_Prim_Op (Typ, Name_Adjust);
                     if Present (Prim) then
                        Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
                     end if;
                  end if;

                  Prim := Find_Controlled_Prim_Op (Typ, Name_Finalize);
                  if Present (Prim) then
                     Append_Freeze_Actions (Typ, Freeze_Entity (Prim, Typ));
                  end if;
               end;
            end if;

            --  Freeze rest of primitive operations. There is no need to handle
            --  the predefined primitives if we are compiling under restriction
            --  No_Dispatching_Calls.

            if not Restriction_Active (No_Dispatching_Calls) then
               Append_Freeze_Actions (Typ, Predefined_Primitive_Freeze (Typ));
            end if;
         end if;

      --  In the untagged case, ever since Ada 83 an equality function must
      --  be provided for variant records that are not unchecked unions.

      elsif Has_Discriminants (Typ)
        and then not Is_Limited_Type (Typ)
        and then Present (Component_List (Type_Definition (Typ_Decl)))
        and then
          Present (Variant_Part (Component_List (Type_Definition (Typ_Decl))))
      then
         Build_Variant_Record_Equality (Typ);

      --  In Ada 2012 the equality function composes, and thus must be built
      --  explicitly just as for tagged records.

      --  This is done unconditionally to ensure that tools can be linked
      --  properly with user programs compiled with older language versions.
      --  In addition, this is needed because "=" composes for bounded strings
      --  in all language versions (see Exp_Ch4.Expand_Composite_Equality).

      elsif Comes_From_Source (Typ)
        and then Convention (Typ) = Convention_Ada
        and then not Is_Limited_Type (Typ)
      then
         Build_Untagged_Record_Equality (Typ);
      end if;

      --  Freeze constructors as predefined operations

      Append_Freeze_Actions (Typ, Constructor_Freeze (Typ));

      --  Before building the record initialization procedure, if we are
      --  dealing with a concurrent record value type, then we must go through
      --  the discriminants, exchanging discriminals between the concurrent
      --  type and the concurrent record value type. See the section "Handling
      --  of Discriminants" in the Einfo spec for details.

      if Is_Concurrent_Record_Type (Typ) and then Has_Discriminants (Typ) then
         declare
            Ctyp       : constant Entity_Id :=
                           Corresponding_Concurrent_Type (Typ);
            Conc_Discr : Entity_Id;
            Rec_Discr  : Entity_Id;
            Temp       : Entity_Id;

         begin
            Conc_Discr := First_Discriminant (Ctyp);
            Rec_Discr  := First_Discriminant (Typ);
            while Present (Conc_Discr) loop
               Temp := Discriminal (Conc_Discr);
               Set_Discriminal (Conc_Discr, Discriminal (Rec_Discr));
               Set_Discriminal (Rec_Discr, Temp);

               Set_Discriminal_Link (Discriminal (Conc_Discr), Conc_Discr);
               Set_Discriminal_Link (Discriminal (Rec_Discr),  Rec_Discr);

               Next_Discriminant (Conc_Discr);
               Next_Discriminant (Rec_Discr);
            end loop;
         end;
      end if;

      if Has_Controlled_Component (Typ) or else Has_Destructor (Typ) then
         Build_Controlling_Procs (Typ);
      end if;

      Adjust_Discriminants (Typ);

      --  Do not need init for interfaces on virtual targets since they're
      --  abstract.

      if not Is_Mutably_Tagged_CW_Equivalent_Type (Typ)
        and then (Tagged_Type_Expansion or else not Is_Interface (Typ))
      then
         Build_Record_Init_Proc (Typ_Decl, Typ);
         Build_Implicit_Copy_Constructor (Typ_Decl, Typ);
      end if;

      --  Create the body of TSS primitive Finalize_Address. This must be done
      --  before the bodies of all predefined primitives are created. If Typ
      --  is limited, Stream_Input and Stream_Read may produce build-in-place
      --  allocations and for those the expander needs Finalize_Address.

      if Is_Controlled (Typ) then
         Make_Finalize_Address_Body (Typ);
      end if;

      --  For tagged type that are not interfaces, build bodies of primitive
      --  operations. Note: do this after building the record initialization
      --  procedure, since the primitive operations may need the initialization
      --  routine. There is no need to add predefined primitives of interfaces
      --  because all their predefined primitives are abstract.

      if Is_Tagged_Type (Typ) and then not Is_Interface (Typ) then

         --  Do not add the body of predefined primitives in case of CPP tagged
         --  type derivations that have convention CPP.

         if Is_CPP_Class (Root_Type (Typ))
           and then Convention (Typ) = Convention_CPP
         then
            null;

         --  Do not add the body of the predefined primitives if we are
         --  compiling under restriction No_Dispatching_Calls.

         elsif not Restriction_Active (No_Dispatching_Calls) then
            --  Create the body of the class-wide type's TSS primitive
            --  Finalize_Address. This must be done before any class-wide
            --  precondition functions are created.

            Make_Finalize_Address_Body (Class_Wide_Type (Typ));

            Predef_List := Predefined_Primitive_Bodies (Typ, Renamed_Eq);
            Append_Freeze_Actions (Typ, Predef_List);
         end if;

         --  Ada 2005 (AI-391): If any wrappers were created for nonoverridden
         --  inherited functions, then add their bodies to the freeze actions.

         Append_Freeze_Actions (Typ, Wrapper_Body_List);

      --  Create body of an interface type's class-wide type's TSS primitive
      --  Finalize_Address.

      elsif Is_Tagged_Type (Typ)
        and then Is_Interface (Typ)
        and then not Restriction_Active (No_Dispatching_Calls)
      then
         Make_Finalize_Address_Body (Class_Wide_Type (Typ));
      end if;

      --  Create extra formals for the primitive operations of the type.
      --  This must be done before analyzing the body of the initialization
      --  procedure, because a self-referential type might call one of these
      --  primitives in the body of the init_proc itself.
      --
      --  This is not needed when expansion is disabled, because extra formals
      --  are only added when we are generating code.
      --
      --  Notice that for tagged types with foreign convention this is also
      --  required because (although primitives with foreign convention don't
      --  have extra formals), a tagged type with foreign convention may have
      --  primitives with convention Ada.

      if Expander_Active
        and then Is_Tagged_Type (Typ)
      then
         declare
            Elmt : Elmt_Id;
            E    : Entity_Id;

         begin
            --  Add extra formals to primitive operations

            Elmt := First_Elmt (Primitive_Operations (Typ));
            while Present (Elmt) loop
               Create_Extra_Formals (Node (Elmt), Related_Nod => N);
               Next_Elmt (Elmt);
            end loop;

            --  Add extra formals to renamings of primitive operations. The
            --  addition of extra formals is done in two steps to minimize
            --  the compile time required for this action; the evaluation of
            --  Find_Dispatching_Type() and Contains() is only done here for
            --  renamings that are not primitive operations.

            E := First_Entity (Scope (Typ));
            while Present (E) loop
               if Is_Dispatching_Operation (E)
                 and then Present (Alias (E))
                 and then Find_Dispatching_Type (E) = Typ
                 and then not Contains (Primitive_Operations (Typ), E)
               then
                  Create_Extra_Formals (E, Related_Nod => N);
               end if;

               Next_Entity (E);
            end loop;

            pragma Debug (Validate_Tagged_Type_Extra_Formals (Typ));
         end;
      end if;

      --  Build internal subprograms of primitives with class-wide
      --  pre/postconditions.

      if Is_Tagged_Type (Typ) then
         Build_Class_Condition_Subprograms (Typ);
      end if;
   end Expand_Freeze_Record_Type;

   ------------------------------------
   -- Expand_N_Full_Type_Declaration --
   ------------------------------------

   procedure Expand_N_Full_Type_Declaration (N : Node_Id) is
      procedure Build_Master (Ptr_Typ : Entity_Id);
      --  Create the master associated with Ptr_Typ

      ------------------
      -- Build_Master --
      ------------------

      procedure Build_Master (Ptr_Typ : Entity_Id) is
         Desig_Typ : Entity_Id := Designated_Type (Ptr_Typ);

      begin
         --  If the designated type is an incomplete view coming from a
         --  limited-with'ed package, we need to use the nonlimited view in
         --  case it has tasks.

         if Is_Incomplete_Type (Desig_Typ)
           and then Present (Non_Limited_View (Desig_Typ))
         then
            Desig_Typ := Non_Limited_View (Desig_Typ);
         end if;

         --  Anonymous access types are created for the components of the
         --  record parameter for an entry declaration. No master is created
         --  for such a type.

         if Has_Task (Desig_Typ) then
            Build_Master_Entity (Ptr_Typ);
            Build_Master_Renaming (Ptr_Typ);

         --  Create a class-wide master because a Master_Id must be generated
         --  for access-to-limited-class-wide types whose root may be extended
         --  with task components.

         --  Note: This code covers access-to-limited-interfaces because they
         --        can be used to reference tasks implementing them.

         --  Suppress the master creation for access types created for entry
         --  formal parameters (parameter block component types). Seems like
         --  suppression should be more general for compiler-generated types,
         --  but testing Comes_From_Source may be too general in this case
         --  (affects some test output)???

         elsif not Is_Param_Block_Component_Type (Ptr_Typ)
           and then Is_Limited_Class_Wide_Type (Desig_Typ)
         then
            Build_Master_Entity (Ptr_Typ);
            Build_Master_Renaming (Ptr_Typ);
         end if;
      end Build_Master;

      --  Local declarations

      Def_Id : constant Entity_Id := Defining_Identifier (N);
      B_Id   : constant Entity_Id := Base_Type (Def_Id);
      FN     : Node_Id;
      Par_Id : Entity_Id;

   --  Start of processing for Expand_N_Full_Type_Declaration

   begin
      if Is_Access_Type (Def_Id) then
         Build_Master (Def_Id);

         if Ekind (Def_Id) = E_Access_Protected_Subprogram_Type then
            Expand_Access_Protected_Subprogram_Type (N);
         end if;

      --  Array of anonymous access-to-task pointers

      elsif Ada_Version >= Ada_2005
        and then Is_Array_Type (Def_Id)
        and then Is_Access_Type (Component_Type (Def_Id))
        and then Ekind (Component_Type (Def_Id)) = E_Anonymous_Access_Type
      then
         Build_Master (Component_Type (Def_Id));

      elsif Has_Task (Def_Id) then
         Expand_Previous_Access_Type (Def_Id);

      --  Check the components of a record type or array of records for
      --  anonymous access-to-task pointers.

      elsif Ada_Version >= Ada_2005
        and then (Is_Record_Type (Def_Id)
                   or else
                     (Is_Array_Type (Def_Id)
                       and then Is_Record_Type (Component_Type (Def_Id))))
      then
         declare
            Comp  : Entity_Id;
            First : Boolean;
            M_Id  : Entity_Id := Empty;
            Typ   : Entity_Id;

         begin
            if Is_Array_Type (Def_Id) then
               Comp := First_Entity (Component_Type (Def_Id));
            else
               Comp := First_Entity (Def_Id);
            end if;

            --  Examine all components looking for anonymous access-to-task
            --  types.

            First := True;
            while Present (Comp) loop
               Typ := Etype (Comp);

               if Ekind (Typ) = E_Anonymous_Access_Type
                 and then Might_Have_Tasks
                            (Available_View (Designated_Type (Typ)))
                 and then No (Master_Id (Typ))
               then
                  --  Ensure that the record or array type have a _master

                  if First then
                     Build_Master_Entity (Def_Id);
                     Build_Master_Renaming (Typ);
                     M_Id := Master_Id (Typ);

                     First := False;

                  --  Reuse the same master to service any additional types

                  else
                     pragma Assert (Present (M_Id));
                     Set_Master_Id (Typ, M_Id);
                  end if;
               end if;

               Next_Entity (Comp);
            end loop;
         end;
      end if;

      --  Handle mutably tagged types by replacing their declarations with
      --  their class-wide equivalent types.

      declare
         Comp : Entity_Id;
      begin
         if Is_Array_Type (Def_Id) then
            Comp := First_Entity (Component_Type (Def_Id));
         else
            Comp := First_Entity (Def_Id);
         end if;

         while Present (Comp) loop
            if Ekind (Etype (Comp)) /= E_Void
              and then Is_Mutably_Tagged_Type (Etype (Comp))
            then
               Set_Etype
                 (Comp, Class_Wide_Equivalent_Type (Etype (Comp)));
            end if;
            Next_Entity (Comp);
         end loop;
      end;

      Par_Id := Etype (B_Id);

      --  The parent type is private then we need to inherit any TSS operations
      --  from the full view.

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

      if Nkind (Type_Definition (N)) = N_Derived_Type_Definition
        and then not Is_Tagged_Type (Def_Id)
        and then Present (Freeze_Node (Par_Id))
        and then Present (TSS_Elist (Freeze_Node (Par_Id)))
      then
         Ensure_Freeze_Node (B_Id);
         FN := Freeze_Node (B_Id);

         if No (TSS_Elist (FN)) then
            Set_TSS_Elist (FN, New_Elmt_List);
         end if;

         declare
            T_E  : constant Elist_Id := TSS_Elist (FN);
            Elmt : Elmt_Id;

         begin
            Elmt := First_Elmt (TSS_Elist (Freeze_Node (Par_Id)));
            while Present (Elmt) loop
               if Chars (Node (Elmt)) /= Name_uInit then
                  Append_Elmt (Node (Elmt), T_E);
               end if;

               Next_Elmt (Elmt);
            end loop;

            --  If the derived type itself is private with a full view, then
            --  associate the full view with the inherited TSS_Elist as well.

            if Is_Private_Type (B_Id)
              and then Present (Full_View (B_Id))
            then
               Ensure_Freeze_Node (Base_Type (Full_View (B_Id)));
               Set_TSS_Elist
                 (Freeze_Node (Base_Type (Full_View (B_Id))), TSS_Elist (FN));
            end if;
         end;
      end if;
   end Expand_N_Full_Type_Declaration;

   ---------------------------------
   -- Expand_N_Object_Declaration --
   ---------------------------------

   procedure Expand_N_Object_Declaration (N : Node_Id) is
      Loc      : constant Source_Ptr := Sloc (N);
      Def_Id   : constant Entity_Id  := Defining_Identifier (N);
      Obj_Def  : constant Node_Id    := Object_Definition (N);
      Typ      : constant Entity_Id  := Etype (Def_Id);
      Base_Typ : constant Entity_Id  := Base_Type (Typ);
      Next_N   : constant Node_Id    := Next (N);

      Expr : Node_Id := Expression (N);

      Special_Ret_Obj : constant Boolean := Is_Special_Return_Object (Def_Id);
      --  If this is a special return object, it will be allocated differently
      --  and ultimately rewritten as a renaming, so initialization activities
      --  need to be deferred until after that is done.

      Func_Id : constant Entity_Id :=
       (if Special_Ret_Obj then Return_Applies_To (Scope (Def_Id)) else Empty);
      --  The function if this is a special return object, otherwise Empty

      function Build_Heap_Or_Pool_Allocator
        (Temp_Id    : Entity_Id;
         Temp_Typ   : Entity_Id;
         Ret_Typ    : Entity_Id;
         Alloc_Expr : Node_Id) return Node_Id;
      --  Create the statements necessary to allocate a return object on the
      --  heap or user-defined storage pool. The object may need finalization
      --  actions depending on the return type.
      --
      --    * Controlled case
      --
      --       if BIPcollection = null then
      --          Temp_Id := <Alloc_Expr>;
      --       else
      --          declare
      --             type Ptr_Typ is access Ret_Typ;
      --             for Ptr_Typ'Storage_Pool use BIPstoragepool.all;
      --             Local : Ptr_Typ;
      --
      --          begin
      --             procedure Allocate (...) is
      --             begin
      --                System.Storage_Pools.Subpools.Allocate_Any (...);
      --             end Allocate;
      --
      --             Local := <Alloc_Expr>;
      --             Temp_Id := Temp_Typ (Local);
      --          end;
      --       end if;
      --
      --    * Non-controlled case
      --
      --       Temp_Id := <Alloc_Expr>;
      --
      --  Temp_Id is the temporary which is used to reference the internally
      --  created object in all allocation forms. Temp_Typ is the type of the
      --  temporary. Func_Id is the enclosing function. Ret_Typ is the return
      --  type of Func_Id. Alloc_Expr is the actual allocator.

      function BIP_Function_Call_Id return Entity_Id;
      --  If the object initialization expression is a call to a build-in-place
      --  function, return the id of the called function; otherwise return
      --  Empty.

      procedure Count_Default_Sized_Task_Stacks
        (Typ         : Entity_Id;
         Pri_Stacks  : out Nat;
         Sec_Stacks  : out Nat);
      --  Count the number of default-sized primary and secondary task stacks
      --  required for task objects contained within type Typ. If the number of
      --  task objects contained within the type is not known at compile time
      --  the procedure will return the stack counts of zero.

      procedure Default_Initialize_Object (After : Node_Id);
      --  Generate all default initialization actions for object Def_Id. Any
      --  new code is inserted after node After.

      procedure Initialize_Return_Object
        (Tag_Assign : Node_Id;
         Adj_Call   : Node_Id;
         Expr       : Node_Id;
         Init_Stmt  : Node_Id;
         After      : Node_Id);
      --  Generate all initialization actions for return object Def_Id. Any
      --  new code is inserted after node After.

      function Is_Renamable_Function_Call (Expr : Node_Id) return Boolean;
      --  If we are not at library level and the object declaration originally
      --  appears in the form:

      --    Obj : Typ := Func (...);

      --  and has been rewritten as the dereference of a captured reference
      --  to the function result built either on the primary or the secondary
      --  stack, then the declaration can be rewritten as the renaming of this
      --  dereference:

      --    type Ann is access all Typ;
      --    Rnn : constant Axx := Func (...)'reference;
      --    Obj : Typ renames Rnn.all;

      --  This will avoid making an extra copy and, in the case where Typ needs
      --  finalization, a pair of calls to the Adjust and Finalize primitives,
      --  or Deep_Adjust and Deep_Finalize routines, depending on whether Typ
      --  has components that themselves need finalization.

      --  However, in the case of a special return object, we need to make sure
      --  that the object Rnn is recognized by the Is_Related_To_Func_Return
      --  predicate; otherwise, if it is of a type that needs finalization,
      --  then Requires_Cleanup_Actions would return true because of this and
      --  Build_Finalizer would finalize it prematurely because of this (see
      --  also Expand_Simple_Function_Return for the same test in the case of
      --  a simple return).

      --  Finally, in the case of a special return object, we also need to make
      --  sure that the two functions return on the same stack, otherwise we
      --  would create a dangling reference.

      function Make_Allocator_For_Return (Expr : Node_Id) return Node_Id;
      --  Make an allocator for a return object initialized with Expr

      function OK_To_Rename_Ref (N : Node_Id) return Boolean;
      --  Return True if N denotes an entity with OK_To_Rename set

      ----------------------------------
      -- Build_Heap_Or_Pool_Allocator --
      ----------------------------------

      function Build_Heap_Or_Pool_Allocator
        (Temp_Id    : Entity_Id;
         Temp_Typ   : Entity_Id;
         Ret_Typ    : Entity_Id;
         Alloc_Expr : Node_Id) return Node_Id
      is
      begin
         pragma Assert (Is_Build_In_Place_Function (Func_Id));

         --  Processing for objects that require finalization actions

         if Needs_Finalization (Ret_Typ)
           and then not Has_Relaxed_Finalization (Ret_Typ)
         then
            declare
               Decls       : constant List_Id := New_List;
               Fin_Coll_Id : constant Entity_Id :=
                 Build_In_Place_Formal (Func_Id, BIP_Collection);
               Orig_Expr   : constant Node_Id := New_Copy_Tree (Alloc_Expr);
               Stmts       : constant List_Id := New_List;
               Local_Id    : Entity_Id;
               Pool_Id     : Entity_Id;
               Ptr_Typ     : Entity_Id;

            begin
               --  Generate:
               --    Pool_Id renames BIPstoragepool.all;

               --  This formal is not added on ZFP as those targets do not
               --  support pools.

               if RTE_Available (RE_Root_Storage_Pool_Ptr) then
                  Pool_Id := Make_Temporary (Loc, 'P');

                  Append_To (Decls,
                    Make_Object_Renaming_Declaration (Loc,
                      Defining_Identifier => Pool_Id,
                      Subtype_Mark        =>
                        New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc),
                      Name                =>
                        Make_Explicit_Dereference (Loc,
                          New_Occurrence_Of
                            (Build_In_Place_Formal
                               (Func_Id, BIP_Storage_Pool), Loc))));
               else
                  Pool_Id := Empty;
               end if;

               --  Create an access type which uses the storage pool of the
               --  caller. This additional type is necessary because the
               --  finalization collection cannot be associated with the type
               --  of the temporary. Otherwise the secondary stack allocation
               --  will fail.

               --  Generate:
               --    type Ptr_Typ is access Ret_Typ;

               Ptr_Typ := Make_Temporary (Loc, 'P');

               Append_To (Decls,
                 Make_Full_Type_Declaration (Loc,
                   Defining_Identifier => Ptr_Typ,
                   Type_Definition     =>
                     Make_Access_To_Object_Definition (Loc,
                       Subtype_Indication =>
                         New_Occurrence_Of (Ret_Typ, Loc))));

               --  Perform minor decoration in order to set the collection and
               --  the storage pool attributes.

               Mutate_Ekind                (Ptr_Typ, E_Access_Type);
               Set_Finalization_Collection (Ptr_Typ, Fin_Coll_Id);
               Set_Associated_Storage_Pool (Ptr_Typ, Pool_Id);

               --  Create the temporary, generate:
               --    Local_Id : Ptr_Typ;

               Local_Id := Make_Temporary (Loc, 'T');

               Append_To (Decls,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Local_Id,
                   Object_Definition   =>
                     New_Occurrence_Of (Ptr_Typ, Loc)));
               Set_No_Initialization (Last (Decls));

               --  Allocate the object, generate:
               --    Local_Id := <Alloc_Expr>;

               Append_To (Stmts,
                 Make_Assignment_Statement (Loc,
                   Name       => New_Occurrence_Of (Local_Id, Loc),
                   Expression => Alloc_Expr));

               --  Generate:
               --    Temp_Id := Temp_Typ (Local_Id);

               Append_To (Stmts,
                 Make_Assignment_Statement (Loc,
                   Name       => New_Occurrence_Of (Temp_Id, Loc),
                   Expression =>
                     Unchecked_Convert_To (Temp_Typ,
                       New_Occurrence_Of (Local_Id, Loc))));

               --  Wrap the allocation in a block to make it conditioned by the
               --  presence of the caller's collection at run time.

               --  Generate:
               --    if BIPcollection = null then
               --       Temp_Id := <Orig_Expr>;
               --    else
               --       declare
               --          <Decls>
               --       begin
               --          <Stmts>
               --       end;
               --    end if;

               return
                 Make_If_Statement (Loc,
                   Condition       =>
                     Make_Op_Eq (Loc,
                       Left_Opnd  => New_Occurrence_Of (Fin_Coll_Id, Loc),
                       Right_Opnd => Make_Null (Loc)),

                   Then_Statements => New_List (
                     Make_Assignment_Statement (Loc,
                       Name       => New_Occurrence_Of (Temp_Id, Loc),
                       Expression => Orig_Expr)),

                   Else_Statements => New_List (
                     Make_Block_Statement (Loc,
                       Declarations               => Decls,
                       Handled_Statement_Sequence =>
                         Make_Handled_Sequence_Of_Statements (Loc,
                           Statements => Stmts))));
            end;

         --  For all other cases, generate:
         --    Temp_Id := <Alloc_Expr>;

         else
            return
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (Temp_Id, Loc),
                Expression => Alloc_Expr);
         end if;
      end Build_Heap_Or_Pool_Allocator;

      --------------------------
      -- BIP_Function_Call_Id --
      --------------------------

      function BIP_Function_Call_Id return Entity_Id is

         function Func_Call_Id (Function_Call : Node_Id) return Entity_Id;
         --  Return the id of the called function.

         function Func_Call_Id (Function_Call : Node_Id) return Entity_Id is
            Call_Node : constant Node_Id := Unqual_Conv (Function_Call);

         begin
            if Is_Entity_Name (Name (Call_Node)) then
               return Entity (Name (Call_Node));

            elsif Nkind (Name (Call_Node)) = N_Explicit_Dereference then
               return Etype (Name (Call_Node));

            else
               pragma Assert (Nkind (Name (Call_Node)) = N_Selected_Component);
               return Etype (Entity (Selector_Name (Name (Call_Node))));
            end if;
         end Func_Call_Id;

         --  Local declarations

         BIP_Func_Call : Node_Id;
         Expr_Q        : constant Node_Id := Unqual_Conv (Expr);

      --  Start of processing for BIP_Function_Call_Id

      begin
         if Is_Build_In_Place_Function_Call (Expr_Q) then
            return Func_Call_Id (Expr_Q);
         end if;

         BIP_Func_Call := Unqual_BIP_Iface_Function_Call (Expr_Q);

         if Present (BIP_Func_Call) then

            --  In the case of an explicitly dereferenced call, return the
            --  subprogram type.

            if Nkind (Name (BIP_Func_Call)) = N_Explicit_Dereference then
               return Etype (Name (BIP_Func_Call));
            else
               pragma Assert (Is_Entity_Name (Name (BIP_Func_Call)));
               return Entity (Name (BIP_Func_Call));
            end if;

         elsif Nkind (Expr_Q) = N_Reference
                 and then Is_Build_In_Place_Function_Call (Prefix (Expr_Q))
         then
            return Func_Call_Id (Prefix (Expr_Q));

         else
            return Empty;
         end if;
      end BIP_Function_Call_Id;

      -------------------------------------
      -- Count_Default_Sized_Task_Stacks --
      -------------------------------------

      procedure Count_Default_Sized_Task_Stacks
        (Typ         : Entity_Id;
         Pri_Stacks  : out Nat;
         Sec_Stacks  : out Nat)
      is
         Component : Entity_Id;

      begin
         --  To calculate the number of default-sized task stacks required for
         --  an object of Typ, a depth-first recursive traversal of the AST
         --  from the Typ entity node is undertaken. Only type nodes containing
         --  task objects are visited.

         Pri_Stacks := 0;
         Sec_Stacks := 0;

         if not Has_Task (Typ) then
            return;
         end if;

         case Ekind (Typ) is
            when E_Task_Subtype
               | E_Task_Type
            =>
               --  A task type is found marking the bottom of the descent. If
               --  the type has no representation aspect for the corresponding
               --  stack then that stack is using the default size.

               if Present (Get_Rep_Item (Typ, Name_Storage_Size)) then
                  Pri_Stacks := 0;
               else
                  Pri_Stacks := 1;
               end if;

               if Present (Get_Rep_Item (Typ, Name_Secondary_Stack_Size)) then
                  Sec_Stacks := 0;
               else
                  Sec_Stacks := 1;
               end if;

            when E_Array_Subtype
               | E_Array_Type
            =>
               --  First find the number of default stacks contained within an
               --  array component.

               Count_Default_Sized_Task_Stacks
                 (Component_Type (Typ),
                  Pri_Stacks,
                  Sec_Stacks);

               --  Then multiply the result by the size of the array

               declare
                  Quantity : constant Nat := Number_Of_Elements_In_Array (Typ);
                  --  Number_Of_Elements_In_Array is non-trival, consequently
                  --  its result is captured as an optimization.

               begin
                  Pri_Stacks := Pri_Stacks * Quantity;
                  Sec_Stacks := Sec_Stacks * Quantity;
               end;

            when E_Protected_Subtype
               | E_Protected_Type
               | E_Record_Subtype
               | E_Record_Type
            =>
               Component := First_Component (Typ);

               --  Recursively descend each component of the composite type
               --  looking for tasks.

               while Present (Component) loop
                  declare
                     P : Nat;
                     S : Nat;

                  begin
                     Count_Default_Sized_Task_Stacks (Etype (Component), P, S);
                     Pri_Stacks := Pri_Stacks + P;
                     Sec_Stacks := Sec_Stacks + S;
                  end;

                  Next_Component (Component);
               end loop;

            when E_Limited_Private_Subtype
               | E_Limited_Private_Type
               | E_Record_Subtype_With_Private
               | E_Record_Type_With_Private
            =>
               --  Switch to the full view of the private type to continue
               --  search.

               Count_Default_Sized_Task_Stacks
                 (Full_View (Typ), Pri_Stacks, Sec_Stacks);

            --  Other types should not contain tasks

            when others =>
               raise Program_Error;
         end case;
      end Count_Default_Sized_Task_Stacks;

      -------------------------------
      -- Default_Initialize_Object --
      -------------------------------

      procedure Default_Initialize_Object (After : Node_Id) is
         Init_Expr  : Node_Id;
         Init_Stmts : List_Id;

      begin
         --  Nothing to do if the object has an initialization expression or
         --  need not be initialized.

         if Has_Init_Expression (N) or else No_Initialization (N) then
            return;

         --  Default initialization is suppressed for objects that are already
         --  known to be imported (i.e. whose declaration specifies the Import
         --  aspect). Note that for objects with a pragma Import, we generate
         --  initialization here, and then remove it downstream when processing
         --  the pragma. It is also suppressed for variables for which a pragma
         --  Suppress_Initialization has been explicitly given

         elsif Is_Imported (Def_Id)
           or else Suppress_Initialization (Def_Id)
         then
            return;

         --  Nothing to do if the object being initialized is of a task type
         --  and restriction No_Tasking is in effect, because this is a direct
         --  violation of the restriction.

         elsif Is_Task_Type (Base_Typ)
           and then Restriction_Active (No_Tasking)
         then
            return;
         end if;

         --  First try a simple initialization; if it succeeds, then we just
         --  set the value as the expression of the declaration and let the
         --  code generator do the rest.

         Init_Expr := Build_Default_Simple_Initialization (N, Typ, Def_Id);

         if Present (Init_Expr) then
            Set_Expression (N, Init_Expr);
            Analyze_And_Resolve (Init_Expr, Typ);
            return;
         end if;

         --  Or else build the fully-fledged initialization if need be

         if Is_Mutably_Tagged_Type (Typ) then
            Init_Stmts :=
              Build_Default_Initialization (N, Etype (Typ), Def_Id);
         else
            Init_Stmts := Build_Default_Initialization (N, Typ, Def_Id);
         end if;

         --  Insert the whole initialization sequence into the tree. If the
         --  object has a delayed freeze, as will be the case when it has
         --  aspect specifications, the initialization sequence is part of
         --  the freeze actions.

         if Present (Init_Stmts) then
            if Has_Delayed_Freeze (Def_Id) then
               Append_Freeze_Actions (Def_Id, Init_Stmts);
            else
               Insert_Actions_After (After, Init_Stmts);
            end if;
         end if;
      end Default_Initialize_Object;

      ------------------------------
      -- Initialize_Return_Object --
      ------------------------------

      procedure Initialize_Return_Object
        (Tag_Assign : Node_Id;
         Adj_Call   : Node_Id;
         Expr       : Node_Id;
         Init_Stmt  : Node_Id;
         After      : Node_Id)
      is
      begin
         if Present (Tag_Assign) then
            Insert_Action_After (After, Tag_Assign);
         end if;

         if Present (Adj_Call) then
            Insert_Action_After (After, Adj_Call);
         end if;

         if No (Expr) then
            Default_Initialize_Object (After);

         elsif Is_Delayed_Aggregate (Expr)
           and then not No_Initialization (N)
         then
            Convert_Aggr_In_Object_Decl (N);

         elsif Present (Init_Stmt) then
            Insert_Action_After (After, Init_Stmt);
            Set_Expression (N, Empty);
         end if;
      end Initialize_Return_Object;

      --------------------------------
      -- Is_Renamable_Function_Call --
      --------------------------------

      function Is_Renamable_Function_Call (Expr : Node_Id) return Boolean is
      begin
         return not Is_Library_Level_Entity (Def_Id)
           and then Is_Captured_Function_Call (Expr)
           and then (not Special_Ret_Obj
                      or else
                        (Is_Related_To_Func_Return (Entity (Prefix (Expr)))
                          and then Needs_Secondary_Stack (Etype (Expr)) =
                                   Needs_Secondary_Stack (Etype (Func_Id))));
      end Is_Renamable_Function_Call;

      -------------------------------
      -- Make_Allocator_For_Return --
      -------------------------------

      function Make_Allocator_For_Return (Expr : Node_Id) return Node_Id is
         Alloc      : Node_Id;
         Alloc_Expr : Entity_Id;
         Alloc_Typ  : Entity_Id;

      begin
         --  If the return object's declaration does not include an expression,
         --  then we use its subtype for the allocation. Likewise in the case
         --  of a degenerate expression like a raise expression.

         if No (Expr)
           or else Nkind (Original_Node (Expr)) = N_Raise_Expression
         then
            Alloc_Typ := Typ;

         --  If the return object's declaration includes an expression, then
         --  there are two cases: either the nominal subtype of the object is
         --  definite and we can use it for the allocation directly, or it is
         --  not and Analyze_Object_Declaration should have built an actual
         --  subtype from the expression.

         --  However, there are exceptions in the latter case for interfaces
         --  (see Analyze_Object_Declaration), as well as class-wide types and
         --  types with unknown discriminants if they have no underlying record
         --  view or are inherently limited (see Expand_Subtype_From_Expr), so
         --  we must cope with them.

         elsif Is_Interface (Typ) then
            pragma Assert (Is_Class_Wide_Type (Typ));

            --  For interfaces, we use the type of the expression, except if
            --  we need to put back a conversion that we have removed earlier
            --  in the processing.

            if Is_Class_Wide_Type (Etype (Expr)) then
               Alloc_Typ := Typ;
            else
               Alloc_Typ := Etype (Expr);
            end if;

         elsif Is_Class_Wide_Type (Typ) then

            --  For class-wide types, we have to make sure that we use the
            --  dynamic type of the expression for the allocation, either by
            --  means of its (static) subtype or through the actual subtype.

            if Has_Tag_Of_Type (Expr) then
               Alloc_Typ := Etype (Expr);

            else pragma Assert (Ekind (Typ) = E_Class_Wide_Subtype
              and then Present (Equivalent_Type (Typ)));

               Alloc_Typ := Typ;
            end if;

         else pragma Assert (Is_Definite_Subtype (Typ)
           or else (Has_Unknown_Discriminants (Typ)
                     and then (No (Underlying_Record_View (Typ))
                                or else Is_Inherently_Limited_Type (Typ))));

            Alloc_Typ := Typ;
         end if;

         --  If the return object's declaration includes an expression and the
         --  declaration isn't marked as No_Initialization, then we generate an
         --  allocator with a qualified expression. Although this is necessary
         --  only in the case where the result type is an interface (or class-
         --  wide interface), we do it in all cases for the sake of consistency
         --  instead of subsequently generating a separate assignment.

         if Present (Expr)
           and then not Is_Delayed_Aggregate (Expr)
           and then not No_Initialization (N)
         then
            --  Ada 2005 (AI95-344): If the result type is class-wide, insert
            --  a check that the level of the return expression's underlying
            --  type is not deeper than the level of the master enclosing the
            --  function.

            --  AI12-043: The check is made immediately after the return object
            --  is created.

            if Is_Class_Wide_Type (Etype (Func_Id)) then
               Apply_CW_Accessibility_Check (Expr, Func_Id);
            end if;

            if Has_Anonymous_Access_Discriminant (Etype (Expr)) then
               --  Check that access discrims do not designate entities
               --  that the function result could outlive.
               Apply_Access_Discrims_Accessibility_Check (Expr, Func_Id);
            end if;

            Alloc_Expr := New_Copy_Tree (Expr);

            if Etype (Alloc_Expr) /= Alloc_Typ then
               Alloc_Expr := Convert_To (Alloc_Typ, Alloc_Expr);
            end if;

            Alloc :=
              Make_Allocator (Loc,
                Expression =>
                  Make_Qualified_Expression (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (Alloc_Typ, Loc),
                    Expression   => Alloc_Expr));

         else
            Alloc :=
              Make_Allocator (Loc,
                Expression => New_Occurrence_Of (Alloc_Typ, Loc));

            --  If the return object requires default initialization, then it
            --  will happen later following the elaboration of the renaming.
            --  If we don't turn it off here, then the object will be default
            --  initialized twice.

            Set_No_Initialization (Alloc);
         end if;

         --  Set the flag indicating that the allocator is made for a special
         --  return object. This is used to bypass various legality checks as
         --  well as to make sure that the result is not adjusted twice.

         Set_For_Special_Return_Object (Alloc);

         return Alloc;
      end Make_Allocator_For_Return;

      ----------------------
      -- OK_To_Rename_Ref --
      ----------------------

      function OK_To_Rename_Ref (N : Node_Id) return Boolean is
      begin
         return Is_Entity_Name (N)
           and then Ekind (Entity (N)) = E_Variable
           and then OK_To_Rename (Entity (N));
      end OK_To_Rename_Ref;

      --  Local variables

      Adj_Call   : Node_Id := Empty;
      Expr_Q     : Node_Id := Empty;
      Tag_Assign : Node_Id := Empty;

      Init_After : Node_Id := N;
      --  Node after which the initialization actions are to be inserted. This
      --  is normally N, except for the case of a shared passive variable, in
      --  which case the init proc call must be inserted only after the bodies
      --  of the shared variable procedures have been seen.

      Has_BIP_Init_Expr : Boolean := False;
      --  Whether the object is initialized with a BIP function call

      Rewrite_As_Renaming : Boolean := False;
      --  Whether to turn the declaration into a renaming at the end

   --  Start of processing for Expand_N_Object_Declaration

   begin
      --  Don't do anything for deferred constants. All proper actions will be
      --  expanded during the full declaration.

      if No (Expr)
        and then Constant_Present (N)
        and then (not Needs_Construction (Typ)
                   or else not Has_Parameterless_Constructor (Typ))
      then
         return;
      end if;

      --  The type of the object cannot be abstract. This is diagnosed at the
      --  point the object is frozen, which happens after the declaration is
      --  fully expanded, so simply return now.

      if Is_Abstract_Type (Typ) then
         return;
      end if;

      --  No action needed for the internal imported dummy object added by
      --  Make_DT to compute the offset of the components that reference
      --  secondary dispatch tables; required to avoid never-ending loop
      --  processing this internal object declaration.

      if Tagged_Type_Expansion
        and then Is_Internal (Def_Id)
        and then Is_Imported (Def_Id)
        and then Related_Type (Def_Id) = Implementation_Base_Type (Typ)
      then
         return;
      end if;

      --  Expand objects to use constructors if needed

      if Comes_From_Source (N)
        and then Needs_Construction (Typ)

      --  Don't expand copy constructor for objects initialized with aggregates

        and then (if Present (Expr)
                   then Nkind (Expr) not in N_Aggregate
                                          | N_Delta_Aggregate
                                          | N_Extension_Aggregate)

      --  Don't expand copy constructor if a constructor was explicitly called

        and then (if Present (Expr)
                   then (Nkind (Original_Node (Expr)) /= N_Attribute_Reference
                          or else Attribute_Name (Original_Node (Expr))
                                    /= Name_Make))
      then
         if No (Expr) then
            Expr :=
              Make_Attribute_Reference
                (Loc,
                 Attribute_Name => Name_Make,
                 Prefix         => New_Occurrence_Of (Typ, Loc));
         else
            Expr :=
              Make_Attribute_Reference
                (Loc,
                 Attribute_Name => Name_Make,
                 Prefix         => New_Occurrence_Of (Typ, Loc),
                 Expressions    => New_List (Expr));
         end if;
         Set_Expression (N, Expr);
         Analyze_And_Resolve (Expr);
      end if;

      --  Make shared memory routines for shared passive variable

      if Is_Shared_Passive (Def_Id) then
         Init_After := Make_Shared_Var_Procs (N);
      end if;

      --  Determine whether the object is initialized with a BIP function call

      if Present (Expr) then
         Expr_Q := Unqualify (Expr);

         Has_BIP_Init_Expr :=
           Is_Build_In_Place_Function_Call (Expr_Q)
             or else Present (Unqual_BIP_Iface_Function_Call (Expr_Q))
             or else (Nkind (Expr_Q) = N_Reference
                        and then
                      Is_Build_In_Place_Function_Call (Prefix (Expr_Q)));
      end if;

      --  If tasks are being declared, make sure we have an activation chain
      --  defined for the tasks (has no effect if we already have one), and
      --  also that a Master variable is established (and that the appropriate
      --  enclosing construct is established as a task master). And also deal
      --  with objects initialized with a call to a BIP function that has task
      --  formal parameters.

      if Has_Task (Typ)
        or else Might_Have_Tasks (Typ)
        or else (Has_BIP_Init_Expr
                   and then Needs_BIP_Task_Actuals (BIP_Function_Call_Id))
      then
         Build_Activation_Chain_Entity (N);

         if Has_Task (Typ) or else Has_BIP_Init_Expr then
            Build_Master_Entity (Def_Id);
         end if;
      end if;

      --  If No_Implicit_Heap_Allocations or No_Implicit_Task_Allocations
      --  restrictions are active then default-sized secondary stacks are
      --  generated by the binder and allocated by SS_Init. To provide the
      --  binder the number of stacks to generate, the number of default-sized
      --  stacks required for task objects contained within the object
      --  declaration N is calculated here as it is at this point where
      --  unconstrained types become constrained. The result is stored in the
      --  enclosing unit's Unit_Record.

      --  Note if N is an array object declaration that has an initialization
      --  expression, a second object declaration for the initialization
      --  expression is created by the compiler. To prevent double counting
      --  of the stacks in this scenario, the stacks of the first array are
      --  not counted.

      if Might_Have_Tasks (Typ)
        and then not Restriction_Active (No_Secondary_Stack)
        and then (Restriction_Active (No_Implicit_Heap_Allocations)
          or else Restriction_Active (No_Implicit_Task_Allocations))
        and then not (Is_Array_Type (Typ) and then Has_Init_Expression (N))
      then
         declare
            PS_Count, SS_Count : Nat;
         begin
            Count_Default_Sized_Task_Stacks (Typ, PS_Count, SS_Count);
            Increment_Primary_Stack_Count (PS_Count);
            Increment_Sec_Stack_Count (SS_Count);
         end;
      end if;

      --  Default initialization required, and no expression present

      if No (Expr) then
         --  If we have a type with a variant part, the initialization proc
         --  will contain implicit tests of the discriminant values, which
         --  counts as a violation of the restriction No_Implicit_Conditionals.

         if Has_Variant_Part (Typ) then
            declare
               Msg : Boolean;

            begin
               Check_Restriction (Msg, No_Implicit_Conditionals, Obj_Def);

               if Msg then
                  Error_Msg_N
                    ("\initialization of variant record tests discriminants",
                     Obj_Def);
                  return;
               end if;
            end;
         end if;

         --  For the default initialization case, if we have a private type
         --  with invariants, and invariant checks are enabled, then insert an
         --  invariant check after the object declaration. Note that it is OK
         --  to clobber the object with an invalid value since if the exception
         --  is raised, then the object will go out of scope. In the case where
         --  an array object is initialized with an aggregate, the expression
         --  is removed. Check flag Has_Init_Expression to avoid generating a
         --  junk invariant check and flag No_Initialization to avoid checking
         --  an uninitialized object such as a compiler temporary used for an
         --  aggregate.

         if Has_Invariants (Base_Typ)
           and then Present (Invariant_Procedure (Base_Typ))
           and then not Has_Init_Expression (N)
           and then not No_Initialization (N)
         then
            --  If entity has an address clause or aspect, make invariant
            --  call into a freeze action for the explicit freeze node for
            --  object. Otherwise insert invariant check after declaration.

            if Present (Following_Address_Clause (N))
              or else Has_Aspect (Def_Id, Aspect_Address)
            then
               Ensure_Freeze_Node (Def_Id);

               if not Partial_View_Has_Unknown_Discr (Typ) then
                  Append_Freeze_Action (Def_Id,
                    Make_Invariant_Call (New_Occurrence_Of (Def_Id, Loc)));
               end if;

            elsif not Partial_View_Has_Unknown_Discr (Typ) then
               Insert_After (N,
                 Make_Invariant_Call (New_Occurrence_Of (Def_Id, Loc)));
            end if;
         end if;

         --  For a special return object, the initialization must wait until
         --  after the object is turned into an allocator.

         if not Special_Ret_Obj then
            Default_Initialize_Object (Init_After);

            --  Check whether the object has been initialized above

            if Present (Expression (N)) then
               if Is_Access_Type (Typ) then
                  if Known_Non_Null (Expression (N)) then
                     Set_Is_Known_Non_Null (Def_Id);
                  elsif Known_Null (Expression (N)) then
                     Set_Is_Known_Null (Def_Id);
                  end if;
               end if;

               if Is_Delayed_Aggregate (Expression (N)) then
                  Convert_Aggr_In_Object_Decl (N);
               end if;
            end if;
         end if;

         --  Generate attribute for Persistent_BSS if needed

         if Persistent_BSS_Mode
           and then Comes_From_Source (N)
           and then Is_Potentially_Persistent_Type (Typ)
           and then not Has_Init_Expression (N)
           and then Is_Library_Level_Entity (Def_Id)
         then
            declare
               Prag : constant Node_Id :=
                 Make_Linker_Section_Pragma (Def_Id, Loc, ".persistent.bss");
            begin
               Insert_After (N, Prag);
               Analyze (Prag);
            end;
         end if;

      --  Explicit initialization present

      else
         --  When we have the appropriate kind of aggregate in the expression
         --  (this has been determined during analysis of the aggregate by
         --  setting the Expansion_Delayed flag), let's perform in place
         --  assignment and thus avoid creating a temporary.

         if Is_Delayed_Aggregate (Expr_Q) then

            --  For a special return object, the transformation must wait until
            --  after the object is turned into an allocator.

            if not Special_Ret_Obj then
               Convert_Aggr_In_Object_Decl (N);
            end if;

         --  If the initialization expression is a conditional expression whose
         --  expansion has been delayed, assign it explicitly to the object but
         --  only after analyzing it again and expanding it.

         elsif Is_Delayed_Conditional_Expression (Expr_Q) then
            --  For a special return object, the transformation must wait until
            --  after the object is turned into an allocator, and will be done
            --  during the expansion of the allocator.

            if not Special_Ret_Obj then
               declare
                  Rhs    : constant Node_Id := Relocate_Node (Expr);
                  Assign : constant Node_Id :=
                    Make_Assignment_Statement (Loc,
                      Name       => New_Occurrence_Of (Def_Id, Loc),
                      Expression => Rhs);

               begin
                  Set_Assignment_OK (Name (Assign));
                  Unanalyze_Delayed_Conditional_Expression (Rhs);
                  Set_No_Finalize_Actions (Assign);
                  Insert_Action_After (Init_After, Assign);

                  --  Save the assignment statement when declaring a controlled
                  --  object. This reference is used later by the finalization
                  --  machinery to mark the object as successfully initialized

                  if Needs_Finalization (Typ) then
                     Set_Last_Aggregate_Assignment (Def_Id, Assign);
                  end if;

                  Set_Expression (N, Empty);
                  Set_No_Initialization (N);
               end;
            end if;

         --  Ada 2005 (AI-318-02): If the initialization expression is a call
         --  to a build-in-place function, then access to the declared object
         --  must be passed to the function.

         elsif Is_Build_In_Place_Function_Call (Expr_Q) then
            Make_Build_In_Place_Call_In_Object_Declaration (N, Expr_Q);

            --  The previous call expands the expression initializing the
            --  built-in-place object into further code that will be analyzed
            --  later. No further expansion needed here.

            return;

         --  This is the same as the previous 'elsif', except that the call has
         --  been transformed by other expansion activities into something like
         --  F(...)'Reference.

         elsif Nkind (Expr_Q) = N_Reference
           and then Is_Build_In_Place_Function_Call (Prefix (Expr_Q))
           and then not Is_Expanded_Build_In_Place_Call
                          (Unqual_Conv (Prefix (Expr_Q)))
         then
            Make_Build_In_Place_Call_In_Anonymous_Context (Prefix (Expr_Q));

            --  The previous call expands the expression initializing the
            --  built-in-place object into further code that will be analyzed
            --  later. No further expansion needed here.

            return;

         --  Ada 2005 (AI-318-02): Specialization of the previous case for
         --  expressions containing a build-in-place function call whose
         --  returned object covers interface types, and Expr_Q has calls to
         --  Ada.Tags.Displace to displace the pointer to the returned build-
         --  in-place object to reference the secondary dispatch table of a
         --  covered interface type.

         elsif Present (Unqual_BIP_Iface_Function_Call (Expr_Q)) then
            Make_Build_In_Place_Iface_Call_In_Object_Declaration (N, Expr_Q);

            --  The previous call expands the expression initializing the
            --  built-in-place object into further code that will be analyzed
            --  later. No further expansion needed here.

            return;

         --  Ada 2005 (AI-251): Rewrite the expression that initializes a
         --  class-wide interface object to ensure that we copy the full
         --  object, unless we are targetting a VM where interfaces are handled
         --  by VM itself. Note that if the root type of Typ is an ancestor of
         --  Expr's type, both types share the same dispatch table and there is
         --  no need to displace the pointer.

         elsif Is_Interface (Typ)

           --  Avoid never-ending recursion because if Equivalent_Type is set
           --  then we've done it already and must not do it again.

           and then not
             (Nkind (Obj_Def) = N_Identifier
               and then Present (Equivalent_Type (Entity (Obj_Def))))
         then
            pragma Assert (Is_Class_Wide_Type (Typ));

            --  If the original node of the expression was a conversion
            --  to this specific class-wide interface type then restore
            --  the original node because we must copy the object before
            --  displacing the pointer to reference the secondary tag
            --  component. This code must be kept synchronized with the
            --  expansion done by routine Expand_Interface_Conversion

            if not Comes_From_Source (Expr)
              and then Nkind (Expr) = N_Explicit_Dereference
              and then Nkind (Original_Node (Expr)) = N_Type_Conversion
              and then Etype (Original_Node (Expr)) = Typ
            then
               Rewrite (Expr, Original_Node (Expression (N)));
            end if;

            --  Avoid expansion of redundant interface conversion

            if Nkind (Expr) = N_Type_Conversion
              and then Etype (Expr) = Typ
            then
               Expr_Q := Expression (Expr);
            else
               Expr_Q := Expr;
            end if;

            --  We may use a renaming if the initialization expression is a
            --  captured function call that meets a few conditions.

            Rewrite_As_Renaming := Is_Renamable_Function_Call (Expr_Q);

            --  If the object is a special return object, then bypass special
            --  treatment of class-wide interface initialization below. In this
            --  case, the expansion of the return object will take care of this
            --  initialization via the expansion of the allocator.

            if Special_Ret_Obj and then not Rewrite_As_Renaming then

               --  If the type needs finalization and is not inherently
               --  limited, then the target is adjusted after the copy
               --  and attached to the finalization list.

               if Needs_Finalization (Typ)
                 and then not Is_Inherently_Limited_Type (Typ)
               then
                  Adj_Call :=
                    Make_Adjust_Call (
                      Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
                      Typ     => Base_Typ);
               end if;

            --  Renaming an expression of the object's type is immediate

            elsif Rewrite_As_Renaming
              and then Base_Type (Etype (Expr_Q)) = Base_Type (Typ)
            then
               null;

            elsif Tagged_Type_Expansion then
               declare
                  Iface : constant Entity_Id := Root_Type (Typ);

                  Expr_Typ     : Entity_Id;
                  New_Expr     : Node_Id;
                  Obj_Id       : Entity_Id;
                  Ptr_Obj_Decl : Node_Id;
                  Ptr_Obj_Id   : Entity_Id;
                  Tag_Comp     : Node_Id;

               begin
                  Expr_Typ := Base_Type (Etype (Expr_Q));
                  if Is_Class_Wide_Type (Expr_Typ) then
                     Expr_Typ := Root_Type (Expr_Typ);
                  end if;

                  --  Rename limited objects since they cannot be copied

                  if Is_Limited_Record (Expr_Typ) then
                     Rewrite_As_Renaming := True;
                  end if;

                  Obj_Id := Make_Temporary (Loc, 'D', Expr_Q);

                  --  Replace
                  --     IW : I'Class := Expr;
                  --  by
                  --     Dnn : Tag renames Tag_Ptr!(Expr'Address).all;
                  --     type Ityp is not null access I'Class;
                  --     Rnn : constant Ityp :=
                  --             Ityp!(Displace (Dnn'Address, I'Tag));
                  --     IW : I'Class renames Rnn.all;

                  if Rewrite_As_Renaming then
                     New_Expr :=
                       Make_Explicit_Dereference (Loc,
                         Unchecked_Convert_To (RTE (RE_Tag_Ptr),
                           Make_Attribute_Reference (Loc,
                             Prefix => Relocate_Node (Expr_Q),
                             Attribute_Name => Name_Address)));

                     --  Suppress junk access checks on RE_Tag_Ptr

                     Insert_Action (N,
                       Make_Object_Renaming_Declaration (Loc,
                         Defining_Identifier => Obj_Id,
                         Subtype_Mark        =>
                           New_Occurrence_Of (RTE (RE_Tag), Loc),
                         Name                => New_Expr),
                       Suppress => Access_Check);

                     --  Dynamically reference the tag associated with the
                     --  interface.

                     Tag_Comp :=
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
                         Parameter_Associations => New_List (
                           Make_Attribute_Reference (Loc,
                             Prefix => New_Occurrence_Of (Obj_Id, Loc),
                             Attribute_Name => Name_Address),
                           New_Occurrence_Of
                             (Node (First_Elmt (Access_Disp_Table (Iface))),
                              Loc)));

                  --  Replace
                  --     IW : I'Class := Expr;
                  --  by
                  --     Dnn : Typ := Expr;
                  --     type Ityp is not null access I'Class;
                  --     Rnn : constant Ityp := Ityp (Dnn.I_Tag'Address);
                  --     IW  : I'Class renames Rnn.all;

                  elsif Has_Tag_Of_Type (Expr_Q)
                    and then Interface_Present_In_Ancestor (Expr_Typ, Typ)
                    and then (Expr_Typ = Etype (Expr_Typ)
                               or else not
                                 Is_Variable_Size_Record (Etype (Expr_Typ)))
                  then
                     Insert_Action (N,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Obj_Id,
                         Object_Definition   =>
                           New_Occurrence_Of (Expr_Typ, Loc),
                         Expression          => Relocate_Node (Expr_Q)));

                     --  Statically reference the tag associated with the
                     --  interface

                     Tag_Comp :=
                       Make_Selected_Component (Loc,
                         Prefix        => New_Occurrence_Of (Obj_Id, Loc),
                         Selector_Name =>
                           New_Occurrence_Of
                             (Find_Interface_Tag (Expr_Typ, Iface), Loc));

                  --  Replace
                  --     IW : I'Class := Expr;
                  --  by
                  --     type Equiv_Record is record ... end record;
                  --     implicit subtype CW is <Class_Wide_Subtype>;
                  --     Dnn : CW := CW!(Expr);
                  --     type Ityp is not null access I'Class;
                  --     Rnn : constant Ityp :=
                  --             Ityp!(Displace (Dnn'Address, I'Tag));
                  --     IW : I'Class renames Rnn.all;

                  else
                     --  Generate the equivalent record type and update the
                     --  subtype indication to reference it.

                     Expand_Subtype_From_Expr
                       (N             => N,
                        Unc_Type      => Typ,
                        Subtype_Indic => Obj_Def,
                        Exp           => Expr_Q);

                     --  For interface types we use 'Address which displaces
                     --  the pointer to the base of the object (if required).

                     if Is_Interface (Etype (Expr_Q)) then
                        New_Expr :=
                          Unchecked_Convert_To (Etype (Obj_Def),
                            Make_Explicit_Dereference (Loc,
                              Unchecked_Convert_To (RTE (RE_Tag_Ptr),
                                Make_Attribute_Reference (Loc,
                                  Prefix => Relocate_Node (Expr_Q),
                                  Attribute_Name => Name_Address))));

                     --  For other types, no displacement is needed

                     else
                        New_Expr := Relocate_Node (Expr_Q);
                     end if;

                     --  Suppress junk access checks on RE_Tag_Ptr

                     Insert_Action (N,
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => Obj_Id,
                         Object_Definition   =>
                           New_Occurrence_Of (Etype (Obj_Def), Loc),
                         Expression          => New_Expr),
                       Suppress => Access_Check);

                     --  Dynamically reference the tag associated with the
                     --  interface.

                     Tag_Comp :=
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
                         Parameter_Associations => New_List (
                           Make_Attribute_Reference (Loc,
                             Prefix => New_Occurrence_Of (Obj_Id, Loc),
                             Attribute_Name => Name_Address),
                           New_Occurrence_Of
                             (Node (First_Elmt (Access_Disp_Table (Iface))),
                              Loc)));
                  end if;

                  --  As explained in Exp_Disp, we use Convert_Tag_To_Interface
                  --  to do the final conversion, but we insert an intermediate
                  --  temporary before the dereference so that we can process
                  --  the expansion as part of the analysis of the declaration
                  --  of this temporary, and then rewrite manually the original
                  --  object as the simple renaming of this dereference.

                  Tag_Comp := Convert_Tag_To_Interface (Typ, Tag_Comp);
                  pragma Assert (Nkind (Tag_Comp) = N_Explicit_Dereference
                    and then
                      Nkind (Prefix (Tag_Comp)) = N_Unchecked_Type_Conversion);

                  Ptr_Obj_Id := Make_Temporary (Loc, 'R');

                  Ptr_Obj_Decl :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Ptr_Obj_Id,
                      Constant_Present    => True,
                      Object_Definition   =>
                        New_Occurrence_Of
                          (Entity (Subtype_Mark (Prefix (Tag_Comp))), Loc),
                      Expression => Prefix (Tag_Comp));

                  Insert_Action (N, Ptr_Obj_Decl, Suppress => All_Checks);

                  Set_Prefix (Tag_Comp, New_Occurrence_Of (Ptr_Obj_Id, Loc));
                  Expr_Q := Tag_Comp;
                  Set_Etype (Expr_Q, Typ);
                  Set_Parent (Expr_Q, N);

                  Rewrite_As_Renaming := True;
               end;

            else
               return;
            end if;

         --  Common case of explicit object initialization

         else
            --  Small optimization: if the expression is a function call and
            --  the object is stand-alone, not declared at library level and of
            --  a class-wide type, then we capture the result of the call into
            --  a temporary, with the benefit that, if the result's type does
            --  not need finalization, nothing will be finalized and, if it
            --  does, the temporary only will be finalized by means of a direct
            --  call to the Finalize primitive if the result's type is not a
            --  class-wide type; whereas, in both cases, the stand-alone object
            --  itself would be finalized by means of a dispatching call to the
            --  Deep_Finalize routine.

            if Nkind (Expr_Q) = N_Function_Call
              and then not Special_Ret_Obj
              and then not Is_Library_Level_Entity (Def_Id)
              and then Is_Class_Wide_Type (Typ)
            then
               Remove_Side_Effects (Expr_Q);
            end if;

            --  In most cases, we must check that the initial value meets any
            --  constraint imposed by the declared type. However, there is one
            --  very important exception to this rule. If the entity has an
            --  unconstrained nominal subtype, then it acquired its constraints
            --  from the expression in the first place, and not only does this
            --  mean that the constraint check is not needed, but an attempt to
            --  perform the constraint check can cause order of elaboration
            --  problems.

            if not Is_Constr_Subt_For_U_Nominal (Typ) then

               --  If this is an allocator for an aggregate that has been
               --  allocated in place, delay checks until assignments are
               --  made, because the discriminants are not initialized.

               if Nkind (Expr) = N_Allocator
                 and then No_Initialization (Expr)
               then
                  null;

               --  Otherwise apply a constraint check now if no prev error

               elsif Nkind (Expr) /= N_Error then
                  Apply_Constraint_Check (Expr, Typ);

                  --  Deal with possible range check

                  if Do_Range_Check (Expr) then

                     --  If assignment checks are suppressed, turn off flag

                     if Suppress_Assignment_Checks (N) then
                        Set_Do_Range_Check (Expr, False);

                     --  Otherwise generate the range check

                     else
                        Generate_Range_Check
                          (Expr, Typ, CE_Range_Check_Failed);
                     end if;
                  end if;
               end if;
            end if;

            --  For tagged types, when an init value is given, the tag has to
            --  be re-initialized separately in order to avoid the propagation
            --  of a wrong tag coming from a view conversion unless the type
            --  is class wide (in this case the tag comes from the init value).
            --  Suppress the tag assignment when not Tagged_Type_Expansion
            --  because tags are represented implicitly in objects. Ditto for
            --  types that are CPP_CLASS, and for initializations that are
            --  aggregates, because they have to have the right tag.

            --  The re-assignment of the tag has to be done even if the object
            --  is a constant. The assignment must be analyzed after the
            --  declaration. If an address clause follows, this is handled as
            --  part of the freeze actions for the object, otherwise insert
            --  tag assignment here.

            Tag_Assign := Make_Tag_Assignment (N);

            if Present (Tag_Assign) then
               if Present (Following_Address_Clause (N))
                 or else Has_Aspect (Def_Id, Aspect_Address)
               then
                  Ensure_Freeze_Node (Def_Id);
               elsif not Special_Ret_Obj then
                  Insert_Action_After (Init_After, Tag_Assign);
               end if;

            --  Handle C++ constructor calls. Note that we do not check that
            --  Typ is a tagged type since the equivalent Ada type of a C++
            --  class that has no virtual methods is an untagged limited
            --  record type.

            elsif Is_CPP_Constructor_Call (Expr) then
               declare
                  Id_Ref : constant Node_Id := New_Occurrence_Of (Def_Id, Loc);
                  Marker : constant Node_Id := Next (N);

               begin
                  --  The call to the initialization procedure does NOT freeze
                  --  the object being initialized.

                  Set_Must_Not_Freeze (Id_Ref);
                  Set_Assignment_OK (Id_Ref);

                  Insert_Actions_After (Init_After,
                    Build_Initialization_Call (N, Id_Ref, Typ,
                      Constructor_Ref => Expr));

                  --  We remove here the original call to the constructor
                  --  to avoid its management in the backend

                  Set_Expression (N, Empty);

                  --  Place the call to the constructor into a compound
                  --  statement attached to the object through attribute
                  --  Initialization_Statements; the compound statement will
                  --  be moved to the freezing actions of the object if the
                  --  object has an address clause (see Analyze_Attribute_
                  --  Definition_Clause, Attribute_Address).

                  if Needs_Initialization_Statements (N)
                    and then not (Scope_Is_Transient
                                    and then N = Node_To_Be_Wrapped)
                  then
                     Set_No_Initialization (N);
                     Move_To_Initialization_Statements (N, Marker);
                  end if;

                  return;
               end;

            --  Handle initialization of limited tagged types

            elsif Is_Tagged_Type (Typ)
              and then Is_Class_Wide_Type (Typ)
              and then Is_Limited_Record (Typ)
              and then not Is_Limited_Interface (Typ)
            then
               --  Given that the type is limited we cannot perform a copy. If
               --  Expr_Q is the reference to a variable we mark the variable
               --  as OK_To_Rename to expand this declaration into a renaming
               --  declaration (see below).

               if Is_Entity_Name (Expr_Q) then
                  Set_OK_To_Rename (Entity (Expr_Q));

               --  If we cannot convert the expression into a renaming we must
               --  consider it an internal error because the backend does not
               --  have support to handle it. But avoid crashing on a raise
               --  expression or conditional expression.

               elsif Nkind (Original_Node (Expr_Q)) not in
                 N_Raise_Expression | N_If_Expression | N_Case_Expression
               then
                  raise Program_Error;
               end if;

            --  For discrete types, set the Is_Known_Valid flag if the
            --  initializing value is known to be valid. Only do this for
            --  source assignments, since otherwise we can end up turning
            --  on the known valid flag prematurely from inserted code.

            elsif Comes_From_Source (N)
              and then Is_Discrete_Type (Typ)
              and then Expr_Known_Valid (Expr)
              and then Safe_To_Capture_Value (N, Def_Id)
            then
               Set_Is_Known_Valid (Def_Id);

            --  For access types, set the Is_Known_Non_Null flag if the
            --  initializing value is known to be non-null. We can also
            --  set Can_Never_Be_Null if this is a constant.

            elsif Is_Access_Type (Typ) and then Known_Non_Null (Expr) then
               Set_Is_Known_Non_Null (Def_Id, True);

               if Constant_Present (N) then
                  Set_Can_Never_Be_Null (Def_Id);
               end if;
            end if;

            --  If validity checking on copies, validate initial expression.
            --  But skip this if declaration is for a generic type, since it
            --  makes no sense to validate generic types. Not clear if this
            --  can happen for legal programs, but it definitely can arise
            --  from previous instantiation errors.

            if Validity_Checks_On
              and then Comes_From_Source (N)
              and then Validity_Check_Copies
              and then not Is_Generic_Type (Typ)
            then
               Ensure_Valid (Expr);

               if Safe_To_Capture_Value (N, Def_Id) then
                  Set_Is_Known_Valid (Def_Id);
               end if;
            end if;

            --  Now determine whether we will use a renaming

            Rewrite_As_Renaming :=

              --  The declaration cannot be rewritten if it has got constraints

              Is_Entity_Name (Original_Node (Obj_Def))

                --  If we have "X : S := ...;", and S is a constrained array
                --  subtype, then we cannot rename, because renamings ignore
                --  the constraints of S, so that would change the semantics
                --  (sliding would not occur on the initial value). This is
                --  only a problem for source objects though, the others have
                --  the correct bounds.

                and then not (Comes_From_Source (Obj_Def)
                               and then Is_Array_Type (Typ)
                               and then Is_Constrained (Typ))

                --  Moreover, if we have "X : aliased S := "...;" and S is an
                --  unconstrained array type, then we can rename only if the
                --  initialization expression has an unconstrained subtype too,
                --  because the bounds must be present within X.

                and then not (Is_Constr_Array_Subt_With_Bounds (Typ)
                               and then Is_Constrained (Etype (Expr_Q)))

                --  We may use a renaming if the initialization expression is a
                --  captured function call that meets a few conditions.

                and then
                  (Is_Renamable_Function_Call (Expr_Q)

                    --  Or else if it is a variable with OK_To_Rename set

                    or else (OK_To_Rename_Ref (Expr_Q)
                              and then not Special_Ret_Obj)

                    --  Or else if it is a slice of such a variable

                    or else (Nkind (Expr_Q) = N_Slice
                              and then OK_To_Rename_Ref (Prefix (Expr_Q))
                              and then not Special_Ret_Obj));

            --  If the type needs finalization and is not inherently limited,
            --  then the target is adjusted after the copy and attached to the
            --  finalization list. However, no adjustment is needed in the case
            --  where the object has been initialized by a call to a function
            --  returning on the primary stack (see Expand_Ctrl_Function_Call)
            --  since no copy occurred, given that the type is by-reference.
            --  Likewise if it is initialized by a 2-pass aggregate, since the
            --  actual initialization will only occur during the second pass.
            --  Similarly, no adjustment is needed if we are going to rewrite
            --  the object declaration into a renaming declaration.

            if Needs_Finalization (Typ)
              and then not Is_Inherently_Limited_Type (Typ)
              and then Nkind (Expr_Q) /= N_Function_Call
              and then not Is_Two_Pass_Aggregate (Expr_Q)
              and then not Rewrite_As_Renaming
            then
               Adj_Call :=
                 Make_Adjust_Call (
                   Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
                   Typ     => Base_Typ);

               if Present (Adj_Call) and then not Special_Ret_Obj then
                  Insert_Action_After (Init_After, Adj_Call);
               end if;
            end if;
         end if;

         --  Cases where the back end cannot handle the initialization
         --  directly. In such cases, we expand an assignment that will
         --  be appropriately handled by Expand_N_Assignment_Statement.

         --  The exclusion of the unconstrained case is wrong, but for now it
         --  is too much trouble ???

         if (Is_Possibly_Unaligned_Slice (Expr)
              or else (Is_Possibly_Unaligned_Object (Expr)
                        and then not Represented_As_Scalar (Etype (Expr))))
           and then not (Is_Array_Type (Etype (Expr))
                          and then not Is_Constrained (Etype (Expr)))
         then
            declare
               Stat : constant Node_Id :=
                       Make_Assignment_Statement (Loc,
                         Name       => New_Occurrence_Of (Def_Id, Loc),
                         Expression => Relocate_Node (Expr));
            begin
               Set_Assignment_OK (Name (Stat));
               Set_No_Ctrl_Actions (Stat);
               Insert_Action_After (Init_After, Stat);
               Set_Expression (N, Empty);
               Set_No_Initialization (N);
            end;
         end if;
      end if;

      if Nkind (Obj_Def) = N_Access_Definition
        and then not Is_Local_Anonymous_Access (Typ)
      then
         --  An Ada 2012 stand-alone object of an anonymous access type

         declare
            Level : constant Entity_Id :=
                      Make_Defining_Identifier (Loc,
                        Chars =>
                          New_External_Name (Chars (Def_Id), Suffix => "L"));

            Level_Decl : Node_Id;
            Level_Expr : Node_Id;

         begin
            Mutate_Ekind (Level, Ekind (Def_Id));
            Set_Etype (Level, Standard_Natural);
            Set_Scope (Level, Scope (Def_Id));

            --  Set accessibility level of null

            if No (Expr) then
               Level_Expr :=
                 Make_Integer_Literal
                   (Loc, Scope_Depth (Standard_Standard));

            --  When the expression of the object is a function which returns
            --  an anonymous access type the master of the call is the object
            --  being initialized instead of the type.

            elsif Nkind (Expr) = N_Function_Call
              and then Ekind (Etype (Name (Expr))) = E_Anonymous_Access_Type
            then
               Level_Expr := Accessibility_Level
                               (Def_Id, Object_Decl_Level);

            --  General case

            else
               Level_Expr := Accessibility_Level (Expr, Dynamic_Level);
            end if;

            Level_Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Level,
                Object_Definition   =>
                  New_Occurrence_Of (Standard_Natural, Loc),
                Expression          => Level_Expr,
                Constant_Present    => Constant_Present (N),
                Has_Init_Expression => True);

            Insert_Action_After (Init_After, Level_Decl);

            Set_Extra_Accessibility (Def_Id, Level);
         end;
      end if;

      --  If the object is default initialized and its type is subject to
      --  pragma Default_Initial_Condition, add a runtime check to verify
      --  the assumption of the pragma (SPARK RM 7.3.3). Generate:

      --    <Base_Typ>DIC (<Base_Typ> (Def_Id));

      --  Note that the check is generated for source objects only

      if Comes_From_Source (Def_Id)
        and then Has_DIC (Typ)
        and then Present (DIC_Procedure (Typ))
        and then not Has_Null_Body (DIC_Procedure (Typ))
        and then not Has_Init_Expression (N)
        and then No (Expr)
        and then not Is_Imported (Def_Id)
      then
         declare
            DIC_Call : constant Node_Id :=
                         Build_DIC_Call
                           (Loc, New_Occurrence_Of (Def_Id, Loc), Typ);
         begin
            if Present (Next_N) then
               Insert_Before_And_Analyze (Next_N, DIC_Call);

            --  The object declaration is the last node in a declarative or a
            --  statement list.

            else
               Append_To (List_Containing (N), DIC_Call);
               Analyze (DIC_Call);
            end if;
         end;
      end if;

      --  If this is the return object of a build-in-place function, locate the
      --  implicit BIPaccess parameter designating the caller-supplied return
      --  object and convert the declaration to a renaming of a dereference of
      --  this parameter. If the declaration includes an expression, add an
      --  assignment statement to ensure the return object gets initialized.

      --    Result : T [:= <expression>];

      --  is converted to

      --    Result : T renames BIPaccess.all;
      --    [Result := <expression>;]

      --  in the constrained case, or to

      --    type Txx is access all ...;
      --    Rxx : Txx := null;

      --    if BIPalloc = 1 then
      --       Rxx := BIPaccess;
      --       Rxx.all := <expression>;
      --    elsif BIPalloc = 2 then
      --       Rxx := new <expression-type>'(<expression>)[storage_pool =
      --         system__secondary_stack__ss_pool][procedure_to_call =
      --         system__secondary_stack__ss_allocate];
      --    elsif BIPalloc = 3 then
      --       Rxx := new <expression-type>'(<expression>)
      --    elsif BIPalloc = 4 then
      --       Pxx : system__storage_pools__root_storage_pool renames
      --         BIPstoragepool.all;
      --       Rxx := new <expression-type>'(<expression>)[storage_pool =
      --         Pxx][procedure_to_call =
      --         system__storage_pools__allocate_any];
      --    else
      --       [program_error "build in place mismatch"]
      --    end if;

      --    Result : T renames Rxx.all;

      --  in the unconstrained case.

      if Is_Build_In_Place_Return_Object (Def_Id) then
         declare
            Init_Stmt      : Node_Id;
            Obj_Acc_Formal : Entity_Id;

         begin
            --  Retrieve the implicit access parameter passed by the caller

            Obj_Acc_Formal :=
              Build_In_Place_Formal (Func_Id, BIP_Object_Access);

            --  If the return object's declaration includes an expression
            --  and the declaration isn't marked as No_Initialization, then
            --  we need to generate an assignment to the object and insert
            --  it after the declaration before rewriting it as a renaming
            --  (otherwise we'll lose the initialization). The case where
            --  the result type is an interface (or class-wide interface)
            --  is also excluded because the context of the function call
            --  must be unconstrained, so the initialization will always
            --  be done as part of an allocator evaluation (storage pool
            --  or secondary stack), never to a constrained target object
            --  passed in by the caller. Besides the assignment being
            --  unneeded in this case, it avoids problems with trying to
            --  generate a dispatching assignment when the return expression
            --  is a nonlimited descendant of a limited interface (the
            --  interface has no assignment operation).

            if Present (Expr_Q)
              and then not Is_Delayed_Aggregate (Expr_Q)
              and then not No_Initialization (N)
              and then not Is_Interface (Typ)
            then
               if Is_Class_Wide_Type (Typ)
                 and then not Is_Class_Wide_Type (Etype (Expr_Q))
               then
                  Init_Stmt :=
                    Make_Assignment_Statement (Loc,
                      Name       => New_Occurrence_Of (Def_Id, Loc),
                      Expression =>
                        Make_Type_Conversion (Loc,
                          Subtype_Mark =>
                            New_Occurrence_Of (Typ, Loc),
                          Expression   => New_Copy_Tree (Expr_Q)));

               else
                  Init_Stmt :=
                    Make_Assignment_Statement (Loc,
                      Name       => New_Occurrence_Of (Def_Id, Loc),
                      Expression => New_Copy_Tree (Expr_Q));
               end if;

               Set_Assignment_OK (Name (Init_Stmt));
               Set_No_Ctrl_Actions (Init_Stmt);

            else
               Init_Stmt := Empty;
            end if;

            --  When the function's subtype is unconstrained, a run-time
            --  test may be needed to decide the form of allocation to use
            --  for the return object. The function has an implicit formal
            --  parameter indicating this. If the BIP_Alloc_Form formal has
            --  the value one, then the caller has passed access to an
            --  existing object for use as the return object. If the value
            --  is two, then the return object must be allocated on the
            --  secondary stack. If the value is three, then the return
            --  object must be allocated on the heap. Otherwise, the object
            --  must be allocated in a storage pool. We generate an if
            --  statement to test the BIP_Alloc_Form formal and initialize
            --  a local access value appropriately.

            if Needs_BIP_Alloc_Form (Func_Id) then
               declare
                  Desig_Typ : constant Entity_Id :=
                    (if Ekind (Typ) = E_Array_Subtype
                     then Etype (Func_Id) else Typ);
                  --  Ensure that the we use a fat pointer when allocating
                  --  an unconstrained array on the heap. In this case the
                  --  result object's type is a constrained array type even
                  --  though the function's type is unconstrained.

                  Obj_Alloc_Formal : constant Entity_Id :=
                    Build_In_Place_Formal (Func_Id, BIP_Alloc_Form);
                  Pool_Id          : constant Entity_Id :=
                    Make_Temporary (Loc, 'P');

                  Acc_Typ        : Entity_Id;
                  Alloc_Obj_Decl : Node_Id;
                  Alloc_Obj_Id   : Entity_Id;
                  Alloc_Stmt     : Node_Id;
                  Guard_Except   : Node_Id;
                  Heap_Allocator : Node_Id;
                  Pool_Allocator : Node_Id;
                  Pool_Decl      : Node_Id;
                  Ptr_Typ_Decl   : Node_Id;
                  SS_Allocator   : Node_Id;

               begin
                  --  Create an access type designating the function's
                  --  result subtype.

                  Acc_Typ := Make_Temporary (Loc, 'A');

                  Ptr_Typ_Decl :=
                    Make_Full_Type_Declaration (Loc,
                      Defining_Identifier => Acc_Typ,
                      Type_Definition     =>
                        Make_Access_To_Object_Definition (Loc,
                          All_Present        => True,
                          Subtype_Indication =>
                            New_Occurrence_Of (Desig_Typ, Loc)));

                  Insert_Action (N, Ptr_Typ_Decl, Suppress => All_Checks);

                  --  Create an access object that will be initialized to an
                  --  access value denoting the return object, either coming
                  --  from an implicit access value passed in by the caller
                  --  or from the result of an allocator.

                  Alloc_Obj_Id := Make_Temporary (Loc, 'R');

                  Alloc_Obj_Decl :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Alloc_Obj_Id,
                      Object_Definition   =>
                        New_Occurrence_Of (Acc_Typ, Loc));

                  Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);

                  --  First create the Heap_Allocator

                  Heap_Allocator := Make_Allocator_For_Return (Expr_Q);

                  --  The Pool_Allocator is just like the Heap_Allocator,
                  --  except we set Storage_Pool and Procedure_To_Call so
                  --  it will use the user-defined storage pool.

                  Pool_Allocator := Make_Allocator_For_Return (Expr_Q);

                  --  Do not generate the renaming of the build-in-place
                  --  pool parameter on ZFP because the parameter is not
                  --  created in the first place.

                  if RTE_Available (RE_Root_Storage_Pool_Ptr) then
                     Pool_Decl :=
                       Make_Object_Renaming_Declaration (Loc,
                         Defining_Identifier => Pool_Id,
                         Subtype_Mark        =>
                           New_Occurrence_Of
                             (RTE (RE_Root_Storage_Pool), Loc),
                         Name                =>
                           Make_Explicit_Dereference (Loc,
                             New_Occurrence_Of
                               (Build_In_Place_Formal
                                  (Func_Id, BIP_Storage_Pool), Loc)));
                     Set_Storage_Pool (Pool_Allocator, Pool_Id);
                     Set_Procedure_To_Call
                       (Pool_Allocator, RTE (RE_Allocate_Any));
                  else
                     Pool_Decl := Make_Null_Statement (Loc);
                  end if;

                  --  If the No_Allocators restriction is active, then only
                  --  an allocator for secondary stack allocation is needed.
                  --  It's OK for such allocators to have Comes_From_Source
                  --  set to False, because gigi knows not to flag them as
                  --  being a violation of No_Implicit_Heap_Allocations.

                  if Restriction_Active (No_Allocators) then
                     SS_Allocator   := Heap_Allocator;
                     Heap_Allocator := Make_Null (Loc);
                     Pool_Allocator := Make_Null (Loc);

                  --  Otherwise the heap and pool allocators may be needed,
                  --  so we make another allocator for secondary stack
                  --  allocation.

                  else
                     SS_Allocator := Make_Allocator_For_Return (Expr_Q);

                     --  The heap and pool allocators are marked as
                     --  Comes_From_Source since they correspond to an
                     --  explicit user-written allocator (that is, it will
                     --  only be executed on behalf of callers that call the
                     --  function as initialization for such an allocator).
                     --  Prevents errors when No_Implicit_Heap_Allocations
                     --  is in force.

                     Set_Comes_From_Source (Heap_Allocator, True);
                     Set_Comes_From_Source (Pool_Allocator, True);
                  end if;

                  --  The allocator is returned on the secondary stack

                  Check_Restriction (No_Secondary_Stack, N);
                  Set_Storage_Pool (SS_Allocator, RTE (RE_SS_Pool));
                  Set_Procedure_To_Call
                    (SS_Allocator, RTE (RE_SS_Allocate));

                  --  The allocator is returned on the secondary stack,
                  --  so indicate that the function return, as well as
                  --  all blocks that encloses the allocator, must not
                  --  release it. The flags must be set now because
                  --  the decision to use the secondary stack is done
                  --  very late in the course of expanding the return
                  --  statement, past the point where these flags are
                  --  normally set.

                  Set_Uses_Sec_Stack (Func_Id);
                  Set_Uses_Sec_Stack (Scope (Def_Id));
                  Set_Sec_Stack_Needed_For_Return (Scope (Def_Id));

                  --  Guard against poor expansion on the caller side by
                  --  using a raise statement to catch out-of-range values
                  --  of formal parameter BIP_Alloc_Form.

                  if Exceptions_OK then
                     Guard_Except :=
                       Make_Raise_Program_Error (Loc,
                         Reason => PE_Build_In_Place_Mismatch);
                  else
                     Guard_Except := Make_Null_Statement (Loc);
                  end if;

                  --  Create an if statement to test the BIP_Alloc_Form
                  --  formal and initialize the access object to either the
                  --  BIP_Object_Access formal (BIP_Alloc_Form =
                  --  Caller_Allocation), the result of allocating the
                  --  object in the secondary stack (BIP_Alloc_Form =
                  --  Secondary_Stack), or else an allocator to create the
                  --  return object in the heap or user-defined pool
                  --  (BIP_Alloc_Form = Global_Heap or User_Storage_Pool).

                  --  ??? An unchecked type conversion must be made in the
                  --  case of assigning the access object formal to the
                  --  local access object, because a normal conversion would
                  --  be illegal in some cases (such as converting access-
                  --  to-unconstrained to access-to-constrained), but the
                  --  the unchecked conversion will presumably fail to work
                  --  right in just such cases. In order to handle this
                  --  properly, in the Caller_Allocation case, the callee
                  --  needs to do the constraint check.

                  Alloc_Stmt :=
                    Make_If_Statement (Loc,
                      Condition =>
                        Make_Op_Eq (Loc,
                          Left_Opnd  =>
                            New_Occurrence_Of (Obj_Alloc_Formal, Loc),
                          Right_Opnd =>
                            Make_Integer_Literal (Loc,
                              UI_From_Int (BIP_Allocation_Form'Pos
                                             (Caller_Allocation)))),

                      Then_Statements => New_List (
                        Make_Assignment_Statement (Loc,
                          Name       =>
                            New_Occurrence_Of (Alloc_Obj_Id, Loc),
                          Expression =>
                            Unchecked_Convert_To
                              (Acc_Typ,
                               New_Occurrence_Of (Obj_Acc_Formal, Loc)))),

                      Elsif_Parts => New_List (
                        Make_Elsif_Part (Loc,
                          Condition =>
                            Make_Op_Eq (Loc,
                              Left_Opnd  =>
                                New_Occurrence_Of (Obj_Alloc_Formal, Loc),
                              Right_Opnd =>
                                Make_Integer_Literal (Loc,
                                  UI_From_Int (BIP_Allocation_Form'Pos
                                                 (Secondary_Stack)))),

                          Then_Statements => New_List (
                            Make_Assignment_Statement (Loc,
                              Name       =>
                                New_Occurrence_Of (Alloc_Obj_Id, Loc),
                              Expression => SS_Allocator))),

                        Make_Elsif_Part (Loc,
                          Condition =>
                            Make_Op_Eq (Loc,
                              Left_Opnd  =>
                                New_Occurrence_Of (Obj_Alloc_Formal, Loc),
                              Right_Opnd =>
                                Make_Integer_Literal (Loc,
                                  UI_From_Int (BIP_Allocation_Form'Pos
                                                 (Global_Heap)))),

                          Then_Statements => New_List (
                            Build_Heap_Or_Pool_Allocator
                              (Temp_Id    => Alloc_Obj_Id,
                               Temp_Typ   => Acc_Typ,
                               Ret_Typ    => Desig_Typ,
                               Alloc_Expr => Heap_Allocator))),

                        --  ??? If all is well, we can put the following
                        --  'elsif' in the 'else', but this is a useful
                        --  self-check in case caller and callee don't agree
                        --  on whether BIPAlloc and so on should be passed.

                        Make_Elsif_Part (Loc,
                          Condition =>
                            Make_Op_Eq (Loc,
                              Left_Opnd  =>
                                New_Occurrence_Of (Obj_Alloc_Formal, Loc),
                              Right_Opnd =>
                                Make_Integer_Literal (Loc,
                                  UI_From_Int (BIP_Allocation_Form'Pos
                                                 (User_Storage_Pool)))),

                          Then_Statements => New_List (
                            Pool_Decl,
                            Build_Heap_Or_Pool_Allocator
                              (Temp_Id    => Alloc_Obj_Id,
                               Temp_Typ   => Acc_Typ,
                               Ret_Typ    => Desig_Typ,
                               Alloc_Expr => Pool_Allocator)))),

                      --  Raise Program_Error if it's none of the above;
                      --  this is a compiler bug.

                      Else_Statements => New_List (Guard_Except));

                  --  If a separate initialization assignment was created
                  --  earlier, append that following the assignment of the
                  --  implicit access formal to the access object, to ensure
                  --  that the return object is initialized in that case. In
                  --  this situation, the target of the assignment must be
                  --  rewritten to denote a dereference of the access to the
                  --  return object passed in by the caller.

                  if Present (Init_Stmt) then
                     Set_Name (Init_Stmt,
                       Make_Explicit_Dereference (Loc,
                         Prefix => New_Occurrence_Of (Alloc_Obj_Id, Loc)));
                     Set_Assignment_OK (Name (Init_Stmt));

                     Append_To (Then_Statements (Alloc_Stmt), Init_Stmt);
                     Init_Stmt := Empty;
                  end if;

                  Insert_Action (N, Alloc_Stmt, Suppress => All_Checks);

                  --  From now on, the type of the return object is the
                  --  designated type.

                  if Desig_Typ /= Typ then
                     Set_Etype (Def_Id, Desig_Typ);
                     Set_Actual_Subtype (Def_Id, Typ);
                  end if;

                  --  Remember the local access object for use in the
                  --  dereference of the renaming created below.

                  Obj_Acc_Formal := Alloc_Obj_Id;
               end;

            --  When the function's type is unconstrained and a run-time test
            --  is not needed, we nevertheless need to build the return using
            --  the return object's type.

            elsif not Is_Constrained (Underlying_Type (Etype (Func_Id))) then
               declare
                  Acc_Typ        : Entity_Id;
                  Alloc_Obj_Decl : Node_Id;
                  Alloc_Obj_Id   : Entity_Id;
                  Ptr_Typ_Decl   : Node_Id;

               begin
                  --  Create an access type designating the function's
                  --  result subtype.

                  Acc_Typ := Make_Temporary (Loc, 'A');

                  Ptr_Typ_Decl :=
                    Make_Full_Type_Declaration (Loc,
                      Defining_Identifier => Acc_Typ,
                      Type_Definition     =>
                        Make_Access_To_Object_Definition (Loc,
                          All_Present        => True,
                          Subtype_Indication =>
                            New_Occurrence_Of (Typ, Loc)));

                  Insert_Action (N, Ptr_Typ_Decl, Suppress => All_Checks);

                  --  Create an access object initialized to the conversion
                  --  of the implicit access value passed in by the caller.

                  Alloc_Obj_Id := Make_Temporary (Loc, 'R');

                  --  See the ??? comment a few lines above about the use of
                  --  an unchecked conversion here.

                  Alloc_Obj_Decl :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Alloc_Obj_Id,
                      Constant_Present    => True,
                      Object_Definition   =>
                        New_Occurrence_Of (Acc_Typ, Loc),
                      Expression =>
                        Unchecked_Convert_To
                          (Acc_Typ, New_Occurrence_Of (Obj_Acc_Formal, Loc)));

                  Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);

                  --  Remember the local access object for use in the
                  --  dereference of the renaming created below.

                  Obj_Acc_Formal := Alloc_Obj_Id;
               end;
            end if;

            --  Initialize the object now that it has got its final subtype,
            --  but before rewriting it as a renaming.

            Initialize_Return_Object
              (Tag_Assign, Adj_Call, Expr_Q, Init_Stmt, Init_After);

            --  Save the assignment statement when returning a controlled
            --  object. This reference is used later by the finalization
            --  machinery to mark the object as successfully initialized.

            if Present (Init_Stmt) and then Needs_Finalization (Typ) then
               Set_Last_Aggregate_Assignment (Def_Id, Init_Stmt);
            end if;

            --  Replace the return object declaration with a renaming of a
            --  dereference of the access value designating the return object.

            Expr_Q :=
              Make_Explicit_Dereference (Loc,
                Prefix => New_Occurrence_Of (Obj_Acc_Formal, Loc));
            Set_Etype (Expr_Q, Etype (Def_Id));

            Rewrite_As_Renaming := True;
         end;

      --  If we can rename the initialization expression, we need to make sure
      --  that we use the proper type in the case of a return object that lives
      --  on the secondary stack (see other cases below for a similar handling)
      --  and that the tag is assigned in the case of any return object.

      elsif Rewrite_As_Renaming then
         if Special_Ret_Obj then
            declare
               Desig_Typ : constant Entity_Id :=
                 (if Ekind (Typ) = E_Array_Subtype
                  then Etype (Func_Id) else Typ);

            begin
               --  From now on, the type of the return object is the
               --  designated type.

               if Desig_Typ /= Typ then
                  Set_Etype (Def_Id, Desig_Typ);
                  Set_Actual_Subtype (Def_Id, Typ);
               end if;

               if Present (Tag_Assign) then
                  Insert_Action_After (Init_After, Tag_Assign);
               end if;

               --  Ada 2005 (AI95-344): If the result type is class-wide,
               --  insert a check that the level of the return expression's
               --  underlying type is not deeper than the level of the master
               --  enclosing the function.

               --  AI12-043: The check is made immediately after the return
               --  object is created.

               if Is_Class_Wide_Type (Etype (Func_Id)) then
                  Apply_CW_Accessibility_Check (Expr_Q, Func_Id);
               end if;

               --  ??? Usually calls to Apply_CW_Accessibility_Check and to
               --  Apply_Access_Discrims_Accessibility_Check come in pairs.
               --  Do we need a (conditional) call here to A_A_D_A_C ?
            end;
         end if;

      --  If this is the return object of a function returning on the secondary
      --  stack, convert the declaration to a renaming of the dereference of ah
      --  allocator for the secondary stack.

      --    Result : T [:= <expression>];

      --  is converted to

      --    type Txx is access all ...;
      --    Rxx : constant Txx :=
      --      new <expression-type>['(<expression>)][storage_pool =
      --        system__secondary_stack__ss_pool][procedure_to_call =
      --        system__secondary_stack__ss_allocate];

      --    Result : T renames Rxx.all;

      elsif Is_Secondary_Stack_Return_Object (Def_Id) then
         declare
            Desig_Typ : constant Entity_Id :=
              (if Ekind (Typ) = E_Array_Subtype
               then Etype (Func_Id) else Typ);
            --  Ensure that the we use a fat pointer when allocating
            --  an unconstrained array on the heap. In this case the
            --  result object's type is a constrained array type even
            --  though the function's type is unconstrained.

            Acc_Typ        : Entity_Id;
            Alloc_Obj_Decl : Node_Id;
            Alloc_Obj_Id   : Entity_Id;
            Ptr_Type_Decl  : Node_Id;

         begin
            --  Create an access type designating the function's
            --  result subtype.

            Acc_Typ := Make_Temporary (Loc, 'A');

            Ptr_Type_Decl :=
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Acc_Typ,
                Type_Definition     =>
                  Make_Access_To_Object_Definition (Loc,
                    All_Present        => True,
                    Subtype_Indication =>
                      New_Occurrence_Of (Desig_Typ, Loc)));

            Insert_Action (N, Ptr_Type_Decl, Suppress => All_Checks);

            Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_SS_Pool));

            Alloc_Obj_Id := Make_Temporary (Loc, 'R');

            Alloc_Obj_Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Alloc_Obj_Id,
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (Acc_Typ, Loc),
                Expression => Make_Allocator_For_Return (Expr_Q));

            Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);

            Set_Uses_Sec_Stack (Func_Id);
            Set_Uses_Sec_Stack (Scope (Def_Id));
            Set_Sec_Stack_Needed_For_Return (Scope (Def_Id));

            --  From now on, the type of the return object is the
            --  designated type.

            if Desig_Typ /= Typ then
               Set_Etype (Def_Id, Desig_Typ);
               Set_Actual_Subtype (Def_Id, Typ);
            end if;

            --  Initialize the object now that it has got its final subtype,
            --  but before rewriting it as a renaming.

            Initialize_Return_Object
              (Tag_Assign, Adj_Call, Expr_Q, Empty, Init_After);

            --  Replace the return object declaration with a renaming of a
            --  dereference of the access value designating the return object.

            Expr_Q :=
              Make_Explicit_Dereference (Loc,
                Prefix => New_Occurrence_Of (Alloc_Obj_Id, Loc));
            Set_Etype (Expr_Q, Etype (Def_Id));

            Rewrite_As_Renaming := True;
         end;

      --  If this is the return object of a function returning a by-reference
      --  type, convert the declaration to a renaming of the dereference of ah
      --  allocator for the return stack.

      --    Result : T [:= <expression>];

      --  is converted to

      --    type Txx is access all ...;
      --    Rxx : constant Txx :=
      --      new <expression-type>['(<expression>)][storage_pool =
      --        system__return_stack__rs_pool][procedure_to_call =
      --        system__return_stack__rs_allocate];

      --    Result : T renames Rxx.all;

      elsif Back_End_Return_Slot
        and then Is_By_Reference_Return_Object (Def_Id)
      then
         declare
            Acc_Typ        : Entity_Id;
            Alloc_Obj_Decl : Node_Id;
            Alloc_Obj_Id   : Entity_Id;
            Ptr_Type_Decl  : Node_Id;

         begin
            --  Create an access type designating the function's
            --  result subtype.

            Acc_Typ := Make_Temporary (Loc, 'A');

            Ptr_Type_Decl :=
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Acc_Typ,
                Type_Definition     =>
                  Make_Access_To_Object_Definition (Loc,
                    All_Present        => True,
                    Subtype_Indication =>
                      New_Occurrence_Of (Typ, Loc)));

            Insert_Action (N, Ptr_Type_Decl, Suppress => All_Checks);

            Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_RS_Pool));

            Alloc_Obj_Id := Make_Temporary (Loc, 'R');

            Alloc_Obj_Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Alloc_Obj_Id,
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (Acc_Typ, Loc),
                Expression => Make_Allocator_For_Return (Expr_Q));

            Insert_Action (N, Alloc_Obj_Decl, Suppress => All_Checks);

            --  Initialize the object now that it has got its final subtype,
            --  but before rewriting it as a renaming.

            Initialize_Return_Object
              (Tag_Assign, Adj_Call, Expr_Q, Empty, Init_After);

            --  Replace the return object declaration with a renaming of a
            --  dereference of the access value designating the return object.

            Expr_Q :=
              Make_Explicit_Dereference (Loc,
                Prefix => New_Occurrence_Of (Alloc_Obj_Id, Loc));
            Set_Etype (Expr_Q, Etype (Def_Id));

            Rewrite_As_Renaming := True;
         end;
      end if;

      --  Final transformation - turn the object declaration into a renaming
      --  if appropriate. If this is the completion of a deferred constant
      --  declaration, then this transformation generates what would be
      --  illegal code if written by hand, but that's OK.

      if Rewrite_As_Renaming then
         Rewrite_Object_Declaration_As_Renaming (N, Expr_Q);
      end if;

   --  Exception on library entity not available

   exception
      when RE_Not_Available =>
         null;
   end Expand_N_Object_Declaration;

   ---------------------------------
   -- Expand_N_Subtype_Indication --
   ---------------------------------

   --  Add a check on the range of the subtype and deal with validity checking

   procedure Expand_N_Subtype_Indication (N : Node_Id) is
      Ran : constant Node_Id   := Range_Expression (Constraint (N));
      Typ : constant Entity_Id := Entity (Subtype_Mark (N));

   begin
      if Nkind (Constraint (N)) = N_Range_Constraint then
         Validity_Check_Range (Range_Expression (Constraint (N)));
      end if;

      --  Do not duplicate the work of Process_Range_Expr_In_Decl in Sem_Ch3

      if Nkind (Parent (N)) in N_Constrained_Array_Definition | N_Slice
        and then Nkind (Parent (Parent (N))) not in
                   N_Full_Type_Declaration | N_Object_Declaration
      then
         Apply_Range_Check (Ran, Typ);
      end if;
   end Expand_N_Subtype_Indication;

   ---------------------------
   -- Expand_N_Variant_Part --
   ---------------------------

   --  Note: this procedure no longer has any effect. It used to be that we
   --  would replace the choices in the last variant by a when others, and
   --  also expanded static predicates in variant choices here, but both of
   --  those activities were being done too early, since we can't check the
   --  choices until the statically predicated subtypes are frozen, which can
   --  happen as late as the free point of the record, and we can't change the
   --  last choice to an others before checking the choices, which is now done
   --  at the freeze point of the record.

   procedure Expand_N_Variant_Part (N : Node_Id) is
   begin
      null;
   end Expand_N_Variant_Part;

   ---------------------------------
   -- Expand_Previous_Access_Type --
   ---------------------------------

   procedure Expand_Previous_Access_Type (Def_Id : Entity_Id) is
      Ptr_Typ : Entity_Id;

   begin
      --  Find all access types in the current scope whose designated type is
      --  Def_Id and build master renamings for them.

      Ptr_Typ := First_Entity (Current_Scope);
      while Present (Ptr_Typ) loop
         if Is_Access_Type (Ptr_Typ)
           and then Designated_Type (Ptr_Typ) = Def_Id
           and then No (Master_Id (Ptr_Typ))
         then
            --  Ensure that the designated type has a master

            Build_Master_Entity (Def_Id);

            --  Private and incomplete types complicate the insertion of master
            --  renamings because the access type may precede the full view of
            --  the designated type. For this reason, the master renamings are
            --  inserted relative to the designated type.

            Build_Master_Renaming (Ptr_Typ, Ins_Nod => Parent (Def_Id));
         end if;

         Next_Entity (Ptr_Typ);
      end loop;
   end Expand_Previous_Access_Type;

   -----------------------------
   -- Expand_Record_Extension --
   -----------------------------

   --  Add a field _parent at the beginning of the record extension. This is
   --  used to implement inheritance. Here are some examples of expansion:

   --  1. no discriminants
   --      type T2 is new T1 with null record;
   --   gives
   --      type T2 is new T1 with record
   --        _Parent : T1;
   --      end record;

   --  2. renamed discriminants
   --    type T2 (B, C : Int) is new T1 (A => B) with record
   --       _Parent : T1 (A => B);
   --       D : Int;
   --    end;

   --  3. inherited discriminants
   --    type T2 is new T1 with record -- discriminant A inherited
   --       _Parent : T1 (A);
   --       D : Int;
   --    end;

   procedure Expand_Record_Extension (T : Entity_Id; Def : Node_Id) is
      Indic        : constant Node_Id    := Subtype_Indication (Def);
      Loc          : constant Source_Ptr := Sloc (Def);
      Rec_Ext_Part : Node_Id             := Record_Extension_Part (Def);
      Par_Subtype  : Entity_Id;
      Comp_List    : Node_Id;
      Comp_Decl    : Node_Id;
      Parent_N     : Node_Id;
      D            : Entity_Id;
      List_Constr  : constant List_Id    := New_List;

   begin
      --  Expand_Record_Extension is called directly from the semantics, so
      --  we must check to see whether expansion is active before proceeding,
      --  because this affects the visibility of selected components in bodies
      --  of instances. Within a generic we still need to set Parent_Subtype
      --  link because the visibility of inherited components will have to be
      --  verified in subsequent instances.

      if not Expander_Active then
         if Inside_A_Generic and then Ekind (T) = E_Record_Type then
            Set_Parent_Subtype (T, Etype (T));
         end if;
         return;
      end if;

      --  This may be a derivation of an untagged private type whose full
      --  view is tagged, in which case the Derived_Type_Definition has no
      --  extension part. Build an empty one now.

      if No (Rec_Ext_Part) then
         Rec_Ext_Part :=
           Make_Record_Definition (Loc,
             End_Label      => Empty,
             Component_List => Empty,
             Null_Present   => True);

         Set_Record_Extension_Part (Def, Rec_Ext_Part);
         Mark_Rewrite_Insertion (Rec_Ext_Part);
      end if;

      Comp_List := Component_List (Rec_Ext_Part);

      Parent_N := Make_Defining_Identifier (Loc, Name_uParent);

      --  If the derived type inherits its discriminants the type of the
      --  _parent field must be constrained by the inherited discriminants

      if Has_Discriminants (T)
        and then Nkind (Indic) /= N_Subtype_Indication
        and then not Is_Constrained (Entity (Indic))
      then
         D := First_Discriminant (T);
         while Present (D) loop
            Append_To (List_Constr, New_Occurrence_Of (D, Loc));
            Next_Discriminant (D);
         end loop;

         Par_Subtype :=
           Process_Subtype (
             Make_Subtype_Indication (Loc,
               Subtype_Mark => New_Occurrence_Of (Entity (Indic), Loc),
               Constraint   =>
                 Make_Index_Or_Discriminant_Constraint (Loc,
                   Constraints => List_Constr)),
             Def);

      --  Otherwise the original subtype_indication is just what is needed

      else
         Par_Subtype := Process_Subtype (New_Copy_Tree (Indic), Def);
      end if;

      Set_Parent_Subtype (T, Par_Subtype);

      Comp_Decl :=
        Make_Component_Declaration (Loc,
          Defining_Identifier => Parent_N,
          Component_Definition =>
            Make_Component_Definition (Loc,
              Subtype_Indication => New_Occurrence_Of (Par_Subtype, Loc)));

      if Null_Present (Rec_Ext_Part) then
         Set_Component_List (Rec_Ext_Part,
           Make_Component_List (Loc,
             Component_Items => New_List (Comp_Decl),
             Variant_Part => Empty,
             Null_Present => False));
         Set_Null_Present (Rec_Ext_Part, False);

      elsif Null_Present (Comp_List)
        or else Is_Empty_List (Component_Items (Comp_List))
      then
         Set_Component_Items (Comp_List, New_List (Comp_Decl));
         Set_Null_Present (Comp_List, False);

      else
         Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
      end if;

      Analyze (Comp_Decl);
   end Expand_Record_Extension;

   ------------------------
   -- Expand_Tagged_Root --
   ------------------------

   procedure Expand_Tagged_Root (T : Entity_Id) is
      Def       : constant Node_Id := Type_Definition (Parent (T));
      Comp_List : Node_Id;
      Comp_Decl : Node_Id;
      Sloc_N    : Source_Ptr;

   begin
      if Null_Present (Def) then
         Set_Component_List (Def,
           Make_Component_List (Sloc (Def),
             Component_Items => Empty_List,
             Variant_Part => Empty,
             Null_Present => True));
      end if;

      Comp_List := Component_List (Def);

      if Null_Present (Comp_List)
        or else Is_Empty_List (Component_Items (Comp_List))
      then
         Sloc_N := Sloc (Comp_List);
      else
         Sloc_N := Sloc (First (Component_Items (Comp_List)));
      end if;

      Comp_Decl :=
        Make_Component_Declaration (Sloc_N,
          Defining_Identifier => First_Tag_Component (T),
          Component_Definition =>
            Make_Component_Definition (Sloc_N,
              Subtype_Indication => New_Occurrence_Of (RTE (RE_Tag), Sloc_N)));

      if Null_Present (Comp_List)
        or else Is_Empty_List (Component_Items (Comp_List))
      then
         Set_Component_Items (Comp_List, New_List (Comp_Decl));
         Set_Null_Present (Comp_List, False);

      else
         Insert_Before (First (Component_Items (Comp_List)), Comp_Decl);
      end if;

      --  We don't Analyze the whole expansion because the tag component has
      --  already been analyzed previously. Here we just insure that the tree
      --  is coherent with the semantic decoration

      Find_Type (Subtype_Indication (Component_Definition (Comp_Decl)));

   exception
      when RE_Not_Available =>
         null;
   end Expand_Tagged_Root;

   ------------------------------
   -- Freeze_Stream_Operations --
   ------------------------------

   procedure Freeze_Stream_Operations (N : Node_Id; Typ : Entity_Id) is
      Names     : constant array (1 .. 4) of TSS_Name_Type :=
                    (TSS_Stream_Input,
                     TSS_Stream_Output,
                     TSS_Stream_Read,
                     TSS_Stream_Write);
      Stream_Op : Entity_Id;

   begin
      --  Primitive operations of tagged types are frozen when the dispatch
      --  table is constructed.

      if not Comes_From_Source (Typ) or else Is_Tagged_Type (Typ) then
         return;
      end if;

      for J in Names'Range loop
         Stream_Op := TSS (Typ, Names (J));

         if Present (Stream_Op)
           and then Is_Subprogram (Stream_Op)
           and then Nkind (Unit_Declaration_Node (Stream_Op)) =
                                                    N_Subprogram_Declaration
           and then not Is_Frozen (Stream_Op)
         then
            Append_Freeze_Actions (Typ, Freeze_Entity (Stream_Op, N));
         end if;
      end loop;
   end Freeze_Stream_Operations;

   -----------------
   -- Freeze_Type --
   -----------------

   --  Full type declarations are expanded at the point at which the type is
   --  frozen. The formal N is the Freeze_Node for the type. Any statements or
   --  declarations generated by the freezing (e.g. the procedure generated
   --  for initialization) are chained in the Actions field list of the freeze
   --  node using Append_Freeze_Actions.

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   function Freeze_Type (N : Node_Id) return Boolean is
      procedure Process_RACW_Types (Typ : Entity_Id);
      --  Validate and generate stubs for all RACW types associated with type
      --  Typ.

      ------------------------
      -- Process_RACW_Types --
      ------------------------

      procedure Process_RACW_Types (Typ : Entity_Id) is
         List : constant Elist_Id := Access_Types_To_Process (N);
         E    : Elmt_Id;
         Seen : Boolean := False;

      begin
         if Present (List) then
            E := First_Elmt (List);
            while Present (E) loop
               if Is_Remote_Access_To_Class_Wide_Type (Node (E)) then
                  Validate_RACW_Primitives (Node (E));
                  Seen := True;
               end if;

               Next_Elmt (E);
            end loop;
         end if;

         --  If there are RACWs designating this type, make stubs now

         if Seen then
            Remote_Types_Tagged_Full_View_Encountered (Typ);
         end if;
      end Process_RACW_Types;

      --  Local variables

      Def_Id : constant Entity_Id := Entity (N);

      Saved_Ghost_Config : constant Ghost_Config_Type := Ghost_Config;
      --  Save the Ghost-related attributes to restore on exit

      Result : Boolean := False;

   --  Start of processing for Freeze_Type

   begin
      --  The type being frozen may be subject to pragma Ghost. Set the mode
      --  now to ensure that any nodes generated during freezing are properly
      --  marked as Ghost.

      Set_Ghost_Mode (Def_Id);

      --  Process any remote access-to-class-wide types designating the type
      --  being frozen.

      Process_RACW_Types (Def_Id);

      --  Freeze processing for record types

      if Is_Record_Type (Def_Id) then
         if Ekind (Def_Id) = E_Record_Type then
            Expand_Freeze_Record_Type (N);
         elsif Is_Class_Wide_Type (Def_Id) then
            Expand_Freeze_Class_Wide_Type (N);
         end if;

      --  Freeze processing for array types

      elsif Is_Array_Type (Def_Id) then
         Expand_Freeze_Array_Type (N);

      --  Freeze processing for access types

      --  For pool-specific access types, find out the pool object used for
      --  this type, needs actual expansion of it in some cases. Here are the
      --  different cases :

      --  1. Rep Clause "for Def_Id'Storage_Size use 0;"
      --      ---> don't use any storage pool

      --  2. Rep Clause : for Def_Id'Storage_Size use Expr.
      --     Expand:
      --      Def_Id__Pool : Stack_Bounded_Pool (Expr, DT'Size, DT'Alignment);

      --  3. Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
      --      ---> Storage Pool is the specified one

      --  See GNAT Pool packages in the Run-Time for more details

      elsif Ekind (Def_Id) in E_Access_Type | E_General_Access_Type then
         declare
            Loc        : constant Source_Ptr := Sloc (N);
            Desig_Type : constant Entity_Id  := Designated_Type (Def_Id);

            Freeze_Action_Typ : Entity_Id;
            Pool_Object       : Entity_Id;

         begin
            --  Case 1

            --    Rep Clause "for Def_Id'Storage_Size use 0;"
            --    ---> don't use any storage pool

            if No_Pool_Assigned (Def_Id) then
               null;

            --  Case 2

            --    Rep Clause : for Def_Id'Storage_Size use Expr.
            --    ---> Expand:
            --           Def_Id__Pool : Stack_Bounded_Pool
            --                            (Expr, DT'Size, DT'Alignment);

            elsif Has_Storage_Size_Clause (Def_Id) then
               declare
                  DT_Align : Node_Id;
                  DT_Size  : Node_Id;

               begin
                  --  For unconstrained composite types we give a size of zero
                  --  so that the pool knows that it needs a special algorithm
                  --  for variable size object allocation.

                  if Is_Composite_Type (Desig_Type)
                    and then not Is_Constrained (Desig_Type)
                  then
                     DT_Size  := Make_Integer_Literal (Loc, 0);
                     DT_Align := Make_Integer_Literal (Loc, Maximum_Alignment);

                  else
                     DT_Size :=
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Desig_Type, Loc),
                         Attribute_Name => Name_Max_Size_In_Storage_Elements);

                     DT_Align :=
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Desig_Type, Loc),
                         Attribute_Name => Name_Alignment);
                  end if;

                  Pool_Object :=
                    Make_Defining_Identifier (Loc,
                      Chars => New_External_Name (Chars (Def_Id), 'P'));

                  --  We put the code associated with the pools in the entity
                  --  that has the later freeze node, usually the access type
                  --  but it can also be the designated_type; because the pool
                  --  code requires both those types to be frozen

                  if Is_Frozen (Desig_Type)
                    and then (No (Freeze_Node (Desig_Type))
                               or else Analyzed (Freeze_Node (Desig_Type)))
                  then
                     Freeze_Action_Typ := Def_Id;

                  --  A Taft amendment type cannot get the freeze actions
                  --  since the full view is not there.

                  elsif Is_Incomplete_Or_Private_Type (Desig_Type)
                    and then No (Full_View (Desig_Type))
                  then
                     Freeze_Action_Typ := Def_Id;

                  else
                     Freeze_Action_Typ := Desig_Type;
                  end if;

                  Append_Freeze_Action (Freeze_Action_Typ,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Pool_Object,
                      Object_Definition   =>
                        Make_Subtype_Indication (Loc,
                          Subtype_Mark =>
                            New_Occurrence_Of
                              (RTE (RE_Stack_Bounded_Pool), Loc),

                          Constraint   =>
                            Make_Index_Or_Discriminant_Constraint (Loc,
                              Constraints => New_List (

                                --  First discriminant is the Pool Size

                                New_Occurrence_Of (
                                  Storage_Size_Variable (Def_Id), Loc),

                                --  Second discriminant is the element size

                                DT_Size,

                                --  Third discriminant is the alignment

                                DT_Align)))));
               end;

               Set_Associated_Storage_Pool (Def_Id, Pool_Object);

            --  Case 3

            --    Rep Clause "for Def_Id'Storage_Pool use a_Pool_Object"
            --    ---> Storage Pool is the specified one

            --  When compiling in Ada 2012 mode, ensure that the accessibility
            --  level of the subpool access type is not deeper than that of the
            --  pool_with_subpools.

            elsif Ada_Version >= Ada_2012
              and then Present (Associated_Storage_Pool (Def_Id))
              and then RTU_Loaded (System_Storage_Pools_Subpools)
            then
               declare
                  Loc   : constant Source_Ptr := Sloc (Def_Id);
                  Pool  : constant Entity_Id :=
                            Associated_Storage_Pool (Def_Id);

               begin
                  --  It is known that the accessibility level of the access
                  --  type is deeper than that of the pool.

                  if Type_Access_Level (Def_Id)
                       > Static_Accessibility_Level (Pool, Object_Decl_Level)
                    and then Is_Class_Wide_Type (Etype (Pool))
                    and then not Accessibility_Checks_Suppressed (Def_Id)
                    and then not Accessibility_Checks_Suppressed (Pool)
                  then
                     --  When the pool is of a class-wide type, it may or may
                     --  not support subpools depending on the path of
                     --  derivation. Generate:

                     --    if Def_Id in RSPWS'Class then
                     --       raise Program_Error;
                     --    end if;

                     Append_Freeze_Action (Def_Id,
                       Make_If_Statement (Loc,
                         Condition       =>
                           Make_In (Loc,
                             Left_Opnd  => New_Occurrence_Of (Pool, Loc),
                             Right_Opnd =>
                               New_Occurrence_Of
                                 (Class_Wide_Type
                                   (RTE
                                     (RE_Root_Storage_Pool_With_Subpools)),
                                  Loc)),
                         Then_Statements => New_List (
                           Make_Raise_Program_Error (Loc,
                             Reason => PE_Accessibility_Check_Failed))));
                  end if;
               end;
            end if;

            --  For access-to-controlled types (including class-wide types and
            --  Taft-amendment types, which potentially have controlled
            --  components), expand the list controller object that will store
            --  the dynamically allocated objects. Don't do this transformation
            --  for expander-generated access types, except do it for types
            --  that are the full view of types derived from other private
            --  types and for access types used to implement indirect temps.
            --  Also suppress the list controller in the case of a designated
            --  type with convention Java, since this is used when binding to
            --  Java API specs, where there's no equivalent of a finalization
            --  list and we don't want to pull in the finalization support if
            --  not needed.

            if not Comes_From_Source (Def_Id)
              and then not Has_Private_Declaration (Def_Id)
              and then not Old_Attr_Util.Indirect_Temps
                             .Is_Access_Type_For_Indirect_Temp (Def_Id)
            then
               null;

            --  An exception is made for types defined in the run-time because
            --  Ada.Tags.Tag itself is such a type and cannot afford this
            --  unnecessary overhead that would generates a loop in the
            --  expansion scheme. Another exception is if Restrictions
            --  (No_Finalization) is active, since then we know nothing is
            --  controlled.

            elsif Restriction_Active (No_Finalization)
              or else In_Runtime (Def_Id)
            then
               null;

            --  Create a finalization collection for an access-to-controlled
            --  type or an access-to-incomplete type. It is assumed that the
            --  full view will be controlled.

            elsif Needs_Finalization (Desig_Type)
              or else (Is_Incomplete_Type (Desig_Type)
                        and then No (Full_View (Desig_Type)))
            then
               Build_Finalization_Collection (Def_Id);

            --  Also create a finalization collection when the designated type
            --  contains a private component. It is assumed that the full view
            --  will be controlled.

            elsif Has_Private_Component (Desig_Type) then
               Build_Finalization_Collection
                 (Typ            => Def_Id,
                  For_Private    => True,
                  Context_Scope  => Scope (Def_Id),
                  Insertion_Node => Declaration_Node (Desig_Type));
            end if;
         end;

      --  Freeze processing for enumeration types

      elsif Ekind (Def_Id) = E_Enumeration_Type then

         --  We only have something to do if we have a non-standard
         --  representation (i.e. at least one literal whose pos value
         --  is not the same as its representation)

         if Has_Non_Standard_Rep (Def_Id) then
            Expand_Freeze_Enumeration_Type (N);
         end if;

      --  Private types that are completed by a derivation from a private
      --  type have an internally generated full view, that needs to be
      --  frozen. This must be done explicitly because the two views share
      --  the freeze node, and the underlying full view is not visible when
      --  the freeze node is analyzed.

      elsif Is_Private_Type (Def_Id)
        and then Is_Derived_Type (Def_Id)
        and then Present (Full_View (Def_Id))
        and then Is_Itype (Full_View (Def_Id))
        and then Has_Private_Declaration (Full_View (Def_Id))
        and then Freeze_Node (Full_View (Def_Id)) = N
      then
         Set_Entity (N, Full_View (Def_Id));
         Result := Freeze_Type (N);
         Set_Entity (N, Def_Id);

      --  All other types require no expander action. There are such cases
      --  (e.g. task types and protected types). In such cases, the freeze
      --  nodes are there for use by Gigi.

      end if;

      Freeze_Stream_Operations (N, Def_Id);

      --  Generate the [spec and] body of the invariant procedure tasked with
      --  the runtime verification of all invariants that pertain to the type.
      --  This includes invariants on the partial and full view, inherited
      --  class-wide invariants from parent types or interfaces, and invariants
      --  on array elements or record components. But skip internal types.

      if Is_Itype (Def_Id) then
         null;

      elsif Is_Interface (Def_Id) then

         --  Interfaces are treated as the partial view of a private type in
         --  order to achieve uniformity with the general case. As a result, an
         --  interface receives only a "partial" invariant procedure which is
         --  never called.

         if Has_Own_Invariants (Def_Id) then
            Build_Invariant_Procedure_Body
              (Typ               => Def_Id,
               Partial_Invariant => Is_Interface (Def_Id));
         end if;

      --  Non-interface types

      --  Do not generate invariant procedure within other assertion
      --  subprograms, which may involve local declarations of local
      --  subtypes to which these checks do not apply.

      else
         if Has_Invariants (Def_Id) then
            if not Predicate_Check_In_Scope (Def_Id)
              or else (Ekind (Current_Scope) = E_Function
                        and then Is_Predicate_Function (Current_Scope))
            then
               null;
            else
               Build_Invariant_Procedure_Body (Def_Id);
            end if;
         end if;

         --  Generate the [spec and] body of the procedure tasked with the
         --  run-time verification of pragma Default_Initial_Condition's
         --  expression.

         if Has_DIC (Def_Id) then
            Build_DIC_Procedure_Body (Def_Id);
         end if;
      end if;

      Restore_Ghost_Region (Saved_Ghost_Config);

      return Result;

   exception
      when RE_Not_Available =>
         Restore_Ghost_Region (Saved_Ghost_Config);

         return False;
   end Freeze_Type;

   -------------------------
   -- Get_Simple_Init_Val --
   -------------------------

   function Get_Simple_Init_Val
     (Typ  : Entity_Id;
      N    : Node_Id;
      Size : Uint := No_Uint) return Node_Id
   is
      IV_Attribute : constant Boolean :=
                       Nkind (N) = N_Attribute_Reference
                         and then Attribute_Name (N) = Name_Invalid_Value;

      Loc : constant Source_Ptr := Sloc (N);

      procedure Extract_Subtype_Bounds
        (Lo_Bound : out Uint;
         Hi_Bound : out Uint);
      --  Inspect subtype Typ as well its ancestor subtypes and derived types
      --  to determine the best known information about the bounds of the type.
      --  The output parameters are set as follows:
      --
      --    * Lo_Bound - Set to No_Unit when there is no information available,
      --      or to the known low bound.
      --
      --    * Hi_Bound - Set to No_Unit when there is no information available,
      --      or to the known high bound.

      function Simple_Init_Array_Type return Node_Id;
      --  Build an expression to initialize array type Typ

      function Simple_Init_Defaulted_Type return Node_Id;
      --  Build an expression to initialize type Typ which is subject to
      --  aspect Default_Value.

      function Simple_Init_Initialize_Scalars_Type
        (Size_To_Use : Uint) return Node_Id;
      --  Build an expression to initialize scalar type Typ which is subject to
      --  pragma Initialize_Scalars. Size_To_Use is the size of the object.

      function Simple_Init_Normalize_Scalars_Type
        (Size_To_Use : Uint) return Node_Id;
      --  Build an expression to initialize scalar type Typ which is subject to
      --  pragma Normalize_Scalars. Size_To_Use is the size of the object.

      function Simple_Init_Private_Type return Node_Id;
      --  Build an expression to initialize private type Typ

      function Simple_Init_Scalar_Type return Node_Id;
      --  Build an expression to initialize scalar type Typ

      ----------------------------
      -- Extract_Subtype_Bounds --
      ----------------------------

      procedure Extract_Subtype_Bounds
        (Lo_Bound : out Uint;
         Hi_Bound : out Uint)
      is
         ST1    : Entity_Id;
         ST2    : Entity_Id;
         Lo     : Node_Id;
         Hi     : Node_Id;
         Lo_Val : Uint;
         Hi_Val : Uint;

      begin
         Lo_Bound := No_Uint;
         Hi_Bound := No_Uint;

         --  Loop to climb ancestor subtypes and derived types

         ST1 := Typ;
         loop
            if not Is_Discrete_Type (ST1) then
               return;
            end if;

            Lo := Type_Low_Bound (ST1);
            Hi := Type_High_Bound (ST1);

            if Compile_Time_Known_Value (Lo) then
               Lo_Val := Expr_Value (Lo);

               if No (Lo_Bound) or else Lo_Bound < Lo_Val then
                  Lo_Bound := Lo_Val;
               end if;
            end if;

            if Compile_Time_Known_Value (Hi) then
               Hi_Val := Expr_Value (Hi);

               if No (Hi_Bound) or else Hi_Bound > Hi_Val then
                  Hi_Bound := Hi_Val;
               end if;
            end if;

            ST2 := Ancestor_Subtype (ST1);

            if No (ST2) then
               ST2 := Etype (ST1);
            end if;

            exit when ST1 = ST2;
            ST1 := ST2;
         end loop;
      end Extract_Subtype_Bounds;

      ----------------------------
      -- Simple_Init_Array_Type --
      ----------------------------

      function Simple_Init_Array_Type return Node_Id is
         Comp_Typ : constant Entity_Id := Component_Type (Typ);

         function Simple_Init_Dimension (Index : Node_Id) return Node_Id;
         --  Initialize a single array dimension with index constraint Index

         --------------------
         -- Simple_Init_Dimension --
         --------------------

         function Simple_Init_Dimension (Index : Node_Id) return Node_Id is
         begin
            --  Process the current dimension

            if Present (Index) then

               --  Build a suitable "others" aggregate for the next dimension,
               --  or initialize the component itself. Generate:
               --
               --    (others => ...)

               return
                 Make_Aggregate (Loc,
                   Component_Associations => New_List (
                     Make_Component_Association (Loc,
                       Choices    => New_List (Make_Others_Choice (Loc)),
                       Expression =>
                         Simple_Init_Dimension (Next_Index (Index)))));

            --  Otherwise all dimensions have been processed. Initialize the
            --  component itself.

            else
               return
                 Get_Simple_Init_Val
                   (Typ  => Comp_Typ,
                    N    => N,
                    Size => Esize (Comp_Typ));
            end if;
         end Simple_Init_Dimension;

      --  Start of processing for Simple_Init_Array_Type

      begin
         return Simple_Init_Dimension (First_Index (Typ));
      end Simple_Init_Array_Type;

      --------------------------------
      -- Simple_Init_Defaulted_Type --
      --------------------------------

      function Simple_Init_Defaulted_Type return Node_Id is
         Subtyp : Entity_Id := First_Subtype (Typ);

      begin
         --  When the first subtype is private, retrieve the expression of the
         --  Default_Value from the underlying type.

         if Is_Private_Type (Subtyp) then
            Subtyp := Full_View (Subtyp);
         end if;

         --  Use the Sloc of the context node when constructing the initial
         --  value because the expression of Default_Value may come from a
         --  different unit. Updating the Sloc will result in accurate error
         --  diagnostics.

         return
           OK_Convert_To
             (Typ  => Typ,
              Expr =>
                New_Copy_Tree
                  (Source   => Default_Aspect_Value (Subtyp),
                   New_Sloc => Loc));
      end Simple_Init_Defaulted_Type;

      -----------------------------------------
      -- Simple_Init_Initialize_Scalars_Type --
      -----------------------------------------

      function Simple_Init_Initialize_Scalars_Type
        (Size_To_Use : Uint) return Node_Id
      is
         Float_Typ : Entity_Id;
         Hi_Bound  : Uint;
         Lo_Bound  : Uint;
         Scal_Typ  : Scalar_Id;

      begin
         Extract_Subtype_Bounds (Lo_Bound, Hi_Bound);

         --  Float types

         if Is_Floating_Point_Type (Typ) then
            Float_Typ := Root_Type (Typ);

            if Float_Typ = Standard_Short_Float then
               Scal_Typ := Name_Short_Float;
            elsif Float_Typ = Standard_Float then
               Scal_Typ := Name_Float;
            elsif Float_Typ = Standard_Long_Float then
               Scal_Typ := Name_Long_Float;
            else pragma Assert (Float_Typ = Standard_Long_Long_Float);
               Scal_Typ := Name_Long_Long_Float;
            end if;

         --  If zero is invalid, it is a convenient value to use that is for
         --  sure an appropriate invalid value in all situations.

         elsif Present (Lo_Bound) and then Lo_Bound > Uint_0 then
            return Make_Integer_Literal (Loc, 0);

         --  Unsigned types

         elsif Is_Unsigned_Type (Typ) then
            if Size_To_Use <= 8 then
               Scal_Typ := Name_Unsigned_8;
            elsif Size_To_Use <= 16 then
               Scal_Typ := Name_Unsigned_16;
            elsif Size_To_Use <= 32 then
               Scal_Typ := Name_Unsigned_32;
            elsif Size_To_Use <= 64 then
               Scal_Typ := Name_Unsigned_64;
            else
               Scal_Typ := Name_Unsigned_128;
            end if;

         --  Signed types

         else
            if Size_To_Use <= 8 then
               Scal_Typ := Name_Signed_8;
            elsif Size_To_Use <= 16 then
               Scal_Typ := Name_Signed_16;
            elsif Size_To_Use <= 32 then
               Scal_Typ := Name_Signed_32;
            elsif Size_To_Use <= 64 then
               Scal_Typ := Name_Signed_64;
            else
               Scal_Typ := Name_Signed_128;
            end if;
         end if;

         --  Use the values specified by pragma Initialize_Scalars or the ones
         --  provided by the binder. Higher precedence is given to the pragma.

         return Invalid_Scalar_Value (Loc, Scal_Typ);
      end Simple_Init_Initialize_Scalars_Type;

      ----------------------------------------
      -- Simple_Init_Normalize_Scalars_Type --
      ----------------------------------------

      function Simple_Init_Normalize_Scalars_Type
        (Size_To_Use : Uint) return Node_Id
      is
         Signed_Size : constant Uint := UI_Min (Uint_63, Size_To_Use - 1);

         Expr     : Node_Id;
         Hi_Bound : Uint;
         Lo_Bound : Uint;

      begin
         Extract_Subtype_Bounds (Lo_Bound, Hi_Bound);

         --  If zero is invalid, it is a convenient value to use that is for
         --  sure an appropriate invalid value in all situations.

         if Present (Lo_Bound) and then Lo_Bound > Uint_0 then
            Expr := Make_Integer_Literal (Loc, 0);

         --  Cases where all one bits is the appropriate invalid value

         --  For modular types, all 1 bits is either invalid or valid. If it
         --  is valid, then there is nothing that can be done since there are
         --  no invalid values (we ruled out zero already).

         --  For signed integer types that have no negative values, either
         --  there is room for negative values, or there is not. If there
         --  is, then all 1-bits may be interpreted as minus one, which is
         --  certainly invalid. Alternatively it is treated as the largest
         --  positive value, in which case the observation for modular types
         --  still applies.

         --  For float types, all 1-bits is a NaN (not a number), which is
         --  certainly an appropriately invalid value.

         elsif Is_Enumeration_Type (Typ)
           or else Is_Floating_Point_Type (Typ)
           or else Is_Unsigned_Type (Typ)
         then
            Expr := Make_Integer_Literal (Loc, 2 ** Size_To_Use - 1);

            --  Resolve as Long_Long_Long_Unsigned, because the largest number
            --  we can generate is out of range of universal integer.

            Analyze_And_Resolve (Expr, Standard_Long_Long_Long_Unsigned);

         --  Case of signed types

         else
            --  Normally we like to use the most negative number. The one
            --  exception is when this number is in the known subtype range and
            --  the largest positive number is not in the known subtype range.

            --  For this exceptional case, use largest positive value

            if Present (Lo_Bound) and then Present (Hi_Bound)
              and then Lo_Bound <= (-(2 ** Signed_Size))
              and then Hi_Bound < 2 ** Signed_Size
            then
               Expr := Make_Integer_Literal (Loc, 2 ** Signed_Size - 1);

            --  Normal case of largest negative value

            else
               Expr := Make_Integer_Literal (Loc, -(2 ** Signed_Size));
            end if;
         end if;

         return Expr;
      end Simple_Init_Normalize_Scalars_Type;

      ------------------------------
      -- Simple_Init_Private_Type --
      ------------------------------

      function Simple_Init_Private_Type return Node_Id is
         Under_Typ : constant Entity_Id := Underlying_Type (Typ);
         Expr      : Node_Id;

      begin
         --  The availability of the underlying view must be checked by routine
         --  Needs_Simple_Initialization.

         pragma Assert (Present (Under_Typ));

         Expr := Get_Simple_Init_Val (Under_Typ, N, Size);

         --  If the initial value is null or an aggregate, qualify it with the
         --  underlying type in order to provide a proper context.

         if Nkind (Expr) in N_Aggregate | N_Null then
            Expr :=
              Make_Qualified_Expression (Loc,
                Subtype_Mark => New_Occurrence_Of (Under_Typ, Loc),
                Expression   => Expr);
         end if;

         Expr := Unchecked_Convert_To (Typ, Expr);

         --  Do not truncate the result when scalar types are involved and
         --  Initialize/Normalize_Scalars is in effect.

         if Nkind (Expr) = N_Unchecked_Type_Conversion
           and then Is_Scalar_Type (Under_Typ)
         then
            Set_Kill_Range_Check (Expr);
            Set_No_Truncation    (Expr);
         end if;

         return Expr;
      end Simple_Init_Private_Type;

      -----------------------------
      -- Simple_Init_Scalar_Type --
      -----------------------------

      function Simple_Init_Scalar_Type return Node_Id is
         Expr        : Node_Id;
         Size_To_Use : Uint;

      begin
         pragma Assert (Init_Or_Norm_Scalars or IV_Attribute);

         --  Determine the size of the object. This is either the size provided
         --  by the caller, or the Esize of the scalar type.

         if No (Size) or else Size <= Uint_0 then
            Size_To_Use := UI_Max (Uint_1, Esize (Typ));
         else
            Size_To_Use := Size;
         end if;

         --  The maximum size to use is System_Max_Integer_Size bits. This
         --  will create values of type Long_Long_Long_Unsigned and the range
         --  must fit this type.

         if Present (Size_To_Use)
           and then Size_To_Use > System_Max_Integer_Size
         then
            Size_To_Use := UI_From_Int (System_Max_Integer_Size);
         end if;

         if Normalize_Scalars and then not IV_Attribute then
            Expr := Simple_Init_Normalize_Scalars_Type (Size_To_Use);
         else
            Expr := Simple_Init_Initialize_Scalars_Type (Size_To_Use);
         end if;

         --  The final expression is obtained by doing an unchecked conversion
         --  of this result to the base type of the required subtype. Use the
         --  base type to prevent the unchecked conversion from chopping bits,
         --  and then we set Kill_Range_Check to preserve the "bad" value.

         Expr := Unchecked_Convert_To (Base_Type (Typ), Expr);

         --  Ensure that the expression is not truncated since the "bad" bits
         --  are desired, and also kill the range checks.

         if Nkind (Expr) = N_Unchecked_Type_Conversion then
            Set_Kill_Range_Check (Expr);
            Set_No_Truncation    (Expr);
         end if;

         return Expr;
      end Simple_Init_Scalar_Type;

   --  Start of processing for Get_Simple_Init_Val

   begin
      if Is_Private_Type (Typ) then
         return Simple_Init_Private_Type;

      elsif Is_Scalar_Type (Typ) then
         if Has_Default_Aspect (Typ) then
            return Simple_Init_Defaulted_Type;
         else
            return Simple_Init_Scalar_Type;
         end if;

      --  Array type with Initialize or Normalize_Scalars

      elsif Is_Array_Type (Typ) then
         pragma Assert (Init_Or_Norm_Scalars);
         return Simple_Init_Array_Type;

      --  Access type is initialized to null

      elsif Is_Access_Type (Typ) then
         return Make_Null (Loc);

      --  No other possibilities should arise, since we should only be calling
      --  Get_Simple_Init_Val if Needs_Simple_Initialization returned True,
      --  indicating one of the above cases held.

      else
         raise Program_Error;
      end if;

   exception
      when RE_Not_Available =>
         return Empty;
   end Get_Simple_Init_Val;

   ------------------------------
   -- Has_New_Non_Standard_Rep --
   ------------------------------

   function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean is
   begin
      if not Is_Derived_Type (T) then
         return Has_Non_Standard_Rep (T)
           or else Has_Non_Standard_Rep (Root_Type (T));

      --  If Has_Non_Standard_Rep is not set on the derived type, the
      --  representation is fully inherited.

      elsif not Has_Non_Standard_Rep (T) then
         return False;

      else
         return First_Rep_Item (T) /= First_Rep_Item (Root_Type (T));

         --  May need a more precise check here: the First_Rep_Item may be a
         --  stream attribute, which does not affect the representation of the
         --  type ???

      end if;
   end Has_New_Non_Standard_Rep;

   ----------------------
   -- Inline_Init_Proc --
   ----------------------

   function Inline_Init_Proc (Typ : Entity_Id) return Boolean is
   begin
      --  The initialization proc of protected records is not worth inlining.
      --  In addition, when compiled for another unit for inlining purposes,
      --  it may make reference to entities that have not been elaborated yet.
      --  The initialization proc of records that need finalization contains
      --  a nested clean-up procedure that makes it impractical to inline as
      --  well, except for simple controlled types themselves. And similar
      --  considerations apply to task types.

      if Is_Concurrent_Type (Typ) then
         return False;

      elsif Needs_Finalization (Typ) and then not Is_Controlled (Typ) then
         return False;

      elsif Has_Task (Typ) then
         return False;

      else
         return True;
      end if;
   end Inline_Init_Proc;

   ----------------
   -- In_Runtime --
   ----------------

   function In_Runtime (E : Entity_Id) return Boolean is
      S1 : Entity_Id;

   begin
      S1 := Scope (E);
      while Scope (S1) /= Standard_Standard loop
         S1 := Scope (S1);
      end loop;

      return Is_RTU (S1, System) or else Is_RTU (S1, Ada);
   end In_Runtime;

   package body Initialization_Control is

      ------------------------
      -- Requires_Late_Init --
      ------------------------

      function Requires_Late_Init
        (Decl     : Node_Id;
         Rec_Type : Entity_Id) return Boolean
      is
         function Is_Access_Discriminant
           (N : Node_Id) return Traverse_Result;
         --  Look for a name denoting an access discriminant

         function Is_Current_Instance
           (N : Node_Id) return Traverse_Result;
         --  Look for a reference to the current instance of the type

         function Is_Internal_Call
           (N : Node_Id) return Traverse_Result;
         --  Look for an internal protected function call

         ----------------------------
         -- Is_Access_Discriminant --
         ----------------------------

         function Is_Access_Discriminant
           (N : Node_Id) return Traverse_Result is
         begin
            if Is_Entity_Name (N)
              and then Denotes_Discriminant (N)
              and then Is_Access_Type (Etype (N))
            then
               return Abandon;
            else
               return OK;
            end if;
         end Is_Access_Discriminant;

         -------------------------
         -- Is_Current_Instance --
         -------------------------

         function Is_Current_Instance
           (N : Node_Id) return Traverse_Result is
         begin
            if Is_Entity_Name (N)
              and then Present (Entity (N))
              and then Is_Current_Instance (N)
            then
               return Abandon;
            else
               return OK;
            end if;
         end Is_Current_Instance;

         ----------------------
         -- Is_Internal_Call --
         ----------------------

         function Is_Internal_Call (N : Node_Id) return Traverse_Result is

            function Call_Scope (N : Node_Id) return Entity_Id;
            --  Return the scope enclosing a given call node N

            ----------------
            -- Call_Scope --
            ----------------

            function Call_Scope (N : Node_Id) return Entity_Id is
               Nam : constant Node_Id := Name (N);
            begin
               if Nkind (Nam) = N_Selected_Component then
                  return Scope (Entity (Prefix (Nam)));
               else
                  return Scope (Entity (Nam));
               end if;
            end Call_Scope;

         begin
            if Nkind (N) = N_Function_Call
              and then Call_Scope (N)
                         = Corresponding_Concurrent_Type (Rec_Type)
            then
               return Abandon;
            else
               return OK;
            end if;
         end Is_Internal_Call;

         function Search_Access_Discriminant is new
           Traverse_Func (Is_Access_Discriminant);

         function Search_Current_Instance is new
           Traverse_Func (Is_Current_Instance);

         function Search_Internal_Call is new
           Traverse_Func (Is_Internal_Call);

         --  Start of processing for Requires_Late_Init

      begin
         --  A component of an object is said to require late initialization
         --  if:

         --  it has an access discriminant value constrained by a per-object
         --  expression;

         if Has_Access_Constraint (Defining_Identifier (Decl))
           and then No (Expression (Decl))
         then
            return True;

         elsif Present (Expression (Decl)) then

            --  it has an initialization expression that includes a name
            --  denoting an access discriminant;

            if Search_Access_Discriminant (Expression (Decl)) = Abandon then
               return True;
            end if;

            --  or it has an initialization expression that includes a
            --  reference to the current instance of the type either by
            --  name...

            if Search_Current_Instance (Expression (Decl)) = Abandon then
               return True;
            end if;

            --  ...or implicitly as the target object of a call.

            if Is_Protected_Record_Type (Rec_Type) then
               if Search_Internal_Call (Expression (Decl)) = Abandon then
                  return True;
               end if;
            end if;
         end if;

         return False;
      end Requires_Late_Init;

      -----------------------------
      -- Has_Late_Init_Component --
      -----------------------------

      function Has_Late_Init_Component
        (Tagged_Rec_Type : Entity_Id) return Boolean
      is
         Comp_Id : Entity_Id :=
           First_Component (Implementation_Base_Type (Tagged_Rec_Type));
      begin
         while Present (Comp_Id) loop
            if Requires_Late_Init (Decl     => Parent (Comp_Id),
                                   Rec_Type => Tagged_Rec_Type)
            then
               return True; -- found a component that requires late init

            elsif Chars (Comp_Id) = Name_uParent
              and then Has_Late_Init_Component (Etype (Comp_Id))
            then
               return True; -- an ancestor type has a late init component
            end if;

            Next_Component (Comp_Id);
         end loop;

         return False;
      end Has_Late_Init_Component;

      ------------------------
      -- Tag_Init_Condition --
      ------------------------

      function Tag_Init_Condition
        (Loc : Source_Ptr;
         Init_Control_Formal : Entity_Id) return Node_Id is
      begin
         return Make_Op_Eq (Loc,
                  New_Occurrence_Of (Init_Control_Formal, Loc),
                  Make_Mode_Literal (Loc, Full_Init));
      end Tag_Init_Condition;

      --------------------------
      -- Early_Init_Condition --
      --------------------------

      function Early_Init_Condition
        (Loc : Source_Ptr;
         Init_Control_Formal : Entity_Id) return Node_Id is
      begin
         return Make_Op_Ne (Loc,
                  New_Occurrence_Of (Init_Control_Formal, Loc),
                  Make_Mode_Literal (Loc, Late_Init_Only));
      end Early_Init_Condition;

      -------------------------
      -- Late_Init_Condition --
      -------------------------

      function Late_Init_Condition
        (Loc : Source_Ptr;
         Init_Control_Formal : Entity_Id) return Node_Id is
      begin
         return Make_Op_Ne (Loc,
                  New_Occurrence_Of (Init_Control_Formal, Loc),
                  Make_Mode_Literal (Loc, Early_Init_Only));
      end Late_Init_Condition;

   end Initialization_Control;

   ----------------------------
   -- Initialization_Warning --
   ----------------------------

   procedure Initialization_Warning (E : Entity_Id) is
      Warning_Needed : Boolean;

   begin
      Warning_Needed := False;

      if Ekind (Current_Scope) = E_Package
        and then Static_Elaboration_Desired (Current_Scope)
      then
         if Is_Type (E) then
            if Is_Record_Type (E) then
               if Has_Discriminants (E)
                 or else Is_Limited_Type (E)
                 or else Has_Non_Standard_Rep (E)
               then
                  Warning_Needed := True;

               else
                  --  Verify that at least one component has an initialization
                  --  expression. No need for a warning on a type if all its
                  --  components have no initialization.

                  declare
                     Comp : Entity_Id;

                  begin
                     Comp := First_Component (E);
                     while Present (Comp) loop
                        pragma Assert
                          (Nkind (Parent (Comp)) = N_Component_Declaration);

                        if Present (Expression (Parent (Comp))) then
                           Warning_Needed := True;
                           exit;
                        end if;

                        Next_Component (Comp);
                     end loop;
                  end;
               end if;

               if Warning_Needed then
                  Error_Msg_N
                    ("objects of the type cannot be initialized statically "
                     & "by default??", Parent (E));
               end if;
            end if;

         else
            Error_Msg_N ("object cannot be initialized statically??", E);
         end if;
      end if;
   end Initialization_Warning;

   ------------------
   -- Init_Formals --
   ------------------

   function Init_Formals (Typ : Entity_Id; Proc_Id : Entity_Id) return List_Id
   is
      Loc        : constant Source_Ptr := Sloc (Typ);
      Unc_Arr    : constant Boolean :=
                     Is_Array_Type (Typ) and then not Is_Constrained (Typ);
      With_Prot  : constant Boolean :=
                     Has_Protected (Typ)
                       or else (Is_Record_Type (Typ)
                                 and then Is_Protected_Record_Type (Typ));
      With_Task  : constant Boolean :=
                     Has_Task (Typ)
                       or else (Is_Record_Type (Typ)
                                 and then Is_Task_Record_Type (Typ));
      Formals : List_Id;

   begin
      --  The first parameter is always _Init : [in] out Typ. Note that we need
      --  it to be in/out in the case of an unconstrained array, because of the
      --  need to have the bounds, and in the case of protected or task record
      --  value, because there are default record fields that may be referenced
      --  in the generated initialization routine.

      Formals := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uInit),
          In_Present          => Unc_Arr or else With_Prot or else With_Task,
          Out_Present         => True,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));

      --  For task record value, or type that contains tasks, add two more
      --  formals, _Master : Master_Id and _Chain : in out Activation_Chain
      --  We also add these parameters for the task record type case.

      if With_Task then
         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier =>
               Make_Defining_Identifier (Loc, Name_uMaster),
             Parameter_Type      =>
               New_Occurrence_Of (Standard_Integer, Loc)));

         Set_Has_Master_Entity (Proc_Id);

         --  Add _Chain (not done for sequential elaboration policy, see
         --  comment for Create_Restricted_Task_Sequential in s-tarest.ads).

         if Partition_Elaboration_Policy /= 'S' then
            Append_To (Formals,
              Make_Parameter_Specification (Loc,
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uChain),
                In_Present          => True,
                Out_Present         => True,
                Parameter_Type      =>
                  New_Occurrence_Of (RTE (RE_Activation_Chain), Loc)));
         end if;

         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier =>
               Make_Defining_Identifier (Loc, Name_uTask_Name),
             In_Present          => True,
             Parameter_Type      => New_Occurrence_Of (Standard_String, Loc)));
      end if;

      --  Due to certain edge cases such as arrays with null-excluding
      --  components being built with the secondary stack it becomes necessary
      --  to add a formal to the Init_Proc which controls whether we raise
      --  Constraint_Errors on generated calls for internal object
      --  declarations.

      if Needs_Conditional_Null_Excluding_Check (Typ) then
         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier =>
               Make_Defining_Identifier (Loc,
                 New_External_Name (Chars
                   (Component_Type (Typ)), "_skip_null_excluding_check")),
             Expression          => New_Occurrence_Of (Standard_False, Loc),
             In_Present          => True,
             Parameter_Type      =>
               New_Occurrence_Of (Standard_Boolean, Loc)));
      end if;

      return Formals;

   exception
      when RE_Not_Available =>
         return Empty_List;
   end Init_Formals;

   -------------------------
   -- Init_Secondary_Tags --
   -------------------------

   procedure Init_Secondary_Tags
     (Typ            : Entity_Id;
      Target         : Node_Id;
      Init_Tags_List : List_Id;
      Stmts_List     : List_Id;
      Fixed_Comps    : Boolean := True;
      Variable_Comps : Boolean := True)
   is
      Loc : constant Source_Ptr := Sloc (Target);

      --  Inherit the C++ tag of the secondary dispatch table of Typ associated
      --  with Iface. Tag_Comp is the component of Typ that stores Iface_Tag.

      procedure Initialize_Tag
        (Typ       : Entity_Id;
         Iface     : Entity_Id;
         Tag_Comp  : Entity_Id;
         Iface_Tag : Node_Id);
      --  Initialize the tag of the secondary dispatch table of Typ associated
      --  with Iface. Tag_Comp is the component of Typ that stores Iface_Tag.
      --  Compiling under the CPP full ABI compatibility mode, if the ancestor
      --  of Typ CPP tagged type we generate code to inherit the contents of
      --  the dispatch table directly from the ancestor.

      --------------------
      -- Initialize_Tag --
      --------------------

      procedure Initialize_Tag
        (Typ       : Entity_Id;
         Iface     : Entity_Id;
         Tag_Comp  : Entity_Id;
         Iface_Tag : Node_Id)
      is
         Comp_Typ           : Entity_Id;
         Offset_To_Top_Comp : Entity_Id := Empty;

      begin
         --  Initialize pointer to secondary DT associated with the interface

         if not Is_Ancestor (Iface, Typ, Use_Full_View => True) then
            Append_To (Init_Tags_List,
              Make_Assignment_Statement (Loc,
                Name       =>
                  Make_Selected_Component (Loc,
                    Prefix        => New_Copy_Tree (Target),
                    Selector_Name => New_Occurrence_Of (Tag_Comp, Loc)),
                Expression =>
                  New_Occurrence_Of (Iface_Tag, Loc)));
         end if;

         Comp_Typ := Scope (Tag_Comp);

         --  Initialize the entries of the table of interfaces. We generate a
         --  different call when the parent of the type has variable size
         --  components.

         if Comp_Typ /= Etype (Comp_Typ)
           and then Is_Variable_Size_Record (Etype (Comp_Typ))
           and then Chars (Tag_Comp) /= Name_uTag
         then
            pragma Assert (Present (DT_Offset_To_Top_Func (Tag_Comp)));

            --  Issue error if Set_Dynamic_Offset_To_Top is not available in a
            --  configurable run-time environment.

            if not RTE_Available (RE_Set_Dynamic_Offset_To_Top) then
               Error_Msg_CRT
                 ("variable size record with interface types", Typ);
               return;
            end if;

            --  Generate:
            --    Set_Dynamic_Offset_To_Top
            --      (This         => Init,
            --       Prim_T       => Typ'Tag,
            --       Interface_T  => Iface'Tag,
            --       Offset_Value => n,
            --       Offset_Func  => Fn'Unrestricted_Access)

            Append_To (Stmts_List,
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (RTE (RE_Set_Dynamic_Offset_To_Top), Loc),
                Parameter_Associations => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Copy_Tree (Target),
                    Attribute_Name => Name_Address),

                  Unchecked_Convert_To (RTE (RE_Tag),
                    New_Occurrence_Of
                      (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)),

                  Unchecked_Convert_To (RTE (RE_Tag),
                    New_Occurrence_Of
                      (Node (First_Elmt (Access_Disp_Table (Iface))),
                       Loc)),

                  Unchecked_Convert_To
                    (RTE (RE_Storage_Offset),
                     Make_Op_Minus (Loc,
                       Make_Attribute_Reference (Loc,
                         Prefix         =>
                           Make_Selected_Component (Loc,
                             Prefix        => New_Copy_Tree (Target),
                             Selector_Name =>
                               New_Occurrence_Of (Tag_Comp, Loc)),
                         Attribute_Name => Name_Position))),

                  Unchecked_Convert_To (RTE (RE_Offset_To_Top_Function_Ptr),
                    Make_Attribute_Reference (Loc,
                      Prefix => New_Occurrence_Of
                                  (DT_Offset_To_Top_Func (Tag_Comp), Loc),
                      Attribute_Name => Name_Unrestricted_Access)))));

            --  In this case the next component stores the value of the offset
            --  to the top.

            Offset_To_Top_Comp := Next_Entity (Tag_Comp);
            pragma Assert (Present (Offset_To_Top_Comp));

            Append_To (Init_Tags_List,
              Make_Assignment_Statement (Loc,
                Name       =>
                  Make_Selected_Component (Loc,
                    Prefix        => New_Copy_Tree (Target),
                    Selector_Name =>
                      New_Occurrence_Of (Offset_To_Top_Comp, Loc)),

                Expression =>
                  Make_Op_Minus (Loc,
                    Make_Attribute_Reference (Loc,
                      Prefix       =>
                        Make_Selected_Component (Loc,
                          Prefix        => New_Copy_Tree (Target),
                          Selector_Name => New_Occurrence_Of (Tag_Comp, Loc)),
                    Attribute_Name => Name_Position))));

         --  Normal case: No discriminants in the parent type

         else
            --  Don't need to set any value if the offset-to-top field is
            --  statically set or if this interface shares the primary
            --  dispatch table.

            if not Building_Static_Secondary_DT (Typ)
              and then not Is_Ancestor (Iface, Typ, Use_Full_View => True)
            then
               Append_To (Stmts_List,
                 Build_Set_Static_Offset_To_Top (Loc,
                   Iface_Tag    => New_Occurrence_Of (Iface_Tag, Loc),
                   Offset_Value =>
                     Unchecked_Convert_To (RTE (RE_Storage_Offset),
                       Make_Op_Minus (Loc,
                         Make_Attribute_Reference (Loc,
                           Prefix         =>
                             Make_Selected_Component (Loc,
                               Prefix        => New_Copy_Tree (Target),
                               Selector_Name =>
                                 New_Occurrence_Of (Tag_Comp, Loc)),
                           Attribute_Name => Name_Position)))));
            end if;

            --  Generate:
            --    Register_Interface_Offset
            --      (Prim_T       => Typ'Tag,
            --       Interface_T  => Iface'Tag,
            --       Is_Constant  => True,
            --       Offset_Value => n,
            --       Offset_Func  => null);

            if not Building_Static_Secondary_DT (Typ)
              and then RTE_Available (RE_Register_Interface_Offset)
            then
               Append_To (Stmts_List,
                 Make_Procedure_Call_Statement (Loc,
                   Name                   =>
                     New_Occurrence_Of
                       (RTE (RE_Register_Interface_Offset), Loc),
                   Parameter_Associations => New_List (
                     Unchecked_Convert_To (RTE (RE_Tag),
                       New_Occurrence_Of
                         (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)),

                     Unchecked_Convert_To (RTE (RE_Tag),
                       New_Occurrence_Of
                         (Node (First_Elmt (Access_Disp_Table (Iface))), Loc)),

                     New_Occurrence_Of (Standard_True, Loc),

                     Unchecked_Convert_To (RTE (RE_Storage_Offset),
                       Make_Op_Minus (Loc,
                         Make_Attribute_Reference (Loc,
                           Prefix         =>
                             Make_Selected_Component (Loc,
                               Prefix         => New_Copy_Tree (Target),
                               Selector_Name  =>
                                 New_Occurrence_Of (Tag_Comp, Loc)),
                           Attribute_Name => Name_Position))),

                     Make_Null (Loc))));
            end if;
         end if;
      end Initialize_Tag;

      --  Local variables

      Full_Typ         : Entity_Id;
      Ifaces_List      : Elist_Id;
      Ifaces_Comp_List : Elist_Id;
      Ifaces_Tag_List  : Elist_Id;
      Iface_Elmt       : Elmt_Id;
      Iface_Comp_Elmt  : Elmt_Id;
      Iface_Tag_Elmt   : Elmt_Id;
      Tag_Comp         : Node_Id;
      In_Variable_Pos  : Boolean;

   --  Start of processing for Init_Secondary_Tags

   begin
      --  Handle private types

      if Present (Full_View (Typ)) then
         Full_Typ := Full_View (Typ);
      else
         Full_Typ := Typ;
      end if;

      Collect_Interfaces_Info
        (Full_Typ, Ifaces_List, Ifaces_Comp_List, Ifaces_Tag_List);

      Iface_Elmt      := First_Elmt (Ifaces_List);
      Iface_Comp_Elmt := First_Elmt (Ifaces_Comp_List);
      Iface_Tag_Elmt  := First_Elmt (Ifaces_Tag_List);
      while Present (Iface_Elmt) loop
         Tag_Comp := Node (Iface_Comp_Elmt);

         --  Check if parent of record type has variable size components

         In_Variable_Pos := Scope (Tag_Comp) /= Etype (Scope (Tag_Comp))
           and then Is_Variable_Size_Record (Etype (Scope (Tag_Comp)));

         --  If we are compiling under the CPP full ABI compatibility mode and
         --  the ancestor is a CPP_Pragma tagged type then we generate code to
         --  initialize the secondary tag components from tags that reference
         --  secondary tables filled with copy of parent slots.

         if Is_CPP_Class (Root_Type (Full_Typ)) then

            --  Reject interface components located at variable offset in
            --  C++ derivations. This is currently unsupported.

            if not Fixed_Comps and then In_Variable_Pos then

               --  Locate the first dynamic component of the record. Done to
               --  improve the text of the warning.

               declare
                  Comp     : Entity_Id;
                  Comp_Typ : Entity_Id;

               begin
                  Comp := First_Entity (Typ);
                  while Present (Comp) loop
                     Comp_Typ := Etype (Comp);

                     if Ekind (Comp) /= E_Discriminant
                       and then not Is_Tag (Comp)
                     then
                        exit when
                          (Is_Record_Type (Comp_Typ)
                            and then
                              Is_Variable_Size_Record (Base_Type (Comp_Typ)))
                         or else
                           (Is_Array_Type (Comp_Typ)
                             and then Is_Variable_Size_Array (Comp_Typ));
                     end if;

                     Next_Entity (Comp);
                  end loop;

                  pragma Assert (Present (Comp));

                  --  Move this check to sem???
                  Error_Msg_Node_2 := Comp;
                  Error_Msg_NE
                    ("parent type & with dynamic component & cannot be parent"
                     & " of 'C'P'P derivation if new interfaces are present",
                     Typ, Scope (Original_Record_Component (Comp)));

                  Error_Msg_Sloc :=
                    Sloc (Scope (Original_Record_Component (Comp)));
                  Error_Msg_NE
                    ("type derived from 'C'P'P type & defined #",
                     Typ, Scope (Original_Record_Component (Comp)));

                  --  Avoid duplicated warnings

                  exit;
               end;

            --  Initialize secondary tags

            else
               Initialize_Tag
                 (Typ       => Full_Typ,
                  Iface     => Node (Iface_Elmt),
                  Tag_Comp  => Tag_Comp,
                  Iface_Tag => Node (Iface_Tag_Elmt));
            end if;

         --  Otherwise generate code to initialize the tag

         else
            if (In_Variable_Pos and then Variable_Comps)
              or else (not In_Variable_Pos and then Fixed_Comps)
            then
               Initialize_Tag
                 (Typ       => Full_Typ,
                  Iface     => Node (Iface_Elmt),
                  Tag_Comp  => Tag_Comp,
                  Iface_Tag => Node (Iface_Tag_Elmt));
            end if;
         end if;

         Next_Elmt (Iface_Elmt);
         Next_Elmt (Iface_Comp_Elmt);
         Next_Elmt (Iface_Tag_Elmt);
      end loop;
   end Init_Secondary_Tags;

   ----------------------------
   -- Is_Null_Statement_List --
   ----------------------------

   function Is_Null_Statement_List (Stmts : List_Id) return Boolean is
      Stmt : Node_Id;

   begin
      --  We must skip SCIL nodes because they may have been added to the list
      --  by Insert_Actions.

      Stmt := First_Non_SCIL_Node (Stmts);
      while Present (Stmt) loop
         if Nkind (Stmt) = N_Case_Statement then
            declare
               Alt : Node_Id;
            begin
               Alt := First (Alternatives (Stmt));
               while Present (Alt) loop
                  if not Is_Null_Statement_List (Statements (Alt)) then
                     return False;
                  end if;

                  Next (Alt);
               end loop;
            end;

         elsif Nkind (Stmt) /= N_Null_Statement then
            return False;
         end if;

         Stmt := Next_Non_SCIL_Node (Stmt);
      end loop;

      return True;
   end Is_Null_Statement_List;

   ----------------------------------------
   -- Make_Controlling_Function_Wrappers --
   ----------------------------------------

   procedure Make_Controlling_Function_Wrappers
     (Tag_Typ   : Entity_Id;
      Decl_List : out List_Id;
      Body_List : out List_Id)
   is
      Loc : constant Source_Ptr := Sloc (Tag_Typ);

      function Make_Wrapper_Specification (Subp : Entity_Id) return Node_Id;
      --  Returns a function specification with the same profile as Subp

      --------------------------------
      -- Make_Wrapper_Specification --
      --------------------------------

      function Make_Wrapper_Specification (Subp : Entity_Id) return Node_Id is
      begin
         return
           Make_Function_Specification (Loc,
             Defining_Unit_Name       =>
               Make_Defining_Identifier (Loc,
                 Chars => Chars (Subp)),
             Parameter_Specifications =>
               Copy_Parameter_List (Subp),
             Result_Definition        =>
               New_Occurrence_Of (Etype (Subp), Loc));
      end Make_Wrapper_Specification;

      Prim_Elmt   : Elmt_Id;
      Subp        : Entity_Id;
      Actual_List : List_Id;
      Formal      : Entity_Id;
      Par_Formal  : Entity_Id;
      Ext_Aggr    : Node_Id;
      Formal_Node : Node_Id;
      Func_Body   : Node_Id;
      Func_Decl   : Node_Id;
      Func_Id     : Entity_Id;

   --  Start of processing for Make_Controlling_Function_Wrappers

   begin
      Decl_List := New_List;
      Body_List := New_List;

      Prim_Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
      while Present (Prim_Elmt) loop
         Subp := Node (Prim_Elmt);

         --  If a primitive function with a controlling result of the type has
         --  not been overridden by the user, then we must create a wrapper
         --  function here that effectively overrides it and invokes the
         --  (non-abstract) parent function. This can only occur for a null
         --  extension. Note that functions with anonymous controlling access
         --  results don't qualify and must be overridden. We also exclude
         --  Input attributes, since each type will have its own version of
         --  Input constructed by the expander. The test for Comes_From_Source
         --  is needed to distinguish inherited operations from renamings
         --  (which also have Alias set). We exclude internal entities with
         --  Interface_Alias to avoid generating duplicated wrappers since
         --  the primitive which covers the interface is also available in
         --  the list of primitive operations.

         --  The function may be abstract, or require_Overriding may be set
         --  for it, because tests for null extensions may already have reset
         --  the Is_Abstract_Subprogram_Flag. If Requires_Overriding is not
         --  set, functions that need wrappers are recognized by having an
         --  alias that returns the parent type.

         if Comes_From_Source (Subp)
           or else No (Alias (Subp))
           or else Present (Interface_Alias (Subp))
           or else Ekind (Subp) /= E_Function
           or else not Has_Controlling_Result (Subp)
           or else Is_Access_Type (Etype (Subp))
           or else Is_Abstract_Subprogram (Alias (Subp))
           or else Is_TSS (Subp, TSS_Stream_Input)
         then
            goto Next_Prim;

         elsif Is_Abstract_Subprogram (Subp)
           or else Requires_Overriding (Subp)
           or else
             (Is_Null_Extension (Etype (Subp))
               and then Etype (Alias (Subp)) /= Etype (Subp))
         then
            --  If there is a non-overloadable homonym in the current
            --  scope, the implicit declaration remains invisible.
            --  We check the current entity with the same name, or its
            --  homonym in case the derivation takes place after the
            --  hiding object declaration.

            if Present (Current_Entity (Subp)) then
               declare
                  Curr : constant Entity_Id := Current_Entity (Subp);
                  Prev : constant Entity_Id := Homonym (Curr);
               begin
                  if (Comes_From_Source (Curr)
                    and then Scope (Curr) = Current_Scope
                    and then not Is_Overloadable (Curr))
                  or else
                    (Present (Prev)
                      and then Comes_From_Source (Prev)
                      and then Scope (Prev) = Current_Scope
                      and then not Is_Overloadable (Prev))
                  then
                     goto Next_Prim;
                  end if;
               end;
            end if;

            Func_Decl :=
              Make_Subprogram_Declaration (Loc,
                Specification => Make_Wrapper_Specification (Subp));

            Append_To (Decl_List, Func_Decl);

            --  Build a wrapper body that calls the parent function. The body
            --  contains a single return statement that returns an extension
            --  aggregate whose ancestor part is a call to the parent function,
            --  passing the formals as actuals (with any controlling arguments
            --  converted to the types of the corresponding formals of the
            --  parent function, which might be anonymous access types), and
            --  having a null extension.

            Formal      := First_Formal (Subp);
            Par_Formal  := First_Formal (Alias (Subp));
            Formal_Node :=
              First (Parameter_Specifications (Specification (Func_Decl)));

            if Present (Formal) then
               Actual_List := New_List;

               while Present (Formal) loop
                  if Is_Controlling_Formal (Formal) then
                     Append_To (Actual_List,
                       Make_Type_Conversion (Loc,
                         Subtype_Mark =>
                           New_Occurrence_Of (Etype (Par_Formal), Loc),
                         Expression   =>
                           New_Occurrence_Of
                             (Defining_Identifier (Formal_Node), Loc)));
                  else
                     Append_To
                       (Actual_List,
                        New_Occurrence_Of
                          (Defining_Identifier (Formal_Node), Loc));
                  end if;

                  Next_Formal (Formal);
                  Next_Formal (Par_Formal);
                  Next (Formal_Node);
               end loop;
            else
               Actual_List := No_List;
            end if;

            Ext_Aggr :=
              Make_Extension_Aggregate (Loc,
                Ancestor_Part       =>
                  Make_Function_Call (Loc,
                    Name                   =>
                      New_Occurrence_Of (Alias (Subp), Loc),
                    Parameter_Associations => Actual_List),
                Null_Record_Present => True);

            --  GNATprove will use expression of an expression function as an
            --  implicit postcondition. GNAT will also benefit from expression
            --  function to avoid premature freezing, but would struggle if we
            --  added an expression function to freezing actions, so we create
            --  the expanded form directly.

            if GNATprove_Mode then
               Func_Body :=
                 Make_Expression_Function (Loc,
                   Specification =>
                     Make_Wrapper_Specification (Subp),
                   Expression => Ext_Aggr);
            else
               Func_Body :=
                 Make_Subprogram_Body (Loc,
                   Specification              =>
                     Make_Wrapper_Specification (Subp),
                   Declarations               => Empty_List,
                   Handled_Statement_Sequence =>
                     Make_Handled_Sequence_Of_Statements (Loc,
                       Statements => New_List (
                         Make_Simple_Return_Statement (Loc,
                           Expression => Ext_Aggr))));
               Set_Was_Expression_Function (Func_Body);
            end if;

            Append_To (Body_List, Func_Body);

            --  Replace the inherited function with the wrapper function in the
            --  primitive operations list. We add the minimum decoration needed
            --  to override interface primitives.

            Func_Id := Defining_Unit_Name (Specification (Func_Decl));

            Mutate_Ekind (Func_Id, E_Function);
            Set_Is_Wrapper (Func_Id);

            --  Corresponding_Spec will be set again to the same value during
            --  analysis, but we need this information earlier.
            --  Expand_N_Freeze_Entity needs to know whether a subprogram body
            --  is a wrapper's body in order to get check suppression right.

            Set_Corresponding_Spec (Func_Body, Func_Id);
         end if;

      <<Next_Prim>>
         Next_Elmt (Prim_Elmt);
      end loop;
   end Make_Controlling_Function_Wrappers;

   ------------------
   -- Make_Eq_Body --
   ------------------

   function Make_Eq_Body
     (Typ     : Entity_Id;
      Eq_Name : Name_Id) return Node_Id
   is
      Loc          : constant Source_Ptr := Sloc (Parent (Typ));
      Decl         : Node_Id;
      Def          : constant Node_Id := Parent (Typ);
      Stmts        : constant List_Id := New_List;
      Variant_Case : Boolean := Has_Discriminants (Typ);
      Comps        : Node_Id := Empty;
      Typ_Def      : Node_Id := Type_Definition (Def);

   begin
      Decl :=
        Predef_Spec_Or_Body (Loc,
          Tag_Typ  => Typ,
          Name     => Eq_Name,
          Profile  => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Name_X),
              Parameter_Type      => New_Occurrence_Of (Typ, Loc)),

            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Name_Y),
              Parameter_Type      => New_Occurrence_Of (Typ, Loc))),

          Ret_Type => Standard_Boolean,
          For_Body => True);

      if Variant_Case then
         if Nkind (Typ_Def) = N_Derived_Type_Definition then
            Typ_Def := Record_Extension_Part (Typ_Def);
         end if;

         if Present (Typ_Def) then
            Comps := Component_List (Typ_Def);
         end if;

         Variant_Case :=
           Present (Comps) and then Present (Variant_Part (Comps));
      end if;

      if Variant_Case then
         Append_To (Stmts,
           Make_Eq_If (Typ, Discriminant_Specifications (Def)));
         Append_List_To (Stmts, Make_Eq_Case (Typ, Comps));
         Append_To (Stmts,
           Make_Simple_Return_Statement (Loc,
             Expression => New_Occurrence_Of (Standard_True, Loc)));

      else
         Append_To (Stmts,
           Make_Simple_Return_Statement (Loc,
             Expression =>
               Expand_Record_Equality
                 (Typ,
                  Typ => Typ,
                  Lhs => Make_Identifier (Loc, Name_X),
                  Rhs => Make_Identifier (Loc, Name_Y))));
      end if;

      Set_Handled_Statement_Sequence
        (Decl, Make_Handled_Sequence_Of_Statements (Loc, Stmts));
      return Decl;
   end Make_Eq_Body;

   ------------------
   -- Make_Eq_Case --
   ------------------

   --  <Make_Eq_If shared components>

   --  case X.D1 is
   --     when V1 => <Make_Eq_Case> on subcomponents
   --     ...
   --     when Vn => <Make_Eq_Case> on subcomponents
   --  end case;

   function Make_Eq_Case
     (E      : Entity_Id;
      CL     : Node_Id;
      Discrs : Elist_Id := New_Elmt_List) return List_Id
   is
      Loc      : constant Source_Ptr := Sloc (E);
      Result   : constant List_Id    := New_List;
      Variant  : Node_Id;
      Alt_List : List_Id;

      function Corresponding_Formal (C : Node_Id) return Entity_Id;
      --  Given the discriminant that controls a given variant of an unchecked
      --  union, find the formal of the equality function that carries the
      --  inferred value of the discriminant.

      function External_Name (E : Entity_Id) return Name_Id;
      --  The value of a given discriminant is conveyed in the corresponding
      --  formal parameter of the equality routine. The name of this formal
      --  parameter carries a one-character suffix which is removed here.

      --------------------------
      -- Corresponding_Formal --
      --------------------------

      function Corresponding_Formal (C : Node_Id) return Entity_Id is
         Discr : constant Entity_Id := Entity (Name (Variant_Part (C)));
         Elm   : Elmt_Id;

      begin
         Elm := First_Elmt (Discrs);
         while Present (Elm) loop
            if Chars (Discr) = External_Name (Node (Elm)) then
               return Node (Elm);
            end if;

            Next_Elmt (Elm);
         end loop;

         --  A formal of the proper name must be found

         raise Program_Error;
      end Corresponding_Formal;

      -------------------
      -- External_Name --
      -------------------

      function External_Name (E : Entity_Id) return Name_Id is
      begin
         Get_Name_String (Chars (E));
         Name_Len := Name_Len - 1;
         return Name_Find;
      end External_Name;

   --  Start of processing for Make_Eq_Case

   begin
      Append_To (Result, Make_Eq_If (E, Component_Items (CL)));

      if No (Variant_Part (CL)) then
         return Result;
      end if;

      Variant := First_Non_Pragma (Variants (Variant_Part (CL)));

      if No (Variant) then
         return Result;
      end if;

      Alt_List := New_List;
      while Present (Variant) loop
         Append_To (Alt_List,
           Make_Case_Statement_Alternative (Loc,
             Discrete_Choices => New_Copy_List (Discrete_Choices (Variant)),
             Statements =>
               Make_Eq_Case (E, Component_List (Variant), Discrs)));
         Next_Non_Pragma (Variant);
      end loop;

      --  If we have an Unchecked_Union, use one of the parameters of the
      --  enclosing equality routine that captures the discriminant, to use
      --  as the expression in the generated case statement.

      if Is_Unchecked_Union (E) then
         Append_To (Result,
           Make_Case_Statement (Loc,
             Expression =>
               New_Occurrence_Of (Corresponding_Formal (CL), Loc),
             Alternatives => Alt_List));

      else
         Append_To (Result,
           Make_Case_Statement (Loc,
             Expression =>
               Make_Selected_Component (Loc,
                 Prefix        => Make_Identifier (Loc, Name_X),
                 Selector_Name => New_Copy (Name (Variant_Part (CL)))),
             Alternatives => Alt_List));
      end if;

      return Result;
   end Make_Eq_Case;

   ----------------
   -- Make_Eq_If --
   ----------------

   --  Generates:

   --    if
   --      X.C1 /= Y.C1
   --        or else
   --      X.C2 /= Y.C2
   --        ...
   --    then
   --       return False;
   --    end if;

   --  or a null statement if the list L is empty

   --  Equality may be user-defined for a given component type, in which case
   --  a function call is constructed instead of an operator node. This is an
   --  Ada 2012 change in the composability of equality for untagged composite
   --  types.

   function Make_Eq_If
     (E : Entity_Id;
      L : List_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (E);

      C          : Node_Id;
      Cond       : Node_Id;
      Field_Name : Name_Id;
      Next_Test  : Node_Id;
      Typ        : Entity_Id;

   begin
      if No (L) then
         return Make_Null_Statement (Loc);

      else
         Cond := Empty;

         C := First_Non_Pragma (L);
         while Present (C) loop
            Typ        := Etype (Defining_Identifier (C));
            Field_Name := Chars (Defining_Identifier (C));

            --  The tags must not be compared: they are not part of the value.
            --  Ditto for parent interfaces because their equality operator is
            --  abstract.

            --  Note also that in the following, we use Make_Identifier for
            --  the component names. Use of New_Occurrence_Of to identify the
            --  components would be incorrect because the wrong entities for
            --  discriminants could be picked up in the private type case.

            if Field_Name = Name_uParent
              and then Is_Interface (Typ)
            then
               null;

            elsif Field_Name /= Name_uTag then
               declare
                  Lhs : constant Node_Id :=
                    Make_Selected_Component (Loc,
                      Prefix        => Make_Identifier (Loc, Name_X),
                      Selector_Name => Make_Identifier (Loc, Field_Name));

                  Rhs : constant Node_Id :=
                    Make_Selected_Component (Loc,
                      Prefix        => Make_Identifier (Loc, Name_Y),
                      Selector_Name => Make_Identifier (Loc, Field_Name));
                  Eq_Call : Node_Id;

               begin
                  --  Build equality code with a user-defined operator, if
                  --  available, and with the predefined "=" otherwise. For
                  --  compatibility with older Ada versions, we also use the
                  --  predefined operation if the component-type equality is
                  --  abstract, rather than raising Program_Error.

                  if Ada_Version < Ada_2012 then
                     Next_Test := Make_Op_Ne (Loc, Lhs, Rhs);

                  else
                     Eq_Call := Build_Eq_Call (Typ, Loc, Lhs, Rhs);

                     if No (Eq_Call) then
                        Next_Test := Make_Op_Ne (Loc, Lhs, Rhs);

                     --  If a component has a defined abstract equality, its
                     --  application raises Program_Error on that component
                     --  and therefore on the current variant.

                     elsif Nkind (Eq_Call) = N_Raise_Program_Error then
                        Set_Etype (Eq_Call, Standard_Boolean);
                        Next_Test := Make_Op_Not (Loc, Eq_Call);

                     else
                        Next_Test := Make_Op_Not (Loc, Eq_Call);
                     end if;
                  end if;
               end;

               Evolve_Or_Else (Cond, Next_Test);
            end if;

            Next_Non_Pragma (C);
         end loop;

         if No (Cond) then
            return Make_Null_Statement (Loc);

         else
            return
              Make_Implicit_If_Statement (E,
                Condition       => Cond,
                Then_Statements => New_List (
                  Make_Simple_Return_Statement (Loc,
                    Expression => New_Occurrence_Of (Standard_False, Loc))));
         end if;
      end if;
   end Make_Eq_If;

   -------------------
   -- Make_Neq_Body --
   -------------------

   function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id is

      function Is_Predefined_Neq_Renaming (Prim : Node_Id) return Boolean;
      --  Returns true if Prim is a renaming of an unresolved predefined
      --  inequality operation.

      --------------------------------
      -- Is_Predefined_Neq_Renaming --
      --------------------------------

      function Is_Predefined_Neq_Renaming (Prim : Node_Id) return Boolean is
      begin
         return Chars (Prim) /= Name_Op_Ne
           and then Present (Alias (Prim))
           and then Comes_From_Source (Prim)
           and then Is_Intrinsic_Subprogram (Alias (Prim))
           and then Chars (Alias (Prim)) = Name_Op_Ne;
      end Is_Predefined_Neq_Renaming;

      --  Local variables

      Loc           : constant Source_Ptr := Sloc (Parent (Tag_Typ));
      Decl          : Node_Id;
      Eq_Prim       : Entity_Id;
      Left_Op       : Entity_Id;
      Renaming_Prim : Entity_Id;
      Right_Op      : Entity_Id;
      Target        : Entity_Id;

   --  Start of processing for Make_Neq_Body

   begin
      --  For a call on a renaming of a dispatching subprogram that is
      --  overridden, if the overriding occurred before the renaming, then
      --  the body executed is that of the overriding declaration, even if the
      --  overriding declaration is not visible at the place of the renaming;
      --  otherwise, the inherited or predefined subprogram is called, see
      --  (RM 8.5.4(8)).

      --  Stage 1: Search for a renaming of the inequality primitive and also
      --  search for an overriding of the equality primitive located before the
      --  renaming declaration.

      declare
         Elmt : Elmt_Id;
         Prim : Node_Id;

      begin
         Eq_Prim       := Empty;
         Renaming_Prim := Empty;

         Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
         while Present (Elmt) loop
            Prim := Node (Elmt);

            if Is_User_Defined_Equality (Prim) and then No (Alias (Prim)) then
               if No (Renaming_Prim) then
                  pragma Assert (No (Eq_Prim));
                  Eq_Prim := Prim;
               end if;

            elsif Is_Predefined_Neq_Renaming (Prim) then
               Renaming_Prim := Prim;
            end if;

            Next_Elmt (Elmt);
         end loop;
      end;

      --  No further action needed if no renaming was found

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

      --  Stage 2: Replace the renaming declaration by a subprogram declaration
      --  (required to add its body)

      Decl := Parent (Parent (Renaming_Prim));
      Rewrite (Decl,
        Make_Subprogram_Declaration (Loc,
          Specification => Specification (Decl)));
      Set_Analyzed (Decl);

      --  Remove the decoration of intrinsic renaming subprogram

      Set_Is_Intrinsic_Subprogram (Renaming_Prim, False);
      Set_Convention (Renaming_Prim, Convention_Ada);
      Set_Alias (Renaming_Prim, Empty);
      Set_Has_Completion (Renaming_Prim, False);

      --  Stage 3: Build the corresponding body

      Left_Op  := First_Formal (Renaming_Prim);
      Right_Op := Next_Formal (Left_Op);

      Decl :=
        Predef_Spec_Or_Body (Loc,
          Tag_Typ  => Tag_Typ,
          Name     => Chars (Renaming_Prim),
          Profile  => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Chars (Left_Op)),
              Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),

            Make_Parameter_Specification (Loc,
              Defining_Identifier =>
                Make_Defining_Identifier (Loc, Chars (Right_Op)),
              Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),

          Ret_Type => Standard_Boolean,
          For_Body => True);

      --  If the overriding of the equality primitive occurred before the
      --  renaming, then generate:

      --    function <Neq_Name> (X : Y : Typ) return Boolean is
      --    begin
      --       return not Oeq (X, Y);
      --    end;

      if Present (Eq_Prim) then
         Target := Eq_Prim;

      --  Otherwise build a nested subprogram which performs the predefined
      --  evaluation of the equality operator. That is, generate:

      --    function <Neq_Name> (X : Y : Typ) return Boolean is
      --       function Oeq (X : Y) return Boolean is
      --       begin
      --          <<body of default implementation>>
      --       end;
      --    begin
      --       return not Oeq (X, Y);
      --    end;

      else
         declare
            Local_Subp : Node_Id;
         begin
            Local_Subp := Make_Eq_Body (Tag_Typ, Name_Op_Eq);
            Set_Declarations (Decl, New_List (Local_Subp));
            Target := Defining_Entity (Local_Subp);
         end;
      end if;

      Set_Handled_Statement_Sequence
        (Decl,
         Make_Handled_Sequence_Of_Statements (Loc, New_List (
           Make_Simple_Return_Statement (Loc,
              Expression =>
                Make_Op_Not (Loc,
                  Make_Function_Call (Loc,
                  Name                   => New_Occurrence_Of (Target, Loc),
                  Parameter_Associations => New_List (
                    Make_Identifier (Loc, Chars (Left_Op)),
                    Make_Identifier (Loc, Chars (Right_Op)))))))));

      return Decl;
   end Make_Neq_Body;

   -------------------------------
   -- Make_Null_Procedure_Specs --
   -------------------------------

   function Make_Null_Procedure_Specs (Tag_Typ : Entity_Id) return List_Id is
      Decl_List      : constant List_Id    := New_List;
      Loc            : constant Source_Ptr := Sloc (Tag_Typ);
      Formal         : Entity_Id;
      New_Param_Spec : Node_Id;
      New_Spec       : Node_Id;
      Parent_Subp    : Entity_Id;
      Prim_Elmt      : Elmt_Id;
      Subp           : Entity_Id;

   begin
      Prim_Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
      while Present (Prim_Elmt) loop
         Subp := Node (Prim_Elmt);

         --  If a null procedure inherited from an interface has not been
         --  overridden, then we build a null procedure declaration to
         --  override the inherited procedure.

         Parent_Subp := Alias (Subp);

         if Present (Parent_Subp)
           and then Is_Null_Interface_Primitive (Parent_Subp)
         then
            --  The null procedure spec is copied from the inherited procedure,
            --  except for the IS NULL (which must be added) and the overriding
            --  indicators (which must be removed, if present).

            New_Spec :=
              Copy_Subprogram_Spec (Subprogram_Specification (Subp), Loc);

            Set_Null_Present      (New_Spec, True);
            Set_Must_Override     (New_Spec, False);
            Set_Must_Not_Override (New_Spec, False);

            Formal := First_Formal (Subp);
            New_Param_Spec := First (Parameter_Specifications (New_Spec));

            while Present (Formal) loop

               --  For controlling arguments we must change their parameter
               --  type to reference the tagged type (instead of the interface
               --  type).

               if Is_Controlling_Formal (Formal) then
                  if Nkind (Parameter_Type (Parent (Formal))) = N_Identifier
                  then
                     Set_Parameter_Type (New_Param_Spec,
                       New_Occurrence_Of (Tag_Typ, Loc));

                  else pragma Assert
                         (Nkind (Parameter_Type (Parent (Formal))) =
                                                     N_Access_Definition);
                     Set_Subtype_Mark (Parameter_Type (New_Param_Spec),
                       New_Occurrence_Of (Tag_Typ, Loc));
                  end if;
               end if;

               Next_Formal (Formal);
               Next (New_Param_Spec);
            end loop;

            Append_To (Decl_List,
              Make_Subprogram_Declaration (Loc,
                Specification => New_Spec));
         end if;

         Next_Elmt (Prim_Elmt);
      end loop;

      return Decl_List;
   end Make_Null_Procedure_Specs;

   ---------------------------------------
   -- Make_Predefined_Primitive_Eq_Spec --
   ---------------------------------------

   procedure Make_Predefined_Primitive_Eq_Spec
     (Tag_Typ     : Entity_Id;
      Predef_List : List_Id;
      Renamed_Eq  : out Entity_Id)
   is
      function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean;
      --  Returns true if Prim is a renaming of an unresolved predefined
      --  equality operation.

      -------------------------------
      -- Is_Predefined_Eq_Renaming --
      -------------------------------

      function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean is
      begin
         return Chars (Prim) /= Name_Op_Eq
           and then Present (Alias (Prim))
           and then Comes_From_Source (Prim)
           and then Is_Intrinsic_Subprogram (Alias (Prim))
           and then Chars (Alias (Prim)) = Name_Op_Eq;
      end Is_Predefined_Eq_Renaming;

      --  Local variables

      Loc : constant Source_Ptr := Sloc (Tag_Typ);

      Eq_Name   : Name_Id := Name_Op_Eq;
      Eq_Needed : Boolean := True;
      Eq_Spec   : Node_Id;
      Prim      : Elmt_Id;

      Has_Predef_Eq_Renaming : Boolean := False;
      --  Set to True if Tag_Typ has a primitive that renames the predefined
      --  equality operator. Used to implement (RM 8-5-4(8)).

   --  Start of processing for Make_Predefined_Primitive_Specs

   begin
      Renamed_Eq := Empty;

      Prim := First_Elmt (Primitive_Operations (Tag_Typ));
      while Present (Prim) loop

         --  If a primitive is encountered that renames the predefined equality
         --  operator before reaching any explicit equality primitive, then we
         --  still need to create a predefined equality function, because calls
         --  to it can occur via the renaming. A new name is created for the
         --  equality to avoid conflicting with any user-defined equality.
         --  (Note that this doesn't account for renamings of equality nested
         --  within subpackages???)

         if Is_Predefined_Eq_Renaming (Node (Prim)) then
            Has_Predef_Eq_Renaming := True;
            Eq_Name := New_External_Name (Chars (Node (Prim)), 'E');

         --  User-defined equality

         elsif Is_User_Defined_Equality (Node (Prim)) then
            if No (Alias (Node (Prim)))
              or else Nkind (Unit_Declaration_Node (Node (Prim))) =
                        N_Subprogram_Renaming_Declaration
            then
               Eq_Needed := False;
               exit;

            --  If the parent is not an interface type and has an abstract
            --  equality function explicitly defined in the sources, then the
            --  inherited equality is abstract as well, and no body can be
            --  created for it.

            elsif not Is_Interface (Etype (Tag_Typ))
              and then Present (Alias (Node (Prim)))
              and then Comes_From_Source (Alias (Node (Prim)))
              and then Is_Abstract_Subprogram (Alias (Node (Prim)))
            then
               Eq_Needed := False;
               exit;

            --  If the type has an equality function corresponding with a
            --  primitive defined in an interface type, the inherited equality
            --  is abstract as well, and no body can be created for it.

            elsif Present (Alias (Node (Prim)))
              and then Comes_From_Source (Ultimate_Alias (Node (Prim)))
              and then
                Is_Interface
                  (Find_Dispatching_Type (Ultimate_Alias (Node (Prim))))
            then
               Eq_Needed := False;
               exit;
            end if;
         end if;

         Next_Elmt (Prim);
      end loop;

      --  If a renaming of predefined equality was found but there was no
      --  user-defined equality (so Eq_Needed is still true), then set the name
      --  back to Name_Op_Eq. But in the case where a user-defined equality was
      --  located after such a renaming, then the predefined equality function
      --  is still needed, so Eq_Needed must be set back to True.

      if Eq_Name /= Name_Op_Eq then
         if Eq_Needed then
            Eq_Name := Name_Op_Eq;
         else
            Eq_Needed := True;
         end if;
      end if;

      if Eq_Needed then
         Eq_Spec := Predef_Spec_Or_Body (Loc,
           Tag_Typ  => Tag_Typ,
           Name     => Eq_Name,
           Profile  => New_List (
             Make_Parameter_Specification (Loc,
               Defining_Identifier =>
                 Make_Defining_Identifier (Loc, Name_X),
               Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),

             Make_Parameter_Specification (Loc,
               Defining_Identifier =>
                 Make_Defining_Identifier (Loc, Name_Y),
               Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
           Ret_Type => Standard_Boolean);
         Append_To (Predef_List, Eq_Spec);

         if Has_Predef_Eq_Renaming then
            Renamed_Eq := Defining_Unit_Name (Specification (Eq_Spec));

            Prim := First_Elmt (Primitive_Operations (Tag_Typ));
            while Present (Prim) loop

               --  Any renamings of equality that appeared before an overriding
               --  equality must be updated to refer to the entity for the
               --  predefined equality, otherwise calls via the renaming would
               --  get incorrectly resolved to call the user-defined equality
               --  function.

               if Is_Predefined_Eq_Renaming (Node (Prim)) then
                  Set_Alias (Node (Prim), Renamed_Eq);

               --  Exit upon encountering a user-defined equality

               elsif Chars (Node (Prim)) = Name_Op_Eq
                 and then No (Alias (Node (Prim)))
               then
                  exit;
               end if;

               Next_Elmt (Prim);
            end loop;
         end if;
      end if;
   end Make_Predefined_Primitive_Eq_Spec;

   -------------------------------------
   -- Make_Predefined_Primitive_Specs --
   -------------------------------------

   procedure Make_Predefined_Primitive_Specs
     (Tag_Typ     : Entity_Id;
      Predef_List : out List_Id;
      Renamed_Eq  : out Entity_Id)
   is
      Loc : constant Source_Ptr := Sloc (Tag_Typ);
      Res : constant List_Id    := New_List;

      use Exp_Put_Image;

   begin
      Renamed_Eq := Empty;

      --  Spec of _Size

      Append_To (Res, Predef_Spec_Or_Body (Loc,
        Tag_Typ  => Tag_Typ,
        Name     => Name_uSize,
        Profile  => New_List (
          Make_Parameter_Specification (Loc,
            Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
            Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),

        Ret_Type => Standard_Long_Long_Integer));

      --  Spec of Put_Image

      if not No_Run_Time_Mode
        and then RTE_Available (RE_Root_Buffer_Type)
      then
         --  No_Run_Time_Mode implies that the declaration of Tag_Typ
         --  (like any tagged type) will be rejected. Given this, avoid
         --  cascading errors associated with the Tag_Typ's TSS_Put_Image
         --  procedure.

         Append_To (Res, Predef_Spec_Or_Body (Loc,
           Tag_Typ => Tag_Typ,
           Name    => Make_TSS_Name (Tag_Typ, TSS_Put_Image),
           Profile => Build_Put_Image_Profile (Loc, Tag_Typ)));
      end if;

      --  Specs for dispatching stream attributes

      declare
         Stream_Op_TSS_Names :
           constant array (Positive range <>) of TSS_Name_Type :=
             (TSS_Stream_Read,
              TSS_Stream_Write,
              TSS_Stream_Input,
              TSS_Stream_Output);

      begin
         for Op in Stream_Op_TSS_Names'Range loop
            if Stream_Operation_OK (Tag_Typ, Stream_Op_TSS_Names (Op)) then
               Append_To (Res,
                 Predef_Stream_Attr_Spec (Loc, Tag_Typ,
                  Stream_Op_TSS_Names (Op)));
            end if;
         end loop;
      end;

      --  Spec of "=" is expanded if the type is not limited and if a user
      --  defined "=" was not already declared for the non-full view of a
      --  private extension.

      if not Is_Limited_Type (Tag_Typ) then
         Make_Predefined_Primitive_Eq_Spec (Tag_Typ, Res, Renamed_Eq);

         --  Spec for dispatching assignment

         Append_To (Res, Predef_Spec_Or_Body (Loc,
           Tag_Typ => Tag_Typ,
           Name    => Name_uAssign,
           Profile => New_List (
             Make_Parameter_Specification (Loc,
               Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
               Out_Present         => True,
               Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),

             Make_Parameter_Specification (Loc,
               Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
               Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)))));
      end if;

      --  Ada 2005: Generate declarations for the following primitive
      --  operations for limited interfaces and synchronized types that
      --  implement a limited interface.

      --    Disp_Asynchronous_Select
      --    Disp_Conditional_Select
      --    Disp_Get_Prim_Op_Kind
      --    Disp_Get_Task_Id
      --    Disp_Requeue
      --    Disp_Timed_Select

      --  Disable the generation of these bodies if Ravenscar or ZFP is active

      if Ada_Version >= Ada_2005
        and then not Restriction_Active (No_Select_Statements)
        and then RTE_Available (RE_Select_Specific_Data)
      then
         --  These primitives are defined abstract in interface types

         if Is_Interface (Tag_Typ)
           and then Is_Limited_Record (Tag_Typ)
         then
            Append_To (Res,
              Make_Abstract_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Asynchronous_Select_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Abstract_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Conditional_Select_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Abstract_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Get_Prim_Op_Kind_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Abstract_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Get_Task_Id_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Abstract_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Requeue_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Abstract_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Timed_Select_Spec (Tag_Typ)));

         --  If ancestor is an interface type, declare non-abstract primitives
         --  to override the abstract primitives of the interface type.

         --  In VM targets we define these primitives in all root tagged types
         --  that are not interface types. Done because in VM targets we don't
         --  have secondary dispatch tables and any derivation of Tag_Typ may
         --  cover limited interfaces (which always have these primitives since
         --  they may be ancestors of synchronized interface types).

         elsif (not Is_Interface (Tag_Typ)
                 and then Is_Interface (Etype (Tag_Typ))
                 and then Is_Limited_Record (Etype (Tag_Typ)))
             or else
               (Is_Concurrent_Record_Type (Tag_Typ)
                 and then Has_Interfaces (Tag_Typ))
             or else
               (not Tagged_Type_Expansion
                 and then not Is_Interface (Tag_Typ)
                 and then Tag_Typ = Root_Type (Tag_Typ))
         then
            Append_To (Res,
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Asynchronous_Select_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Conditional_Select_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Get_Prim_Op_Kind_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Get_Task_Id_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Requeue_Spec (Tag_Typ)));

            Append_To (Res,
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Make_Disp_Timed_Select_Spec (Tag_Typ)));
         end if;
      end if;

      --  All tagged types receive their own Deep_Adjust and Deep_Finalize
      --  regardless of whether they are controlled or may contain controlled
      --  components.

      --  Do not generate the routines if finalization is disabled

      if Restriction_Active (No_Finalization) then
         null;

      else
         if not Is_Limited_Type (Tag_Typ) then
            Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust));
         end if;

         Append_To (Res, Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize));
      end if;

      Predef_List := Res;
   end Make_Predefined_Primitive_Specs;

   -------------------------
   -- Make_Tag_Assignment --
   -------------------------

   function Make_Tag_Assignment (N : Node_Id) return Node_Id is
      Loc      : constant Source_Ptr := Sloc (N);
      Def_Id   : constant Entity_Id  := Defining_Identifier (N);
      Expr     : constant Node_Id    := Expression (N);
      Typ      : constant Entity_Id  := Etype (Def_Id);
      Full_Typ : constant Entity_Id  := Underlying_Type (Typ);

   begin
      --  This expansion activity is called during analysis

      if Is_Tagged_Type (Typ)
        and then not Is_Class_Wide_Type (Typ)
        and then not Is_CPP_Class (Typ)
        and then Tagged_Type_Expansion
        and then Nkind (Unqualify (Expr)) /= N_Aggregate
      then
         return
           Make_Tag_Assignment_From_Type
             (Loc, New_Occurrence_Of (Def_Id, Loc), Full_Typ);

      else
         return Empty;
      end if;
   end Make_Tag_Assignment;

   ----------------------
   -- Predef_Deep_Spec --
   ----------------------

   function Predef_Deep_Spec
     (Loc      : Source_Ptr;
      Tag_Typ  : Entity_Id;
      Name     : TSS_Name_Type;
      For_Body : Boolean := False) return Node_Id
   is
      Formals : List_Id;

   begin
      --  V : in out Tag_Typ

      Formals := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
          In_Present          => True,
          Out_Present         => True,
          Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)));

      --  F : Boolean := True

      if Name = TSS_Deep_Adjust
        or else Name = TSS_Deep_Finalize
      then
         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_F),
             Parameter_Type      => New_Occurrence_Of (Standard_Boolean, Loc),
             Expression          => New_Occurrence_Of (Standard_True, Loc)));
      end if;

      return
        Predef_Spec_Or_Body (Loc,
          Name     => Make_TSS_Name (Tag_Typ, Name),
          Tag_Typ  => Tag_Typ,
          Profile  => Formals,
          For_Body => For_Body);

   exception
      when RE_Not_Available =>
         return Empty;
   end Predef_Deep_Spec;

   -------------------------
   -- Predef_Spec_Or_Body --
   -------------------------

   function Predef_Spec_Or_Body
     (Loc      : Source_Ptr;
      Tag_Typ  : Entity_Id;
      Name     : Name_Id;
      Profile  : List_Id;
      Ret_Type : Entity_Id := Empty;
      For_Body : Boolean := False) return Node_Id
   is
      Id   : constant Entity_Id := Make_Defining_Identifier (Loc, Name);
      Spec : Node_Id;

   begin
      Set_Is_Public (Id, Is_Public (Tag_Typ));

      --  The internal flag is set to mark these declarations because they have
      --  specific properties. First, they are primitives even if they are not
      --  defined in the type scope (the freezing point is not necessarily in
      --  the same scope). Second, the predefined equality can be overridden by
      --  a user-defined equality, no body will be generated in this case.

      Set_Is_Internal (Id);

      if not Debug_Generated_Code then
         Set_Debug_Info_Off (Id);
      end if;

      if No (Ret_Type) then
         Spec :=
           Make_Procedure_Specification (Loc,
             Defining_Unit_Name       => Id,
             Parameter_Specifications => Profile);
      else
         Spec :=
           Make_Function_Specification (Loc,
             Defining_Unit_Name       => Id,
             Parameter_Specifications => Profile,
             Result_Definition        => New_Occurrence_Of (Ret_Type, Loc));
      end if;

      --  Declare an abstract subprogram for primitive subprograms of an
      --  interface type (except for "=").

      if Is_Interface (Tag_Typ) then
         if Name /= Name_Op_Eq then
            return Make_Abstract_Subprogram_Declaration (Loc, Spec);

         --  The equality function (if any) for an interface type is defined
         --  to be nonabstract, so we create an expression function for it that
         --  always returns False. Note that the function can never actually be
         --  invoked because interface types are abstract, so there aren't any
         --  objects of such types (and their equality operation will always
         --  dispatch).

         else
            return Make_Expression_Function
                     (Loc, Spec, New_Occurrence_Of (Standard_False, Loc));
         end if;

      --  If body case, return empty subprogram body. Note that this is ill-
      --  formed, because there is not even a null statement, and certainly not
      --  a return in the function case. The caller is expected to do surgery
      --  on the body to add the appropriate stuff.

      elsif For_Body then
         return Make_Subprogram_Body (Loc,
                  Specification              => Spec,
                  Declarations               => Empty_List,
                  Handled_Statement_Sequence => Empty);

      --  For the case of an Input attribute predefined for an abstract type,
      --  generate an abstract specification. This will never be called, but we
      --  need the slot allocated in the dispatching table so that attributes
      --  typ'Class'Input and typ'Class'Output will work properly.

      elsif Is_TSS (Name, TSS_Stream_Input)
        and then Is_Abstract_Type (Tag_Typ)
      then
         return Make_Abstract_Subprogram_Declaration (Loc, Spec);

      --  Normal spec case, where we return a subprogram declaration

      else
         return Make_Subprogram_Declaration (Loc, Spec);
      end if;
   end Predef_Spec_Or_Body;

   -----------------------------
   -- Predef_Stream_Attr_Spec --
   -----------------------------

   function Predef_Stream_Attr_Spec
     (Loc     : Source_Ptr;
      Tag_Typ : Entity_Id;
      Name    : TSS_Name_Type) return Node_Id
   is
      Ret_Type : Entity_Id;

   begin
      if Name = TSS_Stream_Input then
         Ret_Type := Tag_Typ;
      else
         Ret_Type := Empty;
      end if;

      return
        Predef_Spec_Or_Body
          (Loc,
           Name     => Make_TSS_Name (Tag_Typ, Name),
           Tag_Typ  => Tag_Typ,
           Profile  => Build_Stream_Attr_Profile (Loc, Tag_Typ, Name),
           Ret_Type => Ret_Type,
           For_Body => False);
   end Predef_Stream_Attr_Spec;

   ----------------------------------
   -- Predefined_Primitive_Eq_Body --
   ----------------------------------

   procedure Predefined_Primitive_Eq_Body
     (Tag_Typ     : Entity_Id;
      Predef_List : List_Id;
      Renamed_Eq  : Entity_Id)
   is
      Decl      : Node_Id;
      Eq_Needed : Boolean;
      Eq_Name   : Name_Id;
      Prim      : Elmt_Id;

   begin
      --  See if we have a predefined "=" operator

      if Present (Renamed_Eq) then
         Eq_Needed := True;
         Eq_Name   := Chars (Renamed_Eq);

      --  If the parent is an interface type then it has defined all the
      --  predefined primitives abstract and we need to check if the type
      --  has some user defined "=" function which matches the profile of
      --  the Ada predefined equality operator to avoid generating it.

      elsif Is_Interface (Etype (Tag_Typ)) then
         Eq_Needed := True;
         Eq_Name := Name_Op_Eq;

         Prim := First_Elmt (Primitive_Operations (Tag_Typ));
         while Present (Prim) loop
            if Is_User_Defined_Equality (Node (Prim))
              and then not Is_Internal (Node (Prim))
            then
               Eq_Needed := False;
               Eq_Name := No_Name;
               exit;
            end if;

            Next_Elmt (Prim);
         end loop;

      else
         Eq_Needed := False;
         Eq_Name   := No_Name;

         Prim := First_Elmt (Primitive_Operations (Tag_Typ));
         while Present (Prim) loop
            if Is_User_Defined_Equality (Node (Prim))
              and then Is_Internal (Node (Prim))
            then
               Eq_Needed := True;
               Eq_Name := Name_Op_Eq;
               exit;
            end if;

            Next_Elmt (Prim);
         end loop;
      end if;

      --  If equality is needed, we will have its name

      pragma Assert (Eq_Needed = Present (Eq_Name));

      --  Body for equality

      if Eq_Needed then
         Decl := Make_Eq_Body (Tag_Typ, Eq_Name);
         Append_To (Predef_List, Decl);
      end if;

      --  Body for inequality (if required)

      Decl := Make_Neq_Body (Tag_Typ);

      if Present (Decl) then
         Append_To (Predef_List, Decl);
      end if;
   end Predefined_Primitive_Eq_Body;

   ---------------------------------
   -- Predefined_Primitive_Bodies --
   ---------------------------------

   function Predefined_Primitive_Bodies
     (Tag_Typ    : Entity_Id;
      Renamed_Eq : Entity_Id) return List_Id
   is
      Loc      : constant Source_Ptr := Sloc (Tag_Typ);
      Res      : constant List_Id    := New_List;
      Adj_Call : Node_Id;
      Decl     : Node_Id;
      Fin_Call : Node_Id;
      Ent      : Entity_Id;

      pragma Warnings (Off, Ent);

      use Exp_Put_Image;

   begin
      pragma Assert (not Is_Interface (Tag_Typ));

      --  Body of _Size

      Decl := Predef_Spec_Or_Body (Loc,
        Tag_Typ => Tag_Typ,
        Name    => Name_uSize,
        Profile => New_List (
          Make_Parameter_Specification (Loc,
            Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
            Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),

        Ret_Type => Standard_Long_Long_Integer,
        For_Body => True);

      Set_Handled_Statement_Sequence (Decl,
        Make_Handled_Sequence_Of_Statements (Loc, New_List (
          Make_Simple_Return_Statement (Loc,
            Expression =>
              Make_Attribute_Reference (Loc,
                Prefix          => Make_Identifier (Loc, Name_X),
                Attribute_Name  => Name_Size)))));

      Append_To (Res, Decl);

      --  Body of Put_Image

      if No (TSS (Tag_Typ, TSS_Put_Image))
         and then not No_Run_Time_Mode
         and then RTE_Available (RE_Root_Buffer_Type)
      then
         Build_Record_Put_Image_Procedure (Tag_Typ, Decl, Ent);
         Append_To (Res, Decl);
      end if;

      --  Bodies for Dispatching stream IO routines. We need these only for
      --  non-limited types (in the limited case there is no dispatching).
      --  We also skip them if dispatching or finalization are not available
      --  or if stream operations are prohibited by restriction No_Streams or
      --  from use of pragma/aspect No_Tagged_Streams.

      if Stream_Operation_OK (Tag_Typ, TSS_Stream_Read)
        and then No (TSS (Tag_Typ, TSS_Stream_Read))
      then
         Build_Record_Read_Procedure (Tag_Typ, Decl, Ent);
         Append_To (Res, Decl);
      end if;

      if Stream_Operation_OK (Tag_Typ, TSS_Stream_Write)
        and then No (TSS (Tag_Typ, TSS_Stream_Write))
      then
         Build_Record_Write_Procedure (Tag_Typ, Decl, Ent);
         Append_To (Res, Decl);
      end if;

      --  Skip body of _Input for the abstract case, since the corresponding
      --  spec is abstract (see Predef_Spec_Or_Body).

      if not Is_Abstract_Type (Tag_Typ)
        and then Stream_Operation_OK (Tag_Typ, TSS_Stream_Input)
        and then No (TSS (Tag_Typ, TSS_Stream_Input))
      then
         Build_Record_Or_Elementary_Input_Function (Tag_Typ, Decl, Ent);
         Append_To (Res, Decl);
      end if;

      if Stream_Operation_OK (Tag_Typ, TSS_Stream_Output)
        and then No (TSS (Tag_Typ, TSS_Stream_Output))
      then
         Build_Record_Or_Elementary_Output_Procedure (Tag_Typ, Decl, Ent);
         Append_To (Res, Decl);
      end if;

      --  Ada 2005: Generate bodies for the following primitive operations for
      --  limited interfaces and synchronized types that implement a limited
      --  interface.

      --    disp_asynchronous_select
      --    disp_conditional_select
      --    disp_get_prim_op_kind
      --    disp_get_task_id
      --    disp_timed_select

      --  The interface versions will have null bodies

      --  Disable the generation of these bodies if Ravenscar or ZFP is active

      --  In VM targets we define these primitives in all root tagged types
      --  that are not interface types. Done because in VM targets we don't
      --  have secondary dispatch tables and any derivation of Tag_Typ may
      --  cover limited interfaces (which always have these primitives since
      --  they may be ancestors of synchronized interface types).

      if Ada_Version >= Ada_2005
        and then
          ((Is_Interface (Etype (Tag_Typ))
             and then Is_Limited_Record (Etype (Tag_Typ)))
           or else
             (Is_Concurrent_Record_Type (Tag_Typ)
               and then Has_Interfaces (Tag_Typ))
           or else
             (not Tagged_Type_Expansion
               and then Tag_Typ = Root_Type (Tag_Typ)))
        and then not Restriction_Active (No_Select_Statements)
        and then RTE_Available (RE_Select_Specific_Data)
      then
         Append_To (Res, Make_Disp_Asynchronous_Select_Body (Tag_Typ));
         Append_To (Res, Make_Disp_Conditional_Select_Body  (Tag_Typ));
         Append_To (Res, Make_Disp_Get_Prim_Op_Kind_Body    (Tag_Typ));
         Append_To (Res, Make_Disp_Get_Task_Id_Body         (Tag_Typ));
         Append_To (Res, Make_Disp_Requeue_Body             (Tag_Typ));
         Append_To (Res, Make_Disp_Timed_Select_Body        (Tag_Typ));
      end if;

      if not Is_Limited_Type (Tag_Typ) then
         --  Body for equality and inequality

         Predefined_Primitive_Eq_Body (Tag_Typ, Res, Renamed_Eq);

         --  Body for dispatching assignment

         Decl :=
           Predef_Spec_Or_Body (Loc,
             Tag_Typ => Tag_Typ,
             Name    => Name_uAssign,
             Profile => New_List (
               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Make_Defining_Identifier (Loc, Name_X),
                 Out_Present         => True,
                 Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc)),

               Make_Parameter_Specification (Loc,
                 Defining_Identifier => Make_Defining_Identifier (Loc, Name_Y),
                 Parameter_Type      => New_Occurrence_Of (Tag_Typ, Loc))),
             For_Body => True);

         Set_Handled_Statement_Sequence (Decl,
           Make_Handled_Sequence_Of_Statements (Loc, New_List (
             Make_Assignment_Statement (Loc,
               Name       => Make_Identifier (Loc, Name_X),
               Expression => Make_Identifier (Loc, Name_Y)))));

         Append_To (Res, Decl);
      end if;

      --  Generate empty bodies of routines Deep_Adjust and Deep_Finalize for
      --  tagged types which do not contain controlled components.

      --  Do not generate the routines if finalization is disabled

      if Restriction_Active (No_Finalization) then
         null;

      elsif not Has_Controlled_Component (Tag_Typ) then
         if not Is_Limited_Type (Tag_Typ) then
            Adj_Call := Empty;
            Decl     := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust, True);

            if Is_Controlled (Tag_Typ) then
               Adj_Call :=
                 Make_Adjust_Call (
                   Obj_Ref => Make_Identifier (Loc, Name_V),
                   Typ     => Tag_Typ);
            end if;

            if No (Adj_Call) then
               Adj_Call := Make_Null_Statement (Loc);
            end if;

            Set_Handled_Statement_Sequence (Decl,
              Make_Handled_Sequence_Of_Statements (Loc,
                Statements => New_List (Adj_Call)));

            Append_To (Res, Decl);
         end if;

         if not Has_Destructor (Tag_Typ) then
            Fin_Call := Empty;
            Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True);

            if Is_Controlled (Tag_Typ) then
               Fin_Call :=
                 Make_Final_Call
                   (Obj_Ref => Make_Identifier (Loc, Name_V), Typ => Tag_Typ);
            end if;

            if No (Fin_Call) then
               Fin_Call := Make_Null_Statement (Loc);
            end if;

            Set_Handled_Statement_Sequence
              (Decl,
               Make_Handled_Sequence_Of_Statements
                 (Loc, Statements => New_List (Fin_Call)));

            Append_To (Res, Decl);
         end if;
      end if;

      return Res;
   end Predefined_Primitive_Bodies;

   ---------------------------------
   -- Predefined_Primitive_Freeze --
   ---------------------------------

   function Predefined_Primitive_Freeze
     (Tag_Typ : Entity_Id) return List_Id
   is
      Res     : constant List_Id := New_List;
      Prim    : Elmt_Id;
      Frnodes : List_Id;

   begin
      Prim := First_Elmt (Primitive_Operations (Tag_Typ));
      while Present (Prim) loop
         if Is_Predefined_Dispatching_Operation (Node (Prim)) then
            Frnodes := Freeze_Entity (Node (Prim), Tag_Typ);

            if Present (Frnodes) then
               Append_List_To (Res, Frnodes);
            end if;
         end if;

         Next_Elmt (Prim);
      end loop;

      return Res;
   end Predefined_Primitive_Freeze;

   ------------------------
   -- Constructor_Freeze --
   ------------------------

   function Constructor_Freeze (Typ : Entity_Id) return List_Id is
      Res     : constant List_Id := New_List;
      Cursor  : Entity_Id;
      Frnodes : List_Id;

   begin
      if not Needs_Construction (Typ) then
         return No_List;
      end if;

      Cursor :=
        Get_Name_Entity_Id
          (Direct_Attribute_Definition_Name (Typ, Name_Constructor));
      while Present (Cursor) loop
         Frnodes := Freeze_Entity (Cursor, Typ);

         if Present (Frnodes) then
            Append_List_To (Res, Frnodes);
         end if;

         Cursor := Homonym (Cursor);
      end loop;

      return Res;
   end Constructor_Freeze;

   -------------------------
   -- Stream_Operation_OK --
   -------------------------

   function Stream_Operation_OK
     (Typ       : Entity_Id;
      Operation : TSS_Name_Type) return Boolean
   is
      Has_Predefined_Or_Specified_Stream_Attribute : Boolean := False;

   begin
      --  Special case of a limited type extension: a default implementation
      --  of the stream attributes Read or Write exists if that attribute
      --  has been specified or is available for an ancestor type; a default
      --  implementation of the attribute Output (resp. Input) exists if the
      --  attribute has been specified or Write (resp. Read) is available for
      --  an ancestor type. The last condition only applies under Ada 2005.

      if Is_Limited_Type (Typ) and then Is_Tagged_Type (Typ) then
         if Operation = TSS_Stream_Read then
            Has_Predefined_Or_Specified_Stream_Attribute :=
              Has_Specified_Stream_Read (Typ);

         elsif Operation = TSS_Stream_Write then
            Has_Predefined_Or_Specified_Stream_Attribute :=
              Has_Specified_Stream_Write (Typ);

         elsif Operation = TSS_Stream_Input then
            Has_Predefined_Or_Specified_Stream_Attribute :=
              Has_Specified_Stream_Input (Typ)
                or else
                  (Ada_Version >= Ada_2005
                    and then Stream_Operation_OK (Typ, TSS_Stream_Read));

         elsif Operation = TSS_Stream_Output then
            Has_Predefined_Or_Specified_Stream_Attribute :=
              Has_Specified_Stream_Output (Typ)
                or else
                  (Ada_Version >= Ada_2005
                    and then Stream_Operation_OK (Typ, TSS_Stream_Write));
         end if;

         --  Case of inherited TSS_Stream_Read or TSS_Stream_Write

         if not Has_Predefined_Or_Specified_Stream_Attribute
           and then Is_Derived_Type (Typ)
           and then (Operation = TSS_Stream_Read
                      or else Operation = TSS_Stream_Write)
         then
            Has_Predefined_Or_Specified_Stream_Attribute :=
              Present
                (Find_Inherited_TSS (Base_Type (Etype (Typ)), Operation));
         end if;
      end if;

      --  If the type is not limited, or else is limited but the attribute is
      --  explicitly specified or is predefined for the type, then return True,
      --  unless other conditions prevail, such as restrictions prohibiting
      --  streams or dispatching operations. We also return True for limited
      --  interfaces, because they may be extended by nonlimited types and
      --  permit inheritance in this case (addresses cases where an abstract
      --  extension doesn't get 'Input declared, as per comments below, but
      --  'Class'Input must still be allowed). Note that attempts to apply
      --  stream attributes to a limited interface or its class-wide type
      --  (or limited extensions thereof) will still get properly rejected
      --  by Check_Stream_Attribute.

      --  We exclude the Input operation from being a predefined subprogram in
      --  the case where the associated type is an abstract extension, because
      --  the attribute is not callable in that case, per 13.13.2(49/2). Also,
      --  we don't want an abstract version created because types derived from
      --  the abstract type may not even have Input available (for example if
      --  derived from a private view of the abstract type that doesn't have
      --  a visible Input).

      return
          (not Is_Limited_Type (Typ)
            or else Is_Interface (Typ)
            or else Has_Predefined_Or_Specified_Stream_Attribute)
        and then
          (Operation /= TSS_Stream_Input
            or else not Is_Abstract_Type (Typ)
            or else not Is_Derived_Type (Typ))
        and then not Has_Unknown_Discriminants (Typ)
        and then not Is_Concurrent_Interface (Typ)
        and then not Restriction_Active (No_Streams)
        and then not Restriction_Active (No_Dispatch)
        and then No (No_Tagged_Streams_Pragma (Typ))
        and then not No_Run_Time_Mode
        and then RTE_Available (RE_Tag)
        and then
          (not Restriction_Active (No_Default_Stream_Attributes)
             or else No (Type_Without_Stream_Operation (Typ)))
        and then RTE_Available (RE_Root_Stream_Type);
   end Stream_Operation_OK;

end Exp_Ch3;
