------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             E X P _ U N S T                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2014-2019, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;    use Atree;
with Debug;    use Debug;
with Einfo;    use Einfo;
with Elists;   use Elists;
with Lib;      use Lib;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;
with Output;   use Output;
with Rtsfind;  use Rtsfind;
with Sem;      use Sem;
with Sem_Aux;  use Sem_Aux;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Mech; use Sem_Mech;
with Sem_Res;  use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Sinput;   use Sinput;
with Snames;   use Snames;
with Stand;    use Stand;
with Tbuild;   use Tbuild;
with Uintp;    use Uintp;

package body Exp_Unst is

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

   procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id);
   --  Subp is a library-level subprogram which has nested subprograms, and
   --  Subp_Body is the corresponding N_Subprogram_Body node. This procedure
   --  declares the AREC types and objects, adds assignments to the AREC record
   --  as required, defines the xxxPTR types for uplevel referenced objects,
   --  adds the ARECP parameter to all nested subprograms which need it, and
   --  modifies all uplevel references appropriately.

   -----------
   -- Calls --
   -----------

   --  Table to record calls within the nest being analyzed. These are the
   --  calls which may need to have an AREC actual added. This table is built
   --  new for each subprogram nest and cleared at the end of processing each
   --  subprogram nest.

   type Call_Entry is record
      N : Node_Id;
      --  The actual call

      Caller : Entity_Id;
      --  Entity of the subprogram containing the call (can be at any level)

      Callee : Entity_Id;
      --  Entity of the subprogram called (always at level 2 or higher). Note
      --  that in accordance with the basic rules of nesting, the level of To
      --  is either less than or equal to the level of From, or one greater.
   end record;

   package Calls is new Table.Table (
     Table_Component_Type => Call_Entry,
     Table_Index_Type     => Nat,
     Table_Low_Bound      => 1,
     Table_Initial        => 100,
     Table_Increment      => 200,
     Table_Name           => "Unnest_Calls");
   --  Records each call within the outer subprogram and all nested subprograms
   --  that are to other subprograms nested within the outer subprogram. These
   --  are the calls that may need an additional parameter.

   procedure Append_Unique_Call (Call : Call_Entry);
   --  Append a call entry to the Calls table. A check is made to see if the
   --  table already contains this entry and if so it has no effect.

   ----------------------------------
   -- Subprograms For Fat Pointers --
   ----------------------------------

   function Build_Access_Type_Decl
     (E    : Entity_Id;
      Scop : Entity_Id) return Node_Id;
   --  For an uplevel reference that involves an unconstrained array type,
   --  build an access type declaration for the corresponding activation
   --  record component. The relevant attributes of the access type are
   --  set here to avoid a full analysis that would require a scope stack.

   function Needs_Fat_Pointer (E : Entity_Id) return Boolean;
   --  A formal parameter of an unconstrained array type that appears in an
   --  uplevel reference requires the construction of an access type, to be
   --  used in the corresponding component declaration.

   -----------
   -- Urefs --
   -----------

   --  Table to record explicit uplevel references to objects (variables,
   --  constants, formal parameters). These are the references that will
   --  need rewriting to use the activation table (AREC) pointers. Also
   --  included are implicit and explicit uplevel references to types, but
   --  these do not get rewritten by the front end. This table is built new
   --  for each subprogram nest and cleared at the end of processing each
   --  subprogram nest.

   type Uref_Entry is record
      Ref : Node_Id;
      --  The reference itself. For objects this is always an entity reference
      --  and the referenced entity will have its Is_Uplevel_Referenced_Entity
      --  flag set and will appear in the Uplevel_Referenced_Entities list of
      --  the subprogram declaring this entity.

      Ent : Entity_Id;
      --  The Entity_Id of the uplevel referenced object or type

      Caller : Entity_Id;
      --  The entity for the subprogram immediately containing this entity

      Callee : Entity_Id;
      --  The entity for the subprogram containing the referenced entity. Note
      --  that the level of Callee must be less than the level of Caller, since
      --  this is an uplevel reference.
   end record;

   package Urefs is new Table.Table (
     Table_Component_Type => Uref_Entry,
     Table_Index_Type     => Nat,
     Table_Low_Bound      => 1,
     Table_Initial        => 100,
     Table_Increment      => 200,
     Table_Name           => "Unnest_Urefs");

   ------------------------
   -- Append_Unique_Call --
   ------------------------

   procedure Append_Unique_Call (Call : Call_Entry) is
   begin
      for J in Calls.First .. Calls.Last loop
         if Calls.Table (J) = Call then
            return;
         end if;
      end loop;

      Calls.Append (Call);
   end Append_Unique_Call;

   -----------------------------
   --  Build_Access_Type_Decl --
   -----------------------------

   function Build_Access_Type_Decl
     (E    : Entity_Id;
      Scop : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (E);
      Typ : Entity_Id;

   begin
      Typ := Make_Temporary (Loc, 'S');
      Set_Ekind (Typ, E_General_Access_Type);
      Set_Etype (Typ, Typ);
      Set_Scope (Typ, Scop);
      Set_Directly_Designated_Type (Typ, Etype (E));

      return
        Make_Full_Type_Declaration (Loc,
          Defining_Identifier => Typ,
          Type_Definition     =>
            Make_Access_To_Object_Definition (Loc,
              Subtype_Indication => New_Occurrence_Of (Etype (E), Loc)));
   end Build_Access_Type_Decl;

   ---------------
   -- Get_Level --
   ---------------

   function Get_Level (Subp : Entity_Id; Sub : Entity_Id) return Nat is
      Lev : Nat;
      S   : Entity_Id;

   begin
      Lev := 1;
      S   := Sub;
      loop
         if S = Subp then
            return Lev;
         else
            Lev := Lev + 1;
            S   := Enclosing_Subprogram (S);
         end if;
      end loop;
   end Get_Level;

   --------------------------
   -- In_Synchronized_Unit --
   --------------------------

   function In_Synchronized_Unit (Subp : Entity_Id) return Boolean is
      S : Entity_Id := Scope (Subp);

   begin
      while Present (S) and then S /= Standard_Standard loop
         if Is_Concurrent_Type (S) then
            return True;

         elsif Is_Private_Type (S)
           and then Present (Full_View (S))
           and then Is_Concurrent_Type (Full_View (S))
         then
            return True;
         end if;

         S := Scope (S);
      end loop;

      return False;
   end In_Synchronized_Unit;

   -----------------------
   -- Needs_Fat_Pointer --
   -----------------------

   function Needs_Fat_Pointer (E : Entity_Id) return Boolean is
      Typ : Entity_Id;
   begin
      if Is_Formal (E) then
         Typ := Etype (E);
         if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
            Typ := Full_View (Typ);
         end if;

         return Is_Array_Type (Typ)
           and then not Is_Constrained (Typ);
      else
         return False;
      end if;
   end Needs_Fat_Pointer;

   ----------------
   -- Subp_Index --
   ----------------

   function Subp_Index (Sub : Entity_Id) return SI_Type is
      E : Entity_Id := Sub;

   begin
      pragma Assert (Is_Subprogram (E));

      if Subps_Index (E) = Uint_0 then
         E := Ultimate_Alias (E);

         --  The body of a protected operation has a different name and
         --  has been scanned at this point, and thus has an entry in the
         --  subprogram table.

         if E = Sub and then Convention (E) = Convention_Protected then
            E := Protected_Body_Subprogram (E);
         end if;

         if Ekind (E) = E_Function
           and then Rewritten_For_C (E)
           and then Present (Corresponding_Procedure (E))
         then
            E := Corresponding_Procedure (E);
         end if;
      end if;

      pragma Assert (Subps_Index (E) /= Uint_0);
      return SI_Type (UI_To_Int (Subps_Index (E)));
   end Subp_Index;

   -----------------------
   -- Unnest_Subprogram --
   -----------------------

   procedure Unnest_Subprogram (Subp : Entity_Id; Subp_Body : Node_Id) is
      function AREC_Name (J : Pos; S : String) return Name_Id;
      --  Returns name for string ARECjS, where j is the decimal value of j

      function Enclosing_Subp (Subp : SI_Type) return SI_Type;
      --  Subp is the index of a subprogram which has a Lev greater than 1.
      --  This function returns the index of the enclosing subprogram which
      --  will have a Lev value one less than this.

      function Img_Pos (N : Pos) return String;
      --  Return image of N without leading blank

      function Upref_Name
        (Ent   : Entity_Id;
         Index : Pos;
         Clist : List_Id) return Name_Id;
      --  This function returns the name to be used in the activation record to
      --  reference the variable uplevel. Clist is the list of components that
      --  have been created in the activation record so far. Normally the name
      --  is just a copy of the Chars field of the entity. The exception is
      --  when the name has already been used, in which case we suffix the name
      --  with the index value Index to avoid duplication. This happens with
      --  declare blocks and generic parameters at least.

      ---------------
      -- AREC_Name --
      ---------------

      function AREC_Name (J : Pos; S : String) return Name_Id is
      begin
         return Name_Find ("AREC" & Img_Pos (J) & S);
      end AREC_Name;

      --------------------
      -- Enclosing_Subp --
      --------------------

      function Enclosing_Subp (Subp : SI_Type) return SI_Type is
         STJ : Subp_Entry renames Subps.Table (Subp);
         Ret : constant SI_Type := Subp_Index (Enclosing_Subprogram (STJ.Ent));
      begin
         pragma Assert (STJ.Lev > 1);
         pragma Assert (Subps.Table (Ret).Lev = STJ.Lev - 1);
         return Ret;
      end Enclosing_Subp;

      -------------
      -- Img_Pos --
      -------------

      function Img_Pos (N : Pos) return String is
         Buf : String (1 .. 20);
         Ptr : Natural;
         NV  : Nat;

      begin
         Ptr := Buf'Last;
         NV := N;
         while NV /= 0 loop
            Buf (Ptr) := Character'Val (48 + NV mod 10);
            Ptr := Ptr - 1;
            NV := NV / 10;
         end loop;

         return Buf (Ptr + 1 .. Buf'Last);
      end Img_Pos;

      ----------------
      -- Upref_Name --
      ----------------

      function Upref_Name
        (Ent   : Entity_Id;
         Index : Pos;
         Clist : List_Id) return Name_Id
      is
         C : Node_Id;
      begin
         C := First (Clist);
         loop
            if No (C) then
               return Chars (Ent);

            elsif Chars (Defining_Identifier (C)) = Chars (Ent) then
               return
                 Name_Find (Get_Name_String (Chars (Ent)) & Img_Pos (Index));
            else
               Next (C);
            end if;
         end loop;
      end Upref_Name;

   --  Start of processing for Unnest_Subprogram

   begin
      --  Nothing to do inside a generic (all processing is for instance)

      if Inside_A_Generic then
         return;
      end if;

      --  If the main unit is a package body then we need to examine the spec
      --  to determine whether the main unit is generic (the scope stack is not
      --  present when this is called on the main unit).

      if Ekind (Cunit_Entity (Main_Unit)) = E_Package_Body
        and then Is_Generic_Unit (Spec_Entity (Cunit_Entity (Main_Unit)))
      then
         return;
      end if;

      --  Only unnest when generating code for the main source unit

      if not In_Extended_Main_Code_Unit (Subp_Body) then
         return;
      end if;

      --  This routine is called late, after the scope stack is gone. The
      --  following creates a suitable dummy scope stack to be used for the
      --  analyze/expand calls made from this routine.

      Push_Scope (Subp);

      --  First step, we must mark all nested subprograms that require a static
      --  link (activation record) because either they contain explicit uplevel
      --  references (as indicated by Is_Uplevel_Referenced_Entity being set at
      --  this point), or they make calls to other subprograms in the same nest
      --  that require a static link (in which case we set this flag).

      --  This is a recursive definition, and to implement this, we have to
      --  build a call graph for the set of nested subprograms, and then go
      --  over this graph to implement recursively the invariant that if a
      --  subprogram has a call to a subprogram requiring a static link, then
      --  the calling subprogram requires a static link.

      --  First populate the above tables

      Subps_First := Subps.Last + 1;
      Calls.Init;
      Urefs.Init;

      Build_Tables : declare
         Current_Subprogram : Entity_Id := Empty;
         --  When we scan a subprogram body, we set Current_Subprogram to the
         --  corresponding entity. This gets recursively saved and restored.

         function Visit_Node (N : Node_Id) return Traverse_Result;
         --  Visit a single node in Subp

         -----------
         -- Visit --
         -----------

         procedure Visit is new Traverse_Proc (Visit_Node);
         --  Used to traverse the body of Subp, populating the tables

         ----------------
         -- Visit_Node --
         ----------------

         function Visit_Node (N : Node_Id) return Traverse_Result is
            Ent    : Entity_Id;
            Caller : Entity_Id;
            Callee : Entity_Id;

            procedure Check_Static_Type
              (T : Entity_Id; N : Node_Id; DT : in out Boolean);
            --  Given a type T, checks if it is a static type defined as a type
            --  with no dynamic bounds in sight. If so, the only action is to
            --  set Is_Static_Type True for T. If T is not a static type, then
            --  all types with dynamic bounds associated with T are detected,
            --  and their bounds are marked as uplevel referenced if not at the
            --  library level, and DT is set True. If N is specified, it's the
            --  node that will need to be replaced. If not specified, it means
            --  we can't do a replacement because the bound is implicit.

            procedure Note_Uplevel_Ref
              (E      : Entity_Id;
               N      : Node_Id;
               Caller : Entity_Id;
               Callee : Entity_Id);
            --  Called when we detect an explicit or implicit uplevel reference
            --  from within Caller to entity E declared in Callee. E can be a
            --  an object or a type.

            procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id);
            --  Enter a subprogram whose body is visible or which is a
            --  subprogram instance into the subprogram table.

            -----------------------
            -- Check_Static_Type --
            -----------------------

            procedure Check_Static_Type
              (T : Entity_Id; N : Node_Id; DT : in out Boolean)
            is
               procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id);
               --  N is the bound of a dynamic type. This procedure notes that
               --  this bound is uplevel referenced, it can handle references
               --  to entities (typically _FIRST and _LAST entities), and also
               --  attribute references of the form T'name (name is typically
               --  FIRST or LAST) where T is the uplevel referenced bound.
               --  Ref, if Present, is the location of the reference to
               --  replace.

               ------------------------
               -- Note_Uplevel_Bound --
               ------------------------

               procedure Note_Uplevel_Bound (N : Node_Id; Ref : Node_Id) is
               begin
                  --  Entity name case. Make sure that the entity is declared
                  --  in a subprogram. This may not be the case for for a type
                  --  in a loop appearing in a precondition.
                  --  Exclude explicitly  discriminants (that can appear
                  --  in bounds of discriminated components).

                  if Is_Entity_Name (N) then
                     if Present (Entity (N))
                       and then not Is_Type (Entity (N))
                       and then Present (Enclosing_Subprogram (Entity (N)))
                       and then Ekind (Entity (N)) /= E_Discriminant
                     then
                        Note_Uplevel_Ref
                          (E      => Entity (N),
                           N      => Empty,
                           Caller => Current_Subprogram,
                           Callee => Enclosing_Subprogram (Entity (N)));
                     end if;

                  --  Attribute or indexed component case

                  elsif Nkind_In (N, N_Attribute_Reference,
                                     N_Indexed_Component)
                  then
                     Note_Uplevel_Bound (Prefix (N), Ref);

                     --  The indices of the indexed components, or the
                     --  associated expressions of an attribute reference,
                     --  may also involve uplevel references.

                     declare
                        Expr : Node_Id;

                     begin
                        Expr := First (Expressions (N));
                        while Present (Expr) loop
                           Note_Uplevel_Bound (Expr, Ref);
                           Next (Expr);
                        end loop;
                     end;

                     --  The type of the prefix may be have an uplevel
                     --  reference if this needs bounds.

                     if Nkind (N) = N_Attribute_Reference then
                        declare
                           Attr : constant Attribute_Id :=
                                    Get_Attribute_Id (Attribute_Name (N));
                           DT   : Boolean := False;

                        begin
                           if (Attr = Attribute_First
                                 or else Attr = Attribute_Last
                                 or else Attr = Attribute_Length)
                             and then Is_Constrained (Etype (Prefix (N)))
                           then
                              Check_Static_Type
                                (Etype (Prefix (N)), Empty, DT);
                           end if;
                        end;
                     end if;

                  --  Binary operator cases. These can apply to arrays for
                  --  which we may need bounds.

                  elsif Nkind (N) in N_Binary_Op then
                     Note_Uplevel_Bound (Left_Opnd (N),  Ref);
                     Note_Uplevel_Bound (Right_Opnd (N), Ref);

                  --  Unary operator case

                  elsif Nkind (N) in N_Unary_Op then
                     Note_Uplevel_Bound (Right_Opnd (N), Ref);

                  --  Explicit dereference and selected component case

                  elsif Nkind_In (N, N_Explicit_Dereference,
                                     N_Selected_Component)
                  then
                     Note_Uplevel_Bound (Prefix (N), Ref);

                  --  Conversion case

                  elsif Nkind (N) = N_Type_Conversion then
                     Note_Uplevel_Bound (Expression (N), Ref);
                  end if;
               end Note_Uplevel_Bound;

            --  Start of processing for Check_Static_Type

            begin
               --  If already marked static, immediate return

               if Is_Static_Type (T) then
                  return;
               end if;

               --  If the type is at library level, always consider it static,
               --  since such uplevel references are irrelevant.

               if Is_Library_Level_Entity (T) then
                  Set_Is_Static_Type (T);
                  return;
               end if;

               --  Otherwise figure out what the story is with this type

               --  For a scalar type, check bounds

               if Is_Scalar_Type (T) then

                  --  If both bounds static, then this is a static type

                  declare
                     LB : constant Node_Id := Type_Low_Bound (T);
                     UB : constant Node_Id := Type_High_Bound (T);

                  begin
                     if not Is_Static_Expression (LB) then
                        Note_Uplevel_Bound (LB, N);
                        DT := True;
                     end if;

                     if not Is_Static_Expression (UB) then
                        Note_Uplevel_Bound (UB, N);
                        DT := True;
                     end if;
                  end;

               --  For record type, check all components and discriminant
               --  constraints if present.

               elsif Is_Record_Type (T) then
                  declare
                     C : Entity_Id;
                     D : Elmt_Id;

                  begin
                     C := First_Component_Or_Discriminant (T);
                     while Present (C) loop
                        Check_Static_Type (Etype (C), N, DT);
                        Next_Component_Or_Discriminant (C);
                     end loop;

                     if Has_Discriminants (T)
                       and then Present (Discriminant_Constraint (T))
                     then
                        D := First_Elmt (Discriminant_Constraint (T));
                        while Present (D) loop
                           if not Is_Static_Expression (Node (D)) then
                              Note_Uplevel_Bound (Node (D), N);
                              DT := True;
                           end if;

                           Next_Elmt (D);
                        end loop;
                     end if;
                  end;

               --  For array type, check index types and component type

               elsif Is_Array_Type (T) then
                  declare
                     IX : Node_Id;
                  begin
                     Check_Static_Type (Component_Type (T), N, DT);

                     IX := First_Index (T);
                     while Present (IX) loop
                        Check_Static_Type (Etype (IX), N, DT);
                        Next_Index (IX);
                     end loop;
                  end;

               --  For private type, examine whether full view is static

               elsif Is_Private_Type (T) and then Present (Full_View (T)) then
                  Check_Static_Type (Full_View (T), N, DT);

                  if Is_Static_Type (Full_View (T)) then
                     Set_Is_Static_Type (T);
                  end if;

               --  For now, ignore other types

               else
                  return;
               end if;

               if not DT then
                  Set_Is_Static_Type (T);
               end if;
            end Check_Static_Type;

            ----------------------
            -- Note_Uplevel_Ref --
            ----------------------

            procedure Note_Uplevel_Ref
              (E      : Entity_Id;
               N      : Node_Id;
               Caller : Entity_Id;
               Callee : Entity_Id)
            is
               Full_E : Entity_Id := E;
            begin
               --  Nothing to do for static type

               if Is_Static_Type (E) then
                  return;
               end if;

               --  Nothing to do if Caller and Callee are the same

               if Caller = Callee then
                  return;

               --  Callee may be a function that returns an array, and that has
               --  been rewritten as a procedure. If caller is that procedure,
               --  nothing to do either.

               elsif Ekind (Callee) = E_Function
                 and then Rewritten_For_C (Callee)
                 and then Corresponding_Procedure (Callee) = Caller
               then
                  return;

               elsif Ekind_In (Callee, E_Entry, E_Entry_Family) then
                  return;
               end if;

               --  We have a new uplevel referenced entity

               if Ekind (E) = E_Constant and then Present (Full_View (E)) then
                  Full_E := Full_View (E);
               end if;

               --  All we do at this stage is to add the uplevel reference to
               --  the table. It's too early to do anything else, since this
               --  uplevel reference may come from an unreachable subprogram
               --  in which case the entry will be deleted.

               Urefs.Append ((N, Full_E, Caller, Callee));
            end Note_Uplevel_Ref;

            -------------------------
            -- Register_Subprogram --
            -------------------------

            procedure Register_Subprogram (E : Entity_Id; Bod : Node_Id) is
               L : constant Nat := Get_Level (Subp, E);

            begin
               --  Subprograms declared in tasks and protected types cannot be
               --  eliminated because calls to them may be in other units, so
               --  they must be treated as reachable.

               Subps.Append
                 ((Ent           => E,
                   Bod           => Bod,
                   Lev           => L,
                   Reachable     => In_Synchronized_Unit (E)
                                      or else Address_Taken (E),
                   Uplevel_Ref   => L,
                   Declares_AREC => False,
                   Uents         => No_Elist,
                   Last          => 0,
                   ARECnF        => Empty,
                   ARECn         => Empty,
                   ARECnT        => Empty,
                   ARECnPT       => Empty,
                   ARECnP        => Empty,
                   ARECnU        => Empty));

               Set_Subps_Index (E, UI_From_Int (Subps.Last));

               --  If we marked this reachable because it's in a synchronized
               --  unit, we have to mark all enclosing subprograms as reachable
               --  as well.

               if In_Synchronized_Unit (E) then
                  declare
                     S : Entity_Id := E;

                  begin
                     for J in reverse 1 .. L  - 1 loop
                        S := Enclosing_Subprogram (S);
                        Subps.Table (Subp_Index (S)).Reachable := True;
                     end loop;
                  end;
               end if;
            end Register_Subprogram;

         --  Start of processing for Visit_Node

         begin
            case Nkind (N) is

               --  Record a subprogram call

               when N_Function_Call
                  | N_Procedure_Call_Statement
               =>
                  --  We are only interested in direct calls, not indirect
                  --  calls (where Name (N) is an explicit dereference) at
                  --  least for now!

                  if Nkind (Name (N)) in N_Has_Entity then
                     Ent := Entity (Name (N));

                     --  We are only interested in calls to subprograms nested
                     --  within Subp. Calls to Subp itself or to subprograms
                     --  outside the nested structure do not affect us.

                     if Scope_Within (Ent, Subp)
                        and then Is_Subprogram (Ent)
                        and then not Is_Imported (Ent)
                     then
                        Append_Unique_Call ((N, Current_Subprogram, Ent));
                     end if;
                  end if;

                  --  For all calls where the formal is an unconstrained array
                  --  and the actual is constrained we need to check the bounds
                  --  for uplevel references.

                  declare
                     Actual : Entity_Id;
                     DT     : Boolean := False;
                     Formal : Node_Id;
                     Subp   : Entity_Id;

                  begin
                     if Nkind (Name (N)) = N_Explicit_Dereference then
                        Subp := Etype (Name (N));
                     else
                        Subp := Entity (Name (N));
                     end if;

                     Actual := First_Actual (N);
                     Formal := First_Formal_With_Extras (Subp);
                     while Present (Actual) loop
                        if Is_Array_Type (Etype (Formal))
                          and then not Is_Constrained (Etype (Formal))
                          and then Is_Constrained (Etype (Actual))
                        then
                           Check_Static_Type (Etype (Actual), Empty, DT);
                        end if;

                        Next_Actual (Actual);
                        Next_Formal_With_Extras (Formal);
                     end loop;
                  end;

               --  An At_End_Proc in a statement sequence indicates that there
               --  is a call from the enclosing construct or block to that
               --  subprogram. As above, the called entity must be local and
               --  not imported.

               when N_Handled_Sequence_Of_Statements =>
                  if Present (At_End_Proc (N))
                    and then Scope_Within (Entity (At_End_Proc (N)), Subp)
                    and then not Is_Imported (Entity (At_End_Proc (N)))
                  then
                     Append_Unique_Call
                       ((N, Current_Subprogram, Entity (At_End_Proc (N))));
                  end if;

               --  Similarly, the following constructs include a semantic
               --  attribute Procedure_To_Call that must be handled like
               --  other calls. Likewise for attribute Storage_Pool.

               when N_Allocator
                  | N_Extended_Return_Statement
                  | N_Free_Statement
                  | N_Simple_Return_Statement
               =>
                  declare
                     Pool : constant Entity_Id := Storage_Pool (N);
                     Proc : constant Entity_Id := Procedure_To_Call (N);

                  begin
                     if Present (Proc)
                       and then Scope_Within (Proc, Subp)
                       and then not Is_Imported (Proc)
                     then
                        Append_Unique_Call ((N, Current_Subprogram, Proc));
                     end if;

                     if Present (Pool)
                       and then not Is_Library_Level_Entity (Pool)
                       and then Scope_Within_Or_Same (Scope (Pool), Subp)
                     then
                        Caller := Current_Subprogram;
                        Callee := Enclosing_Subprogram (Pool);

                        if Callee /= Caller then
                           Note_Uplevel_Ref (Pool, Empty, Caller, Callee);
                        end if;
                     end if;
                  end;

                  --  For an allocator with a qualified expression, check type
                  --  of expression being qualified. The explicit type name is
                  --  handled as an entity reference.

                  if Nkind (N) = N_Allocator
                    and then Nkind (Expression (N)) = N_Qualified_Expression
                  then
                     declare
                        DT : Boolean := False;
                     begin
                        Check_Static_Type
                          (Etype (Expression (Expression (N))), Empty,  DT);
                     end;

                  --  For a Return or Free (all other nodes we handle here),
                  --  we usually need the size of the object, so we need to be
                  --  sure that any nonstatic bounds of the expression's type
                  --  that are uplevel are handled.

                  elsif Nkind (N) /= N_Allocator
                    and then Present (Expression (N))
                  then
                     declare
                        DT : Boolean := False;
                     begin
                        Check_Static_Type (Etype (Expression (N)), Empty,  DT);
                     end;
                  end if;

               --  A 'Access reference is a (potential) call. So is 'Address,
               --  in particular on imported subprograms. Other attributes
               --  require special handling.

               when N_Attribute_Reference =>
                  declare
                     Attr : constant Attribute_Id :=
                              Get_Attribute_Id (Attribute_Name (N));
                  begin
                     case Attr is
                        when Attribute_Access
                           | Attribute_Unchecked_Access
                           | Attribute_Unrestricted_Access
                           | Attribute_Address
                        =>
                           if Nkind (Prefix (N)) in N_Has_Entity then
                              Ent := Entity (Prefix (N));

                              --  We only need to examine calls to subprograms
                              --  nested within current Subp.

                              if Scope_Within (Ent, Subp) then
                                 if Is_Imported (Ent) then
                                    null;

                                 elsif Is_Subprogram (Ent) then
                                    Append_Unique_Call
                                      ((N, Current_Subprogram, Ent));
                                 end if;
                              end if;
                           end if;

                        --  References to bounds can be uplevel references if
                        --  the type isn't static.

                        when Attribute_First
                           | Attribute_Last
                           | Attribute_Length
                        =>
                           --  Special-case attributes of objects whose bounds
                           --  may be uplevel references. More complex prefixes
                           --  handled during full traversal. Note that if the
                           --  nominal subtype of the prefix is unconstrained,
                           --  the bound must be obtained from the object, not
                           --  from the (possibly) uplevel reference.

                           if Is_Constrained (Etype (Prefix (N))) then
                              declare
                                 DT : Boolean := False;
                              begin
                                 Check_Static_Type
                                   (Etype (Prefix (N)), Empty, DT);
                              end;

                              return OK;
                           end if;

                        when others =>
                           null;
                     end case;
                  end;

               --  Component associations in aggregates are either static or
               --  else the aggregate will be expanded into assignments, in
               --  which case the expression is analyzed later and provides
               --  no relevant code generation.

               when N_Component_Association =>
                  if No (Expression (N))
                    or else No (Etype (Expression (N)))
                  then
                     return Skip;
                  end if;

               --  Generic associations are not analyzed: the actuals are
               --  transferred to renaming and subtype declarations that
               --  are the ones that must be examined.

               when N_Generic_Association =>
                  return Skip;

               --  Indexed references can be uplevel if the type isn't static
               --  and if the lower bound (or an inner bound for a multi-
               --  dimensional array) is uplevel.

               when N_Indexed_Component
                  | N_Slice
               =>
                  if Is_Constrained (Etype (Prefix (N))) then
                     declare
                        DT : Boolean := False;
                     begin
                        Check_Static_Type (Etype (Prefix (N)), Empty, DT);
                     end;
                  end if;

                  --  A selected component can have an implicit up-level
                  --  reference due to the bounds of previous fields in the
                  --  record. We simplify the processing here by examining
                  --  all components of the record.

                  --  Selected components appear as unit names and end labels
                  --  for child units. Prefixes of these nodes denote parent
                  --  units and carry no type information so they are skipped.

               when N_Selected_Component =>
                  if Present (Etype (Prefix (N))) then
                     declare
                        DT : Boolean := False;
                     begin
                        Check_Static_Type (Etype (Prefix (N)), Empty, DT);
                     end;
                  end if;

               --  For EQ/NE comparisons, we need the type of the operands
               --  in order to do the comparison, which means we need the
               --  bounds.

               when N_Op_Eq
                  | N_Op_Ne
               =>
                  declare
                     DT : Boolean := False;
                  begin
                     Check_Static_Type (Etype (Left_Opnd  (N)), Empty, DT);
                     Check_Static_Type (Etype (Right_Opnd (N)), Empty, DT);
                  end;

               --  Likewise we need the sizes to compute how much to move in
               --  an assignment.

               when N_Assignment_Statement =>
                  declare
                     DT : Boolean := False;
                  begin
                     Check_Static_Type (Etype (Name       (N)), Empty, DT);
                     Check_Static_Type (Etype (Expression (N)), Empty, DT);
                  end;

               --  Record a subprogram. We record a subprogram body that acts
               --  as a spec. Otherwise we record a subprogram declaration,
               --  providing that it has a corresponding body we can get hold
               --  of. The case of no corresponding body being available is
               --  ignored for now.

               when N_Subprogram_Body =>
                  Ent := Unique_Defining_Entity (N);

                  --  Ignore generic subprogram

                  if Is_Generic_Subprogram (Ent) then
                     return Skip;
                  end if;

                  --  Make new entry in subprogram table if not already made

                  Register_Subprogram (Ent, N);

                  --  We make a recursive call to scan the subprogram body, so
                  --  that we can save and restore Current_Subprogram.

                  declare
                     Save_CS : constant Entity_Id := Current_Subprogram;
                     Decl    : Node_Id;

                  begin
                     Current_Subprogram := Ent;

                     --  Scan declarations

                     Decl := First (Declarations (N));
                     while Present (Decl) loop
                        Visit (Decl);
                        Next (Decl);
                     end loop;

                     --  Scan statements

                     Visit (Handled_Statement_Sequence (N));

                     --  Restore current subprogram setting

                     Current_Subprogram := Save_CS;
                  end;

                  --  Now at this level, return skipping the subprogram body
                  --  descendants, since we already took care of them!

                  return Skip;

               --  If we have a body stub, visit the associated subunit, which
               --  is a semantic descendant of the stub.

               when N_Body_Stub =>
                  Visit (Library_Unit (N));

               --  A declaration of a wrapper package indicates a subprogram
               --  instance for which there is no explicit body. Enter the
               --  subprogram instance in the table.

               when N_Package_Declaration =>
                  if Is_Wrapper_Package (Defining_Entity (N)) then
                     Register_Subprogram
                       (Related_Instance (Defining_Entity (N)), Empty);
                  end if;

               --  Skip generic declarations

               when N_Generic_Declaration =>
                  return Skip;

               --  Skip generic package body

               when N_Package_Body =>
                  if Present (Corresponding_Spec (N))
                    and then Ekind (Corresponding_Spec (N)) = E_Generic_Package
                  then
                     return Skip;
                  end if;

               --  Pragmas and component declarations are ignored. Quantified
               --  expressions are expanded into explicit loops and the
               --  original epression must be ignored.

               when N_Component_Declaration
                  | N_Pragma
                  | N_Quantified_Expression
               =>
                  return Skip;

               --  We want to skip the function spec for a generic function
               --  to avoid looking at any generic types that might be in
               --  its formals.

               when N_Function_Specification =>
                  if Is_Generic_Subprogram  (Unique_Defining_Entity (N)) then
                     return Skip;
                  end if;

               --  Otherwise record an uplevel reference in a local identifier

               when others =>
                  if Nkind (N) in N_Has_Entity
                    and then Present (Entity (N))
                  then
                     Ent := Entity (N);

                     --  Only interested in entities declared within our nest

                     if not Is_Library_Level_Entity (Ent)
                       and then Scope_Within_Or_Same (Scope (Ent), Subp)

                        --  Skip entities defined in inlined subprograms

                       and then
                         Chars (Enclosing_Subprogram (Ent)) /= Name_uParent

                        --  Constants and variables are potentially uplevel
                        --  references to global declarations.

                       and then
                         (Ekind_In (Ent, E_Constant,
                                         E_Loop_Parameter,
                                         E_Variable)

                           --  Formals are interesting, but not if being used
                           --  as mere names of parameters for name notation
                           --  calls.

                           or else
                             (Is_Formal (Ent)
                               and then not
                                 (Nkind (Parent (N)) = N_Parameter_Association
                                   and then Selector_Name (Parent (N)) = N))

                           --  Types other than known Is_Static types are
                           --  potentially interesting.

                           or else
                             (Is_Type (Ent) and then not Is_Static_Type (Ent)))
                     then
                        --  Here we have a potentially interesting uplevel
                        --  reference to examine.

                        if Is_Type (Ent) then
                           declare
                              DT : Boolean := False;

                           begin
                              Check_Static_Type (Ent, N, DT);
                              return OK;
                           end;
                        end if;

                        Caller := Current_Subprogram;
                        Callee := Enclosing_Subprogram (Ent);

                        if Callee /= Caller
                          and then (not Is_Static_Type (Ent)
                                     or else Needs_Fat_Pointer (Ent))
                        then
                           Note_Uplevel_Ref (Ent, N, Caller, Callee);

                        --  Check the type of a formal parameter of the current
                        --  subprogram, whose formal type may be an uplevel
                        --  reference.

                        elsif Is_Formal (Ent)
                          and then Scope (Ent) = Current_Subprogram
                        then
                           declare
                              DT : Boolean := False;

                           begin
                              Check_Static_Type (Etype (Ent), Empty, DT);
                           end;
                        end if;
                     end if;
                  end if;
            end case;

            --  Fall through to continue scanning children of this node

            return OK;
         end Visit_Node;

      --  Start of processing for Build_Tables

      begin
         --  Traverse the body to get subprograms, calls and uplevel references

         Visit (Subp_Body);
      end Build_Tables;

      --  Now do the first transitive closure which determines which
      --  subprograms in the nest are actually reachable.

      Reachable_Closure : declare
         Modified : Boolean;

      begin
         Subps.Table (Subps_First).Reachable := True;

         --  We use a simple minded algorithm as follows (obviously this can
         --  be done more efficiently, using one of the standard algorithms
         --  for efficient transitive closure computation, but this is simple
         --  and most likely fast enough that its speed does not matter).

         --  Repeatedly scan the list of calls. Any time we find a call from
         --  A to B, where A is reachable, but B is not, then B is reachable,
         --  and note that we have made a change by setting Modified True. We
         --  repeat this until we make a pass with no modifications.

         Outer : loop
            Modified := False;
            Inner : for J in Calls.First .. Calls.Last loop
               declare
                  CTJ : Call_Entry renames Calls.Table (J);

                  SINF : constant SI_Type := Subp_Index (CTJ.Caller);
                  SINT : constant SI_Type := Subp_Index (CTJ.Callee);

                  SUBF : Subp_Entry renames Subps.Table (SINF);
                  SUBT : Subp_Entry renames Subps.Table (SINT);

               begin
                  if SUBF.Reachable and then not SUBT.Reachable then
                     SUBT.Reachable := True;
                     Modified := True;
                  end if;
               end;
            end loop Inner;

            exit Outer when not Modified;
         end loop Outer;
      end Reachable_Closure;

      --  Remove calls from unreachable subprograms

      declare
         New_Index : Nat;

      begin
         New_Index := 0;
         for J in Calls.First .. Calls.Last loop
            declare
               CTJ : Call_Entry renames Calls.Table (J);

               SINF : constant SI_Type := Subp_Index (CTJ.Caller);
               SINT : constant SI_Type := Subp_Index (CTJ.Callee);

               SUBF : Subp_Entry renames Subps.Table (SINF);
               SUBT : Subp_Entry renames Subps.Table (SINT);

            begin
               if SUBF.Reachable then
                  pragma Assert (SUBT.Reachable);
                  New_Index := New_Index + 1;
                  Calls.Table (New_Index) := Calls.Table (J);
               end if;
            end;
         end loop;

         Calls.Set_Last (New_Index);
      end;

      --  Remove uplevel references from unreachable subprograms

      declare
         New_Index : Nat;

      begin
         New_Index := 0;
         for J in Urefs.First .. Urefs.Last loop
            declare
               URJ : Uref_Entry renames Urefs.Table (J);

               SINF : constant SI_Type := Subp_Index (URJ.Caller);
               SINT : constant SI_Type := Subp_Index (URJ.Callee);

               SUBF : Subp_Entry renames Subps.Table (SINF);
               SUBT : Subp_Entry renames Subps.Table (SINT);

               S : Entity_Id;

            begin
               --  Keep reachable reference

               if SUBF.Reachable then
                  New_Index := New_Index + 1;
                  Urefs.Table (New_Index) := Urefs.Table (J);

                  --  And since we know we are keeping this one, this is a good
                  --  place to fill in information for a good reference.

                  --  Mark all enclosing subprograms need to declare AREC

                  S := URJ.Caller;
                  loop
                     S := Enclosing_Subprogram (S);

                     --  If we are at the top level, as can happen with
                     --  references to formals in aspects of nested subprogram
                     --  declarations, there are no further subprograms to mark
                     --  as requiring activation records.

                     exit when No (S);

                     declare
                        SUBI : Subp_Entry renames Subps.Table (Subp_Index (S));
                     begin
                        SUBI.Declares_AREC := True;

                        --  If this entity was marked reachable because it is
                        --  in a task or protected type, there may not appear
                        --  to be any calls to it, which would normally adjust
                        --  the levels of the parent subprograms. So we need to
                        --  be sure that the uplevel reference of that entity
                        --  takes into account possible calls.

                        if In_Synchronized_Unit (SUBF.Ent)
                          and then SUBT.Lev < SUBI.Uplevel_Ref
                        then
                           SUBI.Uplevel_Ref := SUBT.Lev;
                        end if;
                     end;

                     exit when S = URJ.Callee;
                  end loop;

                  --  Add to list of uplevel referenced entities for Callee.
                  --  We do not add types to this list, only actual references
                  --  to objects that will be referenced uplevel, and we use
                  --  the flag Is_Uplevel_Referenced_Entity to avoid making
                  --  duplicate entries in the list. Discriminants are also
                  --  excluded, only the enclosing object can appear in the
                  --  list.

                  if not Is_Uplevel_Referenced_Entity (URJ.Ent)
                    and then Ekind (URJ.Ent) /= E_Discriminant
                  then
                     Set_Is_Uplevel_Referenced_Entity (URJ.Ent);
                     Append_New_Elmt (URJ.Ent, SUBT.Uents);
                  end if;

                  --  And set uplevel indication for caller

                  if SUBT.Lev < SUBF.Uplevel_Ref then
                     SUBF.Uplevel_Ref := SUBT.Lev;
                  end if;
               end if;
            end;
         end loop;

         Urefs.Set_Last (New_Index);
      end;

      --  Remove unreachable subprograms from Subps table. Note that we do
      --  this after eliminating entries from the other two tables, since
      --  those elimination steps depend on referencing the Subps table.

      declare
         New_SI : SI_Type;

      begin
         New_SI := Subps_First - 1;
         for J in Subps_First .. Subps.Last loop
            declare
               STJ  : Subp_Entry renames Subps.Table (J);
               Spec : Node_Id;
               Decl : Node_Id;

            begin
               --  Subprogram is reachable, copy and reset index

               if STJ.Reachable then
                  New_SI := New_SI + 1;
                  Subps.Table (New_SI) := STJ;
                  Set_Subps_Index (STJ.Ent, UI_From_Int (New_SI));

               --  Subprogram is not reachable

               else
                  --  Clear index, since no longer active

                  Set_Subps_Index (Subps.Table (J).Ent, Uint_0);

                  --  Output debug information if -gnatd.3 set

                  if Debug_Flag_Dot_3 then
                     Write_Str ("Eliminate ");
                     Write_Name (Chars (Subps.Table (J).Ent));
                     Write_Str (" at ");
                     Write_Location (Sloc (Subps.Table (J).Ent));
                     Write_Str (" (not referenced)");
                     Write_Eol;
                  end if;

                  --  Rewrite declaration, body, and corresponding freeze node
                  --  to null statements.

                  --  A subprogram instantiation does not have an explicit
                  --  body. If unused, we could remove the corresponding
                  --  wrapper package and its body (TBD).

                  if Present (STJ.Bod) then
                     Spec := Corresponding_Spec (STJ.Bod);

                     if Present (Spec) then
                        Decl := Parent (Declaration_Node (Spec));
                        Rewrite (Decl, Make_Null_Statement (Sloc (Decl)));

                        if Present (Freeze_Node (Spec)) then
                           Rewrite (Freeze_Node (Spec),
                                    Make_Null_Statement (Sloc (Decl)));
                        end if;
                     end if;

                     Rewrite (STJ.Bod, Make_Null_Statement (Sloc (STJ.Bod)));
                  end if;
               end if;
            end;
         end loop;

         Subps.Set_Last (New_SI);
      end;

      --  Now it is time for the second transitive closure, which follows calls
      --  and makes sure that A calls B, and B has uplevel references, then A
      --  is also marked as having uplevel references.

      Closure_Uplevel : declare
         Modified : Boolean;

      begin
         --  We use a simple minded algorithm as follows (obviously this can
         --  be done more efficiently, using one of the standard algorithms
         --  for efficient transitive closure computation, but this is simple
         --  and most likely fast enough that its speed does not matter).

         --  Repeatedly scan the list of calls. Any time we find a call from
         --  A to B, where B has uplevel references, make sure that A is marked
         --  as having at least the same level of uplevel referencing.

         Outer2 : loop
            Modified := False;
            Inner2 : for J in Calls.First .. Calls.Last loop
               declare
                  CTJ  : Call_Entry renames Calls.Table (J);
                  SINF : constant SI_Type := Subp_Index (CTJ.Caller);
                  SINT : constant SI_Type := Subp_Index (CTJ.Callee);
                  SUBF : Subp_Entry renames Subps.Table (SINF);
                  SUBT : Subp_Entry renames Subps.Table (SINT);
               begin
                  if SUBT.Lev > SUBT.Uplevel_Ref
                    and then SUBF.Uplevel_Ref > SUBT.Uplevel_Ref
                  then
                     SUBF.Uplevel_Ref := SUBT.Uplevel_Ref;
                     Modified := True;
                  end if;
               end;
            end loop Inner2;

            exit Outer2 when not Modified;
         end loop Outer2;
      end Closure_Uplevel;

      --  We have one more step before the tables are complete. An uplevel
      --  call from subprogram A to subprogram B where subprogram B has uplevel
      --  references is in effect an uplevel reference, and must arrange for
      --  the proper activation link to be passed.

      for J in Calls.First .. Calls.Last loop
         declare
            CTJ : Call_Entry renames Calls.Table (J);

            SINF : constant SI_Type := Subp_Index (CTJ.Caller);
            SINT : constant SI_Type := Subp_Index (CTJ.Callee);

            SUBF : Subp_Entry renames Subps.Table (SINF);
            SUBT : Subp_Entry renames Subps.Table (SINT);

            A : Entity_Id;

         begin
            --  If callee has uplevel references

            if SUBT.Uplevel_Ref < SUBT.Lev

              --  And this is an uplevel call

              and then SUBT.Lev < SUBF.Lev
            then
               --  We need to arrange for finding the uplink

               A := CTJ.Caller;
               loop
                  A := Enclosing_Subprogram (A);
                  Subps.Table (Subp_Index (A)).Declares_AREC := True;
                  exit when A = CTJ.Callee;

                  --  In any case exit when we get to the outer level. This
                  --  happens in some odd cases with generics (in particular
                  --  sem_ch3.adb does not compile without this kludge ???).

                  exit when A = Subp;
               end loop;
            end if;
         end;
      end loop;

      --  The tables are now complete, so we can record the last index in the
      --  Subps table for later reference in Cprint.

      Subps.Table (Subps_First).Last := Subps.Last;

      --  Next step, create the entities for code we will insert. We do this
      --  at the start so that all the entities are defined, regardless of the
      --  order in which we do the code insertions.

      Create_Entities : for J in Subps_First .. Subps.Last loop
         declare
            STJ : Subp_Entry renames Subps.Table (J);
            Loc : constant Source_Ptr := Sloc (STJ.Bod);

         begin
            --  First we create the ARECnF entity for the additional formal for
            --  all subprograms which need an activation record passed.

            if STJ.Uplevel_Ref < STJ.Lev then
               STJ.ARECnF :=
                 Make_Defining_Identifier (Loc, Chars => AREC_Name (J, "F"));
            end if;

            --  Define the AREC entities for the activation record if needed

            if STJ.Declares_AREC then
               STJ.ARECn   :=
                 Make_Defining_Identifier (Loc, AREC_Name (J, ""));
               STJ.ARECnT  :=
                 Make_Defining_Identifier (Loc, AREC_Name (J, "T"));
               STJ.ARECnPT :=
                 Make_Defining_Identifier (Loc, AREC_Name (J, "PT"));
               STJ.ARECnP  :=
                 Make_Defining_Identifier (Loc, AREC_Name (J, "P"));

               --  Define uplink component entity if inner nesting case

               if Present (STJ.ARECnF) then
                  STJ.ARECnU :=
                    Make_Defining_Identifier (Loc, AREC_Name (J, "U"));
               end if;
            end if;
         end;
      end loop Create_Entities;

      --  Loop through subprograms

      Subp_Loop : declare
         Addr : Entity_Id := Empty;

      begin
         for J in Subps_First .. Subps.Last loop
            declare
               STJ : Subp_Entry renames Subps.Table (J);

            begin
               --  First add the extra formal if needed. This applies to all
               --  nested subprograms that require an activation record to be
               --  passed, as indicated by ARECnF being defined.

               if Present (STJ.ARECnF) then

                  --  Here we need the extra formal. We do the expansion and
                  --  analysis of this manually, since it is fairly simple,
                  --  and it is not obvious how we can get what we want if we
                  --  try to use the normal Analyze circuit.

                  Add_Extra_Formal : declare
                     Encl : constant SI_Type := Enclosing_Subp (J);
                     STJE : Subp_Entry renames Subps.Table (Encl);
                     --  Index and Subp_Entry for enclosing routine

                     Form : constant Entity_Id := STJ.ARECnF;
                     --  The formal to be added. Note that n here is one less
                     --  than the level of the subprogram itself (STJ.Ent).

                     procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id);
                     --  S is an N_Function/Procedure_Specification node, and F
                     --  is the new entity to add to this subprogramn spec as
                     --  the last Extra_Formal.

                     ----------------------
                     -- Add_Form_To_Spec --
                     ----------------------

                     procedure Add_Form_To_Spec (F : Entity_Id; S : Node_Id) is
                        Sub : constant Entity_Id := Defining_Entity (S);
                        Ent : Entity_Id;

                     begin
                        --  Case of at least one Extra_Formal is present, set
                        --  ARECnF as the new last entry in the list.

                        if Present (Extra_Formals (Sub)) then
                           Ent := Extra_Formals (Sub);
                           while Present (Extra_Formal (Ent)) loop
                              Ent := Extra_Formal (Ent);
                           end loop;

                           Set_Extra_Formal (Ent, F);

                        --  No Extra formals present

                        else
                           Set_Extra_Formals (Sub, F);
                           Ent := Last_Formal (Sub);

                           if Present (Ent) then
                              Set_Extra_Formal (Ent, F);
                           end if;
                        end if;
                     end Add_Form_To_Spec;

                  --  Start of processing for Add_Extra_Formal

                  begin
                     --  Decorate the new formal entity

                     Set_Scope                (Form, STJ.Ent);
                     Set_Ekind                (Form, E_In_Parameter);
                     Set_Etype                (Form, STJE.ARECnPT);
                     Set_Mechanism            (Form, By_Copy);
                     Set_Never_Set_In_Source  (Form, True);
                     Set_Analyzed             (Form, True);
                     Set_Comes_From_Source    (Form, False);
                     Set_Is_Activation_Record (Form, True);

                     --  Case of only body present

                     if Acts_As_Spec (STJ.Bod) then
                        Add_Form_To_Spec (Form, Specification (STJ.Bod));

                     --  Case of separate spec

                     else
                        Add_Form_To_Spec (Form, Parent (STJ.Ent));
                     end if;
                  end Add_Extra_Formal;
               end if;

               --  Processing for subprograms that declare an activation record

               if Present (STJ.ARECn) then

                  --  Local declarations for one such subprogram

                  declare
                     Loc : constant Source_Ptr := Sloc (STJ.Bod);

                     Decls : constant List_Id := New_List;
                     --  List of new declarations we create

                     Clist : List_Id;
                     Comp  : Entity_Id;

                     Decl_Assign : Node_Id;
                     --  Assigment to set uplink, Empty if none

                     Decl_ARECnT  : Node_Id;
                     Decl_ARECnPT : Node_Id;
                     Decl_ARECn   : Node_Id;
                     Decl_ARECnP  : Node_Id;
                     --  Declaration nodes for the AREC entities we build

                  begin
                     --  Build list of component declarations for ARECnT and
                     --  load System.Address.

                     Clist := Empty_List;

                     if No (Addr) then
                        Addr := RTE (RE_Address);
                     end if;

                     --  If we are in a subprogram that has a static link that
                     --  is passed in (as indicated by ARECnF being defined),
                     --  then include ARECnU : ARECmPT where ARECmPT comes from
                     --  the level one higher than the current level, and the
                     --  entity ARECnPT comes from the enclosing subprogram.

                     if Present (STJ.ARECnF) then
                        declare
                           STJE : Subp_Entry
                                    renames Subps.Table (Enclosing_Subp (J));
                        begin
                           Append_To (Clist,
                             Make_Component_Declaration (Loc,
                               Defining_Identifier  => STJ.ARECnU,
                               Component_Definition =>
                                 Make_Component_Definition (Loc,
                                   Subtype_Indication =>
                                     New_Occurrence_Of (STJE.ARECnPT, Loc))));
                        end;
                     end if;

                     --  Add components for uplevel referenced entities

                     if Present (STJ.Uents) then
                        declare
                           Elmt     : Elmt_Id;
                           Ptr_Decl : Node_Id;
                           Uent     : Entity_Id;

                           Indx : Nat;
                           --  1's origin of index in list of elements. This is
                           --  used to uniquify names if needed in Upref_Name.

                        begin
                           Elmt := First_Elmt (STJ.Uents);
                           Indx := 0;
                           while Present (Elmt) loop
                              Uent := Node (Elmt);
                              Indx := Indx + 1;

                              Comp :=
                                Make_Defining_Identifier (Loc,
                                  Chars => Upref_Name (Uent, Indx, Clist));

                              Set_Activation_Record_Component
                                (Uent, Comp);

                              if Needs_Fat_Pointer (Uent) then

                                 --  Build corresponding access type

                                 Ptr_Decl :=
                                   Build_Access_Type_Decl
                                     (Etype (Uent), STJ.Ent);
                                 Append_To (Decls, Ptr_Decl);

                                 --  And use its type in the corresponding
                                 --  component.

                                 Append_To (Clist,
                                   Make_Component_Declaration (Loc,
                                     Defining_Identifier  => Comp,
                                     Component_Definition =>
                                       Make_Component_Definition (Loc,
                                         Subtype_Indication =>
                                           New_Occurrence_Of
                                             (Defining_Identifier (Ptr_Decl),
                                              Loc))));
                              else
                                 Append_To (Clist,
                                   Make_Component_Declaration (Loc,
                                     Defining_Identifier  => Comp,
                                     Component_Definition =>
                                       Make_Component_Definition (Loc,
                                         Subtype_Indication =>
                                           New_Occurrence_Of (Addr, Loc))));
                              end if;
                              Next_Elmt (Elmt);
                           end loop;
                        end;
                     end if;

                     --  Now we can insert the AREC declarations into the body
                     --    type ARECnT is record .. end record;
                     --    pragma Suppress_Initialization (ARECnT);

                     --  Note that we need to set the Suppress_Initialization
                     --  flag after Decl_ARECnT has been analyzed.

                     Decl_ARECnT :=
                       Make_Full_Type_Declaration (Loc,
                         Defining_Identifier => STJ.ARECnT,
                         Type_Definition     =>
                           Make_Record_Definition (Loc,
                             Component_List =>
                               Make_Component_List (Loc,
                                 Component_Items => Clist)));
                     Append_To (Decls, Decl_ARECnT);

                     --  type ARECnPT is access all ARECnT;

                     Decl_ARECnPT :=
                       Make_Full_Type_Declaration (Loc,
                         Defining_Identifier => STJ.ARECnPT,
                         Type_Definition     =>
                           Make_Access_To_Object_Definition (Loc,
                             All_Present        => True,
                             Subtype_Indication =>
                               New_Occurrence_Of (STJ.ARECnT, Loc)));
                     Append_To (Decls, Decl_ARECnPT);

                     --  ARECn : aliased ARECnT;

                     Decl_ARECn :=
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => STJ.ARECn,
                           Aliased_Present   => True,
                           Object_Definition =>
                             New_Occurrence_Of (STJ.ARECnT, Loc));
                     Append_To (Decls, Decl_ARECn);

                     --  ARECnP : constant ARECnPT := ARECn'Access;

                     Decl_ARECnP :=
                       Make_Object_Declaration (Loc,
                         Defining_Identifier => STJ.ARECnP,
                         Constant_Present    => True,
                         Object_Definition   =>
                           New_Occurrence_Of (STJ.ARECnPT, Loc),
                         Expression          =>
                           Make_Attribute_Reference (Loc,
                             Prefix         =>
                               New_Occurrence_Of (STJ.ARECn, Loc),
                             Attribute_Name => Name_Access));
                     Append_To (Decls, Decl_ARECnP);

                     --  If we are in a subprogram that has a static link that
                     --  is passed in (as indicated by ARECnF being defined),
                     --  then generate ARECn.ARECmU := ARECmF where m is
                     --  one less than the current level to set the uplink.

                     if Present (STJ.ARECnF) then
                        Decl_Assign :=
                          Make_Assignment_Statement (Loc,
                            Name       =>
                              Make_Selected_Component (Loc,
                                Prefix        =>
                                  New_Occurrence_Of (STJ.ARECn, Loc),
                                Selector_Name =>
                                  New_Occurrence_Of (STJ.ARECnU, Loc)),
                            Expression =>
                              New_Occurrence_Of (STJ.ARECnF, Loc));
                        Append_To (Decls, Decl_Assign);

                     else
                        Decl_Assign := Empty;
                     end if;

                     if No (Declarations (STJ.Bod)) then
                        Set_Declarations (STJ.Bod, Decls);
                     else
                        Prepend_List_To (Declarations (STJ.Bod), Decls);
                     end if;

                     --  Analyze the newly inserted declarations. Note that we
                     --  do not need to establish the whole scope stack, since
                     --  we have already set all entity fields (so there will
                     --  be no searching of upper scopes to resolve names). But
                     --  we do set the scope of the current subprogram, so that
                     --  newly created entities go in the right entity chain.

                     --  We analyze with all checks suppressed (since we do
                     --  not expect any exceptions).

                     Push_Scope (STJ.Ent);
                     Analyze (Decl_ARECnT,  Suppress => All_Checks);

                     --  Note that we need to call Set_Suppress_Initialization
                     --  after Decl_ARECnT has been analyzed, but before
                     --  analyzing Decl_ARECnP so that the flag is properly
                     --  taking into account.

                     Set_Suppress_Initialization (STJ.ARECnT);

                     Analyze (Decl_ARECnPT, Suppress => All_Checks);
                     Analyze (Decl_ARECn,   Suppress => All_Checks);
                     Analyze (Decl_ARECnP,  Suppress => All_Checks);

                     if Present (Decl_Assign) then
                        Analyze (Decl_Assign, Suppress => All_Checks);
                     end if;

                     Pop_Scope;

                     --  Next step, for each uplevel referenced entity, add
                     --  assignment operations to set the component in the
                     --  activation record.

                     if Present (STJ.Uents) then
                        declare
                           Elmt : Elmt_Id;

                        begin
                           Elmt := First_Elmt (STJ.Uents);
                           while Present (Elmt) loop
                              declare
                                 Ent : constant Entity_Id  := Node (Elmt);
                                 Loc : constant Source_Ptr := Sloc (Ent);
                                 Dec : constant Node_Id    :=
                                         Declaration_Node (Ent);

                                 Asn  : Node_Id;
                                 Attr : Name_Id;
                                 Comp : Entity_Id;
                                 Ins  : Node_Id;
                                 Rhs  : Node_Id;

                              begin
                                 --  For parameters, we insert the assignment
                                 --  right after the declaration of ARECnP.
                                 --  For all other entities, we insert the
                                 --  assignment immediately after the
                                 --  declaration of the entity or after the
                                 --  freeze node if present.

                                 --  Note: we don't need to mark the entity
                                 --  as being aliased, because the address
                                 --  attribute will mark it as Address_Taken,
                                 --  and that is good enough.

                                 if Is_Formal (Ent) then
                                    Ins := Decl_ARECnP;

                                 elsif Has_Delayed_Freeze (Ent) then
                                    Ins := Freeze_Node (Ent);

                                 else
                                    Ins := Dec;
                                 end if;

                                 --  Build and insert the assignment:
                                 --    ARECn.nam := nam'Address
                                 --  or else 'Access for unconstrained array

                                 if Needs_Fat_Pointer (Ent) then
                                    Attr := Name_Access;
                                 else
                                    Attr := Name_Address;
                                 end if;

                                 Rhs :=
                                  Make_Attribute_Reference (Loc,
                                    Prefix         =>
                                      New_Occurrence_Of (Ent, Loc),
                                    Attribute_Name => Attr);

                                 --  If the entity is an unconstrained formal
                                 --  we wrap the attribute reference in an
                                 --  unchecked conversion to the type of the
                                 --  activation record component, to prevent
                                 --  spurious subtype conformance errors within
                                 --  instances.

                                 if Is_Formal (Ent)
                                   and then not Is_Constrained (Etype (Ent))
                                 then
                                    --  Find target component and its type

                                    Comp := First_Component (STJ.ARECnT);
                                    while Chars (Comp) /= Chars (Ent) loop
                                       Comp := Next_Component (Comp);
                                    end loop;

                                    Rhs :=
                                      Unchecked_Convert_To (Etype (Comp), Rhs);
                                 end if;

                                 Asn :=
                                   Make_Assignment_Statement (Loc,
                                     Name       =>
                                       Make_Selected_Component (Loc,
                                         Prefix        =>
                                           New_Occurrence_Of (STJ.ARECn, Loc),
                                         Selector_Name =>
                                           New_Occurrence_Of
                                             (Activation_Record_Component
                                                (Ent),
                                              Loc)),
                                     Expression => Rhs);

                                 --  If we have a loop parameter, we have
                                 --  to insert before the first statement
                                 --  of the loop. Ins points to the
                                 --  N_Loop_Parameter_Specification or to
                                 --  an N_Iterator_Specification.

                                 if Nkind_In
                                      (Ins, N_Iterator_Specification,
                                            N_Loop_Parameter_Specification)
                                 then
                                    --  Quantified expression are rewritten as
                                    --  loops during expansion.

                                    if Nkind (Parent (Ins)) =
                                         N_Quantified_Expression
                                    then
                                       null;

                                    else
                                       Ins :=
                                         First
                                           (Statements
                                             (Parent (Parent (Ins))));
                                       Insert_Before (Ins, Asn);
                                    end if;

                                 else
                                    Insert_After (Ins, Asn);
                                 end if;

                                 --  Analyze the assignment statement. We do
                                 --  not need to establish the relevant scope
                                 --  stack entries here, because we have
                                 --  already set the correct entity references,
                                 --  so no name resolution is required, and no
                                 --  new entities are created, so we don't even
                                 --  need to set the current scope.

                                 --  We analyze with all checks suppressed
                                 --  (since we do not expect any exceptions).

                                 Analyze (Asn, Suppress => All_Checks);
                              end;

                              Next_Elmt (Elmt);
                           end loop;
                        end;
                     end if;
                  end;
               end if;
            end;
         end loop;
      end Subp_Loop;

      --  Next step, process uplevel references. This has to be done in a
      --  separate pass, after completing the processing in Sub_Loop because we
      --  need all the AREC declarations generated, inserted, and analyzed so
      --  that the uplevel references can be successfully analyzed.

      Uplev_Refs : for J in Urefs.First .. Urefs.Last loop
         declare
            UPJ : Uref_Entry renames Urefs.Table (J);

         begin
            --  Ignore type references, these are implicit references that do
            --  not need rewriting (e.g. the appearence in a conversion).
            --  Also ignore if no reference was specified or if the rewriting
            --  has already been done (this can happen if the N_Identifier
            --  occurs more than one time in the tree).

            if No (UPJ.Ref)
              or else not Is_Entity_Name (UPJ.Ref)
              or else not Present (Entity (UPJ.Ref))
            then
               goto Continue;
            end if;

            --  Rewrite one reference

            Rewrite_One_Ref : declare
               Loc : constant Source_Ptr := Sloc (UPJ.Ref);
               --  Source location for the reference

               Typ : constant Entity_Id := Etype (UPJ.Ent);
               --  The type of the referenced entity

               Atyp : Entity_Id;
               --  The actual subtype of the reference

               RS_Caller : constant SI_Type := Subp_Index (UPJ.Caller);
               --  Subp_Index for caller containing reference

               STJR : Subp_Entry renames Subps.Table (RS_Caller);
               --  Subp_Entry for subprogram containing reference

               RS_Callee : constant SI_Type := Subp_Index (UPJ.Callee);
               --  Subp_Index for subprogram containing referenced entity

               STJE : Subp_Entry renames Subps.Table (RS_Callee);
               --  Subp_Entry for subprogram containing referenced entity

               Pfx  : Node_Id;
               Comp : Entity_Id;
               SI   : SI_Type;

            begin
               Atyp := Etype (UPJ.Ref);

               if Ekind (Atyp) /= E_Record_Subtype then
                  Atyp := Get_Actual_Subtype (UPJ.Ref);
               end if;

               --  Ignore if no ARECnF entity for enclosing subprogram which
               --  probably happens as a result of not properly treating
               --  instance bodies. To be examined ???

               --  If this test is omitted, then the compilation of freeze.adb
               --  and inline.adb fail in unnesting mode.

               if No (STJR.ARECnF) then
                  goto Continue;
               end if;

               --  If this is a reference to a global constant, use its value
               --  rather than create a reference. It is more efficient and
               --  furthermore indispensable if the context requires a
               --  constant, such as a branch of a case statement.

               if Ekind (UPJ.Ent) = E_Constant
                 and then Is_True_Constant (UPJ.Ent)
                 and then Present (Constant_Value (UPJ.Ent))
                 and then Is_Static_Expression (Constant_Value (UPJ.Ent))
               then
                  Rewrite (UPJ.Ref,
                    New_Copy_Tree (Constant_Value (UPJ.Ent)));
                  goto Continue;
               end if;

               --  Push the current scope, so that the pointer type Tnn, and
               --  any subsidiary entities resulting from the analysis of the
               --  rewritten reference, go in the right entity chain.

               Push_Scope (STJR.Ent);

               --  Now we need to rewrite the reference. We have a reference
               --  from level STJR.Lev to level STJE.Lev. The general form of
               --  the rewritten reference for entity X is:

               --    Typ'Deref (ARECaF.ARECbU.ARECcU.ARECdU....ARECmU.X)

               --  where a,b,c,d .. m =
               --    STJR.Lev - 1,  STJR.Lev - 2, .. STJE.Lev

               pragma Assert (STJR.Lev > STJE.Lev);

               --  Compute the prefix of X. Here are examples to make things
               --  clear (with parens to show groupings, the prefix is
               --  everything except the .X at the end).

               --   level 2 to level 1

               --     AREC1F.X

               --   level 3 to level 1

               --     (AREC2F.AREC1U).X

               --   level 4 to level 1

               --     ((AREC3F.AREC2U).AREC1U).X

               --   level 6 to level 2

               --     (((AREC5F.AREC4U).AREC3U).AREC2U).X

               --  In the above, ARECnF and ARECnU are pointers, so there are
               --  explicit dereferences required for these occurrences.

               Pfx :=
                 Make_Explicit_Dereference (Loc,
                   Prefix => New_Occurrence_Of (STJR.ARECnF, Loc));
               SI := RS_Caller;
               for L in STJE.Lev .. STJR.Lev - 2 loop
                  SI := Enclosing_Subp (SI);
                  Pfx :=
                    Make_Explicit_Dereference (Loc,
                      Prefix =>
                        Make_Selected_Component (Loc,
                          Prefix        => Pfx,
                          Selector_Name =>
                            New_Occurrence_Of (Subps.Table (SI).ARECnU, Loc)));
               end loop;

               --  Get activation record component (must exist)

               Comp := Activation_Record_Component (UPJ.Ent);
               pragma Assert (Present (Comp));

               --  Do the replacement. If the component type is an access type,
               --  this is an uplevel reference for an entity that requires a
               --  fat pointer, so dereference the component.

               if Is_Access_Type (Etype (Comp)) then
                  Rewrite (UPJ.Ref,
                    Make_Explicit_Dereference (Loc,
                      Prefix =>
                        Make_Selected_Component (Loc,
                          Prefix        => Pfx,
                          Selector_Name =>
                            New_Occurrence_Of (Comp, Loc))));

               else
                  Rewrite (UPJ.Ref,
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Atyp, Loc),
                      Attribute_Name => Name_Deref,
                      Expressions    => New_List (
                        Make_Selected_Component (Loc,
                          Prefix        => Pfx,
                          Selector_Name =>
                            New_Occurrence_Of (Comp, Loc)))));
               end if;

               --  Analyze and resolve the new expression. We do not need to
               --  establish the relevant scope stack entries here, because we
               --  have already set all the correct entity references, so no
               --  name resolution is needed. We have already set the current
               --  scope, so that any new entities created will be in the right
               --  scope.

               --  We analyze with all checks suppressed (since we do not
               --  expect any exceptions)

               Analyze_And_Resolve (UPJ.Ref, Typ, Suppress => All_Checks);
               Pop_Scope;
            end Rewrite_One_Ref;
         end;

      <<Continue>>
         null;
      end loop Uplev_Refs;

      --  Finally, loop through all calls adding extra actual for the
      --  activation record where it is required.

      Adjust_Calls : for J in Calls.First .. Calls.Last loop

         --  Process a single call, we are only interested in a call to a
         --  subprogram that actually needs a pointer to an activation record,
         --  as indicated by the ARECnF entity being set. This excludes the
         --  top level subprogram, and any subprogram not having uplevel refs.

         Adjust_One_Call : declare
            CTJ : Call_Entry renames Calls.Table (J);
            STF : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Caller));
            STT : Subp_Entry renames Subps.Table (Subp_Index (CTJ.Callee));

            Loc : constant Source_Ptr := Sloc (CTJ.N);

            Extra  : Node_Id;
            ExtraP : Node_Id;
            SubX   : SI_Type;
            Act    : Node_Id;

         begin
            if Present (STT.ARECnF)
              and then Nkind (CTJ.N) in N_Subprogram_Call
            then
               --  CTJ.N is a call to a subprogram which may require a pointer
               --  to an activation record. The subprogram containing the call
               --  is CTJ.From and the subprogram being called is CTJ.To, so we
               --  have a call from level STF.Lev to level STT.Lev.

               --  There are three possibilities:

               --  For a call to the same level, we just pass the activation
               --  record passed to the calling subprogram.

               if STF.Lev = STT.Lev then
                  Extra := New_Occurrence_Of (STF.ARECnF, Loc);

               --  For a call that goes down a level, we pass a pointer to the
               --  activation record constructed within the caller (which may
               --  be the outer-level subprogram, but also may be a more deeply
               --  nested caller).

               elsif STT.Lev = STF.Lev + 1 then
                  Extra := New_Occurrence_Of (STF.ARECnP, Loc);

                  --  Otherwise we must have an upcall (STT.Lev < STF.LEV),
                  --  since it is not possible to do a downcall of more than
                  --  one level.

                  --  For a call from level STF.Lev to level STT.Lev, we
                  --  have to find the activation record needed by the
                  --  callee. This is as follows:

                  --    ARECaF.ARECbU.ARECcU....ARECmU

                  --  where a,b,c .. m =
                  --    STF.Lev - 1,  STF.Lev - 2, STF.Lev - 3 .. STT.Lev

               else
                  pragma Assert (STT.Lev < STF.Lev);

                  Extra := New_Occurrence_Of (STF.ARECnF, Loc);
                  SubX  := Subp_Index (CTJ.Caller);
                  for K in reverse STT.Lev .. STF.Lev - 1 loop
                     SubX  := Enclosing_Subp (SubX);
                     Extra :=
                       Make_Selected_Component (Loc,
                         Prefix        => Extra,
                         Selector_Name =>
                           New_Occurrence_Of
                             (Subps.Table (SubX).ARECnU, Loc));
                  end loop;
               end if;

               --  Extra is the additional parameter to be added. Build a
               --  parameter association that we can append to the actuals.

               ExtraP :=
                 Make_Parameter_Association (Loc,
                   Selector_Name             =>
                     New_Occurrence_Of (STT.ARECnF, Loc),
                   Explicit_Actual_Parameter => Extra);

               if No (Parameter_Associations (CTJ.N)) then
                  Set_Parameter_Associations (CTJ.N, Empty_List);
               end if;

               Append (ExtraP, Parameter_Associations (CTJ.N));

               --  We need to deal with the actual parameter chain as well. The
               --  newly added parameter is always the last actual.

               Act := First_Named_Actual (CTJ.N);

               if No (Act) then
                  Set_First_Named_Actual (CTJ.N, Extra);

                  --  If call has been relocated (as with an expression in
                  --  an aggregate), set First_Named pointer in original node
                  --  as well, because that's the parent of the parameter list.

                  Set_First_Named_Actual
                    (Parent (List_Containing (ExtraP)), Extra);

               --  Here we must follow the chain and append the new entry

               else
                  loop
                     declare
                        PAN : Node_Id;
                        NNA : Node_Id;

                     begin
                        PAN := Parent (Act);
                        pragma Assert (Nkind (PAN) = N_Parameter_Association);
                        NNA := Next_Named_Actual (PAN);

                        if No (NNA) then
                           Set_Next_Named_Actual (PAN, Extra);
                           exit;
                        end if;

                        Act := NNA;
                     end;
                  end loop;
               end if;

               --  Analyze and resolve the new actual. We do not need to
               --  establish the relevant scope stack entries here, because
               --  we have already set all the correct entity references, so
               --  no name resolution is needed.

               --  We analyze with all checks suppressed (since we do not
               --  expect any exceptions, and also we temporarily turn off
               --  Unested_Subprogram_Mode to avoid trying to mark uplevel
               --  references (not needed at this stage, and in fact causes
               --  a bit of recursive chaos).

               Opt.Unnest_Subprogram_Mode := False;
               Analyze_And_Resolve
                 (Extra, Etype (STT.ARECnF), Suppress => All_Checks);
               Opt.Unnest_Subprogram_Mode := True;
            end if;
         end Adjust_One_Call;
      end loop Adjust_Calls;

      return;
   end Unnest_Subprogram;

   ------------------------
   -- Unnest_Subprograms --
   ------------------------

   procedure Unnest_Subprograms (N : Node_Id) is
      function Search_Subprograms (N : Node_Id) return Traverse_Result;
      --  Tree visitor that search for outer level procedures with nested
      --  subprograms and invokes Unnest_Subprogram()

      ---------------
      -- Do_Search --
      ---------------

      procedure Do_Search is new Traverse_Proc (Search_Subprograms);
      --  Subtree visitor instantiation

      ------------------------
      -- Search_Subprograms --
      ------------------------

      function Search_Subprograms (N : Node_Id) return Traverse_Result is
      begin
         if Nkind_In (N, N_Subprogram_Body, N_Subprogram_Body_Stub) then
            declare
               Spec_Id : constant Entity_Id := Unique_Defining_Entity (N);

            begin
               --  We are only interested in subprograms (not generic
               --  subprograms), that have nested subprograms.

               if Is_Subprogram (Spec_Id)
                 and then Has_Nested_Subprogram (Spec_Id)
                 and then Is_Library_Level_Entity (Spec_Id)
               then
                  Unnest_Subprogram (Spec_Id, N);
               end if;
            end;

         --  The proper body of a stub may contain nested subprograms, and
         --  therefore must be visited explicitly. Nested stubs are examined
         --  recursively in Visit_Node.

         elsif Nkind (N) in N_Body_Stub then
            Do_Search (Library_Unit (N));

         --  Skip generic packages

         elsif Nkind (N) = N_Package_Body
           and then Ekind (Corresponding_Spec (N)) = E_Generic_Package
         then
            return Skip;
         end if;

         return OK;
      end Search_Subprograms;

   --  Start of processing for Unnest_Subprograms

   begin
      if not Opt.Unnest_Subprogram_Mode or not Opt.Expander_Active then
         return;
      end if;

      --  A specification will contain bodies if it contains instantiations so
      --  examine package or subprogram declaration of the main unit, when it
      --  is present.

      if Nkind (Unit (N)) = N_Package_Body
        or else (Nkind (Unit (N)) = N_Subprogram_Body
                  and then not Acts_As_Spec (N))
      then
         Do_Search (Library_Unit (N));
      end if;

      Do_Search (N);
   end Unnest_Subprograms;

end Exp_Unst;
