------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              E X P _ C H 7                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2006, 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 2,  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 COPYING.  If not, write --
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

--  This package contains virtually all expansion mechanisms related to
--    - controlled types
--    - transient scopes

with Atree;    use Atree;
with Debug;    use Debug;
with Einfo;    use Einfo;
with Errout;   use Errout;
with Exp_Ch9;  use Exp_Ch9;
with Exp_Ch11; use Exp_Ch11;
with Exp_Dbug; use Exp_Dbug;
with Exp_Tss;  use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze;   use Freeze;
with Hostparm; use Hostparm;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Output;   use Output;
with Restrict; use Restrict;
with Rident;   use Rident;
with Rtsfind;  use Rtsfind;
with Targparm; use Targparm;
with Sinfo;    use Sinfo;
with Sem;      use Sem;
with Sem_Ch3;  use Sem_Ch3;
with Sem_Ch7;  use Sem_Ch7;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Res;  use Sem_Res;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Snames;   use Snames;
with Stand;    use Stand;
with Tbuild;   use Tbuild;
with Uintp;    use Uintp;

package body Exp_Ch7 is

   --------------------------------
   -- Transient Scope Management --
   --------------------------------

   --  A transient scope is created when temporary objects are created by the
   --  compiler. These temporary objects are allocated on the secondary stack
   --  and the transient scope is responsible for finalizing the object when
   --  appropriate and reclaiming the memory at the right time. The temporary
   --  objects are generally the objects allocated to store the result of a
   --  function returning an unconstrained or a tagged value. Expressions
   --  needing to be wrapped in a transient scope (functions calls returning
   --  unconstrained or tagged values) may appear in 3 different contexts which
   --  lead to 3 different kinds of transient scope expansion:

   --   1. In a simple statement (procedure call, assignment, ...). In
   --      this case the instruction is wrapped into a transient block.
   --      (See Wrap_Transient_Statement for details)

   --   2. In an expression of a control structure (test in a IF statement,
   --      expression in a CASE statement, ...).
   --      (See Wrap_Transient_Expression for details)

   --   3. In a expression of an object_declaration. No wrapping is possible
   --      here, so the finalization actions, if any are done right after the
   --      declaration and the secondary stack deallocation is done in the
   --      proper enclosing scope (see Wrap_Transient_Declaration for details)

   --  Note about function returning tagged types: It has been decided to
   --  always allocate their result in the secondary stack while it is not
   --  absolutely mandatory when the tagged type is constrained because the
   --  caller knows the size of the returned object and thus could allocate the
   --  result in the primary stack. But, allocating them always in the
   --  secondary stack simplifies many implementation hassles:

   --    - If it is dispatching function call, the computation of the size of
   --      the result is possible but complex from the outside.

   --    - If the returned type is controlled, the assignment of the returned
   --      value to the anonymous object involves an Adjust, and we have no
   --      easy way to access the anonymous object created by the back-end

   --    - If the returned type is class-wide, this is an unconstrained type
   --      anyway

   --  Furthermore, the little loss in efficiency which is the result of this
   --  decision is not such a big deal because function returning tagged types
   --  are not very much used in real life as opposed to functions returning
   --  access to a tagged type

   --------------------------------------------------
   -- Transient Blocks and Finalization Management --
   --------------------------------------------------

   function Find_Node_To_Be_Wrapped (N : Node_Id) return Node_Id;
   --  N is a node wich may generate a transient scope. Loop over the
   --  parent pointers of N until it find the appropriate node to
   --  wrap. It it returns Empty, it means that no transient scope is
   --  needed in this context.

   function Make_Clean
     (N                          : Node_Id;
      Clean                      : Entity_Id;
      Mark                       : Entity_Id;
      Flist                      : Entity_Id;
      Is_Task                    : Boolean;
      Is_Master                  : Boolean;
      Is_Protected_Subprogram    : Boolean;
      Is_Task_Allocation_Block   : Boolean;
      Is_Asynchronous_Call_Block : Boolean) return Node_Id;
   --  Expand a the clean-up procedure for controlled and/or transient
   --  block, and/or task master or task body, or blocks used to
   --  implement task allocation or asynchronous entry calls, or
   --  procedures used to implement protected procedures. Clean is the
   --  entity for such a procedure. Mark is the entity for the secondary
   --  stack mark, if empty only controlled block clean-up will be
   --  performed. Flist is the entity for the local final list, if empty
   --  only transient scope clean-up will be performed. The flags
   --  Is_Task and Is_Master control the calls to the corresponding
   --  finalization actions for a task body or for an entity that is a
   --  task master.

   procedure Set_Node_To_Be_Wrapped (N : Node_Id);
   --  Set the field Node_To_Be_Wrapped of the current scope

   procedure Insert_Actions_In_Scope_Around (N : Node_Id);
   --  Insert the before-actions kept in the scope stack before N, and the
   --  after after-actions, after N which must be a member of a list.

   function Make_Transient_Block
     (Loc    : Source_Ptr;
      Action : Node_Id) return Node_Id;
   --  Create a transient block whose name is Scope, which is also a
   --  controlled block if Flist is not empty and whose only code is
   --  Action (either a single statement or single declaration).

   type Final_Primitives is (Initialize_Case, Adjust_Case, Finalize_Case);
   --  This enumeration type is defined in order to ease sharing code for
   --  building finalization procedures for composite types.

   Name_Of      : constant array (Final_Primitives) of Name_Id :=
                    (Initialize_Case => Name_Initialize,
                     Adjust_Case     => Name_Adjust,
                     Finalize_Case   => Name_Finalize);

   Deep_Name_Of : constant array (Final_Primitives) of TSS_Name_Type :=
                    (Initialize_Case => TSS_Deep_Initialize,
                     Adjust_Case     => TSS_Deep_Adjust,
                     Finalize_Case   => TSS_Deep_Finalize);

   procedure Build_Record_Deep_Procs (Typ : Entity_Id);
   --  Build the deep Initialize/Adjust/Finalize for a record Typ with
   --  Has_Component_Component set and store them using the TSS mechanism.

   procedure Build_Array_Deep_Procs (Typ : Entity_Id);
   --  Build the deep Initialize/Adjust/Finalize for a record Typ with
   --  Has_Controlled_Component set and store them using the TSS mechanism.

   function Make_Deep_Proc
     (Prim  : Final_Primitives;
      Typ   : Entity_Id;
      Stmts : List_Id) return Node_Id;
   --  This function generates the tree for Deep_Initialize, Deep_Adjust
   --  or Deep_Finalize procedures according to the first parameter,
   --  these procedures operate on the type Typ. The Stmts parameter
   --  gives the body of the procedure.

   function Make_Deep_Array_Body
     (Prim : Final_Primitives;
      Typ  : Entity_Id) return List_Id;
   --  This function generates the list of statements for implementing
   --  Deep_Initialize, Deep_Adjust or Deep_Finalize procedures
   --  according to the first parameter, these procedures operate on the
   --  array type Typ.

   function Make_Deep_Record_Body
     (Prim : Final_Primitives;
      Typ  : Entity_Id) return List_Id;
   --  This function generates the list of statements for implementing
   --  Deep_Initialize, Deep_Adjust or Deep_Finalize procedures
   --  according to the first parameter, these procedures operate on the
   --  record type Typ.

   procedure Check_Visibly_Controlled
     (Prim : Final_Primitives;
      Typ  : Entity_Id;
      E    : in out Entity_Id;
      Cref : in out Node_Id);
   --  The controlled operation declared for a derived type may not be
   --  overriding, if the controlled operations of the parent type are
   --  hidden, for example when the parent is a private type whose full
   --  view is controlled. For other primitive operations we modify the
   --  name of the operation to indicate that it is not overriding, but
   --  this is not possible for Initialize, etc. because they have to be
   --  retrievable by name. Before generating the proper call to one of
   --  these operations we check whether Typ is known to be controlled at
   --  the point of definition. If it is not then we must retrieve the
   --  hidden operation of the parent and use it instead.  This is one
   --  case that might be solved more cleanly once Overriding pragmas or
   --  declarations are in place.

   function Convert_View
     (Proc : Entity_Id;
      Arg  : Node_Id;
      Ind  : Pos := 1) return Node_Id;
   --  Proc is one of the Initialize/Adjust/Finalize operations, and
   --  Arg is the argument being passed to it. Ind indicates which
   --  formal of procedure Proc we are trying to match. This function
   --  will, if necessary, generate an conversion between the partial
   --  and full view of Arg to match the type of the formal of Proc,
   --  or force a conversion to the class-wide type in the case where
   --  the operation is abstract.

   -----------------------------
   -- Finalization Management --
   -----------------------------

   --  This part describe how Initialization/Adjusment/Finalization procedures
   --  are generated and called. Two cases must be considered, types that are
   --  Controlled (Is_Controlled flag set) and composite types that contain
   --  controlled components (Has_Controlled_Component flag set). In the first
   --  case the procedures to call are the user-defined primitive operations
   --  Initialize/Adjust/Finalize. In the second case, GNAT generates
   --  Deep_Initialize, Deep_Adjust and Deep_Finalize that are in charge of
   --  calling the former procedures on the controlled components.

   --  For records with Has_Controlled_Component set, a hidden "controller"
   --  component is inserted. This controller component contains its own
   --  finalization list on which all controlled components are attached
   --  creating an indirection on the upper-level Finalization list. This
   --  technique facilitates the management of objects whose number of
   --  controlled components changes during execution. This controller
   --  component is itself controlled and is attached to the upper-level
   --  finalization chain. Its adjust primitive is in charge of calling
   --  adjust on the components and adusting the finalization pointer to
   --  match their new location (see a-finali.adb).

   --  It is not possible to use a similar technique for arrays that have
   --  Has_Controlled_Component set. In this case, deep procedures are
   --  generated that call initialize/adjust/finalize + attachment or
   --  detachment on the finalization list for all component.

   --  Initialize calls: they are generated for declarations or dynamic
   --  allocations of Controlled objects with no initial value. They are
   --  always followed by an attachment to the current Finalization
   --  Chain. For the dynamic allocation case this the chain attached to
   --  the scope of the access type definition otherwise, this is the chain
   --  of the current scope.

   --  Adjust Calls: They are generated on 2 occasions: (1) for
   --  declarations or dynamic allocations of Controlled objects with an
   --  initial value. (2) after an assignment. In the first case they are
   --  followed by an attachment to the final chain, in the second case
   --  they are not.

   --  Finalization Calls: They are generated on (1) scope exit, (2)
   --  assignments, (3) unchecked deallocations. In case (3) they have to
   --  be detached from the final chain, in case (2) they must not and in
   --  case (1) this is not important since we are exiting the scope
   --  anyway.

   --  Other details:
   --    - Type extensions will have a new record controller at each derivation
   --      level containing controlled components.
   --    - For types that are both Is_Controlled and Has_Controlled_Components,
   --      the record controller and the object itself are handled separately.
   --      It could seem simpler to attach the object at the end of its record
   --      controller but this would not tackle view conversions properly.
   --    - A classwide type can always potentially have controlled components
   --      but the record controller of the corresponding actual type may not
   --      be known at compile time so the dispatch table contains a special
   --      field that allows to compute the offset of the record controller
   --      dynamically. See s-finimp.Deep_Tag_Attach and a-tags.RC_Offset

   --  Here is a simple example of the expansion of a controlled block :

   --    declare
   --       X : Controlled ;
   --       Y : Controlled := Init;
   --
   --       type R is record
   --          C : Controlled;
   --       end record;
   --       W : R;
   --       Z : R := (C => X);
   --    begin
   --       X := Y;
   --       W := Z;
   --    end;
   --
   --  is expanded into
   --
   --    declare
   --       _L : System.FI.Finalizable_Ptr;

   --       procedure _Clean is
   --       begin
   --          Abort_Defer;
   --          System.FI.Finalize_List (_L);
   --          Abort_Undefer;
   --       end _Clean;

   --       X : Controlled;
   --       begin
   --          Abort_Defer;
   --          Initialize (X);
   --          Attach_To_Final_List (_L, Finalizable (X), 1);
   --       at end: Abort_Undefer;
   --       Y : Controlled := Init;
   --       Adjust (Y);
   --       Attach_To_Final_List (_L, Finalizable (Y), 1);
   --
   --       type R is record
   --         _C : Record_Controller;
   --          C : Controlled;
   --       end record;
   --       W : R;
   --       begin
   --          Abort_Defer;
   --          Deep_Initialize (W, _L, 1);
   --       at end: Abort_Under;
   --       Z : R := (C => X);
   --       Deep_Adjust (Z, _L, 1);

   --    begin
   --       _Assign (X, Y);
   --       Deep_Finalize (W, False);
   --       <save W's final pointers>
   --       W := Z;
   --       <restore W's final pointers>
   --       Deep_Adjust (W, _L, 0);
   --    at end
   --       _Clean;
   --    end;

   function Global_Flist_Ref (Flist_Ref : Node_Id) return Boolean;
   --  Return True if Flist_Ref refers to a global final list, either
   --  the object GLobal_Final_List which is used to attach standalone
   --  objects, or any of the list controllers associated with library
   --  level access to controlled objects

   procedure Clean_Simple_Protected_Objects (N : Node_Id);
   --  Protected objects without entries are not controlled types, and the
   --  locks have to be released explicitly when such an object goes out
   --  of scope. Traverse declarations in scope to determine whether such
   --  objects are present.

   ----------------------------
   -- Build_Array_Deep_Procs --
   ----------------------------

   procedure Build_Array_Deep_Procs (Typ : Entity_Id) is
   begin
      Set_TSS (Typ,
        Make_Deep_Proc (
          Prim  => Initialize_Case,
          Typ   => Typ,
          Stmts => Make_Deep_Array_Body (Initialize_Case, Typ)));

      if not Is_Return_By_Reference_Type (Typ) then
         Set_TSS (Typ,
           Make_Deep_Proc (
             Prim  => Adjust_Case,
             Typ   => Typ,
             Stmts => Make_Deep_Array_Body (Adjust_Case, Typ)));
      end if;

      Set_TSS (Typ,
        Make_Deep_Proc (
          Prim  => Finalize_Case,
          Typ   => Typ,
          Stmts => Make_Deep_Array_Body (Finalize_Case, Typ)));
   end Build_Array_Deep_Procs;

   -----------------------------
   -- Build_Controlling_Procs --
   -----------------------------

   procedure Build_Controlling_Procs (Typ : Entity_Id) is
   begin
      if Is_Array_Type (Typ) then
         Build_Array_Deep_Procs (Typ);

      else pragma Assert (Is_Record_Type (Typ));
         Build_Record_Deep_Procs (Typ);
      end if;
   end Build_Controlling_Procs;

   ----------------------
   -- Build_Final_List --
   ----------------------

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

   begin
      Set_Associated_Final_Chain (Typ,
        Make_Defining_Identifier (Loc,
          New_External_Name (Chars (Typ), 'L')));

      Decl :=
        Make_Object_Declaration (Loc,
          Defining_Identifier =>
             Associated_Final_Chain (Typ),
          Object_Definition   =>
            New_Reference_To
              (RTE (RE_List_Controller), Loc));

      --  The type may have been frozen already, and this is a late freezing
      --  action, in which case the declaration must be elaborated at once.
      --  If the call is for an allocator, the chain must also be created now,
      --  because the freezing of the type does not build one. Otherwise, the
      --  declaration is one of the freezing actions for a user-defined type.

      if Is_Frozen (Typ)
        or else (Nkind (N) = N_Allocator
                  and then Ekind (Etype (N)) = E_Anonymous_Access_Type)
      then
         Insert_Action (N, Decl);
      else
         Append_Freeze_Action (Typ, Decl);
      end if;
   end Build_Final_List;

   ---------------------
   -- Build_Late_Proc --
   ---------------------

   procedure Build_Late_Proc (Typ : Entity_Id; Nam : Name_Id) is
   begin
      for Final_Prim in Name_Of'Range loop
         if Name_Of (Final_Prim) = Nam then
            Set_TSS (Typ,
              Make_Deep_Proc (
                Prim  => Final_Prim,
                Typ   => Typ,
                Stmts => Make_Deep_Record_Body (Final_Prim, Typ)));
         end if;
      end loop;
   end Build_Late_Proc;

   -----------------------------
   -- Build_Record_Deep_Procs --
   -----------------------------

   procedure Build_Record_Deep_Procs (Typ : Entity_Id) is
   begin
      Set_TSS (Typ,
        Make_Deep_Proc (
          Prim  => Initialize_Case,
          Typ   => Typ,
          Stmts => Make_Deep_Record_Body (Initialize_Case, Typ)));

      if not Is_Return_By_Reference_Type (Typ) then
         Set_TSS (Typ,
           Make_Deep_Proc (
             Prim  => Adjust_Case,
             Typ   => Typ,
             Stmts => Make_Deep_Record_Body (Adjust_Case, Typ)));
      end if;

      Set_TSS (Typ,
        Make_Deep_Proc (
          Prim  => Finalize_Case,
          Typ   => Typ,
          Stmts => Make_Deep_Record_Body (Finalize_Case, Typ)));
   end Build_Record_Deep_Procs;

   -------------------
   -- Cleanup_Array --
   -------------------

   function Cleanup_Array
     (N    : Node_Id;
      Obj  : Node_Id;
      Typ  : Entity_Id) return List_Id
   is
      Loc        : constant Source_Ptr := Sloc (N);
      Index_List : constant List_Id := New_List;

      function Free_Component return List_Id;
      --  Generate the code to finalize the task or protected  subcomponents
      --  of a single component of the array.

      function Free_One_Dimension (Dim : Int) return List_Id;
      --  Generate a loop over one dimension of the array

      --------------------
      -- Free_Component --
      --------------------

      function Free_Component return List_Id is
         Stmts : List_Id := New_List;
         Tsk   : Node_Id;
         C_Typ : constant Entity_Id := Component_Type (Typ);

      begin
         --  Component type is known to contain tasks or protected objects

         Tsk :=
           Make_Indexed_Component (Loc,
             Prefix        => Duplicate_Subexpr_No_Checks (Obj),
             Expressions   => Index_List);

         Set_Etype (Tsk, C_Typ);

         if Is_Task_Type (C_Typ) then
            Append_To (Stmts, Cleanup_Task (N, Tsk));

         elsif Is_Simple_Protected_Type (C_Typ) then
            Append_To (Stmts, Cleanup_Protected_Object (N, Tsk));

         elsif Is_Record_Type (C_Typ) then
            Stmts := Cleanup_Record (N, Tsk, C_Typ);

         elsif Is_Array_Type (C_Typ) then
            Stmts := Cleanup_Array (N, Tsk, C_Typ);
         end if;

         return Stmts;
      end Free_Component;

      ------------------------
      -- Free_One_Dimension --
      ------------------------

      function Free_One_Dimension (Dim : Int) return List_Id is
         Index      : Entity_Id;

      begin
         if Dim > Number_Dimensions (Typ) then
            return Free_Component;

         --  Here we generate the required loop

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

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

            return New_List (
              Make_Implicit_Loop_Statement (N,
                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 => Duplicate_Subexpr (Obj),
                            Attribute_Name  => Name_Range,
                            Expressions => New_List (
                              Make_Integer_Literal (Loc, Dim))))),
                Statements =>  Free_One_Dimension (Dim + 1)));
         end if;
      end Free_One_Dimension;

   --  Start of processing for Cleanup_Array

   begin
      return Free_One_Dimension (1);
   end Cleanup_Array;

   --------------------
   -- Cleanup_Record --
   --------------------

   function Cleanup_Record
     (N    : Node_Id;
      Obj  : Node_Id;
      Typ  : Entity_Id) return List_Id
   is
      Loc   : constant Source_Ptr := Sloc (N);
      Tsk   : Node_Id;
      Comp  : Entity_Id;
      Stmts : constant List_Id    := New_List;
      U_Typ : constant Entity_Id  := Underlying_Type (Typ);

   begin
      if Has_Discriminants (U_Typ)
        and then Nkind (Parent (U_Typ)) = N_Full_Type_Declaration
        and then
          Nkind (Type_Definition (Parent (U_Typ))) = N_Record_Definition
        and then
          Present
            (Variant_Part
              (Component_List (Type_Definition (Parent (U_Typ)))))
      then
         --  For now, do not attempt to free a component that may appear in
         --  a variant, and instead issue a warning. Doing this "properly"
         --  would require building a case statement and would be quite a
         --  mess. Note that the RM only requires that free "work" for the
         --  case of a task access value, so already we go way beyond this
         --  in that we deal with the array case and non-discriminated
         --  record cases.

         Error_Msg_N
           ("task/protected object in variant record will not be freed?", N);
         return New_List (Make_Null_Statement (Loc));
      end if;

      Comp := First_Component (Typ);

      while Present (Comp) loop
         if Has_Task (Etype (Comp))
           or else Has_Simple_Protected_Object (Etype (Comp))
         then
            Tsk :=
              Make_Selected_Component (Loc,
                Prefix        => Duplicate_Subexpr_No_Checks (Obj),
                Selector_Name => New_Occurrence_Of (Comp, Loc));
            Set_Etype (Tsk, Etype (Comp));

            if Is_Task_Type (Etype (Comp)) then
               Append_To (Stmts, Cleanup_Task (N, Tsk));

            elsif Is_Simple_Protected_Type (Etype (Comp)) then
               Append_To (Stmts, Cleanup_Protected_Object (N, Tsk));

            elsif Is_Record_Type (Etype (Comp)) then

               --  Recurse, by generating the prefix of the argument to
               --  the eventual cleanup call.

               Append_List_To
                 (Stmts, Cleanup_Record (N, Tsk, Etype (Comp)));

            elsif Is_Array_Type (Etype (Comp)) then
               Append_List_To
                 (Stmts, Cleanup_Array (N, Tsk, Etype (Comp)));
            end if;
         end if;

         Next_Component (Comp);
      end loop;

      return Stmts;
   end Cleanup_Record;

   ------------------------------
   -- Cleanup_Protected_Object --
   ------------------------------

   function Cleanup_Protected_Object
     (N   : Node_Id;
      Ref : Node_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (N);

   begin
      return
        Make_Procedure_Call_Statement (Loc,
          Name => New_Reference_To (RTE (RE_Finalize_Protection), Loc),
          Parameter_Associations => New_List (
            Concurrent_Ref (Ref)));
   end Cleanup_Protected_Object;

   ------------------------------------
   -- Clean_Simple_Protected_Objects --
   ------------------------------------

   procedure Clean_Simple_Protected_Objects (N : Node_Id) is
      Stmts : constant List_Id := Statements (Handled_Statement_Sequence (N));
      Stmt  : Node_Id          := Last (Stmts);
      E     : Entity_Id;

   begin
      E := First_Entity (Current_Scope);
      while Present (E) loop
         if (Ekind (E) = E_Variable
              or else Ekind (E) = E_Constant)
           and then Has_Simple_Protected_Object (Etype (E))
           and then not Has_Task (Etype (E))
           and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration
         then
            declare
               Typ : constant Entity_Id := Etype (E);
               Ref : constant Node_Id := New_Occurrence_Of (E, Sloc (Stmt));

            begin
               if Is_Simple_Protected_Type (Typ) then
                  Append_To (Stmts, Cleanup_Protected_Object (N, Ref));

               elsif Has_Simple_Protected_Object (Typ) then
                  if Is_Record_Type (Typ) then
                     Append_List_To (Stmts, Cleanup_Record (N, Ref, Typ));

                  elsif Is_Array_Type (Typ) then
                     Append_List_To (Stmts, Cleanup_Array (N, Ref, Typ));
                  end if;
               end if;
            end;
         end if;

         Next_Entity (E);
      end loop;

      --   Analyze inserted cleanup statements

      if Present (Stmt) then
         Stmt := Next (Stmt);

         while Present (Stmt) loop
            Analyze (Stmt);
            Next (Stmt);
         end loop;
      end if;
   end Clean_Simple_Protected_Objects;

   ------------------
   -- Cleanup_Task --
   ------------------

   function Cleanup_Task
     (N   : Node_Id;
      Ref : Node_Id) return Node_Id
   is
      Loc  : constant Source_Ptr := Sloc (N);
   begin
      return
        Make_Procedure_Call_Statement (Loc,
          Name => New_Reference_To (RTE (RE_Free_Task), Loc),
          Parameter_Associations =>
            New_List (Concurrent_Ref (Ref)));
   end Cleanup_Task;

   ---------------------------------
   -- Has_Simple_Protected_Object --
   ---------------------------------

   function Has_Simple_Protected_Object (T : Entity_Id) return Boolean is
      Comp : Entity_Id;

   begin
      if Is_Simple_Protected_Type (T) then
         return True;

      elsif Is_Array_Type (T) then
         return Has_Simple_Protected_Object (Component_Type (T));

      elsif Is_Record_Type (T) then
         Comp := First_Component (T);

         while Present (Comp) loop
            if Has_Simple_Protected_Object (Etype (Comp)) then
               return True;
            end if;

            Next_Component (Comp);
         end loop;

         return False;

      else
         return False;
      end if;
   end Has_Simple_Protected_Object;

   ------------------------------
   -- Is_Simple_Protected_Type --
   ------------------------------

   function Is_Simple_Protected_Type (T : Entity_Id) return Boolean is
   begin
      return Is_Protected_Type (T) and then not Has_Entries (T);
   end Is_Simple_Protected_Type;

   ------------------------------
   -- Check_Visibly_Controlled --
   ------------------------------

   procedure Check_Visibly_Controlled
     (Prim : Final_Primitives;
      Typ  : Entity_Id;
      E    : in out Entity_Id;
      Cref : in out Node_Id)
   is
      Parent_Type : Entity_Id;
      Op          : Entity_Id;

   begin
      if Is_Derived_Type (Typ)
        and then Comes_From_Source (E)
        and then not Is_Overriding_Operation (E)
      then
         --  We know that the explicit operation on the type does not override
         --  the inherited operation of the parent, and that the derivation
         --  is from a private type that is not visibly controlled.

         Parent_Type := Etype (Typ);
         Op := Find_Prim_Op (Parent_Type, Name_Of (Prim));

         if Present (Op) then
            E := Op;

            --  Wrap the object to be initialized into the proper
            --  unchecked conversion, to be compatible with the operation
            --  to be called.

            if Nkind (Cref) = N_Unchecked_Type_Conversion then
               Cref := Unchecked_Convert_To (Parent_Type, Expression (Cref));
            else
               Cref := Unchecked_Convert_To (Parent_Type, Cref);
            end if;
         end if;
      end if;
   end Check_Visibly_Controlled;

   ---------------------
   -- Controlled_Type --
   ---------------------

   function Controlled_Type (T : Entity_Id) return Boolean is

      function Has_Some_Controlled_Component (Rec : Entity_Id) return Boolean;
      --  If type is not frozen yet, check explicitly among its components,
      --  because flag is not necessarily set.

      -----------------------------------
      -- Has_Some_Controlled_Component --
      -----------------------------------

      function Has_Some_Controlled_Component
        (Rec : Entity_Id) return Boolean
      is
         Comp : Entity_Id;

      begin
         if Has_Controlled_Component (Rec) then
            return True;

         elsif not Is_Frozen (Rec) then
            if Is_Record_Type (Rec) then
               Comp := First_Entity (Rec);

               while Present (Comp) loop
                  if not Is_Type (Comp)
                    and then Controlled_Type (Etype (Comp))
                  then
                     return True;
                  end if;

                  Next_Entity (Comp);
               end loop;

               return False;

            elsif Is_Array_Type (Rec) then
               return Is_Controlled (Component_Type (Rec));

            else
               return Has_Controlled_Component (Rec);
            end if;
         else
            return False;
         end if;
      end Has_Some_Controlled_Component;

   --  Start of processing for Controlled_Type

   begin
      --  Class-wide types must be treated as controlled because they may
      --  contain an extension that has controlled components

      --  We can skip this if finalization is not available

      return (Is_Class_Wide_Type (T)
                and then not In_Finalization_Root (T)
                and then not Restriction_Active (No_Finalization))
        or else Is_Controlled (T)
        or else Has_Some_Controlled_Component (T)
        or else (Is_Concurrent_Type (T)
                   and then Present (Corresponding_Record_Type (T))
                   and then Controlled_Type (Corresponding_Record_Type (T)));
   end Controlled_Type;

   --------------------------
   -- Controller_Component --
   --------------------------

   function Controller_Component (Typ : Entity_Id) return Entity_Id is
      T         : Entity_Id := Base_Type (Typ);
      Comp      : Entity_Id;
      Comp_Scop : Entity_Id;
      Res       : Entity_Id := Empty;
      Res_Scop  : Entity_Id := Empty;

   begin
      if Is_Class_Wide_Type (T) then
         T := Root_Type (T);
      end if;

      if Is_Private_Type (T) then
         T := Underlying_Type (T);
      end if;

      --  Fetch the outermost controller

      Comp := First_Entity (T);
      while Present (Comp) loop
         if Chars (Comp) = Name_uController then
            Comp_Scop := Scope (Original_Record_Component (Comp));

            --  If this controller is at the outermost level, no need to
            --  look for another one

            if Comp_Scop = T then
               return Comp;

            --  Otherwise record the outermost one and continue looking

            elsif Res = Empty or else Is_Ancestor (Res_Scop, Comp_Scop) then
               Res      := Comp;
               Res_Scop := Comp_Scop;
            end if;
         end if;

         Next_Entity (Comp);
      end loop;

      --  If we fall through the loop, there is no controller component

      return Res;
   end Controller_Component;

   ------------------
   -- Convert_View --
   ------------------

   function Convert_View
     (Proc : Entity_Id;
      Arg  : Node_Id;
      Ind  : Pos := 1) return Node_Id
   is
      Fent : Entity_Id := First_Entity (Proc);
      Ftyp : Entity_Id;
      Atyp : Entity_Id;

   begin
      for J in 2 .. Ind loop
         Next_Entity (Fent);
      end loop;

      Ftyp := Etype (Fent);

      if Nkind (Arg) = N_Type_Conversion
        or else Nkind (Arg) = N_Unchecked_Type_Conversion
      then
         Atyp := Entity (Subtype_Mark (Arg));
      else
         Atyp := Etype (Arg);
      end if;

      if Is_Abstract (Proc) and then Is_Tagged_Type (Ftyp) then
         return Unchecked_Convert_To (Class_Wide_Type (Ftyp), Arg);

      elsif Ftyp /= Atyp
        and then Present (Atyp)
        and then
          (Is_Private_Type (Ftyp) or else Is_Private_Type (Atyp))
        and then
           Base_Type (Underlying_Type (Atyp)) =
             Base_Type (Underlying_Type (Ftyp))
      then
         return Unchecked_Convert_To (Ftyp, Arg);

      --  If the argument is already a conversion, as generated by
      --  Make_Init_Call, set the target type to the type of the formal
      --  directly, to avoid spurious typing problems.

      elsif (Nkind (Arg) = N_Unchecked_Type_Conversion
              or else Nkind (Arg) = N_Type_Conversion)
        and then not Is_Class_Wide_Type (Atyp)
      then
         Set_Subtype_Mark (Arg, New_Occurrence_Of (Ftyp, Sloc (Arg)));
         Set_Etype (Arg, Ftyp);
         return Arg;

      else
         return Arg;
      end if;
   end Convert_View;

   -------------------------------
   -- Establish_Transient_Scope --
   -------------------------------

   --  This procedure is called each time a transient block has to be inserted
   --  that is to say for each call to a function with unconstrained ot tagged
   --  result. It creates a new scope on the stack scope in order to enclose
   --  all transient variables generated

   procedure Establish_Transient_Scope (N : Node_Id; Sec_Stack : Boolean) is
      Loc       : constant Source_Ptr := Sloc (N);
      Wrap_Node : Node_Id;

      Sec_Stk : constant Boolean :=
                  Sec_Stack and not Functions_Return_By_DSP_On_Target;
      --  We never need a secondary stack if functions return by DSP

   begin
      --  Do not create a transient scope if we are already inside one

      for S in reverse Scope_Stack.First .. Scope_Stack.Last loop

         if Scope_Stack.Table (S).Is_Transient then
            if Sec_Stk then
               Set_Uses_Sec_Stack (Scope_Stack.Table (S).Entity);
            end if;

            return;

         --  If we have encountered Standard there are no enclosing
         --  transient scopes.

         elsif Scope_Stack.Table (S).Entity = Standard_Standard then
            exit;

         end if;
      end loop;

      Wrap_Node := Find_Node_To_Be_Wrapped (N);

      --  Case of no wrap node, false alert, no transient scope needed

      if No (Wrap_Node) then
         null;

      --  If the node to wrap is an iteration_scheme, the expression is
      --  one of the bounds, and the expansion will make an explicit
      --  declaration for it (see Analyze_Iteration_Scheme, sem_ch5.adb),
      --  so do not apply any transformations here.

      elsif Nkind (Wrap_Node) = N_Iteration_Scheme then
         null;

      else
         New_Scope (New_Internal_Entity (E_Block, Current_Scope, Loc, 'B'));
         Set_Scope_Is_Transient;

         if Sec_Stk then
            Set_Uses_Sec_Stack (Current_Scope);
            Check_Restriction (No_Secondary_Stack, N);
         end if;

         Set_Etype (Current_Scope, Standard_Void_Type);
         Set_Node_To_Be_Wrapped (Wrap_Node);

         if Debug_Flag_W then
            Write_Str ("    <Transient>");
            Write_Eol;
         end if;
      end if;
   end Establish_Transient_Scope;

   ----------------------------
   -- Expand_Cleanup_Actions --
   ----------------------------

   procedure Expand_Cleanup_Actions (N : Node_Id) is
      Loc                  :  Source_Ptr;
      S                    : constant Entity_Id  :=
                               Current_Scope;
      Flist                : constant Entity_Id  :=
                               Finalization_Chain_Entity (S);
      Is_Task              : constant Boolean    :=
                               (Nkind (Original_Node (N)) = N_Task_Body);
      Is_Master            : constant Boolean    :=
                               Nkind (N) /= N_Entry_Body
                                 and then Is_Task_Master (N);
      Is_Protected         : constant Boolean    :=
                               Nkind (N) = N_Subprogram_Body
                                 and then Is_Protected_Subprogram_Body (N);
      Is_Task_Allocation   : constant Boolean    :=
                               Nkind (N) = N_Block_Statement
                                 and then Is_Task_Allocation_Block (N);
      Is_Asynchronous_Call : constant Boolean    :=
                               Nkind (N) = N_Block_Statement
                                 and then Is_Asynchronous_Call_Block (N);

      Clean     : Entity_Id;
      Mark      : Entity_Id := Empty;
      New_Decls : constant List_Id := New_List;
      Blok      : Node_Id;
      End_Lab   : Node_Id;
      Wrapped   : Boolean;
      Chain     : Entity_Id := Empty;
      Decl      : Node_Id;
      Old_Poll  : Boolean;

   begin

      --  Compute a location that is not directly in the user code in
      --  order to avoid to generate confusing debug info. A good
      --  approximation is the name of the outer user-defined scope

      declare
         S1 : Entity_Id := S;

      begin
         while not Comes_From_Source (S1) and then S1 /= Standard_Standard loop
            S1 := Scope (S1);
         end loop;

         Loc := Sloc (S1);
      end;

      --  There are cleanup actions only if the secondary stack needs
      --  releasing or some finalizations are needed or in the context
      --  of tasking

      if Uses_Sec_Stack  (Current_Scope)
        and then not Sec_Stack_Needed_For_Return (Current_Scope)
      then
         null;
      elsif No (Flist)
        and then not Is_Master
        and then not Is_Task
        and then not Is_Protected
        and then not Is_Task_Allocation
        and then not Is_Asynchronous_Call
      then
         Clean_Simple_Protected_Objects (N);
         return;
      end if;

      --  If the current scope is the subprogram body that is the rewriting
      --  of a task body, and the descriptors have not been delayed (due to
      --  some nested instantiations) do not generate redundant cleanup
      --  actions: the cleanup procedure already exists for this body.

      if Nkind (N) = N_Subprogram_Body
        and then Nkind (Original_Node (N)) = N_Task_Body
        and then not Delay_Subprogram_Descriptors (Corresponding_Spec (N))
      then
         return;
      end if;

      --  Set polling off, since we don't need to poll during cleanup
      --  actions, and indeed for the cleanup routine, which is executed
      --  with aborts deferred, we don't want polling.

      Old_Poll := Polling_Required;
      Polling_Required := False;

      --  Make sure we have a declaration list, since we will add to it

      if No (Declarations (N)) then
         Set_Declarations (N, New_List);
      end if;

      --  The task activation call has already been built for task
      --  allocation blocks.

      if not Is_Task_Allocation then
         Build_Task_Activation_Call (N);
      end if;

      if Is_Master then
         Establish_Task_Master (N);
      end if;

      --  If secondary stack is in use, expand:
      --    _Mxx : constant Mark_Id := SS_Mark;

      --  Suppress calls to SS_Mark and SS_Release if Java_VM,
      --  since we never use the secondary stack on the JVM.

      if Uses_Sec_Stack (Current_Scope)
        and then not Sec_Stack_Needed_For_Return (Current_Scope)
        and then not Java_VM
      then
         Mark := Make_Defining_Identifier (Loc, New_Internal_Name ('M'));
         Append_To (New_Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Mark,
             Object_Definition   => New_Reference_To (RTE (RE_Mark_Id), Loc),
             Expression =>
               Make_Function_Call (Loc,
                 Name => New_Reference_To (RTE (RE_SS_Mark), Loc))));

         Set_Uses_Sec_Stack (Current_Scope, False);
      end if;

      --  If finalization list is present then expand:
      --   Local_Final_List : System.FI.Finalizable_Ptr;

      if Present (Flist) then
         Append_To (New_Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Flist,
             Object_Definition   =>
               New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
      end if;

      --  Clean-up procedure definition

      Clean := Make_Defining_Identifier (Loc, Name_uClean);
      Set_Suppress_Elaboration_Warnings (Clean);
      Append_To (New_Decls,
        Make_Clean (N, Clean, Mark, Flist,
          Is_Task,
          Is_Master,
          Is_Protected,
          Is_Task_Allocation,
          Is_Asynchronous_Call));

      --  If exception handlers are present, wrap the Sequence of
      --  statements in a block because it is not possible to get
      --  exception handlers and an AT END call in the same scope.

      if Present (Exception_Handlers (Handled_Statement_Sequence (N))) then

         --  Preserve end label to provide proper cross-reference information

         End_Lab := End_Label (Handled_Statement_Sequence (N));
         Blok :=
           Make_Block_Statement (Loc,
             Handled_Statement_Sequence => Handled_Statement_Sequence (N));
         Set_Handled_Statement_Sequence (N,
           Make_Handled_Sequence_Of_Statements (Loc, New_List (Blok)));
         Set_End_Label (Handled_Statement_Sequence (N), End_Lab);
         Wrapped := True;

         --  Comment needed here, see RH for 1.306 ???

         if Nkind (N) = N_Subprogram_Body then
            Set_Has_Nested_Block_With_Handler (Current_Scope);
         end if;

      --  Otherwise we do not wrap

      else
         Wrapped := False;
         Blok    := Empty;
      end if;

      --  Don't move the _chain Activation_Chain declaration in task
      --  allocation blocks. Task allocation blocks use this object
      --  in their cleanup handlers, and gigi complains if it is declared
      --  in the sequence of statements of the scope that declares the
      --  handler.

      if Is_Task_Allocation then
         Chain := Activation_Chain_Entity (N);
         Decl := First (Declarations (N));

         while Nkind (Decl) /= N_Object_Declaration
           or else Defining_Identifier (Decl) /= Chain
         loop
            Next (Decl);
            pragma Assert (Present (Decl));
         end loop;

         Remove (Decl);
         Prepend_To (New_Decls, Decl);
      end if;

      --  Now we move the declarations into the Sequence of statements
      --  in order to get them protected by the AT END call. It may seem
      --  weird to put declarations in the sequence of statement but in
      --  fact nothing forbids that at the tree level. We also set the
      --  First_Real_Statement field so that we remember where the real
      --  statements (i.e. original statements) begin. Note that if we
      --  wrapped the statements, the first real statement is inside the
      --  inner block. If the First_Real_Statement is already set (as is
      --  the case for subprogram bodies that are expansions of task bodies)
      --  then do not reset it, because its declarative part would migrate
      --  to the statement part.

      if not Wrapped then
         if No (First_Real_Statement (Handled_Statement_Sequence (N))) then
            Set_First_Real_Statement (Handled_Statement_Sequence (N),
              First (Statements (Handled_Statement_Sequence (N))));
         end if;

      else
         Set_First_Real_Statement (Handled_Statement_Sequence (N), Blok);
      end if;

      Append_List_To (Declarations (N),
        Statements (Handled_Statement_Sequence (N)));
      Set_Statements (Handled_Statement_Sequence (N), Declarations (N));

      --  We need to reset the Sloc of the handled statement sequence to
      --  properly reflect the new initial "statement" in the sequence.

      Set_Sloc
        (Handled_Statement_Sequence (N), Sloc (First (Declarations (N))));

      --  The declarations of the _Clean procedure and finalization chain
      --  replace the old declarations that have been moved inward

      Set_Declarations (N, New_Decls);
      Analyze_Declarations (New_Decls);

      --  The At_End call is attached to the sequence of statements

      declare
         HSS : Node_Id;

      begin
         --  If the construct is a protected subprogram, then the call to
         --  the corresponding unprotected program appears in a block which
         --  is the last statement in the body, and it is this block that
         --  must be covered by the At_End handler.

         if Is_Protected then
            HSS := Handled_Statement_Sequence
              (Last (Statements (Handled_Statement_Sequence (N))));
         else
            HSS := Handled_Statement_Sequence (N);
         end if;

         Set_At_End_Proc (HSS, New_Occurrence_Of (Clean, Loc));
         Expand_At_End_Handler (HSS, Empty);
      end;

      --  Restore saved polling mode

      Polling_Required := Old_Poll;
   end Expand_Cleanup_Actions;

   -------------------------------
   -- Expand_Ctrl_Function_Call --
   -------------------------------

   procedure Expand_Ctrl_Function_Call (N : Node_Id) is
      Loc     : constant Source_Ptr := Sloc (N);
      Rtype   : constant Entity_Id  := Etype (N);
      Utype   : constant Entity_Id  := Underlying_Type (Rtype);
      Ref     : Node_Id;
      Action  : Node_Id;
      Action2 : Node_Id := Empty;

      Attach_Level : Uint    := Uint_1;
      Len_Ref      : Node_Id := Empty;

      function Last_Array_Component
        (Ref : Node_Id;
         Typ : Entity_Id) return Node_Id;
      --  Creates a reference to the last component of the array object
      --  designated by Ref whose type is Typ.

      --------------------------
      -- Last_Array_Component --
      --------------------------

      function Last_Array_Component
        (Ref : Node_Id;
         Typ : Entity_Id) return Node_Id
      is
         Index_List : constant List_Id := New_List;

      begin
         for N in 1 .. Number_Dimensions (Typ) loop
            Append_To (Index_List,
              Make_Attribute_Reference (Loc,
                Prefix         => Duplicate_Subexpr_No_Checks (Ref),
                Attribute_Name => Name_Last,
                Expressions    => New_List (
                  Make_Integer_Literal (Loc, N))));
         end loop;

         return
           Make_Indexed_Component (Loc,
             Prefix      => Duplicate_Subexpr (Ref),
             Expressions => Index_List);
      end Last_Array_Component;

   --  Start of processing for Expand_Ctrl_Function_Call

   begin
      --  Optimization, if the returned value (which is on the sec-stack)
      --  is returned again, no need to copy/readjust/finalize, we can just
      --  pass the value thru (see Expand_N_Return_Statement), and thus no
      --  attachment is needed

      if Nkind (Parent (N)) = N_Return_Statement then
         return;
      end if;

      --  Resolution is now finished, make sure we don't start analysis again
      --  because of the duplication

      Set_Analyzed (N);
      Ref := Duplicate_Subexpr_No_Checks (N);

      --  Now we can generate the Attach Call, note that this value is
      --  always in the (secondary) stack and thus is attached to a singly
      --  linked final list:

      --    Resx := F (X)'reference;
      --    Attach_To_Final_List (_Lx, Resx.all, 1);

      --  or when there are controlled components

      --    Attach_To_Final_List (_Lx, Resx._controller, 1);

      --  or when it is both is_controlled and has_controlled_components

      --    Attach_To_Final_List (_Lx, Resx._controller, 1);
      --    Attach_To_Final_List (_Lx, Resx, 1);

      --  or if it is an array with is_controlled (and has_controlled)

      --    Attach_To_Final_List (_Lx, Resx (Resx'last), 3);
      --    An attach level of 3 means that a whole array is to be
      --    attached to the finalization list (including the controlled
      --    components)

      --  or if it is an array with has_controlled components but not
      --  is_controlled

      --    Attach_To_Final_List (_Lx, Resx (Resx'last)._controller, 3);

      if Has_Controlled_Component (Rtype) then
         declare
            T1 : Entity_Id := Rtype;
            T2 : Entity_Id := Utype;

         begin
            if Is_Array_Type (T2) then
               Len_Ref :=
                 Make_Attribute_Reference (Loc,
                 Prefix =>
                   Duplicate_Subexpr_Move_Checks
                     (Unchecked_Convert_To (T2, Ref)),
                 Attribute_Name => Name_Length);
            end if;

            while Is_Array_Type (T2) loop
               if T1 /= T2 then
                  Ref := Unchecked_Convert_To (T2, Ref);
               end if;

               Ref := Last_Array_Component (Ref, T2);
               Attach_Level := Uint_3;
               T1 := Component_Type (T2);
               T2 := Underlying_Type (T1);
            end loop;

            --  If the type has controlled components, go to the controller
            --  except in the case of arrays of controlled objects since in
            --  this case objects and their components are already chained
            --  and the head of the chain is the last array element.

            if Is_Array_Type (Rtype) and then Is_Controlled (T2) then
               null;

            elsif Has_Controlled_Component (T2) then
               if T1 /= T2 then
                  Ref := Unchecked_Convert_To (T2, Ref);
               end if;

               Ref :=
                 Make_Selected_Component (Loc,
                   Prefix        => Ref,
                   Selector_Name => Make_Identifier (Loc, Name_uController));
            end if;
         end;

         --  Here we know that 'Ref' has a controller so we may as well
         --  attach it directly

         Action :=
           Make_Attach_Call (
             Obj_Ref      => Ref,
             Flist_Ref    => Find_Final_List (Current_Scope),
             With_Attach  => Make_Integer_Literal (Loc, Attach_Level));

         --  If it is also Is_Controlled we need to attach the global object

         if Is_Controlled (Rtype) then
            Action2 :=
              Make_Attach_Call (
                Obj_Ref      => Duplicate_Subexpr_No_Checks (N),
                Flist_Ref    => Find_Final_List (Current_Scope),
                With_Attach  => Make_Integer_Literal (Loc, Attach_Level));
         end if;

      else
         --  Here, we have a controlled type that does not seem to have
         --  controlled components but it could be a class wide type whose
         --  further derivations have controlled components. So we don't know
         --  if the object itself needs to be attached or if it
         --  has a record controller. We need to call a runtime function
         --  (Deep_Tag_Attach) which knows what to do thanks to the
         --  RC_Offset in the dispatch table.

         Action :=
           Make_Procedure_Call_Statement (Loc,
             Name => New_Reference_To (RTE (RE_Deep_Tag_Attach), Loc),
             Parameter_Associations => New_List (
               Find_Final_List (Current_Scope),

               Make_Attribute_Reference (Loc,
                   Prefix => Ref,
                   Attribute_Name => Name_Address),

               Make_Integer_Literal (Loc, Attach_Level)));
      end if;

      if Present (Len_Ref) then
         Action :=
           Make_Implicit_If_Statement (N,
             Condition => Make_Op_Gt (Loc,
               Left_Opnd  => Len_Ref,
               Right_Opnd => Make_Integer_Literal (Loc, 0)),
             Then_Statements => New_List (Action));
      end if;

      Insert_Action (N, Action);
      if Present (Action2) then
         Insert_Action (N, Action2);
      end if;
   end Expand_Ctrl_Function_Call;

   ---------------------------
   -- Expand_N_Package_Body --
   ---------------------------

   --  Add call to Activate_Tasks if body is an activator (actual
   --  processing is in chapter 9).

   --  Generate subprogram descriptor for elaboration routine

   --  ENcode entity names in package body

   procedure Expand_N_Package_Body (N : Node_Id) is
      Ent : constant Entity_Id := Corresponding_Spec (N);

   begin
      --  This is done only for non-generic packages

      if Ekind (Ent) = E_Package then
         New_Scope (Corresponding_Spec (N));
         Build_Task_Activation_Call (N);
         Pop_Scope;
      end if;

      Set_Elaboration_Flag (N, Corresponding_Spec (N));
      Set_In_Package_Body (Ent, False);

      --  Set to encode entity names in package body before gigi is called

      Qualify_Entity_Names (N);
   end Expand_N_Package_Body;

   ----------------------------------
   -- Expand_N_Package_Declaration --
   ----------------------------------

   --  Add call to Activate_Tasks if there are tasks declared and the
   --  package has no body. Note that in Ada83,  this may result in
   --  premature activation of some tasks, given that we cannot tell
   --  whether a body will eventually appear.

   procedure Expand_N_Package_Declaration (N : Node_Id) is
   begin
      if Nkind (Parent (N)) = N_Compilation_Unit
        and then not Body_Required (Parent (N))
        and then not Unit_Requires_Body (Defining_Entity (N))
        and then Present (Activation_Chain_Entity (N))
      then
         New_Scope (Defining_Entity (N));
         Build_Task_Activation_Call (N);
         Pop_Scope;
      end if;

      --  Note: it is not necessary to worry about generating a subprogram
      --  descriptor, since the only way to get exception handlers into a
      --  package spec is to include instantiations, and that would cause
      --  generation of subprogram descriptors to be delayed in any case.

      --  Set to encode entity names in package spec before gigi is called

      Qualify_Entity_Names (N);
   end Expand_N_Package_Declaration;

   ---------------------
   -- Find_Final_List --
   ---------------------

   function Find_Final_List
     (E   : Entity_Id;
      Ref : Node_Id := Empty) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Ref);
      S   : Entity_Id;
      Id  : Entity_Id;
      R   : Node_Id;

   begin
      --  Case of an internal component. The Final list is the record
      --  controller of the enclosing record

      if Present (Ref) then
         R := Ref;
         loop
            case Nkind (R) is
               when N_Unchecked_Type_Conversion | N_Type_Conversion =>
                  R := Expression (R);

               when N_Indexed_Component | N_Explicit_Dereference =>
                  R := Prefix (R);

               when  N_Selected_Component =>
                  R := Prefix (R);
                  exit;

               when  N_Identifier =>
                  exit;

               when others =>
                  raise Program_Error;
            end case;
         end loop;

         return
           Make_Selected_Component (Loc,
             Prefix =>
               Make_Selected_Component (Loc,
                 Prefix        => R,
                 Selector_Name => Make_Identifier (Loc, Name_uController)),
             Selector_Name => Make_Identifier (Loc, Name_F));

      --  Case of a dynamically allocated object. The final list is the
      --  corresponding list controller (The next entity in the scope of
      --  the access type with the right type). If the type comes from a
      --  With_Type clause, no controller was created, and we use the
      --  global chain instead.

      elsif Is_Access_Type (E) then
         if not From_With_Type (E) then
            return
              Make_Selected_Component (Loc,
                Prefix        =>
                  New_Reference_To
                    (Associated_Final_Chain (Base_Type (E)), Loc),
                Selector_Name => Make_Identifier (Loc, Name_F));
         else
            return New_Reference_To (RTE (RE_Global_Final_List), Sloc (E));
         end if;

      else
         if Is_Dynamic_Scope (E) then
            S := E;
         else
            S := Enclosing_Dynamic_Scope (E);
         end if;

         --  When the finalization chain entity is 'Error', it means that
         --  there should not be any chain at that level and that the
         --  enclosing one should be used

         --  This is a nasty kludge, see ??? note in exp_ch11

         while Finalization_Chain_Entity (S) = Error loop
            S := Enclosing_Dynamic_Scope (S);
         end loop;

         if S = Standard_Standard then
            return New_Reference_To (RTE (RE_Global_Final_List), Sloc (E));
         else
            if No (Finalization_Chain_Entity (S)) then

               Id := Make_Defining_Identifier (Sloc (S),
                 New_Internal_Name ('F'));
               Set_Finalization_Chain_Entity (S, Id);

               --  Set momentarily some semantics attributes to allow normal
               --  analysis of expansions containing references to this chain.
               --  Will be fully decorated during the expansion of the scope
               --  itself

               Set_Ekind (Id, E_Variable);
               Set_Etype (Id, RTE (RE_Finalizable_Ptr));
            end if;

            return New_Reference_To (Finalization_Chain_Entity (S), Sloc (E));
         end if;
      end if;
   end Find_Final_List;

   -----------------------------
   -- Find_Node_To_Be_Wrapped --
   -----------------------------

   function Find_Node_To_Be_Wrapped (N : Node_Id) return Node_Id is
      P          : Node_Id;
      The_Parent : Node_Id;

   begin
      The_Parent := N;
      loop
         P := The_Parent;
         pragma Assert (P /= Empty);
         The_Parent := Parent (P);

         case Nkind (The_Parent) is

            --  Simple statement can be wrapped

            when N_Pragma               =>
               return The_Parent;

            --  Usually assignments are good candidate for wrapping
            --  except when they have been generated as part of a
            --  controlled aggregate where the wrapping should take
            --  place more globally.

            when N_Assignment_Statement =>
               if No_Ctrl_Actions (The_Parent) then
                  null;
               else
                  return The_Parent;
               end if;

            --  An entry call statement is a special case if it occurs in
            --  the context of a Timed_Entry_Call. In this case we wrap
            --  the entire timed entry call.

            when N_Entry_Call_Statement     |
                 N_Procedure_Call_Statement =>
               if Nkind (Parent (The_Parent)) = N_Entry_Call_Alternative
                 and then
                   (Nkind (Parent (Parent (The_Parent)))
                     = N_Timed_Entry_Call
                   or else
                     Nkind (Parent (Parent (The_Parent)))
                       = N_Conditional_Entry_Call)
               then
                  return Parent (Parent (The_Parent));
               else
                  return The_Parent;
               end if;

            --  Object declarations are also a boundary for the transient scope
            --  even if they are not really wrapped
            --  (see Wrap_Transient_Declaration)

            when N_Object_Declaration          |
                 N_Object_Renaming_Declaration |
                 N_Subtype_Declaration         =>
               return The_Parent;

            --  The expression itself is to be wrapped if its parent is a
            --  compound statement or any other statement where the expression
            --  is known to be scalar

            when N_Accept_Alternative               |
                 N_Attribute_Definition_Clause      |
                 N_Case_Statement                   |
                 N_Code_Statement                   |
                 N_Delay_Alternative                |
                 N_Delay_Until_Statement            |
                 N_Delay_Relative_Statement         |
                 N_Discriminant_Association         |
                 N_Elsif_Part                       |
                 N_Entry_Body_Formal_Part           |
                 N_Exit_Statement                   |
                 N_If_Statement                     |
                 N_Iteration_Scheme                 |
                 N_Terminate_Alternative            =>
               return P;

            when N_Attribute_Reference              =>

               if Is_Procedure_Attribute_Name
                    (Attribute_Name (The_Parent))
               then
                  return The_Parent;
               end if;

            --  A raise statement can be wrapped. This will arise when the
            --  expression in a raise_with_expression uses the secondary
            --  stack, for example.

            when N_Raise_Statement  =>
               return The_Parent;

            --  If the expression is within the iteration scheme of a loop,
            --  we must create a declaration for it, followed by an assignment
            --  in order to have a usable statement to wrap.

            when N_Loop_Parameter_Specification =>
               return Parent (The_Parent);

            --  The following nodes contains "dummy calls" which don't
            --  need to be wrapped.

            when N_Parameter_Specification     |
                 N_Discriminant_Specification  |
                 N_Component_Declaration       =>
               return Empty;

            --  The return statement is not to be wrapped when the function
            --  itself needs wrapping at the outer-level

            when N_Return_Statement            =>
               if Requires_Transient_Scope (Return_Type (The_Parent)) then
                  return Empty;
               else
                  return The_Parent;
               end if;

            --  If we leave a scope without having been able to find a node to
            --  wrap, something is going wrong but this can happen in error
            --  situation that are not detected yet (such as a dynamic string
            --  in a pragma export)

            when N_Subprogram_Body     |
                 N_Package_Declaration |
                 N_Package_Body        |
                 N_Block_Statement     =>
               return Empty;

            --  otherwise continue the search

            when others =>
               null;
         end case;
      end loop;
   end Find_Node_To_Be_Wrapped;

   ----------------------
   -- Global_Flist_Ref --
   ----------------------

   function Global_Flist_Ref  (Flist_Ref : Node_Id) return Boolean is
      Flist : Entity_Id;

   begin
      --  Look for the Global_Final_List

      if Is_Entity_Name (Flist_Ref) then
         Flist := Entity (Flist_Ref);

      --  Look for the final list associated with an access to controlled

      elsif  Nkind (Flist_Ref) = N_Selected_Component
        and then Is_Entity_Name (Prefix (Flist_Ref))
      then
         Flist :=  Entity (Prefix (Flist_Ref));
      else
         return False;
      end if;

      return Present (Flist)
        and then Present (Scope (Flist))
        and then Enclosing_Dynamic_Scope (Flist) = Standard_Standard;
   end Global_Flist_Ref;

   ----------------------------------
   -- Has_New_Controlled_Component --
   ----------------------------------

   function Has_New_Controlled_Component (E : Entity_Id) return Boolean is
      Comp : Entity_Id;

   begin
      if not Is_Tagged_Type (E) then
         return Has_Controlled_Component (E);
      elsif not Is_Derived_Type (E) then
         return Has_Controlled_Component (E);
      end if;

      Comp := First_Component (E);
      while Present (Comp) loop

         if Chars (Comp) = Name_uParent then
            null;

         elsif Scope (Original_Record_Component (Comp)) = E
           and then Controlled_Type (Etype (Comp))
         then
            return True;
         end if;

         Next_Component (Comp);
      end loop;

      return False;
   end Has_New_Controlled_Component;

   --------------------------
   -- In_Finalization_Root --
   --------------------------

   --  It would seem simpler to test Scope (RTE (RE_Root_Controlled)) but
   --  the purpose of this function is to avoid a circular call to Rtsfind
   --  which would been caused by such a test.

   function In_Finalization_Root (E : Entity_Id) return Boolean is
      S : constant Entity_Id := Scope (E);

   begin
      return Chars (Scope (S))     = Name_System
        and then Chars (S)         = Name_Finalization_Root
        and then Scope (Scope (S)) = Standard_Standard;
   end  In_Finalization_Root;

   ------------------------------------
   -- Insert_Actions_In_Scope_Around --
   ------------------------------------

   procedure Insert_Actions_In_Scope_Around (N : Node_Id) is
      SE     : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);
      Target : Node_Id;

   begin
      --  If the node to be wrapped is the triggering alternative of an
      --  asynchronous select, it is not part of a statement list. The
      --  actions must be inserted before the Select itself, which is
      --  part of some list of statements.

      if Nkind (Parent (Node_To_Be_Wrapped)) = N_Triggering_Alternative then
         Target := Parent (Parent (Node_To_Be_Wrapped));
      else
         Target := N;
      end if;

      if Present (SE.Actions_To_Be_Wrapped_Before) then
         Insert_List_Before (Target, SE.Actions_To_Be_Wrapped_Before);
         SE.Actions_To_Be_Wrapped_Before := No_List;
      end if;

      if Present (SE.Actions_To_Be_Wrapped_After) then
         Insert_List_After (Target, SE.Actions_To_Be_Wrapped_After);
         SE.Actions_To_Be_Wrapped_After := No_List;
      end if;
   end Insert_Actions_In_Scope_Around;

   -----------------------
   -- Make_Adjust_Call --
   -----------------------

   function Make_Adjust_Call
     (Ref         : Node_Id;
      Typ         : Entity_Id;
      Flist_Ref   : Node_Id;
      With_Attach : Node_Id;
      Allocator   : Boolean := False) return List_Id
   is
      Loc    : constant Source_Ptr := Sloc (Ref);
      Res    : constant List_Id    := New_List;
      Utyp   : Entity_Id;
      Proc   : Entity_Id;
      Cref   : Node_Id := Ref;
      Cref2  : Node_Id;
      Attach : Node_Id := With_Attach;

   begin
      if Is_Class_Wide_Type (Typ) then
         Utyp := Underlying_Type (Base_Type (Root_Type (Typ)));
      else
         Utyp := Underlying_Type (Base_Type (Typ));
      end if;

      Set_Assignment_OK (Cref);

      --  Deal with non-tagged derivation of private views

      if Is_Untagged_Derivation (Typ) then
         Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
         Cref := Unchecked_Convert_To (Utyp, Cref);
         Set_Assignment_OK (Cref);
         --  To prevent problems with UC see 1.156 RH ???
      end if;

      --  If the underlying_type is a subtype, we are dealing with
      --  the completion of a private type. We need to access
      --  the base type and generate a conversion to it.

      if Utyp /= Base_Type (Utyp) then
         pragma Assert (Is_Private_Type (Typ));
         Utyp := Base_Type (Utyp);
         Cref := Unchecked_Convert_To (Utyp, Cref);
      end if;

      --  If the object is unanalyzed, set its expected type for use
      --  in Convert_View in case an additional conversion is needed.

      if No (Etype (Cref))
        and then Nkind (Cref) /= N_Unchecked_Type_Conversion
      then
         Set_Etype (Cref, Typ);
      end if;

      --  We do not need to attach to one of the Global Final Lists
      --  the objects whose type is Finalize_Storage_Only

      if Finalize_Storage_Only (Typ)
        and then (Global_Flist_Ref (Flist_Ref)
          or else Entity (Constant_Value (RTE (RE_Garbage_Collected)))
                  = Standard_True)
      then
         Attach := Make_Integer_Literal (Loc, 0);
      end if;

      --  Special case for allocators: need initialization of the chain
      --  pointers. For the 0 case, reset them to null.

      if Allocator then
         pragma Assert (Nkind (Attach) = N_Integer_Literal);

         if Intval (Attach) = 0 then
            Set_Intval (Attach, Uint_4);
         end if;
      end if;

      --  Generate:
      --    Deep_Adjust (Flist_Ref, Ref, Attach);

      if Has_Controlled_Component (Utyp)
        or else Is_Class_Wide_Type (Typ)
      then
         if Is_Tagged_Type (Utyp) then
            Proc := Find_Prim_Op (Utyp, TSS_Deep_Adjust);

         else
            Proc := TSS (Utyp, TSS_Deep_Adjust);
         end if;

         Cref := Convert_View (Proc, Cref, 2);

         Append_To (Res,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Reference_To (Proc, Loc),
             Parameter_Associations =>
               New_List (Flist_Ref, Cref, Attach)));

      --  Generate:
      --    if With_Attach then
      --       Attach_To_Final_List (Ref, Flist_Ref);
      --    end if;
      --    Adjust (Ref);

      else -- Is_Controlled (Utyp)

         Proc  := Find_Prim_Op (Utyp, Name_Of (Adjust_Case));
         Cref  := Convert_View (Proc, Cref);
         Cref2 := New_Copy_Tree (Cref);

         Append_To (Res,
           Make_Procedure_Call_Statement (Loc,
           Name => New_Reference_To (Proc, Loc),
           Parameter_Associations => New_List (Cref2)));

         Append_To (Res, Make_Attach_Call (Cref, Flist_Ref, Attach));
      end if;

      return Res;
   end Make_Adjust_Call;

   ----------------------
   -- Make_Attach_Call --
   ----------------------

   --  Generate:
   --    System.FI.Attach_To_Final_List (Flist, Ref, Nb_Link)

   function Make_Attach_Call
     (Obj_Ref     : Node_Id;
      Flist_Ref   : Node_Id;
      With_Attach : Node_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Obj_Ref);

   begin
      --  Optimization: If the number of links is statically '0', don't
      --  call the attach_proc.

      if Nkind (With_Attach) = N_Integer_Literal
        and then Intval (With_Attach) = Uint_0
      then
         return Make_Null_Statement (Loc);
      end if;

      return
        Make_Procedure_Call_Statement (Loc,
          Name => New_Reference_To (RTE (RE_Attach_To_Final_List), Loc),
          Parameter_Associations => New_List (
            Flist_Ref,
            OK_Convert_To (RTE (RE_Finalizable), Obj_Ref),
            With_Attach));
   end Make_Attach_Call;

   ----------------
   -- Make_Clean --
   ----------------

   function Make_Clean
     (N                          : Node_Id;
      Clean                      : Entity_Id;
      Mark                       : Entity_Id;
      Flist                      : Entity_Id;
      Is_Task                    : Boolean;
      Is_Master                  : Boolean;
      Is_Protected_Subprogram    : Boolean;
      Is_Task_Allocation_Block   : Boolean;
      Is_Asynchronous_Call_Block : Boolean) return Node_Id
   is
      Loc  : constant Source_Ptr := Sloc (Clean);
      Stmt : constant List_Id    := New_List;

      Sbody        : Node_Id;
      Spec         : Node_Id;
      Name         : Node_Id;
      Param        : Node_Id;
      Param_Type   : Entity_Id;
      Pid          : Entity_Id := Empty;
      Cancel_Param : Entity_Id;

   begin
      if Is_Task then
         if Restricted_Profile then
            Append_To
              (Stmt, Build_Runtime_Call (Loc, RE_Complete_Restricted_Task));
         else
            Append_To (Stmt, Build_Runtime_Call (Loc, RE_Complete_Task));
         end if;

      elsif Is_Master then
         if Restriction_Active (No_Task_Hierarchy) = False then
            Append_To (Stmt, Build_Runtime_Call (Loc, RE_Complete_Master));
         end if;

      elsif Is_Protected_Subprogram then

         --  Add statements to the cleanup handler of the (ordinary)
         --  subprogram expanded to implement a protected subprogram,
         --  unlocking the protected object parameter and undeferring abort.
         --  If this is a protected procedure, and the object contains
         --  entries, this also calls the entry service routine.

         --  NOTE: This cleanup handler references _object, a parameter
         --        to the procedure.

         --  Find the _object parameter representing the protected object

         Spec := Parent (Corresponding_Spec (N));

         Param := First (Parameter_Specifications (Spec));
         loop
            Param_Type := Etype (Parameter_Type (Param));

            if Ekind (Param_Type) = E_Record_Type then
               Pid := Corresponding_Concurrent_Type (Param_Type);
            end if;

            exit when No (Param) or else Present (Pid);
            Next (Param);
         end loop;

         pragma Assert (Present (Param));

         --  If the associated protected object declares entries,
         --  a protected procedure has to service entry queues.
         --  In this case, add

         --  Service_Entries (_object._object'Access);

         --  _object is the record used to implement the protected object.
         --  It is a parameter to the protected subprogram.

         if Nkind (Specification (N)) = N_Procedure_Specification
           and then Has_Entries (Pid)
         then
            if Abort_Allowed
              or else Restriction_Active (No_Entry_Queue) = False
              or else Number_Entries (Pid) > 1
            then
               Name := New_Reference_To (RTE (RE_Service_Entries), Loc);
            else
               Name := New_Reference_To (RTE (RE_Service_Entry), Loc);
            end if;

            Append_To (Stmt,
              Make_Procedure_Call_Statement (Loc,
                Name => Name,
                Parameter_Associations => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix =>
                      Make_Selected_Component (Loc,
                        Prefix => New_Reference_To (
                          Defining_Identifier (Param), Loc),
                        Selector_Name =>
                          Make_Identifier (Loc, Name_uObject)),
                    Attribute_Name => Name_Unchecked_Access))));

         else
            --  Unlock (_object._object'Access);

            --  object is the record used to implement the protected object.
            --  It is a parameter to the protected subprogram.

            --  If the protected object is controlled (i.e it has entries or
            --  needs finalization for interrupt handling), call
            --  Unlock_Entries, except if the protected object follows the
            --  ravenscar profile, in which case call Unlock_Entry, otherwise
            --  call the simplified version, Unlock.

            if Has_Entries (Pid)
              or else Has_Interrupt_Handler (Pid)
              or else (Has_Attach_Handler (Pid)
                         and then not Restricted_Profile)
              or else (Ada_Version >= Ada_05
                         and then Present (Interface_List (Parent (Pid))))
            then
               if Abort_Allowed
                 or else Restriction_Active (No_Entry_Queue) = False
                 or else Number_Entries (Pid) > 1
               then
                  Name := New_Reference_To (RTE (RE_Unlock_Entries), Loc);
               else
                  Name := New_Reference_To (RTE (RE_Unlock_Entry), Loc);
               end if;

            else
               Name := New_Reference_To (RTE (RE_Unlock), Loc);
            end if;

            Append_To (Stmt,
              Make_Procedure_Call_Statement (Loc,
                Name => Name,
                Parameter_Associations => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix =>
                      Make_Selected_Component (Loc,
                        Prefix =>
                          New_Reference_To (Defining_Identifier (Param), Loc),
                        Selector_Name =>
                          Make_Identifier (Loc, Name_uObject)),
                    Attribute_Name => Name_Unchecked_Access))));
         end if;

         if Abort_Allowed then

            --  Abort_Undefer;

            Append_To (Stmt,
              Make_Procedure_Call_Statement (Loc,
                Name =>
                  New_Reference_To (
                    RTE (RE_Abort_Undefer), Loc),
                Parameter_Associations => Empty_List));
         end if;

      elsif Is_Task_Allocation_Block then

         --  Add a call to Expunge_Unactivated_Tasks to the cleanup
         --  handler of a block created for the dynamic allocation of
         --  tasks:

         --  Expunge_Unactivated_Tasks (_chain);

         --  where _chain is the list of tasks created by the allocator
         --  but not yet activated. This list will be empty unless
         --  the block completes abnormally.

         --  This only applies to dynamically allocated tasks;
         --  other unactivated tasks are completed by Complete_Task or
         --  Complete_Master.

         --  NOTE: This cleanup handler references _chain, a local
         --        object.

         Append_To (Stmt,
           Make_Procedure_Call_Statement (Loc,
             Name =>
               New_Reference_To (
                 RTE (RE_Expunge_Unactivated_Tasks), Loc),
             Parameter_Associations => New_List (
               New_Reference_To (Activation_Chain_Entity (N), Loc))));

      elsif Is_Asynchronous_Call_Block then

         --  Add a call to attempt to cancel the asynchronous entry call
         --  whenever the block containing the abortable part is exited.

         --  NOTE: This cleanup handler references C, a local object

         --  Get the argument to the Cancel procedure
         Cancel_Param := Entry_Cancel_Parameter (Entity (Identifier (N)));

         --  If it is of type Communication_Block, this must be a
         --  protected entry call.

         if Is_RTE (Etype (Cancel_Param), RE_Communication_Block) then

            Append_To (Stmt,

            --  if Enqueued (Cancel_Parameter) then

              Make_Implicit_If_Statement (Clean,
                Condition => Make_Function_Call (Loc,
                  Name => New_Reference_To (
                    RTE (RE_Enqueued), Loc),
                  Parameter_Associations => New_List (
                    New_Reference_To (Cancel_Param, Loc))),
                Then_Statements => New_List (

            --  Cancel_Protected_Entry_Call (Cancel_Param);

                  Make_Procedure_Call_Statement (Loc,
                    Name => New_Reference_To (
                      RTE (RE_Cancel_Protected_Entry_Call), Loc),
                    Parameter_Associations => New_List (
                      New_Reference_To (Cancel_Param, Loc))))));

         --  Asynchronous delay

         elsif Is_RTE (Etype (Cancel_Param), RE_Delay_Block) then
            Append_To (Stmt,
              Make_Procedure_Call_Statement (Loc,
                Name => New_Reference_To (RTE (RE_Cancel_Async_Delay), Loc),
                Parameter_Associations => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix => New_Reference_To (Cancel_Param, Loc),
                    Attribute_Name => Name_Unchecked_Access))));

         --  Task entry call

         else
            --  Append call to Cancel_Task_Entry_Call (C);

            Append_To (Stmt,
              Make_Procedure_Call_Statement (Loc,
                Name => New_Reference_To (
                  RTE (RE_Cancel_Task_Entry_Call),
                  Loc),
                Parameter_Associations => New_List (
                  New_Reference_To (Cancel_Param, Loc))));

         end if;
      end if;

      if Present (Flist) then
         Append_To (Stmt,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Reference_To (RTE (RE_Finalize_List), Loc),
             Parameter_Associations => New_List (
                    New_Reference_To (Flist, Loc))));
      end if;

      if Present (Mark) then
         Append_To (Stmt,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Reference_To (RTE (RE_SS_Release), Loc),
             Parameter_Associations => New_List (
                    New_Reference_To (Mark, Loc))));
      end if;

      Sbody :=
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Procedure_Specification (Loc,
              Defining_Unit_Name => Clean),

          Declarations  => New_List,

          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Stmt));

      if Present (Flist) or else Is_Task or else Is_Master then
         Wrap_Cleanup_Procedure (Sbody);
      end if;

      --  We do not want debug information for _Clean routines,
      --  since it just confuses the debugging operation unless
      --  we are debugging generated code.

      if not Debug_Generated_Code then
         Set_Debug_Info_Off (Clean, True);
      end if;

      return Sbody;
   end Make_Clean;

   --------------------------
   -- Make_Deep_Array_Body --
   --------------------------

   --  Array components are initialized and adjusted in the normal order
   --  and finalized in the reverse order. Exceptions are handled and
   --  Program_Error is re-raise in the Adjust and Finalize case
   --  (RM 7.6.1(12)). Generate the following code :
   --
   --  procedure Deep_<P>   --  with <P> being Initialize or Adjust or Finalize
   --   (L : in out Finalizable_Ptr;
   --    V : in out Typ)
   --  is
   --  begin
   --     for J1 in             Typ'First (1) .. Typ'Last (1) loop
   --               ^ reverse ^  --  in the finalization case
   --        ...
   --           for J2 in Typ'First (n) .. Typ'Last (n) loop
   --                 Make_<P>_Call (Typ, V (J1, .. , Jn), L, V);
   --           end loop;
   --        ...
   --     end loop;
   --  exception                                --  not in the
   --     when others => raise Program_Error;   --     Initialize case
   --  end Deep_<P>;

   function Make_Deep_Array_Body
     (Prim : Final_Primitives;
      Typ  : Entity_Id) return List_Id
   is
      Loc : constant Source_Ptr := Sloc (Typ);

      Index_List : constant List_Id := New_List;
      --  Stores the list of references to the indexes (one per dimension)

      function One_Component return List_Id;
      --  Create one statement to initialize/adjust/finalize one array
      --  component, designated by a full set of indices.

      function One_Dimension (N : Int) return List_Id;
      --  Create loop to deal with one dimension of the array. The single
      --  statement in the body of the loop initializes the inner dimensions if
      --  any, or else a single component.

      -------------------
      -- One_Component --
      -------------------

      function One_Component return List_Id is
         Comp_Typ : constant Entity_Id := Component_Type (Typ);
         Comp_Ref : constant Node_Id :=
                      Make_Indexed_Component (Loc,
                        Prefix      => Make_Identifier (Loc, Name_V),
                        Expressions => Index_List);

      begin
         --  Set the etype of the component Reference, which is used to
         --  determine whether a conversion to a parent type is needed.

         Set_Etype (Comp_Ref, Comp_Typ);

         case Prim is
            when Initialize_Case =>
               return Make_Init_Call (Comp_Ref, Comp_Typ,
                        Make_Identifier (Loc, Name_L),
                        Make_Identifier (Loc, Name_B));

            when Adjust_Case =>
               return Make_Adjust_Call (Comp_Ref, Comp_Typ,
                        Make_Identifier (Loc, Name_L),
                        Make_Identifier (Loc, Name_B));

            when Finalize_Case =>
               return Make_Final_Call (Comp_Ref, Comp_Typ,
                        Make_Identifier (Loc, Name_B));
         end case;
      end One_Component;

      -------------------
      -- One_Dimension --
      -------------------

      function One_Dimension (N : Int) return List_Id is
         Index : Entity_Id;

      begin
         if N > Number_Dimensions (Typ) then
            return One_Component;

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

            Append_To (Index_List, New_Reference_To (Index, Loc));

            return New_List (
              Make_Implicit_Loop_Statement (Typ,
                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_V),
                            Attribute_Name  => Name_Range,
                            Expressions => New_List (
                              Make_Integer_Literal (Loc, N))),
                        Reverse_Present => Prim = Finalize_Case)),
                Statements => One_Dimension (N + 1)));
         end if;
      end One_Dimension;

   --  Start of processing for Make_Deep_Array_Body

   begin
      return One_Dimension (1);
   end Make_Deep_Array_Body;

   --------------------
   -- Make_Deep_Proc --
   --------------------

   --  Generate:
   --    procedure DEEP_<prim>
   --      (L : IN OUT Finalizable_Ptr;    -- not for Finalize
   --       V : IN OUT <typ>;
   --       B : IN Short_Short_Integer) is
   --    begin
   --       <stmts>;
   --    exception                   --  Finalize and Adjust Cases only
   --       raise Program_Error;     --  idem
   --    end DEEP_<prim>;

   function Make_Deep_Proc
     (Prim  : Final_Primitives;
      Typ   : Entity_Id;
      Stmts : List_Id) return Entity_Id
   is
      Loc       : constant Source_Ptr := Sloc (Typ);
      Formals   : List_Id;
      Proc_Name : Entity_Id;
      Handler   : List_Id := No_List;
      Type_B    : Entity_Id;

   begin
      if Prim = Finalize_Case then
         Formals := New_List;
         Type_B := Standard_Boolean;

      else
         Formals := New_List (
           Make_Parameter_Specification (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_L),
             In_Present          => True,
             Out_Present         => True,
             Parameter_Type      =>
               New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
         Type_B := Standard_Short_Short_Integer;
      end if;

      Append_To (Formals,
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
          In_Present          => True,
          Out_Present         => True,
          Parameter_Type      => New_Reference_To (Typ, Loc)));

      Append_To (Formals,
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_B),
          Parameter_Type      => New_Reference_To (Type_B, Loc)));

      if Prim = Finalize_Case or else Prim = Adjust_Case then
         Handler := New_List (
           Make_Exception_Handler (Loc,
             Exception_Choices => New_List (Make_Others_Choice (Loc)),
             Statements        => New_List (
               Make_Raise_Program_Error (Loc,
                 Reason => PE_Finalize_Raised_Exception))));
      end if;

      Proc_Name :=
        Make_Defining_Identifier (Loc,
          Chars => Make_TSS_Name (Typ, Deep_Name_Of (Prim)));

      Discard_Node (
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Procedure_Specification (Loc,
              Defining_Unit_Name       => Proc_Name,
              Parameter_Specifications => Formals),

          Declarations =>  Empty_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements         => Stmts,
              Exception_Handlers => Handler)));

      return Proc_Name;
   end Make_Deep_Proc;

   ---------------------------
   -- Make_Deep_Record_Body --
   ---------------------------

   --  The Deep procedures call the appropriate Controlling proc on the
   --  the controller component. In the init case, it also attach the
   --  controller to the current finalization list.

   function Make_Deep_Record_Body
     (Prim : Final_Primitives;
      Typ  : Entity_Id) return List_Id
   is
      Loc            : constant Source_Ptr := Sloc (Typ);
      Controller_Typ : Entity_Id;
      Obj_Ref        : constant Node_Id := Make_Identifier (Loc, Name_V);
      Controller_Ref : constant Node_Id :=
                         Make_Selected_Component (Loc,
                           Prefix        => Obj_Ref,
                           Selector_Name =>
                             Make_Identifier (Loc, Name_uController));
      Res            : constant List_Id := New_List;

   begin
      if Is_Return_By_Reference_Type (Typ) then
         Controller_Typ := RTE (RE_Limited_Record_Controller);
      else
         Controller_Typ := RTE (RE_Record_Controller);
      end if;

      case Prim is
         when Initialize_Case =>
            Append_List_To (Res,
              Make_Init_Call (
                Ref          => Controller_Ref,
                Typ          => Controller_Typ,
                Flist_Ref    => Make_Identifier (Loc, Name_L),
                With_Attach  => Make_Identifier (Loc, Name_B)));

            --  When the type is also a controlled type by itself,
            --  Initialize it and attach it to the finalization chain

            if Is_Controlled (Typ) then
               Append_To (Res,
                 Make_Procedure_Call_Statement (Loc,
                   Name => New_Reference_To (
                     Find_Prim_Op (Typ, Name_Of (Prim)), Loc),
                   Parameter_Associations =>
                     New_List (New_Copy_Tree (Obj_Ref))));

               Append_To (Res, Make_Attach_Call (
                 Obj_Ref      => New_Copy_Tree (Obj_Ref),
                 Flist_Ref    => Make_Identifier (Loc, Name_L),
                 With_Attach => Make_Identifier (Loc, Name_B)));
            end if;

         when Adjust_Case =>
            Append_List_To (Res,
              Make_Adjust_Call (Controller_Ref, Controller_Typ,
                Make_Identifier (Loc, Name_L),
                Make_Identifier (Loc, Name_B)));

            --  When the type is also a controlled type by itself,
            --  Adjust it it and attach it to the finalization chain

            if Is_Controlled (Typ) then
               Append_To (Res,
                 Make_Procedure_Call_Statement (Loc,
                   Name => New_Reference_To (
                     Find_Prim_Op (Typ, Name_Of (Prim)), Loc),
                   Parameter_Associations =>
                     New_List (New_Copy_Tree (Obj_Ref))));

               Append_To (Res, Make_Attach_Call (
                 Obj_Ref      => New_Copy_Tree (Obj_Ref),
                 Flist_Ref    => Make_Identifier (Loc, Name_L),
                 With_Attach => Make_Identifier (Loc, Name_B)));
            end if;

         when Finalize_Case =>
            if Is_Controlled (Typ) then
               Append_To (Res,
                 Make_Implicit_If_Statement (Obj_Ref,
                   Condition => Make_Identifier (Loc, Name_B),
                   Then_Statements => New_List (
                     Make_Procedure_Call_Statement (Loc,
                       Name => New_Reference_To (RTE (RE_Finalize_One), Loc),
                       Parameter_Associations => New_List (
                         OK_Convert_To (RTE (RE_Finalizable),
                           New_Copy_Tree (Obj_Ref))))),

                   Else_Statements => New_List (
                     Make_Procedure_Call_Statement (Loc,
                       Name => New_Reference_To (
                         Find_Prim_Op (Typ, Name_Of (Prim)), Loc),
                       Parameter_Associations =>
                        New_List (New_Copy_Tree (Obj_Ref))))));
            end if;

            Append_List_To (Res,
              Make_Final_Call (Controller_Ref, Controller_Typ,
                Make_Identifier (Loc, Name_B)));
      end case;
      return Res;
   end Make_Deep_Record_Body;

   ----------------------
   -- Make_Final_Call --
   ----------------------

   function Make_Final_Call
     (Ref         : Node_Id;
      Typ         : Entity_Id;
      With_Detach : Node_Id) return List_Id
   is
      Loc   : constant Source_Ptr := Sloc (Ref);
      Res   : constant List_Id    := New_List;
      Cref  : Node_Id;
      Cref2 : Node_Id;
      Proc  : Entity_Id;
      Utyp  : Entity_Id;

   begin
      if Is_Class_Wide_Type (Typ) then
         Utyp := Root_Type (Typ);
         Cref := Ref;

      elsif Is_Concurrent_Type (Typ) then
         Utyp := Corresponding_Record_Type (Typ);
         Cref := Convert_Concurrent (Ref, Typ);

      elsif Is_Private_Type (Typ)
        and then Present (Full_View (Typ))
        and then Is_Concurrent_Type (Full_View (Typ))
      then
         Utyp := Corresponding_Record_Type (Full_View (Typ));
         Cref := Convert_Concurrent (Ref, Full_View (Typ));
      else
         Utyp := Typ;
         Cref := Ref;
      end if;

      Utyp := Underlying_Type (Base_Type (Utyp));
      Set_Assignment_OK (Cref);

      --  Deal with non-tagged derivation of private views. If the parent is
      --  now known to be protected, the finalization routine is the one
      --  defined on the corresponding record of the ancestor (corresponding
      --  records do not automatically inherit operations, but maybe they
      --  should???)

      if Is_Untagged_Derivation (Typ) then
         if Is_Protected_Type (Typ) then
            Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ)));
         else
            Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
         end if;

         Cref := Unchecked_Convert_To (Utyp, Cref);

         --  We need to set Assignment_OK to prevent problems with unchecked
         --  conversions, where we do not want them to be converted back in the
         --  case of untagged record derivation (see code in Make_*_Call
         --  procedures for similar situations).

         Set_Assignment_OK (Cref);
      end if;

      --  If the underlying_type is a subtype, we are dealing with
      --  the completion of a private type. We need to access
      --  the base type and generate a conversion to it.

      if Utyp /= Base_Type (Utyp) then
         pragma Assert (Is_Private_Type (Typ));
         Utyp := Base_Type (Utyp);
         Cref := Unchecked_Convert_To (Utyp, Cref);
      end if;

      --  Generate:
      --    Deep_Finalize (Ref, With_Detach);

      if Has_Controlled_Component (Utyp)
        or else Is_Class_Wide_Type (Typ)
      then
         if Is_Tagged_Type (Utyp) then
            Proc := Find_Prim_Op (Utyp, TSS_Deep_Finalize);
         else
            Proc := TSS (Utyp, TSS_Deep_Finalize);
         end if;

         Cref := Convert_View (Proc, Cref);

         Append_To (Res,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Reference_To (Proc, Loc),
             Parameter_Associations =>
               New_List (Cref, With_Detach)));

      --  Generate:
      --    if With_Detach then
      --       Finalize_One (Ref);
      --    else
      --       Finalize (Ref);
      --    end if;

      else
         Proc := Find_Prim_Op (Utyp, Name_Of (Finalize_Case));

         if Chars (With_Detach) = Chars (Standard_True) then
            Append_To (Res,
              Make_Procedure_Call_Statement (Loc,
                Name => New_Reference_To (RTE (RE_Finalize_One), Loc),
                Parameter_Associations => New_List (
                  OK_Convert_To (RTE (RE_Finalizable), Cref))));

         elsif Chars (With_Detach) = Chars (Standard_False) then
            Append_To (Res,
              Make_Procedure_Call_Statement (Loc,
                Name => New_Reference_To (Proc, Loc),
                Parameter_Associations =>
                  New_List (Convert_View (Proc, Cref))));

         else
            Cref2 := New_Copy_Tree (Cref);
            Append_To (Res,
              Make_Implicit_If_Statement (Ref,
                Condition => With_Detach,
                Then_Statements => New_List (
                  Make_Procedure_Call_Statement (Loc,
                    Name => New_Reference_To (RTE (RE_Finalize_One), Loc),
                    Parameter_Associations => New_List (
                      OK_Convert_To (RTE (RE_Finalizable), Cref)))),

                Else_Statements => New_List (
                  Make_Procedure_Call_Statement (Loc,
                    Name => New_Reference_To (Proc, Loc),
                    Parameter_Associations =>
                      New_List (Convert_View (Proc, Cref2))))));
         end if;
      end if;

      return Res;
   end Make_Final_Call;

   --------------------
   -- Make_Init_Call --
   --------------------

   function Make_Init_Call
     (Ref          : Node_Id;
      Typ          : Entity_Id;
      Flist_Ref    : Node_Id;
      With_Attach  : Node_Id) return List_Id
   is
      Loc     : constant Source_Ptr := Sloc (Ref);
      Is_Conc : Boolean;
      Res     : constant List_Id := New_List;
      Proc    : Entity_Id;
      Utyp    : Entity_Id;
      Cref    : Node_Id;
      Cref2   : Node_Id;
      Attach  : Node_Id := With_Attach;

   begin
      if Is_Concurrent_Type (Typ) then
         Is_Conc := True;
         Utyp    := Corresponding_Record_Type (Typ);
         Cref    := Convert_Concurrent (Ref, Typ);

      elsif Is_Private_Type (Typ)
        and then Present (Full_View (Typ))
        and then Is_Concurrent_Type (Underlying_Type (Typ))
      then
         Is_Conc := True;
         Utyp    := Corresponding_Record_Type (Underlying_Type (Typ));
         Cref    := Convert_Concurrent (Ref, Underlying_Type (Typ));

      else
         Is_Conc := False;
         Utyp    := Typ;
         Cref    := Ref;
      end if;

      Utyp := Underlying_Type (Base_Type (Utyp));

      Set_Assignment_OK (Cref);

      --  Deal with non-tagged derivation of private views

      if Is_Untagged_Derivation (Typ)
        and then not Is_Conc
      then
         Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
         Cref := Unchecked_Convert_To (Utyp, Cref);
         Set_Assignment_OK (Cref);
         --  To prevent problems with UC see 1.156 RH ???
      end if;

      --  If the underlying_type is a subtype, we are dealing with
      --  the completion of a private type. We need to access
      --  the base type and generate a conversion to it.

      if Utyp /= Base_Type (Utyp) then
         pragma Assert (Is_Private_Type (Typ));
         Utyp := Base_Type (Utyp);
         Cref := Unchecked_Convert_To (Utyp, Cref);
      end if;

      --  We do not need to attach to one of the Global Final Lists
      --  the objects whose type is Finalize_Storage_Only

      if Finalize_Storage_Only (Typ)
        and then (Global_Flist_Ref (Flist_Ref)
          or else Entity (Constant_Value (RTE (RE_Garbage_Collected)))
                  = Standard_True)
      then
         Attach := Make_Integer_Literal (Loc, 0);
      end if;

      --  Generate:
      --    Deep_Initialize (Ref, Flist_Ref);

      if Has_Controlled_Component (Utyp) then
         Proc := TSS (Utyp, Deep_Name_Of (Initialize_Case));

         Cref := Convert_View (Proc, Cref, 2);

         Append_To (Res,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Reference_To (Proc, Loc),
             Parameter_Associations => New_List (
               Node1 => Flist_Ref,
               Node2 => Cref,
               Node3 => Attach)));

      --  Generate:
      --    Attach_To_Final_List (Ref, Flist_Ref);
      --    Initialize (Ref);

      else -- Is_Controlled (Utyp)
         Proc  := Find_Prim_Op (Utyp, Name_Of (Initialize_Case));
         Check_Visibly_Controlled (Initialize_Case, Typ, Proc, Cref);

         Cref  := Convert_View (Proc, Cref);
         Cref2 := New_Copy_Tree (Cref);

         Append_To (Res,
           Make_Procedure_Call_Statement (Loc,
           Name => New_Reference_To (Proc, Loc),
           Parameter_Associations => New_List (Cref2)));

         Append_To (Res,
           Make_Attach_Call (Cref, Flist_Ref, Attach));
      end if;

      return Res;
   end Make_Init_Call;

   --------------------------
   -- Make_Transient_Block --
   --------------------------

   --  If finalization is involved, this function just wraps the instruction
   --  into a block whose name is the transient block entity, and then
   --  Expand_Cleanup_Actions (called on the expansion of the handled
   --  sequence of statements will do the necessary expansions for
   --  cleanups).

   function Make_Transient_Block
     (Loc    : Source_Ptr;
      Action : Node_Id) return Node_Id
   is
      Flist  : constant Entity_Id := Finalization_Chain_Entity (Current_Scope);
      Decls  : constant List_Id   := New_List;
      Par    : constant Node_Id   := Parent (Action);
      Instrs : constant List_Id   := New_List (Action);
      Blk    : Node_Id;

   begin
      --  Case where only secondary stack use is involved

      if Uses_Sec_Stack (Current_Scope)
        and then No (Flist)
        and then Nkind (Action) /= N_Return_Statement
        and then Nkind (Par) /= N_Exception_Handler
      then

         declare
            S  : Entity_Id;
            K  : Entity_Kind;
         begin
            S := Scope (Current_Scope);
            loop
               K := Ekind (S);

               --  At the outer level, no need to release the sec stack

               if S = Standard_Standard then
                  Set_Uses_Sec_Stack (Current_Scope, False);
                  exit;

               --  In a function, only release the sec stack if the
               --  function does not return on the sec stack otherwise
               --  the result may be lost. The caller is responsible for
               --  releasing.

               elsif K = E_Function then
                  Set_Uses_Sec_Stack (Current_Scope, False);

                  if not Requires_Transient_Scope (Etype (S)) then
                     if not Functions_Return_By_DSP_On_Target then
                        Set_Uses_Sec_Stack (S, True);
                        Check_Restriction (No_Secondary_Stack, Action);
                     end if;
                  end if;

                  exit;

               --  In a loop or entry we should install a block encompassing
               --  all the construct. For now just release right away.

               elsif K = E_Loop or else K = E_Entry then
                  exit;

               --  In a procedure or a block, we release on exit of the
               --  procedure or block. ??? memory leak can be created by
               --  recursive calls.

               elsif K = E_Procedure
                 or else K = E_Block
               then
                  if not Functions_Return_By_DSP_On_Target then
                     Set_Uses_Sec_Stack (S, True);
                     Check_Restriction (No_Secondary_Stack, Action);
                  end if;

                  Set_Uses_Sec_Stack (Current_Scope, False);
                  exit;

               else
                  S := Scope (S);
               end if;
            end loop;
         end;
      end if;

      --  Insert actions stuck in the transient scopes as well as all
      --  freezing nodes needed by those actions

      Insert_Actions_In_Scope_Around (Action);

      declare
         Last_Inserted : Node_Id := Prev (Action);

      begin
         if Present (Last_Inserted) then
            Freeze_All (First_Entity (Current_Scope), Last_Inserted);
         end if;
      end;

      Blk :=
        Make_Block_Statement (Loc,
          Identifier => New_Reference_To (Current_Scope, Loc),
          Declarations => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, Statements => Instrs),
          Has_Created_Identifier => True);

      --  When the transient scope was established, we pushed the entry for
      --  the transient scope onto the scope stack, so that the scope was
      --  active for the installation of finalizable entities etc. Now we
      --  must remove this entry, since we have constructed a proper block.

      Pop_Scope;

      return Blk;
   end Make_Transient_Block;

   ------------------------
   -- Node_To_Be_Wrapped --
   ------------------------

   function Node_To_Be_Wrapped return Node_Id is
   begin
      return Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped;
   end Node_To_Be_Wrapped;

   ----------------------------
   -- Set_Node_To_Be_Wrapped --
   ----------------------------

   procedure Set_Node_To_Be_Wrapped (N : Node_Id) is
   begin
      Scope_Stack.Table (Scope_Stack.Last).Node_To_Be_Wrapped := N;
   end Set_Node_To_Be_Wrapped;

   ----------------------------------
   -- Store_After_Actions_In_Scope --
   ----------------------------------

   procedure Store_After_Actions_In_Scope (L : List_Id) is
      SE : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);

   begin
      if Present (SE.Actions_To_Be_Wrapped_After) then
         Insert_List_Before_And_Analyze (
          First (SE.Actions_To_Be_Wrapped_After), L);

      else
         SE.Actions_To_Be_Wrapped_After := L;

         if Is_List_Member (SE.Node_To_Be_Wrapped) then
            Set_Parent (L, Parent (SE.Node_To_Be_Wrapped));
         else
            Set_Parent (L, SE.Node_To_Be_Wrapped);
         end if;

         Analyze_List (L);
      end if;
   end Store_After_Actions_In_Scope;

   -----------------------------------
   -- Store_Before_Actions_In_Scope --
   -----------------------------------

   procedure Store_Before_Actions_In_Scope (L : List_Id) is
      SE : Scope_Stack_Entry renames Scope_Stack.Table (Scope_Stack.Last);

   begin
      if Present (SE.Actions_To_Be_Wrapped_Before) then
         Insert_List_After_And_Analyze (
           Last (SE.Actions_To_Be_Wrapped_Before), L);

      else
         SE.Actions_To_Be_Wrapped_Before := L;

         if Is_List_Member (SE.Node_To_Be_Wrapped) then
            Set_Parent (L, Parent (SE.Node_To_Be_Wrapped));
         else
            Set_Parent (L, SE.Node_To_Be_Wrapped);
         end if;

         Analyze_List (L);
      end if;
   end Store_Before_Actions_In_Scope;

   --------------------------------
   -- Wrap_Transient_Declaration --
   --------------------------------

   --  If a transient scope has been established during the processing of the
   --  Expression of an Object_Declaration, it is not possible to wrap the
   --  declaration into a transient block as usual case, otherwise the object
   --  would be itself declared in the wrong scope. Therefore, all entities (if
   --  any) defined in the transient block are moved to the proper enclosing
   --  scope, furthermore, if they are controlled variables they are finalized
   --  right after the declaration. The finalization list of the transient
   --  scope is defined as a renaming of the enclosing one so during their
   --  initialization they will be attached to the proper finalization
   --  list. For instance, the following declaration :

   --        X : Typ := F (G (A), G (B));

   --  (where G(A) and G(B) return controlled values, expanded as _v1 and _v2)
   --  is expanded into :

   --    _local_final_list_1 : Finalizable_Ptr;
   --    X : Typ := [ complex Expression-Action ];
   --    Finalize_One(_v1);
   --    Finalize_One (_v2);

   procedure Wrap_Transient_Declaration (N : Node_Id) is
      S           : Entity_Id;
      LC          : Entity_Id := Empty;
      Nodes       : List_Id;
      Loc         : constant Source_Ptr := Sloc (N);
      Enclosing_S : Entity_Id;
      Uses_SS     : Boolean;
      Next_N      : constant Node_Id := Next (N);

   begin
      S := Current_Scope;
      Enclosing_S := Scope (S);

      --  Insert Actions kept in the Scope stack

      Insert_Actions_In_Scope_Around (N);

      --  If the declaration is consuming some secondary stack, mark the
      --  Enclosing scope appropriately.

      Uses_SS := Uses_Sec_Stack (S);
      Pop_Scope;

      --  Create a List controller and rename the final list to be its
      --  internal final pointer:
      --       Lxxx : Simple_List_Controller;
      --       Fxxx : Finalizable_Ptr renames Lxxx.F;

      if Present (Finalization_Chain_Entity (S)) then
         LC := Make_Defining_Identifier (Loc, New_Internal_Name ('L'));

         Nodes := New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => LC,
             Object_Definition   =>
               New_Reference_To (RTE (RE_Simple_List_Controller), Loc)),

           Make_Object_Renaming_Declaration (Loc,
             Defining_Identifier => Finalization_Chain_Entity (S),
             Subtype_Mark => New_Reference_To (RTE (RE_Finalizable_Ptr), Loc),
             Name =>
               Make_Selected_Component (Loc,
                 Prefix        => New_Reference_To (LC, Loc),
                 Selector_Name => Make_Identifier (Loc, Name_F))));

         --  Put the declaration at the beginning of the declaration part
         --  to make sure it will be before all other actions that have been
         --  inserted before N.

         Insert_List_Before_And_Analyze (First (List_Containing (N)), Nodes);

         --  Generate the Finalization calls by finalizing the list
         --  controller right away. It will be re-finalized on scope
         --  exit but it doesn't matter. It cannot be done when the
         --  call initializes a renaming object though because in this
         --  case, the object becomes a pointer to the temporary and thus
         --  increases its life span.

         if Nkind (N) = N_Object_Renaming_Declaration
           and then Controlled_Type (Etype (Defining_Identifier (N)))
         then
            null;

         else
            Nodes :=
              Make_Final_Call (
                   Ref         => New_Reference_To (LC, Loc),
                   Typ         => Etype (LC),
                   With_Detach => New_Reference_To (Standard_False, Loc));
            if Present (Next_N) then
               Insert_List_Before_And_Analyze (Next_N, Nodes);
            else
               Append_List_To (List_Containing (N), Nodes);
            end if;
         end if;
      end if;

      --  Put the local entities back in the enclosing scope, and set the
      --  Is_Public flag appropriately.

      Transfer_Entities (S, Enclosing_S);

      --  Mark the enclosing dynamic scope so that the sec stack will be
      --  released upon its exit unless this is a function that returns on
      --  the sec stack in which case this will be done by the caller.

      if Uses_SS then
         S := Enclosing_Dynamic_Scope (S);

         if Ekind (S) = E_Function
           and then Requires_Transient_Scope (Etype (S))
         then
            null;
         else
            Set_Uses_Sec_Stack (S);
            Check_Restriction (No_Secondary_Stack, N);
         end if;
      end if;
   end Wrap_Transient_Declaration;

   -------------------------------
   -- Wrap_Transient_Expression --
   -------------------------------

   --  Insert actions before <Expression>:

   --  (lines marked with <CTRL> are expanded only in presence of Controlled
   --   objects needing finalization)

   --     _E : Etyp;
   --     declare
   --        _M : constant Mark_Id := SS_Mark;
   --        Local_Final_List : System.FI.Finalizable_Ptr;    <CTRL>

   --        procedure _Clean is
   --        begin
   --           Abort_Defer;
   --           System.FI.Finalize_List (Local_Final_List);   <CTRL>
   --           SS_Release (M);
   --           Abort_Undefer;
   --        end _Clean;

   --     begin
   --        _E := <Expression>;
   --     at end
   --        _Clean;
   --     end;

   --    then expression is replaced by _E

   procedure Wrap_Transient_Expression (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      E    : constant Entity_Id :=
               Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
      Etyp : constant Entity_Id := Etype (N);

   begin
      Insert_Actions (N, New_List (
        Make_Object_Declaration (Loc,
          Defining_Identifier => E,
          Object_Definition   => New_Reference_To (Etyp, Loc)),

        Make_Transient_Block (Loc,
          Action =>
            Make_Assignment_Statement (Loc,
              Name       => New_Reference_To (E, Loc),
              Expression => Relocate_Node (N)))));

      Rewrite (N, New_Reference_To (E, Loc));
      Analyze_And_Resolve (N, Etyp);
   end Wrap_Transient_Expression;

   ------------------------------
   -- Wrap_Transient_Statement --
   ------------------------------

   --  Transform <Instruction> into

   --  (lines marked with <CTRL> are expanded only in presence of Controlled
   --   objects needing finalization)

   --    declare
   --       _M : Mark_Id := SS_Mark;
   --       Local_Final_List : System.FI.Finalizable_Ptr ;    <CTRL>

   --       procedure _Clean is
   --       begin
   --          Abort_Defer;
   --          System.FI.Finalize_List (Local_Final_List);    <CTRL>
   --          SS_Release (_M);
   --          Abort_Undefer;
   --       end _Clean;

   --    begin
   --       <Instr uction>;
   --    at end
   --       _Clean;
   --    end;

   procedure Wrap_Transient_Statement (N : Node_Id) is
      Loc           : constant Source_Ptr := Sloc (N);
      New_Statement : constant Node_Id := Relocate_Node (N);

   begin
      Rewrite (N, Make_Transient_Block (Loc, New_Statement));

      --  With the scope stack back to normal, we can call analyze on the
      --  resulting block. At this point, the transient scope is being
      --  treated like a perfectly normal scope, so there is nothing
      --  special about it.

      --  Note: Wrap_Transient_Statement is called with the node already
      --  analyzed (i.e. Analyzed (N) is True). This is important, since
      --  otherwise we would get a recursive processing of the node when
      --  we do this Analyze call.

      Analyze (N);
   end Wrap_Transient_Statement;

end Exp_Ch7;
