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

with Aspects;        use Aspects;
with Atree;          use Atree;
with Contracts;      use Contracts;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Exp_Put_Image;
with Exp_Util;       use Exp_Util;
with Elists;         use Elists;
with Fname;          use Fname;
with Fname.UF;       use Fname.UF;
with Freeze;         use Freeze;
with Impunit;        use Impunit;
with Inline;         use Inline;
with Lib;            use Lib;
with Lib.Load;       use Lib.Load;
with Lib.Xref;       use Lib.Xref;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Output;         use Output;
with Par_SCO;        use Par_SCO;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch7;        use Sem_Ch7;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch13;       use Sem_Ch13;
with Sem_Dist;       use Sem_Dist;
with Sem_Prag;       use Sem_Prag;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinfo.CN;       use Sinfo.CN;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Style;          use Style;
with Stylesw;        use Stylesw;
with Tbuild;         use Tbuild;
with Uname;          use Uname;

package body Sem_Ch10 is

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

   procedure Analyze_Context (N : Node_Id);
   --  Analyzes items in the context clause of compilation unit

   procedure Build_Limited_Views (N : Node_Id);
   --  Build and decorate the list of shadow entities for a package mentioned
   --  in a limited_with clause. If the package was not previously analyzed
   --  then it also performs a basic decoration of the real entities. This is
   --  required in order to avoid passing non-decorated entities to the
   --  back-end. Implements Ada 2005 (AI-50217).

   procedure Analyze_Proper_Body (N : Node_Id; Nam : Entity_Id);
   --  Common processing for all stubs (subprograms, tasks, packages, and
   --  protected cases). N is the stub to be analyzed. Once the subunit name
   --  is established, load and analyze. Nam is the non-overloadable entity
   --  for which the proper body provides a completion. Subprogram stubs are
   --  handled differently because they can be declarations.

   procedure Check_Body_Needed_For_SAL (Unit_Name : Entity_Id);
   --  Check whether the source for the body of a compilation unit must be
   --  included in a standalone library.

   procedure Check_No_Elab_Code_All (N : Node_Id);
   --  Carries out possible tests for violation of No_Elab_Code all for withed
   --  units in the Context_Items of unit N.

   procedure Check_Private_Child_Unit (N : Node_Id);
   --  If a with_clause mentions a private child unit, the compilation unit
   --  must be a member of the same family, as described in 10.1.2.

   procedure Check_Stub_Level (N : Node_Id);
   --  Verify that a stub is declared immediately within a compilation unit,
   --  and not in an inner frame.

   procedure Expand_With_Clause (Item : Node_Id; Nam : Node_Id; N : Node_Id);
   --  When a child unit appears in a context clause, the implicit withs on
   --  parents are made explicit, and with clauses are inserted in the context
   --  clause before the one for the child. If a parent in the with_clause
   --  is a renaming, the implicit with_clause is on the renaming whose name
   --  is mentioned in the with_clause, and not on the package it renames.
   --  N is the compilation unit whose list of context items receives the
   --  implicit with_clauses.

   procedure Generate_Parent_References (N : Node_Id; P_Id : Entity_Id);
   --  Generate cross-reference information for the parents of child units
   --  and of subunits. N is a defining_program_unit_name, and P_Id is the
   --  immediate parent scope.

   function Has_With_Clause
     (C_Unit     : Node_Id;
      Pack       : Entity_Id;
      Is_Limited : Boolean := False) return Boolean;
   --  Determine whether compilation unit C_Unit contains a [limited] with
   --  clause for package Pack. Use the flag Is_Limited to designate desired
   --  clause kind.

   procedure Implicit_With_On_Parent (Child_Unit : Node_Id; N : Node_Id);
   --  If the main unit is a child unit, implicit withs are also added for
   --  all its ancestors.

   function In_Chain (E : Entity_Id) return Boolean;
   --  Check that the shadow entity is not already in the homonym chain, for
   --  example through a limited_with clause in a parent unit.

   procedure Install_Context_Clauses (N : Node_Id; Chain : Boolean := True);
   --  Subsidiary to Install_Context and Install_Parents. Process all with
   --  and use clauses for current unit and its library unit if any. The flag
   --  Chain is used to control the "chaining" or linking together of use-type
   --  and use-package clauses to avoid circularities with reinstalling
   --  clauses.

   procedure Install_Limited_Context_Clauses (N : Node_Id);
   --  Subsidiary to Install_Context. Process only limited with_clauses for
   --  current unit. Implements Ada 2005 (AI-50217).

   procedure Install_Limited_With_Clause (N : Node_Id);
   --  Place shadow entities for a limited_with package in the visibility
   --  structures for the current compilation. Implements Ada 2005 (AI-50217).

   procedure Install_Parents
     (Lib_Unit   : Node_Id;
      Is_Private : Boolean;
      Chain      : Boolean := True);
   --  This procedure establishes the context for the compilation of a child
   --  unit. If Lib_Unit is a child library spec then the context of the parent
   --  is installed, and the parent itself made immediately visible, so that
   --  the child unit is processed in the declarative region of the parent.
   --  Install_Parents makes a recursive call to itself to ensure that all
   --  parents are loaded in the nested case. If Lib_Unit is a library body,
   --  the only effect of Install_Parents is to install the private decls of
   --  the parents, because the visible parent declarations will have been
   --  installed as part of the context of the corresponding spec. The flag
   --  Chain is used to control the "chaining" or linking of use-type and
   --  use-package clauses to avoid circularities when installing context.

   procedure Install_Siblings (U_Name : Entity_Id; N : Node_Id);
   --  In the compilation of a child unit, a child of any of the  ancestor
   --  units is directly visible if it is visible, because the parent is in
   --  an enclosing scope. Iterate over context to find child units of U_Name
   --  or of some ancestor of it.

   procedure Install_With_Clause
     (With_Clause     : Node_Id;
      Private_With_OK : Boolean := False);
   --  If the unit is not a child unit, make unit immediately visible. The
   --  caller ensures that the unit is not already currently installed. The
   --  flag Private_With_OK is set true in Install_Private_With_Clauses, which
   --  is called when compiling the private part of a package, or installing
   --  the private declarations of a parent unit.

   function Is_Ancestor_Unit (U1 : Node_Id; U2 : Node_Id) return Boolean;
   --  When compiling a unit Q descended from some parent unit P, a limited
   --  with_clause in the context of P that names some other ancestor of Q
   --  must not be installed because the ancestor is immediately visible.

   function Is_Child_Spec (Lib_Unit : Node_Id) return Boolean;
   --  Lib_Unit is a library unit which may be a spec or a body. Is_Child_Spec
   --  returns True if Lib_Unit is a library spec which is a child spec, i.e.
   --  a library spec that has a parent. If the call to Is_Child_Spec returns
   --  True, then Parent_Spec (Lib_Unit) is non-Empty and points to the
   --  compilation unit for the parent spec.
   --
   --  Lib_Unit can also be a subprogram body that acts as its own spec. If the
   --  Parent_Spec is non-empty, this is also a child unit.

   procedure Remove_Context_Clauses (N : Node_Id);
   --  Subsidiary of previous one. Remove use_ and with_clauses

   procedure Remove_Limited_With_Clause (N : Node_Id);
   --  Remove the shadow entities from visibility introduced for a package
   --  mentioned in limited with clause N. Implements Ada 2005 (AI-50217).

   procedure Remove_Limited_With_Unit
     (Pack_Decl  : Node_Id;
      Lim_Clause : Node_Id := Empty);
   --  Remove the shadow entities from visibility introduced for a package
   --  denoted by declaration Pack_Decl. Lim_Clause is the related limited
   --  with clause, if any. Implements Ada 2005 (AI-50217).

   procedure Remove_Parents (Lib_Unit : Node_Id);
   --  Remove_Parents checks if Lib_Unit is a child spec. If so then the parent
   --  contexts established by the corresponding call to Install_Parents are
   --  removed. Remove_Parents contains a recursive call to itself to ensure
   --  that all parents are removed in the nested case.

   procedure Remove_Unit_From_Visibility (Unit_Name : Entity_Id);
   --  Reset all visibility flags on unit after compiling it, either as a main
   --  unit or as a unit in the context.

   procedure Unchain (E : Entity_Id);
   --  Remove single entity from visibility list

   procedure sm;
   --  A dummy procedure, for debugging use, called just before analyzing the
   --  main unit (after dealing with any context clauses).

   --------------------------
   -- Limited_With_Clauses --
   --------------------------

   --  Limited_With clauses are the mechanism chosen for Ada 2005 to support
   --  mutually recursive types declared in different units. A limited_with
   --  clause that names package P in the context of unit U makes the types
   --  declared in the visible part of P available within U, but with the
   --  restriction that these types can only be used as incomplete types.
   --  The limited_with clause does not impose a semantic dependence on P,
   --  and it is possible for two packages to have limited_with_clauses on
   --  each other without creating an elaboration circularity.

   --  To support this feature, the analysis of a limited_with clause must
   --  create an abbreviated view of the package, without performing any
   --  semantic analysis on it. This "package abstract" contains shadow types
   --  that are in one-one correspondence with the real types in the package,
   --  and that have the properties of incomplete types.

   --  The implementation creates two element lists: one to chain the shadow
   --  entities, and one to chain the corresponding type entities in the tree
   --  of the package. Links between corresponding entities in both chains
   --  allow the compiler to select the proper view of a given type, depending
   --  on the context. Note that in contrast with the handling of private
   --  types, the limited view and the nonlimited view of a type are treated
   --  as separate entities, and no entity exchange needs to take place, which
   --  makes the implementation much simpler than could be feared.

   ------------------------------
   -- Analyze_Compilation_Unit --
   ------------------------------

   procedure Analyze_Compilation_Unit (N : Node_Id) is
      procedure Check_Redundant_Withs
        (Context_Items      : List_Id;
         Spec_Context_Items : List_Id := No_List);
      --  Determine whether the context list of a compilation unit contains
      --  redundant with clauses. When checking body clauses against spec
      --  clauses, set Context_Items to the context list of the body and
      --  Spec_Context_Items to that of the spec. Parent packages are not
      --  examined for documentation purposes.

      ---------------------------
      -- Check_Redundant_Withs --
      ---------------------------

      procedure Check_Redundant_Withs
        (Context_Items      : List_Id;
         Spec_Context_Items : List_Id := No_List)
      is
         Clause : Node_Id;

         procedure Process_Body_Clauses
          (Context_List      : List_Id;
           Clause            : Node_Id;
           Used              : out Boolean;
           Used_Type_Or_Elab : out Boolean);
         --  Examine the context clauses of a package body, trying to match the
         --  name entity of Clause with any list element. If the match occurs
         --  on a use package clause set Used to True, for a use type clause or
         --  pragma Elaborate[_All], set Used_Type_Or_Elab to True.

         procedure Process_Spec_Clauses
          (Context_List : List_Id;
           Clause       : Node_Id;
           Used         : out Boolean;
           Withed       : out Boolean;
           Exit_On_Self : Boolean := False);
         --  Examine the context clauses of a package spec, trying to match
         --  the name entity of Clause with any list element. If the match
         --  occurs on a use package clause, set Used to True, for a with
         --  package clause other than Clause, set Withed to True. Limited
         --  with clauses, implicitly generated with clauses and withs
         --  having pragmas Elaborate or Elaborate_All applied to them are
         --  skipped. Exit_On_Self is used to control the search loop and
         --  force an exit whenever Clause sees itself in the search.

         --------------------------
         -- Process_Body_Clauses --
         --------------------------

         procedure Process_Body_Clauses
          (Context_List      : List_Id;
           Clause            : Node_Id;
           Used              : out Boolean;
           Used_Type_Or_Elab : out Boolean)
         is
            Nam_Ent   : constant Entity_Id := Entity (Name (Clause));
            Cont_Item : Node_Id;
            Prag_Unit : Node_Id;
            Use_Item  : Node_Id;

            function Same_Unit (N : Node_Id; P : Entity_Id) return Boolean;
            --  In an expanded name in a use clause, if the prefix is a renamed
            --  package, the entity is set to the original package as a result,
            --  when checking whether the package appears in a previous with
            --  clause, the renaming has to be taken into account, to prevent
            --  spurious/incorrect warnings. A common case is use of Text_IO.

            ---------------
            -- Same_Unit --
            ---------------

            function Same_Unit (N : Node_Id; P : Entity_Id) return Boolean is
            begin
               return Entity (N) = P
                 or else (Present (Renamed_Object (P))
                           and then Entity (N) = Renamed_Object (P));
            end Same_Unit;

         --  Start of processing for Process_Body_Clauses

         begin
            Used := False;
            Used_Type_Or_Elab := False;

            Cont_Item := First (Context_List);
            while Present (Cont_Item) loop

               --  Package use clause

               if Nkind (Cont_Item) = N_Use_Package_Clause
                 and then not Used
               then
                  --  Search through use clauses

                  Use_Item := Name (Cont_Item);

                  --  Case of a direct use of the one we are looking for

                  if Entity (Use_Item) = Nam_Ent then
                     Used := True;

                  --  Handle nested case, as in "with P; use P.Q.R"

                  else
                     declare
                        UE : Node_Id;

                     begin
                        --  Loop through prefixes looking for match

                        UE := Use_Item;
                        while Nkind (UE) = N_Expanded_Name loop
                           if Same_Unit (Prefix (UE), Nam_Ent) then
                              Used := True;
                              exit;
                           end if;

                           UE := Prefix (UE);
                        end loop;
                     end;
                  end if;

               --  USE TYPE clause

               elsif Nkind (Cont_Item) = N_Use_Type_Clause
                 and then not Used_Type_Or_Elab
               then
                  declare
                     UE : Node_Id;

                  begin
                     --  Loop through prefixes looking for a match

                     UE := Prefix (Subtype_Mark (Cont_Item));
                     loop
                        if not Used_Type_Or_Elab
                          and then Same_Unit (UE, Nam_Ent)
                        then
                           Used_Type_Or_Elab := True;
                        end if;

                        exit when Nkind (UE) /= N_Expanded_Name;
                        UE := Prefix (UE);
                     end loop;
                  end;

               --  Pragma Elaborate or Elaborate_All

               elsif Nkind (Cont_Item) = N_Pragma
                 and then
                   Pragma_Name_Unmapped (Cont_Item)
                     in Name_Elaborate | Name_Elaborate_All
                 and then not Used_Type_Or_Elab
               then
                  Prag_Unit :=
                    First (Pragma_Argument_Associations (Cont_Item));
                  while Present (Prag_Unit) and then not Used_Type_Or_Elab loop
                     if Entity (Expression (Prag_Unit)) = Nam_Ent then
                        Used_Type_Or_Elab := True;
                     end if;

                     Next (Prag_Unit);
                  end loop;
               end if;

               Next (Cont_Item);
            end loop;
         end Process_Body_Clauses;

         --------------------------
         -- Process_Spec_Clauses --
         --------------------------

         procedure Process_Spec_Clauses
          (Context_List : List_Id;
           Clause       : Node_Id;
           Used         : out Boolean;
           Withed       : out Boolean;
           Exit_On_Self : Boolean := False)
         is
            Nam_Ent   : constant Entity_Id := Entity (Name (Clause));
            Cont_Item : Node_Id;

         begin
            Used := False;
            Withed := False;

            Cont_Item := First (Context_List);
            while Present (Cont_Item) loop

               --  Stop the search since the context items after Cont_Item have
               --  already been examined in a previous iteration of the reverse
               --  loop in Check_Redundant_Withs.

               if Exit_On_Self
                 and Cont_Item = Clause
               then
                  exit;
               end if;

               --  Package use clause

               if Nkind (Cont_Item) = N_Use_Package_Clause
                 and then not Used
               then
                  if Entity (Name (Cont_Item)) = Nam_Ent then
                     Used := True;
                  end if;

               --  Package with clause. Avoid processing self, implicitly
               --  generated with clauses or limited with clauses. Note that
               --  we examine with clauses having pragmas Elaborate or
               --  Elaborate_All applied to them due to cases such as:

               --     with Pack;
               --     with Pack;
               --     pragma Elaborate (Pack);

               --  In this case, the second with clause is redundant since
               --  the pragma applies only to the first "with Pack;".

               --  Note that we only consider with_clauses that comes from
               --  source. In the case of renamings used as prefixes of names
               --  in with_clauses, we generate a with_clause for the prefix,
               --  which we do not treat as implicit because it is needed for
               --  visibility analysis, but is also not redundant.

               elsif Nkind (Cont_Item) = N_With_Clause
                 and then Comes_From_Source (Cont_Item)
                 and then not Implicit_With (Cont_Item)
                 and then not Limited_Present (Cont_Item)
                 and then Cont_Item /= Clause
                 and then Entity (Name (Cont_Item)) = Nam_Ent
               then
                  Withed := True;
               end if;

               Next (Cont_Item);
            end loop;
         end Process_Spec_Clauses;

      --  Start of processing for Check_Redundant_Withs

      begin
         Clause := Last (Context_Items);
         while Present (Clause) loop

            --  Avoid checking implicitly generated with clauses, limited with
            --  clauses or withs that have pragma Elaborate or Elaborate_All.

            if Nkind (Clause) = N_With_Clause
              and then not Implicit_With (Clause)
              and then not Limited_Present (Clause)
              and then not Elaborate_Present (Clause)

              --  With_clauses introduced for renamings of parent clauses
              --  are not marked implicit because they need to be properly
              --  installed, but they do not come from source and do not
              --  require warnings.

              and then Comes_From_Source (Clause)
            then
               --  Package body-to-spec check

               if Present (Spec_Context_Items) then
                  declare
                     Used_In_Body      : Boolean;
                     Used_In_Spec      : Boolean;
                     Used_Type_Or_Elab : Boolean;
                     Withed_In_Spec    : Boolean;

                  begin
                     Process_Spec_Clauses
                       (Context_List => Spec_Context_Items,
                        Clause       => Clause,
                        Used         => Used_In_Spec,
                        Withed       => Withed_In_Spec);

                     Process_Body_Clauses
                       (Context_List      => Context_Items,
                        Clause            => Clause,
                        Used              => Used_In_Body,
                        Used_Type_Or_Elab => Used_Type_Or_Elab);

                     --  "Type Elab" refers to the presence of either a use
                     --  type clause, pragmas Elaborate or Elaborate_All.

                     --  +---------------+---------------------------+------+
                     --  | Spec          | Body                      | Warn |
                     --  +--------+------+--------+------+-----------+------+
                     --  | Withed | Used | Withed | Used | Type Elab |      |
                     --  |   X    |      |   X    |      |           |  X   |
                     --  |   X    |      |   X    |  X   |           |      |
                     --  |   X    |      |   X    |      |     X     |      |
                     --  |   X    |      |   X    |  X   |     X     |      |
                     --  |   X    |  X   |   X    |      |           |  X   |
                     --  |   X    |  X   |   X    |      |     X     |      |
                     --  |   X    |  X   |   X    |  X   |           |  X   |
                     --  |   X    |  X   |   X    |  X   |     X     |      |
                     --  +--------+------+--------+------+-----------+------+

                     if (Withed_In_Spec
                           and then not Used_Type_Or_Elab)
                             and then
                               ((not Used_In_Spec and then not Used_In_Body)
                                  or else Used_In_Spec)
                     then
                        Error_Msg_N -- CODEFIX
                          ("redundant with clause in body?r?", Clause);
                     end if;

                     Used_In_Body      := False;
                     Used_In_Spec      := False;
                     Used_Type_Or_Elab := False;
                     Withed_In_Spec    := False;
                  end;

               --  Standalone package spec or body check

               else
                  declare
                     Dummy  : Boolean := False;
                     Withed : Boolean := False;

                  begin
                     --  The mechanism for examining the context clauses of a
                     --  package spec can be applied to package body clauses.

                     Process_Spec_Clauses
                       (Context_List => Context_Items,
                        Clause       => Clause,
                        Used         => Dummy,
                        Withed       => Withed,
                        Exit_On_Self => True);

                     if Withed then
                        Error_Msg_N -- CODEFIX
                          ("redundant with clause?r?", Clause);
                     end if;
                  end;
               end if;
            end if;

            Prev (Clause);
         end loop;
      end Check_Redundant_Withs;

      --  Local variables

      Main_Cunit    : constant Node_Id := Cunit (Main_Unit);
      Unit_Node     : constant Node_Id := Unit (N);
      Lib_Unit      : Node_Id          := Library_Unit (N);
      Par_Spec_Name : Unit_Name_Type;
      Spec_Id       : Entity_Id;
      Unum          : Unit_Number_Type;

   --  Start of processing for Analyze_Compilation_Unit

   begin
      Exp_Put_Image.Preload_Root_Buffer_Type (N);

      Process_Compilation_Unit_Pragmas (N);

      --  If the unit is a subunit whose parent has not been analyzed (which
      --  indicates that the main unit is a subunit, either the current one or
      --  one of its descendants) then the subunit is compiled as part of the
      --  analysis of the parent, which we proceed to do. Basically this gets
      --  handled from the top down and we don't want to do anything at this
      --  level (i.e. this subunit will be handled on the way down from the
      --  parent), so at this level we immediately return. If the subunit ends
      --  up not analyzed, it means that the parent did not contain a stub for
      --  it, or that there errors were detected in some ancestor.

      if Nkind (Unit_Node) = N_Subunit and then not Analyzed (Lib_Unit) then
         Semantics (Lib_Unit);

         if not Analyzed (Proper_Body (Unit_Node)) then
            if Serious_Errors_Detected > 0 then
               Error_Msg_N ("subunit not analyzed (errors in parent unit)", N);
            else
               Error_Msg_N ("missing stub for subunit", N);
            end if;
         end if;

         return;
      end if;

      --  Analyze context (this will call Sem recursively for with'ed units) To
      --  detect circularities among with-clauses that are not caught during
      --  loading, we set the Context_Pending flag on the current unit. If the
      --  flag is already set there is a potential circularity. We exclude
      --  predefined units from this check because they are known to be safe.
      --  We also exclude package bodies that are present because circularities
      --  between bodies are harmless (and necessary).

      if Context_Pending (N) then
         declare
            Circularity : Boolean := True;

         begin
            if In_Predefined_Unit (N) then
               Circularity := False;

            else
               for U in Main_Unit + 1 .. Last_Unit loop
                  if Nkind (Unit (Cunit (U))) = N_Package_Body
                    and then not Analyzed (Cunit (U))
                  then
                     Circularity := False;
                     exit;
                  end if;
               end loop;
            end if;

            if Circularity then
               Error_Msg_N ("circular dependency caused by with_clauses", N);
               Error_Msg_N
                 ("\possibly missing limited_with clause"
                  & " in one of the following", N);

               for U in Main_Unit .. Last_Unit loop
                  if Context_Pending (Cunit (U)) then
                     Error_Msg_Unit_1 := Get_Unit_Name (Unit (Cunit (U)));
                     Error_Msg_N ("\unit$", N);
                  end if;
               end loop;

               raise Unrecoverable_Error;
            end if;
         end;
      else
         Set_Context_Pending (N);
      end if;

      Analyze_Context (N);

      Set_Context_Pending (N, False);

      --  If the unit is a package body, the spec is already loaded and must be
      --  analyzed first, before we analyze the body.

      if Nkind (Unit_Node) = N_Package_Body then

         --  If no Lib_Unit, then there was a serious previous error, so just
         --  ignore the entire analysis effort.

         if No (Lib_Unit) then
            Check_Error_Detected;
            return;

         else
            --  Analyze the package spec

            Semantics (Lib_Unit);

            --  Check for unused with's

            Check_Unused_Withs (Get_Cunit_Unit_Number (Lib_Unit));

            --  Verify that the library unit is a package declaration

            if Nkind (Unit (Lib_Unit)) not in
                 N_Package_Declaration | N_Generic_Package_Declaration
            then
               Error_Msg_N
                 ("no legal package declaration for package body", N);
               return;

            --  Otherwise, the entity in the declaration is visible. Update the
            --  version to reflect dependence of this body on the spec.

            else
               Spec_Id := Defining_Entity (Unit (Lib_Unit));
               Set_Is_Immediately_Visible (Spec_Id, True);
               Version_Update (N, Lib_Unit);

               if Nkind (Defining_Unit_Name (Unit_Node)) =
                                             N_Defining_Program_Unit_Name
               then
                  Generate_Parent_References (Unit_Node, Scope (Spec_Id));
               end if;
            end if;
         end if;

      --  If the unit is a subprogram body, then we similarly need to analyze
      --  its spec. However, things are a little simpler in this case, because
      --  here, this analysis is done mostly for error checking and consistency
      --  purposes (but not only, e.g. there could be a contract on the spec),
      --  so there's nothing else to be done.

      elsif Nkind (Unit_Node) = N_Subprogram_Body then
         if Acts_As_Spec (N) then

            --  If the subprogram body is a child unit, we must create a
            --  declaration for it, in order to properly load the parent(s).
            --  After this, the original unit does not acts as a spec, because
            --  there is an explicit one. If this unit appears in a context
            --  clause, then an implicit with on the parent will be added when
            --  installing the context. If this is the main unit, there is no
            --  Unit_Table entry for the declaration (it has the unit number
            --  of the main unit) and code generation is unaffected.

            Unum := Get_Cunit_Unit_Number (N);
            Par_Spec_Name := Get_Parent_Spec_Name (Unit_Name (Unum));

            if Present (Par_Spec_Name) then
               Unum :=
                 Load_Unit
                   (Load_Name  => Par_Spec_Name,
                    Required   => True,
                    Subunit    => False,
                    Error_Node => N);

               if Unum /= No_Unit then

                  --  Build subprogram declaration and attach parent unit to it
                  --  This subprogram declaration does not come from source,
                  --  Nevertheless the backend must generate debugging info for
                  --  it, and this must be indicated explicitly. We also mark
                  --  the body entity as a child unit now, to prevent a
                  --  cascaded error if the spec entity cannot be entered
                  --  in its scope. Finally we create a Units table entry for
                  --  the subprogram declaration, to maintain a one-to-one
                  --  correspondence with compilation unit nodes. This is
                  --  critical for the tree traversals performed by CodePeer.

                  declare
                     Loc : constant Source_Ptr := Sloc (N);
                     SCS : constant Boolean :=
                             Get_Comes_From_Source_Default;

                  begin
                     Set_Comes_From_Source_Default (False);

                     --  Note: We copy the Context_Items from the explicit body
                     --  to the implicit spec, setting the former to Empty_List
                     --  to preserve the treeish nature of the tree, during
                     --  analysis of the spec. Then we put it back the way it
                     --  was -- copy the Context_Items from the spec to the
                     --  body, and set the spec Context_Items to Empty_List.
                     --  It is necessary to preserve the treeish nature,
                     --  because otherwise we will call End_Use_* twice on the
                     --  same thing.

                     Lib_Unit :=
                       Make_Compilation_Unit (Loc,
                         Context_Items => Context_Items (N),
                         Unit =>
                           Make_Subprogram_Declaration (Sloc (N),
                             Specification =>
                               Copy_Separate_Tree
                                 (Specification (Unit_Node))),
                         Aux_Decls_Node =>
                           Make_Compilation_Unit_Aux (Loc));

                     Set_Context_Items (N, Empty_List);
                     Set_Library_Unit (N, Lib_Unit);
                     Set_Parent_Spec (Unit (Lib_Unit), Cunit (Unum));
                     Make_Child_Decl_Unit (N);
                     Semantics (Lib_Unit);

                     --  Now that a separate declaration exists, the body
                     --  of the child unit does not act as spec any longer.

                     Set_Acts_As_Spec (N, False);
                     Move_Aspects (From => Unit_Node, To => Unit (Lib_Unit));
                     Set_Is_Child_Unit (Defining_Entity (Unit_Node));
                     Set_Debug_Info_Needed (Defining_Entity (Unit (Lib_Unit)));
                     Set_Comes_From_Source_Default (SCS);

                     --  Restore Context_Items to the body

                     Set_Context_Items (N, Context_Items (Lib_Unit));
                     Set_Context_Items (Lib_Unit, Empty_List);
                  end;
               end if;
            end if;

         --  Here for subprogram with separate declaration

         else
            Semantics (Lib_Unit);
            Check_Unused_Withs (Get_Cunit_Unit_Number (Lib_Unit));
            Version_Update (N, Lib_Unit);
         end if;

         --  If this is a child unit, generate references to the parents

         if Nkind (Defining_Unit_Name (Specification (Unit_Node))) =
                                             N_Defining_Program_Unit_Name
         then
            Generate_Parent_References
              (Specification (Unit_Node),
               Scope (Defining_Entity (Unit (Lib_Unit))));
         end if;
      end if;

      --  If it is a child unit, the parent must be elaborated first and we
      --  update version, since we are dependent on our parent.

      if Is_Child_Spec (Unit_Node) then

         --  The analysis of the parent is done with style checks off

         declare
            Save_Style_Check : constant Boolean := Style_Check;

         begin
            if not GNAT_Mode then
               Style_Check := False;
            end if;

            Semantics (Parent_Spec (Unit_Node));
            Version_Update (N, Parent_Spec (Unit_Node));

            --  Restore style check settings

            Style_Check := Save_Style_Check;
         end;
      end if;

      --  With the analysis done, install the context. Note that we can't
      --  install the context from the with clauses as we analyze them, because
      --  each with clause must be analyzed in a clean visibility context, so
      --  we have to wait and install them all at once.

      Install_Context (N);

      if Is_Child_Spec (Unit_Node) then

         --  Set the entities of all parents in the program_unit_name

         Generate_Parent_References
           (Unit_Node, Get_Parent_Entity (Unit (Parent_Spec (Unit_Node))));
      end if;

      --  All components of the context: with-clauses, library unit, ancestors
      --  if any, (and their context) are analyzed and installed.

      --  Call special debug routine sm if this is the main unit

      if Current_Sem_Unit = Main_Unit then
         sm;
      end if;

      --  Now analyze the unit (package, subprogram spec, body) itself

      Analyze (Unit_Node);

      if Warn_On_Redundant_Constructs then
         Check_Redundant_Withs (Context_Items (N));

         if Nkind (Unit_Node) = N_Package_Body then
            Check_Redundant_Withs
              (Context_Items      => Context_Items (N),
               Spec_Context_Items => Context_Items (Lib_Unit));
         end if;
      end if;

      --  The above call might have made Unit_Node an N_Subprogram_Body from
      --  something else, so propagate any Acts_As_Spec flag.

      if Nkind (Unit_Node) = N_Subprogram_Body
        and then Acts_As_Spec (Unit_Node)
      then
         Set_Acts_As_Spec (N);
      end if;

      --  Register predefined units in Rtsfind

      if In_Predefined_Unit (N) then
         Set_RTU_Loaded (Unit_Node);
      end if;

      --  Treat compilation unit pragmas that appear after the library unit

      if Present (Pragmas_After (Aux_Decls_Node (N))) then
         declare
            Prag_Node : Node_Id := First (Pragmas_After (Aux_Decls_Node (N)));
         begin
            while Present (Prag_Node) loop
               Analyze (Prag_Node);
               Next (Prag_Node);
            end loop;
         end;
      end if;

      --  Analyze the contract of a [generic] subprogram that acts as a
      --  compilation unit after all compilation pragmas have been analyzed.

      if Nkind (Unit_Node) in
           N_Generic_Subprogram_Declaration | N_Subprogram_Declaration
      then
         Analyze_Entry_Or_Subprogram_Contract (Defining_Entity (Unit_Node));
      end if;

      --  Generate distribution stubs if requested and no error

      if N = Main_Cunit
        and then (Distribution_Stub_Mode = Generate_Receiver_Stub_Body
                    or else
                  Distribution_Stub_Mode = Generate_Caller_Stub_Body)
        and then Fatal_Error (Main_Unit) /= Error_Detected
      then
         if Is_RCI_Pkg_Spec_Or_Body (N) then

            --  Regular RCI package

            Add_Stub_Constructs (N);

         elsif (Nkind (Unit_Node) = N_Package_Declaration
                 and then Is_Shared_Passive (Defining_Entity
                                              (Specification (Unit_Node))))
           or else (Nkind (Unit_Node) = N_Package_Body
                     and then
                       Is_Shared_Passive (Corresponding_Spec (Unit_Node)))
         then
            --  Shared passive package

            Add_Stub_Constructs (N);

         elsif Nkind (Unit_Node) = N_Package_Instantiation
           and then
             Is_Remote_Call_Interface
               (Defining_Entity (Specification (Instance_Spec (Unit_Node))))
         then
            --  Instantiation of a RCI generic package

            Add_Stub_Constructs (N);
         end if;
      end if;

      --  Remove unit from visibility, so that environment is clean for the
      --  next compilation, which is either the main unit or some other unit
      --  in the context.

      if Nkind (Unit_Node) in N_Package_Declaration
                            | N_Package_Renaming_Declaration
                            | N_Subprogram_Declaration
                            | N_Generic_Declaration
        or else (Nkind (Unit_Node) = N_Subprogram_Body
                  and then Acts_As_Spec (Unit_Node))
      then
         Remove_Unit_From_Visibility (Defining_Entity (Unit_Node));

      --  If the unit is an instantiation whose body will be elaborated for
      --  inlining purposes, use the proper entity of the instance. The entity
      --  may be missing if the instantiation was illegal.

      elsif Nkind (Unit_Node) = N_Package_Instantiation
        and then not Error_Posted (Unit_Node)
        and then Present (Instance_Spec (Unit_Node))
      then
         Remove_Unit_From_Visibility
           (Defining_Entity (Instance_Spec (Unit_Node)));

      elsif Nkind (Unit_Node) = N_Package_Body
        or else (Nkind (Unit_Node) = N_Subprogram_Body
                  and then not Acts_As_Spec (Unit_Node))
      then
         --  Bodies that are not the main unit are compiled if they are generic
         --  or contain generic or inlined units. Their analysis brings in the
         --  context of the corresponding spec (unit declaration) which must be
         --  removed as well, to return the compilation environment to its
         --  proper state.

         Remove_Context (Lib_Unit);
         Set_Is_Immediately_Visible (Defining_Entity (Unit (Lib_Unit)), False);
      end if;

      --  Last step is to deinstall the context we just installed as well as
      --  the unit just compiled.

      Remove_Context (N);

      --  When generating code for a non-generic main unit, check that withed
      --  generic units have a body if they need it, even if the units have not
      --  been instantiated. Force the load of the bodies to produce the proper
      --  error if the body is absent. The same applies to GNATprove mode, with
      --  the added benefit of capturing global references within the generic.
      --  This in turn allows for proper inlining of subprogram bodies without
      --  a previous declaration.

      if Get_Cunit_Unit_Number (N) = Main_Unit
        and then ((Operating_Mode = Generate_Code and then Expander_Active)
                     or else
                  (Operating_Mode = Check_Semantics and then GNATprove_Mode))
      then
         --  Check whether the source for the body of the unit must be included
         --  in a standalone library.

         Check_Body_Needed_For_SAL (Cunit_Entity (Main_Unit));

         --  Indicate that the main unit is now analyzed, to catch possible
         --  circularities between it and generic bodies. Remove main unit from
         --  visibility. This might seem superfluous, but the main unit must
         --  not be visible in the generic body expansions that follow.

         Set_Analyzed (N, True);
         Set_Is_Immediately_Visible (Cunit_Entity (Main_Unit), False);

         declare
            Item  : Node_Id;
            Nam   : Entity_Id;
            Un    : Unit_Number_Type;

            Save_Style_Check : constant Boolean := Style_Check;

         begin
            Item := First (Context_Items (N));
            while Present (Item) loop

               --  Check for explicit with clause

               if Nkind (Item) = N_With_Clause
                 and then not Implicit_With (Item)

                 --  Ada 2005 (AI-50217): Ignore limited-withed units

                 and then not Limited_Present (Item)
               then
                  Nam := Entity (Name (Item));

                  --  Compile the generic subprogram, unless it is intrinsic or
                  --  imported so no body is required, or generic package body
                  --  if the package spec requires a body.

                  if (Is_Generic_Subprogram (Nam)
                       and then not Is_Intrinsic_Subprogram (Nam)
                       and then not Is_Imported (Nam))
                    or else (Ekind (Nam) = E_Generic_Package
                              and then Unit_Requires_Body (Nam))
                  then
                     Style_Check := False;

                     if Present (Renamed_Object (Nam)) then
                        Un :=
                          Load_Unit
                            (Load_Name  =>
                               Get_Body_Name
                                 (Get_Unit_Name
                                   (Unit_Declaration_Node
                                     (Renamed_Object (Nam)))),
                             Required   => False,
                             Subunit    => False,
                             Error_Node => N,
                             Renamings  => True);
                     else
                        Un :=
                          Load_Unit
                            (Load_Name  =>
                               Get_Body_Name (Get_Unit_Name (Item)),
                             Required   => False,
                             Subunit    => False,
                             Error_Node => N,
                             Renamings  => True);
                     end if;

                     if Un = No_Unit then
                        Error_Msg_NE
                          ("body of generic unit& not found", Item, Nam);
                        exit;

                     elsif not Analyzed (Cunit (Un))
                       and then Un /= Main_Unit
                       and then Fatal_Error (Un) /= Error_Detected
                     then
                        Style_Check := False;
                        Semantics (Cunit (Un));
                     end if;
                  end if;
               end if;

               Next (Item);
            end loop;

            --  Restore style checks settings

            Style_Check := Save_Style_Check;
         end;

         --  In GNATprove mode, force the loading of an Interrupt_Priority when
         --  processing compilation units with potentially "main" subprograms.
         --  This is required for the ceiling priority protocol checks, which
         --  are triggered by these subprograms.

         if GNATprove_Mode
           and then Nkind (Unit_Node) in N_Function_Instantiation
                                       | N_Procedure_Instantiation
                                       | N_Subprogram_Body
         then
            declare
               Spec : Node_Id;

            begin
               case Nkind (Unit_Node) is
                  when N_Subprogram_Body =>
                     Spec := Specification (Unit_Node);

                  when N_Subprogram_Instantiation =>
                     Spec :=
                       Subprogram_Specification (Entity (Name (Unit_Node)));

                  when others =>
                     raise Program_Error;
               end case;

               pragma Assert (Nkind (Spec) in N_Subprogram_Specification);

               --  Main subprogram must have no parameters, and if it is a
               --  function, it must return an integer.

               if No (Parameter_Specifications (Spec))
                 and then (Nkind (Spec) = N_Procedure_Specification
                             or else
                           Is_Integer_Type (Etype (Result_Definition (Spec))))
               then
                  SPARK_Implicit_Load (RE_Interrupt_Priority);
               end if;
            end;
         end if;
      end if;

      --  Deal with creating elaboration counter if needed. We create an
      --  elaboration counter only for units that come from source since
      --  units manufactured by the compiler never need elab checks.

      if Comes_From_Source (N)
        and then Nkind (Unit_Node) in N_Package_Declaration
                                    | N_Generic_Package_Declaration
                                    | N_Subprogram_Declaration
                                    | N_Generic_Subprogram_Declaration
      then
         declare
            Loc  : constant Source_Ptr       := Sloc (N);
            Unum : constant Unit_Number_Type := Get_Source_Unit (Loc);

         begin
            Spec_Id := Defining_Entity (Unit_Node);
            Generate_Definition (Spec_Id);

            --  See if an elaboration entity is required for possible access
            --  before elaboration checking. Note that we must allow for this
            --  even if -gnatE is not set, since a client may be compiled in
            --  -gnatE mode and reference the entity.

            --  These entities are also used by the binder to prevent multiple
            --  attempts to execute the elaboration code for the library case
            --  where the elaboration routine might otherwise be called more
            --  than once.

            --  They are also needed to ensure explicit visibility from the
            --  binder generated code of all the units involved in a partition
            --  when control-flow preservation is requested.

            if not Opt.Suppress_Control_Flow_Optimizations
              and then
              ( --  Pure units do not need checks

                Is_Pure (Spec_Id)

                --  Preelaborated units do not need checks

                or else Is_Preelaborated (Spec_Id)

                --  No checks needed if pragma Elaborate_Body present

                or else Has_Pragma_Elaborate_Body (Spec_Id)

                --  No checks needed if unit does not require a body

                or else not Unit_Requires_Body (Spec_Id)

                --  No checks needed for predefined files

                or else Is_Predefined_Unit (Unum)

                --  No checks required if no separate spec

                or else Acts_As_Spec (N)
              )
            then
               --  This is a case where we only need the entity for checking to
               --  prevent multiple elaboration checks.

               Set_Elaboration_Entity_Required (Spec_Id, False);

            --  Otherwise the unit requires an elaboration entity because it
            --  carries a body.

            else
               Set_Elaboration_Entity_Required (Spec_Id);
            end if;

            Build_Elaboration_Entity (N, Spec_Id);
         end;
      end if;

      --  Freeze the compilation unit entity. This for sure is needed because
      --  of some warnings that can be output (see Freeze_Subprogram), but may
      --  in general be required. If freezing actions result, place them in the
      --  compilation unit actions list, and analyze them.

      declare
         L : constant List_Id :=
               Freeze_Entity (Cunit_Entity (Current_Sem_Unit), N);
      begin
         while Is_Non_Empty_List (L) loop
            Insert_Library_Level_Action (Remove_Head (L));
         end loop;
      end;

      Set_Analyzed (N);

      --  Call Check_Package_Body so that a body containing subprograms with
      --  Inline_Always can be made available for front end inlining.

      if Nkind (Unit_Node) = N_Package_Declaration
        and then Get_Cunit_Unit_Number (N) /= Main_Unit

        --  We don't need to do this if the Expander is not active, since there
        --  is no code to inline.

        and then Expander_Active
      then
         declare
            Save_Style_Check : constant Boolean := Style_Check;
            Save_Warning     : constant Warning_Mode_Type := Warning_Mode;
            Options          : Style_Check_Options;

         begin
            Save_Style_Check_Options (Options);
            Reset_Style_Check_Options;
            Opt.Warning_Mode := Suppress;

            Check_Package_Body_For_Inlining (N, Defining_Entity (Unit_Node));

            Reset_Style_Check_Options;
            Set_Style_Check_Options (Options);
            Style_Check := Save_Style_Check;
            Warning_Mode := Save_Warning;
         end;
      end if;

      --  If we are generating obsolescent warnings, then here is where we
      --  generate them for the with'ed items. The reason for this special
      --  processing is that the normal mechanism of generating the warnings
      --  for referenced entities does not work for context clause references.
      --  That's because when we first analyze the context, it is too early to
      --  know if the with'ing unit is itself obsolescent (which suppresses
      --  the warnings).

      if not GNAT_Mode
        and then Warn_On_Obsolescent_Feature
        and then Nkind (Unit_Node) not in N_Generic_Instantiation
      then
         --  Push current compilation unit as scope, so that the test for
         --  being within an obsolescent unit will work correctly. The check
         --  is not performed within an instantiation, because the warning
         --  will have been emitted in the corresponding generic unit.

         Push_Scope (Defining_Entity (Unit_Node));

         --  Loop through context items to deal with with clauses

         declare
            Item : Node_Id;
            Nam  : Node_Id;
            Ent  : Entity_Id;

         begin
            Item := First (Context_Items (N));
            while Present (Item) loop
               if Nkind (Item) = N_With_Clause

                  --  Suppress this check in limited-withed units. Further work
                  --  needed here if we decide to incorporate this check on
                  --  limited-withed units.

                 and then not Limited_Present (Item)
               then
                  Nam := Name (Item);
                  Ent := Entity (Nam);

                  if Is_Obsolescent (Ent) then
                     Output_Obsolescent_Entity_Warnings (Nam, Ent);
                  end if;
               end if;

               Next (Item);
            end loop;
         end;

         --  Remove temporary install of current unit as scope

         Pop_Scope;
      end if;

      --  If No_Elaboration_Code_All was encountered, this is where we do the
      --  transitive test of with'ed units to make sure they have the aspect.
      --  This is delayed till the end of analyzing the compilation unit to
      --  ensure that the pragma/aspect, if present, has been analyzed.

      Check_No_Elab_Code_All (N);
   end Analyze_Compilation_Unit;

   ---------------------
   -- Analyze_Context --
   ---------------------

   procedure Analyze_Context (N : Node_Id) is
      Ukind : constant Node_Kind := Nkind (Unit (N));
      Item  : Node_Id;

   begin
      --  First process all configuration pragmas at the start of the context
      --  items. Strictly these are not part of the context clause, but that
      --  is where the parser puts them. In any case for sure we must analyze
      --  these before analyzing the actual context items, since they can have
      --  an effect on that analysis (e.g. pragma Ada_2005 may allow a unit to
      --  be with'ed as a result of changing categorizations in Ada 2005).

      Item := First (Context_Items (N));
      while Present (Item)
        and then Nkind (Item) = N_Pragma
        and then Pragma_Name (Item) in Configuration_Pragma_Names
      loop
         Analyze (Item);
         Next (Item);
      end loop;

      --  This is the point at which we capture the configuration settings
      --  for the unit. At the moment only the Optimize_Alignment setting
      --  needs to be captured. Probably more later ???

      if Optimize_Alignment_Local then
         Set_OA_Setting (Current_Sem_Unit, 'L');
      else
         Set_OA_Setting (Current_Sem_Unit, Optimize_Alignment);
      end if;

      --  Loop through actual context items. This is done in two passes:

      --  a) The first pass analyzes nonlimited with clauses and also any
      --     configuration pragmas (we need to get the latter analyzed right
      --     away, since they can affect processing of subsequent items).

      --  b) The second pass analyzes limited_with clauses (Ada 2005: AI-50217)

      while Present (Item) loop

         --  For with clause, analyze the with clause, and then update the
         --  version, since we are dependent on a unit that we with.

         if Nkind (Item) = N_With_Clause
           and then not Limited_Present (Item)
         then
            --  Skip analyzing with clause if no unit, nothing to do (this
            --  happens for a with that references a non-existent unit).

            if Present (Library_Unit (Item)) then

               --  Skip analyzing with clause if this is a with_clause for
               --  the main unit, which happens if a subunit has a useless
               --  with_clause on its parent.

               if Library_Unit (Item) /= Cunit (Current_Sem_Unit) then
                  Analyze (Item);

               --  Here for the case of a useless with for the main unit

               else
                  Set_Entity (Name (Item), Cunit_Entity (Current_Sem_Unit));
               end if;
            end if;

            --  Do version update (skipped for implicit with)

            if not Implicit_With (Item) then
               Version_Update (N, Library_Unit (Item));
            end if;

         --  Skip pragmas. Configuration pragmas at the start were handled in
         --  the loop above, and remaining pragmas are not processed until we
         --  actually install the context (see Install_Context). We delay the
         --  analysis of these pragmas to make sure that we have installed all
         --  the implicit with's on parent units.

         --  Skip use clauses at this stage, since we don't want to do any
         --  installing of potentially use-visible entities until we
         --  actually install the complete context (in Install_Context).
         --  Otherwise things can get installed in the wrong context.

         else
            null;
         end if;

         Next (Item);
      end loop;

      --  Second pass: examine all limited_with clauses. All other context
      --  items are ignored in this pass.

      Item := First (Context_Items (N));
      while Present (Item) loop
         if Nkind (Item) = N_With_Clause
           and then Limited_Present (Item)
         then
            --  No need to check errors on implicitly generated limited-with
            --  clauses.

            if not Implicit_With (Item) then

               --  Verify that the illegal contexts given in 10.1.2 (18/2) are
               --  properly rejected, including renaming declarations.

               if Ukind not in N_Package_Declaration
                             | N_Subprogram_Declaration
                             | N_Generic_Declaration
                             | N_Generic_Instantiation
               then
                  Error_Msg_N ("limited with_clause not allowed here", Item);

               --  Check wrong use of a limited with clause applied to the
               --  compilation unit containing the limited-with clause.

               --      limited with P.Q;
               --      package P.Q is ...

               elsif Unit (Library_Unit (Item)) = Unit (N) then
                  Error_Msg_N ("wrong use of limited-with clause", Item);

               --  Check wrong use of limited-with clause applied to some
               --  immediate ancestor.

               elsif Is_Child_Spec (Unit (N)) then
                  declare
                     Lib_U : constant Entity_Id := Unit (Library_Unit (Item));
                     P     : Node_Id;

                  begin
                     P := Parent_Spec (Unit (N));
                     loop
                        if Unit (P) = Lib_U then
                           Error_Msg_N
                             ("limited with_clause cannot name ancestor",
                              Item);
                           exit;
                        end if;

                        exit when not Is_Child_Spec (Unit (P));
                        P := Parent_Spec (Unit (P));
                     end loop;
                  end;
               end if;

               --  Check if the limited-withed unit is already visible through
               --  some context clause of the current compilation unit or some
               --  ancestor of the current compilation unit.

               declare
                  Lim_Unit_Name : constant Node_Id := Name (Item);
                  Comp_Unit     : Node_Id;
                  It            : Node_Id;
                  Unit_Name     : Node_Id;

               begin
                  Comp_Unit := N;
                  loop
                     It := First (Context_Items (Comp_Unit));
                     while Present (It) loop
                        if Item /= It
                          and then Nkind (It) = N_With_Clause
                          and then not Limited_Present (It)
                          and then Nkind (Unit (Library_Unit (It))) in
                                     N_Package_Declaration |
                                     N_Package_Renaming_Declaration
                        then
                           if Nkind (Unit (Library_Unit (It))) =
                                                      N_Package_Declaration
                           then
                              Unit_Name := Name (It);
                           else
                              Unit_Name := Name (Unit (Library_Unit (It)));
                           end if;

                           --  Check if the named package (or some ancestor)
                           --  leaves visible the full-view of the unit given
                           --  in the limited-with clause.

                           loop
                              if Designate_Same_Unit (Lim_Unit_Name,
                                                      Unit_Name)
                              then
                                 Error_Msg_Sloc := Sloc (It);
                                 Error_Msg_N
                                   ("simultaneous visibility of limited and "
                                    & "unlimited views not allowed", Item);
                                 Error_Msg_N
                                   ("\unlimited view visible through context "
                                    & "clause #", Item);
                                 exit;

                              elsif Nkind (Unit_Name) = N_Identifier then
                                 exit;
                              end if;

                              Unit_Name := Prefix (Unit_Name);
                           end loop;
                        end if;

                        Next (It);
                     end loop;

                     exit when not Is_Child_Spec (Unit (Comp_Unit));

                     Comp_Unit := Parent_Spec (Unit (Comp_Unit));
                  end loop;
               end;
            end if;

            --  Skip analyzing with clause if no unit, see above

            if Present (Library_Unit (Item)) then
               Analyze (Item);
            end if;

            --  A limited_with does not impose an elaboration order, but there
            --  is a semantic dependency for recompilation purposes.

            if not Implicit_With (Item) then
               Version_Update (N, Library_Unit (Item));
            end if;

         --  Pragmas and use clauses and with clauses other than limited with's
         --  are ignored in this pass through the context items.

         else
            null;
         end if;

         Next (Item);
      end loop;
   end Analyze_Context;

   -------------------------------
   -- Analyze_Package_Body_Stub --
   -------------------------------

   procedure Analyze_Package_Body_Stub (N : Node_Id) is
      Id   : constant Entity_Id := Defining_Entity (N);
      Nam  : Entity_Id;
      Opts : Config_Switches_Type;

   begin
      --  The package declaration must be in the current declarative part

      Check_Stub_Level (N);
      Nam := Current_Entity_In_Scope (Id);

      if No (Nam) or else not Is_Package_Or_Generic_Package (Nam) then
         Error_Msg_N ("missing specification for package stub", N);

      elsif Has_Completion (Nam)
        and then Present (Corresponding_Body (Unit_Declaration_Node (Nam)))
      then
         Error_Msg_N ("duplicate or redundant stub for package", N);

      else
         --  Retain and restore the configuration options of the enclosing
         --  context as the proper body may introduce a set of its own.

         Opts := Save_Config_Switches;

         --  Indicate that the body of the package exists. If we are doing
         --  only semantic analysis, the stub stands for the body. If we are
         --  generating code, the existence of the body will be confirmed
         --  when we load the proper body.

         Set_Scope (Id, Current_Scope);
         Mutate_Ekind (Id, E_Package_Body);
         Set_Etype (Id, Standard_Void_Type);

         if Has_Aspects (N) then
            Analyze_Aspect_Specifications (N, Id);
         end if;

         Set_Has_Completion (Nam);
         Set_Corresponding_Spec_Of_Stub (N, Nam);
         Generate_Reference (Nam, Id, 'b');
         Analyze_Proper_Body (N, Nam);

         Restore_Config_Switches (Opts);
      end if;
   end Analyze_Package_Body_Stub;

   -------------------------
   -- Analyze_Proper_Body --
   -------------------------

   procedure Analyze_Proper_Body (N : Node_Id; Nam : Entity_Id) is
      Subunit_Name : constant Unit_Name_Type := Get_Unit_Name (N);

      procedure Optional_Subunit;
      --  This procedure is called when the main unit is a stub, or when we
      --  are not generating code. In such a case, we analyze the subunit if
      --  present, which is user-friendly, but we don't complain if the subunit
      --  is missing. In GNATprove_Mode, we issue an error to avoid formal
      --  verification of a partial unit.

      ----------------------
      -- Optional_Subunit --
      ----------------------

      procedure Optional_Subunit is
         Comp_Unit : Node_Id;
         Unum      : Unit_Number_Type;

      begin
         --  Try to load subunit, but ignore any errors that occur during the
         --  loading of the subunit, by using the special feature in Errout to
         --  ignore all errors. Note that Fatal_Error will still be set, so we
         --  will be able to check for this case below.

         if not GNATprove_Mode then
            Ignore_Errors_Enable := Ignore_Errors_Enable + 1;
         end if;

         Unum :=
           Load_Unit
             (Load_Name  => Subunit_Name,
              Required   => GNATprove_Mode,
              Subunit    => True,
              Error_Node => N);

         if not GNATprove_Mode then
            Ignore_Errors_Enable := Ignore_Errors_Enable - 1;
         end if;

         --  All done if we successfully loaded the subunit

         if Unum /= No_Unit
           and then (Fatal_Error (Unum) /= Error_Detected
                      or else Try_Semantics)
         then
            Comp_Unit := Cunit (Unum);

            --  If the file was empty or seriously mangled, the unit itself may
            --  be missing.

            if No (Unit (Comp_Unit)) then
               Error_Msg_N
                 ("subunit does not contain expected proper body", N);

            elsif Nkind (Unit (Comp_Unit)) /= N_Subunit then
               Error_Msg_N
                 ("expected SEPARATE subunit, found child unit",
                  Cunit_Entity (Unum));
            else
               Set_Corresponding_Stub (Unit (Comp_Unit), N);
               Analyze_Subunit (Comp_Unit);
               Set_Library_Unit (N, Comp_Unit);
               Set_Corresponding_Body (N, Defining_Entity (Unit (Comp_Unit)));
            end if;

         elsif Unum = No_Unit
           and then Present (Nam)
         then
            if Is_Protected_Type (Nam) then
               Set_Corresponding_Body (Parent (Nam), Defining_Identifier (N));
            else
               Set_Corresponding_Body (
                 Unit_Declaration_Node (Nam), Defining_Identifier (N));
            end if;
         end if;
      end Optional_Subunit;

      --  Local variables

      Comp_Unit : Node_Id;
      Unum      : Unit_Number_Type;

   --  Start of processing for Analyze_Proper_Body

   begin
      --  If the subunit is already loaded, it means that the main unit is a
      --  subunit, and that the current unit is one of its parents which was
      --  being analyzed to provide the needed context for the analysis of the
      --  subunit. In this case we analyze the subunit and continue with the
      --  parent, without looking at subsequent subunits.

      if Is_Loaded (Subunit_Name) then

         --  If the proper body is already linked to the stub node, the stub is
         --  in a generic unit and just needs analyzing.

         if Present (Library_Unit (N)) then
            Set_Corresponding_Stub (Unit (Library_Unit (N)), N);

            --  If the subunit has severe errors, the spec of the enclosing
            --  body may not be available, in which case do not try analysis.

            if Serious_Errors_Detected > 0
              and then No (Library_Unit (Library_Unit (N)))
            then
               return;
            end if;

            --  Collect SCO information for loaded subunit if we are in the
            --  extended main unit.

            if Generate_SCO
              and then In_Extended_Main_Source_Unit
                         (Cunit_Entity (Current_Sem_Unit))
            then
               SCO_Record_Raw (Get_Cunit_Unit_Number (Library_Unit (N)));
            end if;

            Analyze_Subunit (Library_Unit (N));

         --  Otherwise we must load the subunit and link to it

         else
            --  Load the subunit, this must work, since we originally loaded
            --  the subunit earlier on. So this will not really load it, just
            --  give access to it.

            Unum :=
              Load_Unit
                (Load_Name  => Subunit_Name,
                 Required   => True,
                 Subunit    => False,
                 Error_Node => N);

            --  And analyze the subunit in the parent context (note that we
            --  do not call Semantics, since that would remove the parent
            --  context). Because of this, we have to manually reset the
            --  compiler state to Analyzing since it got destroyed by Load.

            if Unum /= No_Unit then
               Compiler_State := Analyzing;

               --  Check that the proper body is a subunit and not a child
               --  unit. If the unit was previously loaded, the error will
               --  have been emitted when copying the generic node, so we
               --  just return to avoid cascaded errors.

               if Nkind (Unit (Cunit (Unum))) /= N_Subunit then
                  return;
               end if;

               Set_Corresponding_Stub (Unit (Cunit (Unum)), N);
               Analyze_Subunit (Cunit (Unum));
               Set_Library_Unit (N, Cunit (Unum));
            end if;
         end if;

      --  If the main unit is a subunit, then we are just performing semantic
      --  analysis on that subunit, and any other subunits of any parent unit
      --  should be ignored. If the main unit is itself a subunit, another
      --  subunit is irrelevant unless it is a subunit of the current one, that
      --  is to say appears in the current source tree.

      elsif Nkind (Unit (Cunit (Main_Unit))) = N_Subunit
        and then Subunit_Name /= Unit_Name (Main_Unit)
      then
         --  But before we return, set the flag for unloaded subunits. This
         --  will suppress junk warnings of variables in the same declarative
         --  part (or a higher level one) that are in danger of looking unused
         --  when in fact there might be a declaration in the subunit that we
         --  do not intend to load.

         Unloaded_Subunits := True;
         return;

      --  If the subunit is not already loaded, and we are generating code,
      --  then this is the case where compilation started from the parent, and
      --  we are generating code for an entire subunit tree. In that case we
      --  definitely need to load the subunit.

      --  In order to continue the analysis with the rest of the parent,
      --  and other subunits, we load the unit without requiring its
      --  presence, and emit a warning if not found, rather than terminating
      --  the compilation abruptly, as for other missing file problems.

      elsif Original_Operating_Mode = Generate_Code then

         --  If the proper body is already linked to the stub node, the stub is
         --  in a generic unit and just needs analyzing.

         --  We update the version. Although we are not strictly technically
         --  semantically dependent on the subunit, given our approach of macro
         --  substitution of subunits, it makes sense to include it in the
         --  version identification.

         if Present (Library_Unit (N)) then
            Set_Corresponding_Stub (Unit (Library_Unit (N)), N);
            Analyze_Subunit (Library_Unit (N));
            Version_Update (Cunit (Main_Unit), Library_Unit (N));

         --  Otherwise we must load the subunit and link to it

         else
            --  Make sure that, if the subunit is preprocessed and -gnateG is
            --  specified, the preprocessed file will be written.

            Lib.Analysing_Subunit_Of_Main := True;
            Unum :=
              Load_Unit
                (Load_Name  => Subunit_Name,
                 Required   => False,
                 Subunit    => True,
                 Error_Node => N);
            Lib.Analysing_Subunit_Of_Main := False;

            --  Give message if we did not get the unit Emit warning even if
            --  missing subunit is not within main unit, to simplify debugging.

            pragma Assert (Original_Operating_Mode = Generate_Code);
            if Unum = No_Unit then
               Error_Msg_Unit_1 := Subunit_Name;
               Error_Msg_File_1 :=
                 Get_File_Name (Subunit_Name, Subunit => True);
               Error_Msg_N
                 ("subunit$$ in file{ not found??!!", N);
               Subunits_Missing := True;
            end if;

            --  Load_Unit may reset Compiler_State, since it may have been
            --  necessary to parse an additional units, so we make sure that
            --  we reset it to the Analyzing state.

            Compiler_State := Analyzing;

            if Unum /= No_Unit then
               if Debug_Flag_L then
                  Write_Str ("*** Loaded subunit from stub. Analyze");
                  Write_Eol;
               end if;

               Comp_Unit := Cunit (Unum);

               --  Check for child unit instead of subunit

               if Nkind (Unit (Comp_Unit)) /= N_Subunit then
                  Error_Msg_N
                    ("expected SEPARATE subunit, found child unit",
                     Cunit_Entity (Unum));

               --  OK, we have a subunit

               else
                  Set_Corresponding_Stub (Unit (Comp_Unit), N);
                  Set_Library_Unit (N, Comp_Unit);

                  --  We update the version. Although we are not technically
                  --  semantically dependent on the subunit, given our approach
                  --  of macro substitution of subunits, it makes sense to
                  --  include it in the version identification.

                  Version_Update (Cunit (Main_Unit), Comp_Unit);

                  --  Collect SCO information for loaded subunit if we are in
                  --  the extended main unit.

                  if Generate_SCO
                    and then In_Extended_Main_Source_Unit
                               (Cunit_Entity (Current_Sem_Unit))
                  then
                     SCO_Record_Raw (Unum);
                  end if;

                  --  Analyze the unit if semantics active

                  if Fatal_Error (Unum) /= Error_Detected
                    or else Try_Semantics
                  then
                     Analyze_Subunit (Comp_Unit);
                  end if;
               end if;
            end if;
         end if;

      --  The remaining case is when the subunit is not already loaded and we
      --  are not generating code. In this case we are just performing semantic
      --  analysis on the parent, and we are not interested in the subunit. For
      --  subprograms, analyze the stub as a body. For other entities the stub
      --  has already been marked as completed.

      else
         Optional_Subunit;
      end if;
   end Analyze_Proper_Body;

   ----------------------------------
   -- Analyze_Protected_Body_Stub --
   ----------------------------------

   procedure Analyze_Protected_Body_Stub (N : Node_Id) is
      Id   : constant Entity_Id := Defining_Entity (N);
      Nam  : Entity_Id          := Current_Entity_In_Scope (Id);
      Opts : Config_Switches_Type;

   begin
      Check_Stub_Level (N);

      --  First occurrence of name may have been as an incomplete type

      if Present (Nam) and then Ekind (Nam) = E_Incomplete_Type then
         Nam := Full_View (Nam);
      end if;

      if No (Nam) or else not Is_Protected_Type (Etype (Nam)) then
         Error_Msg_N ("missing specification for Protected body", N);

      else
         --  Retain and restore the configuration options of the enclosing
         --  context as the proper body may introduce a set of its own.

         Opts := Save_Config_Switches;

         Set_Scope (Id, Current_Scope);
         Mutate_Ekind (Id, E_Protected_Body);
         Set_Etype (Id, Standard_Void_Type);

         if Has_Aspects (N) then
            Analyze_Aspect_Specifications (N, Id);
         end if;

         Set_Has_Completion (Etype (Nam));
         Set_Corresponding_Spec_Of_Stub (N, Nam);
         Generate_Reference (Nam, Id, 'b');
         Analyze_Proper_Body (N, Etype (Nam));

         Restore_Config_Switches (Opts);
      end if;
   end Analyze_Protected_Body_Stub;

   ----------------------------------
   -- Analyze_Subprogram_Body_Stub --
   ----------------------------------

   --  A subprogram body stub can appear with or without a previous spec. If
   --  there is one, then the analysis of the body will find it and verify
   --  conformance. The formals appearing in the specification of the stub play
   --  no role, except for requiring an additional conformance check. If there
   --  is no previous subprogram declaration, the stub acts as a spec, and
   --  provides the defining entity for the subprogram.

   procedure Analyze_Subprogram_Body_Stub (N : Node_Id) is
      Decl : Node_Id;
      Opts : Config_Switches_Type;

   begin
      Check_Stub_Level (N);

      --  Verify that the identifier for the stub is unique within this
      --  declarative part.

      if Nkind (Parent (N)) in
           N_Block_Statement | N_Package_Body | N_Subprogram_Body
      then
         Decl := First (Declarations (Parent (N)));
         while Present (Decl) and then Decl /= N loop
            if Nkind (Decl) = N_Subprogram_Body_Stub
              and then (Chars (Defining_Unit_Name (Specification (Decl))) =
                        Chars (Defining_Unit_Name (Specification (N))))
            then
               Error_Msg_N ("identifier for stub is not unique", N);
            end if;

            Next (Decl);
         end loop;
      end if;

      --  Retain and restore the configuration options of the enclosing context
      --  as the proper body may introduce a set of its own.

      Opts := Save_Config_Switches;

      --  Treat stub as a body, which checks conformance if there is a previous
      --  declaration, or else introduces entity and its signature.

      Analyze_Subprogram_Body (N);
      Analyze_Proper_Body (N, Empty);

      Restore_Config_Switches (Opts);
   end Analyze_Subprogram_Body_Stub;

   ---------------------
   -- Analyze_Subunit --
   ---------------------

   --  A subunit is compiled either by itself (for semantic checking) or as
   --  part of compiling the parent (for code generation). In either case, by
   --  the time we actually process the subunit, the parent has already been
   --  installed and analyzed. The node N is a compilation unit, whose context
   --  needs to be treated here, because we come directly here from the parent
   --  without calling Analyze_Compilation_Unit.

   --  The compilation context includes the explicit context of the subunit,
   --  and the context of the parent, together with the parent itself. In order
   --  to compile the current context, we remove the one inherited from the
   --  parent, in order to have a clean visibility table. We restore the parent
   --  context before analyzing the proper body itself. On exit, we remove only
   --  the explicit context of the subunit.

   --  WARNING: This routine manages SPARK regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  SPARK mode.

   procedure Analyze_Subunit (N : Node_Id) is
      Lib_Unit : constant Node_Id   := Library_Unit (N);
      Par_Unit : constant Entity_Id := Current_Scope;

      Lib_Spec        : Node_Id := Library_Unit (Lib_Unit);
      Num_Scopes      : Nat := 0;
      Use_Clauses     : array (1 .. Scope_Stack.Last) of Node_Id;
      Enclosing_Child : Entity_Id := Empty;
      Svg             : constant Suppress_Record := Scope_Suppress;

      Save_Cunit_Restrictions : constant Save_Cunit_Boolean_Restrictions :=
                                  Cunit_Boolean_Restrictions_Save;
      --  Save non-partition wide restrictions before processing the subunit.
      --  All subunits are analyzed with config restrictions reset and we need
      --  to restore these saved values at the end.

      procedure Analyze_Subunit_Context;
      --  Capture names in use clauses of the subunit. This must be done before
      --  re-installing parent declarations, because items in the context must
      --  not be hidden by declarations local to the parent.

      procedure Re_Install_Parents (L : Node_Id; Scop : Entity_Id);
      --  Recursive procedure to restore scope of all ancestors of subunit,
      --  from outermost in. If parent is not a subunit, the call to install
      --  context installs context of spec and (if parent is a child unit) the
      --  context of its parents as well. It is confusing that parents should
      --  be treated differently in both cases, but the semantics are just not
      --  identical.

      procedure Re_Install_Use_Clauses;
      --  As part of the removal of the parent scope, the use clauses are
      --  removed, to be reinstalled when the context of the subunit has been
      --  analyzed. Use clauses may also have been affected by the analysis of
      --  the context of the subunit, so they have to be applied again, to
      --  insure that the compilation environment of the rest of the parent
      --  unit is identical.

      procedure Remove_Scope;
      --  Remove current scope from scope stack, and preserve the list of use
      --  clauses in it, to be reinstalled after context is analyzed.

      -----------------------------
      -- Analyze_Subunit_Context --
      -----------------------------

      procedure Analyze_Subunit_Context is
         Item      :  Node_Id;
         Unit_Name : Entity_Id;

      begin
         Analyze_Context (N);
         Check_No_Elab_Code_All (N);

         --  Make withed units immediately visible. If child unit, make the
         --  ultimate parent immediately visible.

         Item := First (Context_Items (N));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause then

               --  Protect frontend against previous errors in context clauses

               if Nkind (Name (Item)) /= N_Selected_Component then
                  if Error_Posted (Item) then
                     null;

                  else
                     --  If a subunits has serious syntax errors, the context
                     --  may not have been loaded. Add a harmless unit name to
                     --  attempt processing.

                     if Serious_Errors_Detected > 0
                       and then No (Entity (Name (Item)))
                     then
                        Set_Entity (Name (Item), Standard_Standard);
                     end if;

                     Unit_Name := Entity (Name (Item));
                     loop
                        Set_Is_Visible_Lib_Unit (Unit_Name);
                        exit when Scope (Unit_Name) = Standard_Standard;
                        Unit_Name := Scope (Unit_Name);

                        if No (Unit_Name) then
                           Check_Error_Detected;
                           return;
                        end if;
                     end loop;

                     if not Is_Immediately_Visible (Unit_Name) then
                        Set_Is_Immediately_Visible (Unit_Name);
                        Set_Context_Installed (Item);
                     end if;
                  end if;
               end if;

            elsif Nkind (Item) = N_Use_Package_Clause then
               Analyze (Name (Item));

            elsif Nkind (Item) = N_Use_Type_Clause then
               Analyze (Subtype_Mark (Item));
            end if;

            Next (Item);
         end loop;

         --  Reset visibility of withed units. They will be made visible again
         --  when we install the subunit context.

         Item := First (Context_Items (N));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause

               --  Protect frontend against previous errors in context clauses

              and then Nkind (Name (Item)) /= N_Selected_Component
              and then not Error_Posted (Item)
            then
               Unit_Name := Entity (Name (Item));
               loop
                  Set_Is_Visible_Lib_Unit (Unit_Name, False);
                  exit when Scope (Unit_Name) = Standard_Standard;
                  Unit_Name := Scope (Unit_Name);
               end loop;

               if Context_Installed (Item) then
                  Set_Is_Immediately_Visible (Unit_Name, False);
                  Set_Context_Installed (Item, False);
               end if;
            end if;

            Next (Item);
         end loop;
      end Analyze_Subunit_Context;

      ------------------------
      -- Re_Install_Parents --
      ------------------------

      procedure Re_Install_Parents (L : Node_Id; Scop : Entity_Id) is
         E : Entity_Id;

      begin
         if Nkind (Unit (L)) = N_Subunit then
            Re_Install_Parents (Library_Unit (L), Scope (Scop));
         end if;

         Install_Context (L, False);

         --  If the subunit occurs within a child unit, we must restore the
         --  immediate visibility of any siblings that may occur in context.
         --  In addition, we must reset the previous visibility of the
         --  parent unit which is now on the scope stack. This is because
         --  the Previous_Visibility was previously set when removing the
         --  context. This is necessary to prevent the parent entity from
         --  remaining visible after the subunit is compiled. This only
         --  has an effect if a homonym exists in a body to be processed
         --  later if inlining is enabled.

         if Present (Enclosing_Child) then
            Install_Siblings (Enclosing_Child, L);
            Scope_Stack.Table (Scope_Stack.Last).Previous_Visibility :=
              False;
         end if;

         Push_Scope (Scop);

         if Scop /= Par_Unit then
            Set_Is_Immediately_Visible (Scop);
         end if;

         --  Make entities in scope visible again. For child units, restore
         --  visibility only if they are actually in context.

         E := First_Entity (Current_Scope);
         while Present (E) loop
            if not Is_Child_Unit (E) or else Is_Visible_Lib_Unit (E) then
               Set_Is_Immediately_Visible (E);
            end if;

            Next_Entity (E);
         end loop;

         --  A subunit appears within a body, and for a nested subunits all the
         --  parents are bodies. Restore full visibility of their private
         --  entities.

         if Is_Package_Or_Generic_Package (Scop) then
            Set_In_Package_Body (Scop);
            Install_Private_Declarations (Scop);
         end if;
      end Re_Install_Parents;

      ----------------------------
      -- Re_Install_Use_Clauses --
      ----------------------------

      procedure Re_Install_Use_Clauses is
         U  : Node_Id;
      begin
         for J in reverse 1 .. Num_Scopes loop
            U := Use_Clauses (J);
            Scope_Stack.Table (Scope_Stack.Last - J + 1).First_Use_Clause := U;
            Install_Use_Clauses (U);
         end loop;
      end Re_Install_Use_Clauses;

      ------------------
      -- Remove_Scope --
      ------------------

      procedure Remove_Scope is
         E : Entity_Id;

      begin
         Num_Scopes := Num_Scopes + 1;
         Use_Clauses (Num_Scopes) :=
           Scope_Stack.Table (Scope_Stack.Last).First_Use_Clause;

         E := First_Entity (Current_Scope);
         while Present (E) loop
            Set_Is_Immediately_Visible (E, False);
            Next_Entity (E);
         end loop;

         if Is_Child_Unit (Current_Scope) then
            Enclosing_Child := Current_Scope;
         end if;

         Pop_Scope;
      end Remove_Scope;

      Saved_SM  : SPARK_Mode_Type := SPARK_Mode;
      Saved_SMP : Node_Id         := SPARK_Mode_Pragma;
      --  Save the SPARK mode-related data to restore on exit. Removing
      --  enclosing scopes and contexts to provide a clean environment for the
      --  context of the subunit will eliminate any previously set SPARK_Mode.

   --  Start of processing for Analyze_Subunit

   begin
      --  For subunit in main extended unit, we reset the configuration values
      --  for the non-partition-wide restrictions. For other units reset them.

      if In_Extended_Main_Source_Unit (N) then
         Restore_Config_Cunit_Boolean_Restrictions;
      else
         Reset_Cunit_Boolean_Restrictions;
      end if;

      if Style_Check then
         declare
            Nam : Node_Id := Name (Unit (N));

         begin
            if Nkind (Nam) = N_Selected_Component then
               Nam := Selector_Name (Nam);
            end if;

            Check_Identifier (Nam, Par_Unit);
         end;
      end if;

      if not Is_Empty_List (Context_Items (N)) then

         --  Save current use clauses

         Remove_Scope;
         Remove_Context (Lib_Unit);

         --  Now remove parents and their context, including enclosing subunits
         --  and the outer parent body which is not a subunit.

         if Present (Lib_Spec) then
            Remove_Context (Lib_Spec);

            while Nkind (Unit (Lib_Spec)) = N_Subunit loop
               Lib_Spec := Library_Unit (Lib_Spec);
               Remove_Scope;
               Remove_Context (Lib_Spec);
            end loop;

            if Nkind (Unit (Lib_Unit)) = N_Subunit then
               Remove_Scope;
            end if;

            if Nkind (Unit (Lib_Spec)) in N_Package_Body | N_Subprogram_Body
            then
               Remove_Context (Library_Unit (Lib_Spec));
            end if;
         end if;

         Set_Is_Immediately_Visible (Par_Unit, False);

         Analyze_Subunit_Context;

         --  Take into account the effect of any SPARK_Mode configuration
         --  pragma, which takes precedence over a different value of
         --  SPARK_Mode inherited from the context of the stub.

         if SPARK_Mode /= None then
            Saved_SM  := SPARK_Mode;
            Saved_SMP := SPARK_Mode_Pragma;
         end if;

         Re_Install_Parents (Lib_Unit, Par_Unit);
         Set_Is_Immediately_Visible (Par_Unit);

         --  If the context includes a child unit of the parent of the subunit,
         --  the parent will have been removed from visibility, after compiling
         --  that cousin in the context. The visibility of the parent must be
         --  restored now. This also applies if the context includes another
         --  subunit of the same parent which in turn includes a child unit in
         --  its context.

         if Is_Package_Or_Generic_Package (Par_Unit) then
            if not Is_Immediately_Visible (Par_Unit)
              or else (Present (First_Entity (Par_Unit))
                        and then not
                          Is_Immediately_Visible (First_Entity (Par_Unit)))
            then
               Set_Is_Immediately_Visible   (Par_Unit);
               Install_Visible_Declarations (Par_Unit);
               Install_Private_Declarations (Par_Unit);
            end if;
         end if;

         Re_Install_Use_Clauses;
         Install_Context (N, Chain => False);

         --  Restore state of suppress flags for current body

         Scope_Suppress := Svg;

         --  If the subunit is within a child unit, then siblings of any parent
         --  unit that appear in the context clause of the subunit must also be
         --  made immediately visible.

         if Present (Enclosing_Child) then
            Install_Siblings (Enclosing_Child, N);
         end if;
      end if;

      Generate_Parent_References (Unit (N), Par_Unit);

      --  Reinstall the SPARK_Mode which was in effect prior to any scope and
      --  context manipulations, taking into account a possible SPARK_Mode
      --  configuration pragma if present.

      Install_SPARK_Mode (Saved_SM, Saved_SMP);

      --  If the subunit is part of a compilation unit which is subject to
      --  pragma Elaboration_Checks, set the model specified by the pragma
      --  because it applies to all parts of the unit.

      Install_Elaboration_Model (Par_Unit);

      --  The syntax rules require a proper body for a subprogram subunit

      if Nkind (Proper_Body (Sinfo.Nodes.Unit (N))) = N_Subprogram_Declaration
      then
         if Null_Present (Specification (Proper_Body (Sinfo.Nodes.Unit (N))))
         then
            Error_Msg_N
              ("null procedure not allowed as subunit",
               Proper_Body (Unit (N)));
         else
            Error_Msg_N
              ("subprogram declaration not allowed as subunit",
               Defining_Unit_Name (Specification (Proper_Body (Unit (N)))));
         end if;
      end if;

      Analyze (Proper_Body (Unit (N)));
      Remove_Context (N);

      --  The subunit may contain a with_clause on a sibling of some ancestor.
      --  Removing the context will remove from visibility those ancestor child
      --  units, which must be restored to the visibility they have in the
      --  enclosing body.

      if Present (Enclosing_Child) then
         declare
            C : Entity_Id;
         begin
            C := Current_Scope;
            while Present (C) and then C /= Standard_Standard loop
               Set_Is_Immediately_Visible (C);
               Set_Is_Visible_Lib_Unit (C);
               C := Scope (C);
            end loop;
         end;
      end if;

      --  Deal with restore of restrictions

      Cunit_Boolean_Restrictions_Restore (Save_Cunit_Restrictions);
   end Analyze_Subunit;

   ----------------------------
   -- Analyze_Task_Body_Stub --
   ----------------------------

   procedure Analyze_Task_Body_Stub (N : Node_Id) is
      Id  : constant Entity_Id  := Defining_Entity (N);
      Loc : constant Source_Ptr := Sloc (N);
      Nam : Entity_Id           := Current_Entity_In_Scope (Id);

   begin
      Check_Stub_Level (N);

      --  First occurrence of name may have been as an incomplete type

      if Present (Nam) and then Ekind (Nam) = E_Incomplete_Type then
         Nam := Full_View (Nam);
      end if;

      if No (Nam) or else not Is_Task_Type (Etype (Nam)) then
         Error_Msg_N ("missing specification for task body", N);

      else
         Set_Scope (Id, Current_Scope);
         Mutate_Ekind (Id, E_Task_Body);
         Set_Etype (Id, Standard_Void_Type);

         if Has_Aspects (N) then
            Analyze_Aspect_Specifications (N, Id);
         end if;

         Generate_Reference (Nam, Id, 'b');
         Set_Corresponding_Spec_Of_Stub (N, Nam);

         --  Check for duplicate stub, if so give message and terminate

         if Has_Completion (Etype (Nam)) then
            Error_Msg_N ("duplicate stub for task", N);
            return;
         else
            Set_Has_Completion (Etype (Nam));
         end if;

         Analyze_Proper_Body (N, Etype (Nam));

         --  Set elaboration flag to indicate that entity is callable. This
         --  cannot be done in the expansion of the body itself, because the
         --  proper body is not in a declarative part. This is only done if
         --  expansion is active, because the context may be generic and the
         --  flag not defined yet.

         if Expander_Active then
            Insert_After (N,
              Make_Assignment_Statement (Loc,
                Name        =>
                  Make_Identifier (Loc,
                    Chars => New_External_Name (Chars (Etype (Nam)), 'E')),
                 Expression => New_Occurrence_Of (Standard_True, Loc)));
         end if;
      end if;
   end Analyze_Task_Body_Stub;

   -------------------------
   -- Analyze_With_Clause --
   -------------------------

   --  Analyze the declaration of a unit in a with clause. At end, label the
   --  with clause with the defining entity for the unit.

   procedure Analyze_With_Clause (N : Node_Id) is

      --  Retrieve the original kind of the unit node, before analysis. If it
      --  is a subprogram instantiation, its analysis below will rewrite the
      --  node as the declaration of the wrapper package. If the same
      --  instantiation appears indirectly elsewhere in the context, it will
      --  have been analyzed already.

      Unit_Kind : constant Node_Kind :=
                    Nkind (Original_Node (Unit (Library_Unit (N))));
      Nam       : constant Node_Id := Name (N);
      E_Name    : Entity_Id;
      Par_Name  : Entity_Id;
      Pref      : Node_Id;
      U         : Node_Id;

      Intunit : Boolean;
      --  Set True if the unit currently being compiled is an internal unit

      Restriction_Violation : Boolean := False;
      --  Set True if a with violates a restriction, no point in giving any
      --  warnings if we have this definite error.

      Save_Style_Check : constant Boolean := Opt.Style_Check;

   begin
      U := Unit (Library_Unit (N));

      --  If this is an internal unit which is a renaming, then this is a
      --  violation of No_Obsolescent_Features.

      --  Note: this is not quite right if the user defines one of these units
      --  himself, but that's a marginal case, and fixing it is hard ???

      if Restriction_Check_Required (No_Obsolescent_Features) then
         if In_Predefined_Renaming (U) then
            Check_Restriction (No_Obsolescent_Features, N);
            Restriction_Violation := True;
         end if;
      end if;

      --  Check No_Implementation_Units violation

      if Restriction_Check_Required (No_Implementation_Units) then
         if Not_Impl_Defined_Unit (Get_Source_Unit (U)) then
            null;
         else
            Check_Restriction (No_Implementation_Units, Nam);
            Restriction_Violation := True;
         end if;
      end if;

      --  Several actions are skipped for dummy packages (those supplied for
      --  with's where no matching file could be found). Such packages are
      --  identified by the Sloc value being set to No_Location.

      if Limited_Present (N) then

         --  Ada 2005 (AI-50217): Build visibility structures but do not
         --  analyze the unit.

         --  If the designated unit is a predefined unit, which might be used
         --  implicitly through the rtsfind machinery, a limited with clause
         --  on such a unit is usually pointless, because run-time units are
         --  unlikely to appear in mutually dependent units, and because this
         --  disables the rtsfind mechanism. We transform such limited with
         --  clauses into regular with clauses.

         if Sloc (U) /= No_Location then
            if In_Predefined_Unit (U) then
               Set_Limited_Present (N, False);
               Analyze_With_Clause (N);
            else
               Build_Limited_Views (N);
            end if;
         end if;

         return;
      end if;

      --  If we are compiling under "don't quit" mode (-gnatq) and we have
      --  already detected serious errors then we mark the with-clause nodes as
      --  analyzed before the corresponding compilation unit is analyzed. This
      --  is done here to protect the frontend against never ending recursion
      --  caused by circularities in the sources (because the previous errors
      --  may break the regular machine of the compiler implemented in
      --  Load_Unit to detect circularities).

      if Serious_Errors_Detected > 0 and then Try_Semantics then
         Set_Analyzed (N);
      end if;

      Semantics (Library_Unit (N));

      Intunit := Is_Internal_Unit (Current_Sem_Unit);

      if Sloc (U) /= No_Location then

         --  Check restrictions, except that we skip the check if this is an
         --  internal unit unless we are compiling the internal unit as the
         --  main unit. We also skip this for dummy packages.

         Check_Restriction_No_Dependence (Nam, N);

         if not Intunit or else Current_Sem_Unit = Main_Unit then
            Check_Restricted_Unit (Unit_Name (Get_Source_Unit (U)), N);
         end if;

         --  Deal with special case of GNAT.Current_Exceptions which interacts
         --  with the optimization of local raise statements into gotos.

         if Nkind (Nam) = N_Selected_Component
           and then Nkind (Prefix (Nam)) = N_Identifier
           and then Chars (Prefix (Nam)) = Name_Gnat
           and then Chars (Selector_Name (Nam))
                      in Name_Most_Recent_Exception | Name_Exception_Traces
         then
            Check_Restriction (No_Exception_Propagation, N);
            Special_Exception_Package_Used := True;
         end if;

         --  Check for inappropriate with of internal implementation unit if we
         --  are not compiling an internal unit and also check for withing unit
         --  in wrong version of Ada. Do not issue these messages for implicit
         --  with's generated by the compiler itself.

         if Implementation_Unit_Warnings
           and then not Intunit
           and then not Implicit_With (N)
           and then not Restriction_Violation
         then
            case Get_Kind_Of_Unit (Get_Source_Unit (U)) is
               when Implementation_Unit =>
                  Error_Msg_F ("& is an internal 'G'N'A'T unit?i?", Name (N));

                  --  Add alternative name if available, otherwise issue a
                  --  general warning message.

                  if Error_Msg_Strlen /= 0 then
                     Error_Msg_F ("\use ""~"" instead?i?", Name (N));
                  else
                     Error_Msg_F
                       ("\use of this unit is non-portable and "
                        & "version-dependent?i?", Name (N));
                  end if;

               when Not_Predefined_Unit | Ada_95_Unit =>
                  null; -- no checks needed

               when Ada_2005_Unit =>
                  if Ada_Version < Ada_2005
                    and then Warn_On_Ada_2005_Compatibility
                  then
                     Error_Msg_N ("& is an Ada 2005 unit?i?", Name (N));
                  end if;

               when Ada_2012_Unit =>
                  if Ada_Version < Ada_2012
                    and then Warn_On_Ada_2012_Compatibility
                  then
                     Error_Msg_N ("& is an Ada 2012 unit?i?", Name (N));
                  end if;

               when Ada_2022_Unit =>
                  if Ada_Version < Ada_2022
                    and then Warn_On_Ada_2022_Compatibility
                  then
                     Error_Msg_N ("& is an Ada 2022 unit?i?", Name (N));
                  end if;
            end case;
         end if;
      end if;

      --  Semantic analysis of a generic unit is performed on a copy of
      --  the original tree. Retrieve the entity on  which semantic info
      --  actually appears.

      if Unit_Kind in N_Generic_Declaration then
         E_Name := Defining_Entity (U);

      --  Note: in the following test, Unit_Kind is the original Nkind, but in
      --  the case of an instantiation, semantic analysis above will have
      --  replaced the unit by its instantiated version. If the instance body
      --  has been generated, the instance now denotes the body entity. For
      --  visibility purposes we need the entity of its spec.

      elsif (Unit_Kind = N_Package_Instantiation
              or else Nkind (Original_Node (Unit (Library_Unit (N)))) =
                                                  N_Package_Instantiation)
        and then Nkind (U) = N_Package_Body
      then
         E_Name := Corresponding_Spec (U);

      elsif Unit_Kind = N_Package_Instantiation
        and then Nkind (U) = N_Package_Instantiation
        and then Present (Instance_Spec (U))
      then
         --  If the instance has not been rewritten as a package declaration,
         --  then it appeared already in a previous with clause. Retrieve
         --  the entity from the previous instance.

         E_Name := Defining_Entity (Specification (Instance_Spec (U)));

      elsif Unit_Kind in N_Subprogram_Instantiation then

         --  The visible subprogram is created during instantiation, and is
         --  an attribute of the wrapper package. We retrieve the wrapper
         --  package directly from the instantiation node. If the instance
         --  is inlined the unit is still an instantiation. Otherwise it has
         --  been rewritten as the declaration of the wrapper itself.

         if Nkind (U) in N_Subprogram_Instantiation then
            E_Name :=
              Related_Instance
                (Defining_Entity (Specification (Instance_Spec (U))));
         else
            E_Name := Related_Instance (Defining_Entity (U));
         end if;

      elsif Unit_Kind = N_Package_Renaming_Declaration
        or else Unit_Kind in N_Generic_Renaming_Declaration
      then
         E_Name := Defining_Entity (U);

      elsif Unit_Kind = N_Subprogram_Body
        and then Nkind (Name (N)) = N_Selected_Component
        and then not Acts_As_Spec (Library_Unit (N))
      then
         --  For a child unit that has no spec, one has been created and
         --  analyzed. The entity required is that of the spec.

         E_Name := Corresponding_Spec (U);

      else
         E_Name := Defining_Entity (U);
      end if;

      if Nkind (Name (N)) = N_Selected_Component then

         --  Child unit in a with clause

         Change_Selected_Component_To_Expanded_Name (Name (N));

         --  If this is a child unit without a spec, and it has been analyzed
         --  already, a declaration has been created for it. The with_clause
         --  must reflect the actual body, and not the generated declaration,
         --  to prevent spurious binding errors involving an out-of-date spec.
         --  Note that this can only happen if the unit includes more than one
         --  with_clause for the child unit (e.g. in separate subunits).

         if Unit_Kind = N_Subprogram_Declaration
           and then Analyzed (Library_Unit (N))
           and then not Comes_From_Source (Library_Unit (N))
         then
            Set_Library_Unit (N,
               Cunit (Get_Source_Unit (Corresponding_Body (U))));
         end if;
      end if;

      --  Restore style checks

      Style_Check := Save_Style_Check;

      --  Record the reference, but do NOT set the unit as referenced, we want
      --  to consider the unit as unreferenced if this is the only reference
      --  that occurs.

      Set_Entity_With_Checks (Name (N), E_Name);
      Generate_Reference (E_Name, Name (N), 'w', Set_Ref => False);

      --  Generate references and check No_Dependence restriction for parents

      if Is_Child_Unit (E_Name) then
         Pref     := Prefix (Name (N));
         Par_Name := Scope (E_Name);
         while Nkind (Pref) = N_Selected_Component loop
            Change_Selected_Component_To_Expanded_Name (Pref);

            if Present (Entity (Selector_Name (Pref)))
              and then
                Present (Renamed_Entity (Entity (Selector_Name (Pref))))
              and then Entity (Selector_Name (Pref)) /= Par_Name
            then
            --  The prefix is a child unit that denotes a renaming declaration.
            --  Replace the prefix directly with the renamed unit, because the
            --  rest of the prefix is irrelevant to the visibility of the real
            --  unit.

               Rewrite (Pref, New_Occurrence_Of (Par_Name, Sloc (Pref)));
               exit;
            end if;

            Set_Entity_With_Checks (Pref, Par_Name);

            Generate_Reference (Par_Name, Pref);
            Check_Restriction_No_Dependence (Pref, N);
            Pref := Prefix (Pref);

            --  If E_Name is the dummy entity for a nonexistent unit, its scope
            --  is set to Standard_Standard, and no attempt should be made to
            --  further unwind scopes.

            if Par_Name /= Standard_Standard then
               Par_Name := Scope (Par_Name);
            end if;

            --  Abandon processing in case of previous errors

            if No (Par_Name) then
               Check_Error_Detected;
               return;
            end if;
         end loop;

         if Present (Entity (Pref))
           and then not Analyzed (Parent (Parent (Entity (Pref))))
         then
            --  If the entity is set without its unit being compiled, the
            --  original parent is a renaming, and Par_Name is the renamed
            --  entity. For visibility purposes, we need the original entity,
            --  which must be analyzed now because Load_Unit directly retrieves
            --  the renamed unit, and the renaming declaration itself has not
            --  been analyzed.

            Analyze (Parent (Parent (Entity (Pref))));
            pragma Assert (Renamed_Object (Entity (Pref)) = Par_Name);
            Par_Name := Entity (Pref);
         end if;

         --  Guard against missing or misspelled child units

         if Present (Par_Name) then
            Set_Entity_With_Checks (Pref, Par_Name);
            Generate_Reference (Par_Name, Pref);

         else
            pragma Assert (Serious_Errors_Detected /= 0);

            --  Mark the node to indicate that a related error has been posted.
            --  This defends further compilation passes against improper use of
            --  the invalid WITH clause node.

            Set_Error_Posted (N);
            Set_Name (N, Error);
            return;
         end if;
      end if;

      --  If the withed unit is System, and a system extension pragma is
      --  present, compile the extension now, rather than waiting for a
      --  visibility check on a specific entity.

      if Chars (E_Name) = Name_System
        and then Scope (E_Name) = Standard_Standard
        and then Present (System_Extend_Unit)
        and then Present_System_Aux (N)
      then
         --  If the extension is not present, an error will have been emitted

         null;
      end if;

      --  Ada 2005 (AI-262): Remove from visibility the entity corresponding
      --  to private_with units; they will be made visible later (just before
      --  the private part is analyzed)

      if Private_Present (N) then
         Set_Is_Immediately_Visible (E_Name, False);
      end if;

      --  Propagate Fatal_Error setting from with'ed unit to current unit

      case Fatal_Error (Get_Source_Unit (Library_Unit (N))) is

         --  Nothing to do if with'ed unit had no error

         when None =>
            null;

         --  If with'ed unit had a detected fatal error, propagate it

         when Error_Detected =>
            Set_Fatal_Error (Current_Sem_Unit, Error_Detected);

         --  If with'ed unit had an ignored error, then propagate it but do not
         --  overide an existring setting.

         when Error_Ignored =>
            if Fatal_Error (Current_Sem_Unit) = None then
               Set_Fatal_Error (Current_Sem_Unit, Error_Ignored);
            end if;
      end case;
   end Analyze_With_Clause;

   ------------------------------
   -- Check_Private_Child_Unit --
   ------------------------------

   procedure Check_Private_Child_Unit (N : Node_Id) is
      Lib_Unit   : constant Node_Id := Unit (N);
      Item       : Node_Id;
      Curr_Unit  : Entity_Id;
      Sub_Parent : Node_Id;
      Priv_Child : Entity_Id;
      Par_Lib    : Entity_Id;
      Par_Spec   : Node_Id;

      function Is_Private_Library_Unit (Unit : Entity_Id) return Boolean;
      --  Returns true if and only if the library unit is declared with
      --  an explicit designation of private.

      -----------------------------
      -- Is_Private_Library_Unit --
      -----------------------------

      function Is_Private_Library_Unit (Unit : Entity_Id) return Boolean is
         Comp_Unit : constant Node_Id := Parent (Unit_Declaration_Node (Unit));

      begin
         return Private_Present (Comp_Unit);
      end Is_Private_Library_Unit;

   --  Start of processing for Check_Private_Child_Unit

   begin
      if Nkind (Lib_Unit) in N_Package_Body | N_Subprogram_Body then
         Curr_Unit := Defining_Entity (Unit (Library_Unit (N)));
         Par_Lib   := Curr_Unit;

      elsif Nkind (Lib_Unit) = N_Subunit then

         --  The parent is itself a body. The parent entity is to be found in
         --  the corresponding spec.

         Sub_Parent := Library_Unit (N);
         Curr_Unit  := Defining_Entity (Unit (Library_Unit (Sub_Parent)));

         --  If the parent itself is a subunit, Curr_Unit is the entity of the
         --  enclosing body, retrieve the spec entity which is the proper
         --  ancestor we need for the following tests.

         if Ekind (Curr_Unit) = E_Package_Body then
            Curr_Unit := Spec_Entity (Curr_Unit);
         end if;

         Par_Lib    := Curr_Unit;

      else
         Curr_Unit := Defining_Entity (Lib_Unit);

         Par_Lib := Curr_Unit;
         Par_Spec  := Parent_Spec (Lib_Unit);

         if No (Par_Spec) then
            Par_Lib := Empty;
         else
            Par_Lib := Defining_Entity (Unit (Par_Spec));
         end if;
      end if;

      --  Loop through context items

      Item := First (Context_Items (N));
      while Present (Item) loop

         --  Ada 2005 (AI-262): Allow private_with of a private child package
         --  in public siblings

         if Nkind (Item) = N_With_Clause
            and then not Implicit_With (Item)
            and then not Limited_Present (Item)
            and then Is_Private_Descendant (Entity (Name (Item)))
         then
            Priv_Child := Entity (Name (Item));

            declare
               Curr_Parent  : Entity_Id := Par_Lib;
               Child_Parent : Entity_Id := Scope (Priv_Child);
               Prv_Ancestor : Entity_Id := Child_Parent;
               Curr_Private : Boolean   := Is_Private_Library_Unit (Curr_Unit);

            begin
               --  If the child unit is a public child then locate the nearest
               --  private ancestor. Child_Parent will then be set to the
               --  parent of that ancestor.

               if not Is_Private_Library_Unit (Priv_Child) then
                  while Present (Prv_Ancestor)
                    and then not Is_Private_Library_Unit (Prv_Ancestor)
                  loop
                     Prv_Ancestor := Scope (Prv_Ancestor);
                  end loop;

                  if Present (Prv_Ancestor) then
                     Child_Parent := Scope (Prv_Ancestor);
                  end if;
               end if;

               while Present (Curr_Parent)
                 and then Curr_Parent /= Standard_Standard
                 and then Curr_Parent /= Child_Parent
               loop
                  Curr_Private :=
                    Curr_Private or else Is_Private_Library_Unit (Curr_Parent);
                  Curr_Parent := Scope (Curr_Parent);
               end loop;

               if No (Curr_Parent) then
                  Curr_Parent := Standard_Standard;
               end if;

               if Curr_Parent /= Child_Parent then
                  if Ekind (Priv_Child) = E_Generic_Package
                    and then Chars (Priv_Child) in Text_IO_Package_Name
                    and then Chars (Scope (Scope (Priv_Child))) = Name_Ada
                    and then Scope (Scope (Scope (Priv_Child))) =
                               Standard_Standard
                  then
                     Error_Msg_NE
                       ("& is a nested package, not a compilation unit",
                        Name (Item), Priv_Child);

                  else
                     Error_Msg_N
                       ("unit in with clause is private child unit!", Item);
                     Error_Msg_NE
                       ("\current unit must also have parent&!",
                        Item, Child_Parent);
                  end if;

               elsif Curr_Private
                 or else Private_Present (Item)
                 or else Nkind (Lib_Unit) in N_Package_Body | N_Subunit
                 or else (Nkind (Lib_Unit) = N_Subprogram_Body
                           and then not Acts_As_Spec (Parent (Lib_Unit)))
               then
                  null;

               else
                  Error_Msg_NE
                    ("current unit must also be private descendant of&",
                     Item, Child_Parent);
               end if;
            end;
         end if;

         Next (Item);
      end loop;
   end Check_Private_Child_Unit;

   ----------------------
   -- Check_Stub_Level --
   ----------------------

   procedure Check_Stub_Level (N : Node_Id) is
      Par  : constant Node_Id   := Parent (N);
      Kind : constant Node_Kind := Nkind (Par);

   begin
      if Kind in
           N_Package_Body | N_Subprogram_Body | N_Task_Body | N_Protected_Body
        and then Nkind (Parent (Par)) in N_Compilation_Unit | N_Subunit
      then
         null;

      --  In an instance, a missing stub appears at any level. A warning
      --  message will have been emitted already for the missing file.

      elsif not In_Instance then
         Error_Msg_N ("stub cannot appear in an inner scope", N);

      elsif Expander_Active then
         Error_Msg_N ("missing proper body", N);
      end if;
   end Check_Stub_Level;

   ------------------------
   -- Expand_With_Clause --
   ------------------------

   procedure Expand_With_Clause (Item : Node_Id; Nam : Node_Id; N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (Nam);

      function Build_Unit_Name (Nam : Node_Id) return Node_Id;
      --  Build name to be used in implicit with_clause. In most cases this
      --  is the source name, but if renamings are present we must make the
      --  original unit visible, not the one it renames. The entity in the
      --  with clause is the renamed unit, but the identifier is the one from
      --  the source, which allows us to recover the unit renaming.

      ---------------------
      -- Build_Unit_Name --
      ---------------------

      function Build_Unit_Name (Nam : Node_Id) return Node_Id is
         Ent      : Entity_Id;
         Result   : Node_Id;

      begin
         if Nkind (Nam) = N_Identifier then
            return New_Occurrence_Of (Entity (Nam), Loc);

         else
            Ent := Entity (Nam);

            if Present (Entity (Selector_Name (Nam)))
              and then Chars (Entity (Selector_Name (Nam))) /= Chars (Ent)
              and then
                Nkind (Unit_Declaration_Node (Entity (Selector_Name (Nam)))) =
                  N_Package_Renaming_Declaration
            then
               --  The name in the with_clause is of the form A.B.C, and B is
               --  given by a renaming declaration. In that case we may not
               --  have analyzed the unit for B, but replaced it directly in
               --  lib-load with the unit it renames. We have to make A.B
               --  visible, so analyze the declaration for B now, in case it
               --  has not been done yet.

               Ent := Entity (Selector_Name (Nam));
               Analyze
                 (Parent
                   (Unit_Declaration_Node (Entity (Selector_Name (Nam)))));
            end if;

            Result :=
              Make_Expanded_Name (Loc,
                Chars         => Chars (Entity (Nam)),
                Prefix        => Build_Unit_Name (Prefix (Nam)),
                Selector_Name => New_Occurrence_Of (Ent, Loc));
            Set_Entity (Result, Ent);

            return Result;
         end if;
      end Build_Unit_Name;

      --  Local variables

      Ent   : constant Entity_Id  := Entity (Nam);
      Withn : Node_Id;

   --  Start of processing for Expand_With_Clause

   begin
      Withn :=
        Make_With_Clause (Loc,
          Name => Build_Unit_Name (Nam));

      Set_Corresponding_Spec (Withn, Ent);
      Set_First_Name         (Withn);
      Set_Implicit_With      (Withn);
      Set_Library_Unit       (Withn, Parent (Unit_Declaration_Node (Ent)));
      Set_Parent_With        (Withn);

      --  If the unit is a [generic] package or subprogram declaration
      --  (including a subprogram body acting as spec), a private_with_clause
      --  on a child unit implies that the implicit with on the parent is also
      --  private.

      if Nkind (Unit (N)) in N_Generic_Package_Declaration
                           | N_Package_Declaration
                           | N_Generic_Subprogram_Declaration
                           | N_Subprogram_Declaration
                           | N_Subprogram_Body
      then
         Set_Private_Present (Withn, Private_Present (Item));
      end if;

      Prepend (Withn, Context_Items (N));
      Mark_Rewrite_Insertion (Withn);

      Install_With_Clause (Withn);

      --  If we have "with X.Y;", we want to recurse on "X", except in the
      --  unusual case where X.Y is a renaming of X. In that case, the scope
      --  of X will be null.

      if Nkind (Nam) = N_Expanded_Name
        and then Present (Scope (Entity (Prefix (Nam))))
      then
         Expand_With_Clause (Item, Prefix (Nam), N);
      end if;
   end Expand_With_Clause;

   --------------------------------
   -- Generate_Parent_References --
   --------------------------------

   procedure Generate_Parent_References (N : Node_Id; P_Id : Entity_Id) is
      Pref   : Node_Id;
      P_Name : Entity_Id := P_Id;

   begin
      if Nkind (N) = N_Subunit then
         Pref := Name (N);
      else
         Pref := Name (Parent (Defining_Entity (N)));
      end if;

      if Nkind (Pref) = N_Expanded_Name then

         --  Done already, if the unit has been compiled indirectly as
         --  part of the closure of its context because of inlining.

         return;
      end if;

      while Nkind (Pref) = N_Selected_Component loop
         Change_Selected_Component_To_Expanded_Name (Pref);
         Set_Entity (Pref, P_Name);
         Set_Etype (Pref, Etype (P_Name));
         Generate_Reference (P_Name, Pref, 'r');
         Pref   := Prefix (Pref);
         P_Name := Scope (P_Name);
      end loop;

      --  The guard here on P_Name is to handle the error condition where
      --  the parent unit is missing because the file was not found.

      if Present (P_Name) then
         Set_Entity (Pref, P_Name);
         Set_Etype (Pref, Etype (P_Name));
         Generate_Reference (P_Name, Pref, 'r');
         Style.Check_Identifier (Pref, P_Name);
      end if;
   end Generate_Parent_References;

   ---------------------
   -- Has_With_Clause --
   ---------------------

   function Has_With_Clause
     (C_Unit     : Node_Id;
      Pack       : Entity_Id;
      Is_Limited : Boolean := False) return Boolean
   is
      Item : Node_Id;

      function Named_Unit (Clause : Node_Id) return Entity_Id;
      --  Return the entity for the unit named in a [limited] with clause

      ----------------
      -- Named_Unit --
      ----------------

      function Named_Unit (Clause : Node_Id) return Entity_Id is
      begin
         if Nkind (Name (Clause)) = N_Selected_Component then
            return Entity (Selector_Name (Name (Clause)));
         else
            return Entity (Name (Clause));
         end if;
      end Named_Unit;

   --  Start of processing for Has_With_Clause

   begin
      if Present (Context_Items (C_Unit)) then
         Item := First (Context_Items (C_Unit));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause
              and then Limited_Present (Item) = Is_Limited
              and then Named_Unit (Item) = Pack
            then
               return True;
            end if;

            Next (Item);
         end loop;
      end if;

      return False;
   end Has_With_Clause;

   -----------------------------
   -- Implicit_With_On_Parent --
   -----------------------------

   procedure Implicit_With_On_Parent
     (Child_Unit : Node_Id;
      N          : Node_Id)
   is
      Loc    : constant Source_Ptr := Sloc (N);
      P      : constant Node_Id    := Parent_Spec (Child_Unit);
      P_Unit : Node_Id             := Unit (P);
      P_Name : constant Entity_Id  := Get_Parent_Entity (P_Unit);
      Withn  : Node_Id;

      function Build_Ancestor_Name (P : Node_Id) return Node_Id;
      --  Build prefix of child unit name. Recurse if needed

      function Build_Unit_Name return Node_Id;
      --  If the unit is a child unit, build qualified name with all ancestors

      -------------------------
      -- Build_Ancestor_Name --
      -------------------------

      function Build_Ancestor_Name (P : Node_Id) return Node_Id is
         P_Ref  : constant Node_Id :=
                   New_Occurrence_Of (Defining_Entity (P), Loc);
         P_Spec : Node_Id := P;

      begin
         --  Ancestor may have been rewritten as a package body. Retrieve the
         --  original spec to trace earlier ancestors.

         if Nkind (P) = N_Package_Body
           and then Nkind (Original_Node (P)) = N_Package_Instantiation
         then
            P_Spec := Original_Node (P);
         end if;

         if No (Parent_Spec (P_Spec)) then
            return P_Ref;
         else
            return
              Make_Selected_Component (Loc,
                Prefix        =>
                  Build_Ancestor_Name (Unit (Parent_Spec (P_Spec))),
                Selector_Name => P_Ref);
         end if;
      end Build_Ancestor_Name;

      ---------------------
      -- Build_Unit_Name --
      ---------------------

      function Build_Unit_Name return Node_Id is
         Result : Node_Id;

      begin
         if No (Parent_Spec (P_Unit)) then
            return New_Occurrence_Of (P_Name, Loc);

         else
            Result :=
              Make_Expanded_Name (Loc,
                Chars         => Chars (P_Name),
                Prefix        =>
                  Build_Ancestor_Name (Unit (Parent_Spec (P_Unit))),
                Selector_Name => New_Occurrence_Of (P_Name, Loc));
            Set_Entity (Result, P_Name);

            return Result;
         end if;
      end Build_Unit_Name;

   --  Start of processing for Implicit_With_On_Parent

   begin
      --  The unit of the current compilation may be a package body that
      --  replaces an instance node. In this case we need the original instance
      --  node to construct the proper parent name.

      if Nkind (P_Unit) = N_Package_Body
        and then Nkind (Original_Node (P_Unit)) = N_Package_Instantiation
      then
         P_Unit := Original_Node (P_Unit);
      end if;

      --  We add the implicit with if the child unit is the current unit being
      --  compiled. If the current unit is a body, we do not want to add an
      --  implicit_with a second time to the corresponding spec.

      if Nkind (Child_Unit) = N_Package_Declaration
        and then Child_Unit /= Unit (Cunit (Current_Sem_Unit))
      then
         return;
      end if;

      Withn := Make_With_Clause (Loc, Name => Build_Unit_Name);

      Set_Corresponding_Spec (Withn, P_Name);
      Set_First_Name         (Withn);
      Set_Implicit_With      (Withn);
      Set_Library_Unit       (Withn, P);
      Set_Parent_With        (Withn);

      --  Node is placed at the beginning of the context items, so that
      --  subsequent use clauses on the parent can be validated.

      Prepend (Withn, Context_Items (N));
      Mark_Rewrite_Insertion (Withn);

      Install_With_Clause (Withn);

      if Is_Child_Spec (P_Unit) then
         Implicit_With_On_Parent (P_Unit, N);
      end if;
   end Implicit_With_On_Parent;

   --------------
   -- In_Chain --
   --------------

   function In_Chain (E : Entity_Id) return Boolean is
      H : Entity_Id;

   begin
      H := Current_Entity (E);
      while Present (H) loop
         if H = E then
            return True;
         else
            H := Homonym (H);
         end if;
      end loop;

      return False;
   end In_Chain;

   ---------------------
   -- Install_Context --
   ---------------------

   procedure Install_Context (N : Node_Id; Chain : Boolean := True) is
      Lib_Unit : constant Node_Id := Unit (N);

   begin
      Install_Context_Clauses (N, Chain);

      if Is_Child_Spec (Lib_Unit) then
         Install_Parents
           (Lib_Unit   => Lib_Unit,
            Is_Private => Private_Present (Parent (Lib_Unit)),
            Chain      => Chain);
      end if;

      Install_Limited_Context_Clauses (N);
   end Install_Context;

   -----------------------------
   -- Install_Context_Clauses --
   -----------------------------

   procedure Install_Context_Clauses (N : Node_Id; Chain : Boolean := True) is
      Lib_Unit      : constant Node_Id := Unit (N);
      Item          : Node_Id;
      Uname_Node    : Entity_Id;
      Check_Private : Boolean := False;
      Decl_Node     : Node_Id;
      Lib_Parent    : Entity_Id;

   begin
      --  First skip configuration pragmas at the start of the context. They
      --  are not technically part of the context clause, but that's where the
      --  parser puts them. Note they were analyzed in Analyze_Context.

      Item := First (Context_Items (N));
      while Present (Item)
        and then Nkind (Item) = N_Pragma
        and then Pragma_Name (Item) in Configuration_Pragma_Names
      loop
         Next (Item);
      end loop;

      --  Loop through the actual context clause items. We process everything
      --  except Limited_With clauses in this routine. Limited_With clauses
      --  are separately installed (see Install_Limited_Context_Clauses).

      while Present (Item) loop

         --  Case of explicit WITH clause

         if Nkind (Item) = N_With_Clause
           and then not Implicit_With (Item)
         then
            if Limited_Present (Item) then

               --  Limited withed units will be installed later

               goto Continue;

            --  If Name (Item) is not an entity name, something is wrong, and
            --  this will be detected in due course, for now ignore the item

            elsif not Is_Entity_Name (Name (Item)) then
               goto Continue;

            elsif No (Entity (Name (Item))) then
               Set_Entity (Name (Item), Any_Id);
               goto Continue;
            end if;

            Uname_Node := Entity (Name (Item));

            if Is_Private_Descendant (Uname_Node) then
               Check_Private := True;
            end if;

            Install_With_Clause (Item);

            Decl_Node := Unit_Declaration_Node (Uname_Node);

            --  If the unit is a subprogram instance, it appears nested within
            --  a package that carries the parent information.

            if Is_Generic_Instance (Uname_Node)
              and then Ekind (Uname_Node) /= E_Package
            then
               Decl_Node := Parent (Parent (Decl_Node));
            end if;

            if Is_Child_Spec (Decl_Node) then
               if Nkind (Name (Item)) = N_Expanded_Name then
                  Expand_With_Clause (Item, Prefix (Name (Item)), N);
               else
                  --  If not an expanded name, the child unit must be a
                  --  renaming, nothing to do.

                  null;
               end if;

            elsif Nkind (Decl_Node) = N_Subprogram_Body
              and then not Acts_As_Spec (Parent (Decl_Node))
              and then Is_Child_Spec (Unit (Library_Unit (Parent (Decl_Node))))
            then
               Implicit_With_On_Parent
                 (Unit (Library_Unit (Parent (Decl_Node))), N);
            end if;

            --  Check license conditions unless this is a dummy unit

            if Sloc (Library_Unit (Item)) /= No_Location then
               License_Check : declare
                  Withu : constant Unit_Number_Type :=
                            Get_Source_Unit (Library_Unit (Item));
                  Withl : constant License_Type :=
                            License (Source_Index (Withu));
                  Unitl : constant License_Type :=
                           License (Source_Index (Current_Sem_Unit));

                  procedure License_Error;
                  --  Signal error of bad license

                  -------------------
                  -- License_Error --
                  -------------------

                  procedure License_Error is
                  begin
                     Error_Msg_N
                       ("license of withed unit & may be inconsistent??",
                        Name (Item));
                  end License_Error;

               --  Start of processing for License_Check

               begin
                  --  Exclude license check if withed unit is an internal unit.
                  --  This situation arises e.g. with the GPL version of GNAT.

                  if Is_Internal_Unit (Withu) then
                     null;

                     --  Otherwise check various cases
                  else
                     case Unitl is
                        when Unknown =>
                           null;

                        when Restricted =>
                           if Withl = GPL then
                              License_Error;
                           end if;

                        when GPL =>
                           if Withl = Restricted then
                              License_Error;
                           end if;

                        when Modified_GPL =>
                           if Withl = Restricted or else Withl = GPL then
                              License_Error;
                           end if;

                        when Unrestricted =>
                           null;
                     end case;
                  end if;
               end License_Check;
            end if;

         --  Case of USE PACKAGE clause

         elsif Nkind (Item) = N_Use_Package_Clause then
            Analyze_Use_Package (Item, Chain);

         --  Case of USE TYPE clause

         elsif Nkind (Item) = N_Use_Type_Clause then
            Analyze_Use_Type (Item, Chain);

         --  case of PRAGMA

         elsif Nkind (Item) = N_Pragma then
            Analyze (Item);
         end if;

      <<Continue>>
         Next (Item);
      end loop;

      if Is_Child_Spec (Lib_Unit) then

         --  The unit also has implicit with_clauses on its own parents

         if No (Context_Items (N)) then
            Set_Context_Items (N, New_List);
         end if;

         Implicit_With_On_Parent (Lib_Unit, N);
      end if;

      --  If the unit is a body, the context of the specification must also
      --  be installed. That includes private with_clauses in that context.

      if Nkind (Lib_Unit) = N_Package_Body
        or else (Nkind (Lib_Unit) = N_Subprogram_Body
                  and then not Acts_As_Spec (N))
      then
         Install_Context (Library_Unit (N), Chain);

         --  Only install private with-clauses of a spec that comes from
         --  source, excluding specs created for a subprogram body that is
         --  a child unit.

         if Comes_From_Source (Library_Unit (N)) then
            Install_Private_With_Clauses
              (Defining_Entity (Unit (Library_Unit (N))));
         end if;

         if Is_Child_Spec (Unit (Library_Unit (N))) then

            --  If the unit is the body of a public child unit, the private
            --  declarations of the parent must be made visible. If the child
            --  unit is private, the private declarations have been installed
            --  already in the call to Install_Parents for the spec. Installing
            --  private declarations must be done for all ancestors of public
            --  child units. In addition, sibling units mentioned in the
            --  context clause of the body are directly visible.

            declare
               Lib_Spec : Node_Id;
               P        : Node_Id;
               P_Name   : Entity_Id;

            begin
               Lib_Spec := Unit (Library_Unit (N));
               while Is_Child_Spec (Lib_Spec) loop
                  P      := Unit (Parent_Spec (Lib_Spec));
                  P_Name := Defining_Entity (P);

                  if not (Private_Present (Parent (Lib_Spec)))
                    and then not In_Private_Part (P_Name)
                  then
                     Install_Private_Declarations (P_Name);
                     Install_Private_With_Clauses (P_Name);
                     Set_Use (Private_Declarations (Specification (P)));
                  end if;

                  Lib_Spec := P;
               end loop;
            end;
         end if;

         --  For a package body, children in context are immediately visible

         Install_Siblings (Defining_Entity (Unit (Library_Unit (N))), N);
      end if;

      if Nkind (Lib_Unit) in N_Generic_Package_Declaration
                           | N_Generic_Subprogram_Declaration
                           | N_Package_Declaration
                           | N_Subprogram_Declaration
      then
         if Is_Child_Spec (Lib_Unit) then
            Lib_Parent := Defining_Entity (Unit (Parent_Spec (Lib_Unit)));
            Set_Is_Private_Descendant
              (Defining_Entity (Lib_Unit),
               Is_Private_Descendant (Lib_Parent)
                 or else Private_Present (Parent (Lib_Unit)));

         else
            Set_Is_Private_Descendant
              (Defining_Entity (Lib_Unit),
               Private_Present (Parent (Lib_Unit)));
         end if;
      end if;

      if Check_Private then
         Check_Private_Child_Unit (N);
      end if;
   end Install_Context_Clauses;

   -------------------------------------
   -- Install_Limited_Context_Clauses --
   -------------------------------------

   procedure Install_Limited_Context_Clauses (N : Node_Id) is
      Item : Node_Id;

      procedure Check_Renamings (P : Node_Id; W : Node_Id);
      --  Check that the unlimited view of a given compilation_unit is not
      --  already visible through "use + renamings".

      procedure Check_Private_Limited_Withed_Unit (Item : Node_Id);
      --  Check that if a limited_with clause of a given compilation_unit
      --  mentions a descendant of a private child of some library unit, then
      --  the given compilation_unit must be the declaration of a private
      --  descendant of that library unit, or a public descendant of such. The
      --  code is analogous to that of Check_Private_Child_Unit but we cannot
      --  use entities on the limited with_clauses because their units have not
      --  been analyzed, so we have to climb the tree of ancestors looking for
      --  private keywords.

      procedure Expand_Limited_With_Clause
        (Comp_Unit : Node_Id;
         Nam       : Node_Id;
         N         : Node_Id);
      --  If a child unit appears in a limited_with clause, there are implicit
      --  limited_with clauses on all parents that are not already visible
      --  through a regular with clause. This procedure creates the implicit
      --  limited with_clauses for the parents and loads the corresponding
      --  units. The shadow entities are created when the inserted clause is
      --  analyzed. Implements Ada 2005 (AI-50217).

      ---------------------
      -- Check_Renamings --
      ---------------------

      procedure Check_Renamings (P : Node_Id; W : Node_Id) is
         Item   : Node_Id;
         Spec   : Node_Id;
         WEnt   : Entity_Id;
         E      : Entity_Id;
         E2     : Entity_Id;

      begin
         pragma Assert (Nkind (W) = N_With_Clause);

         --  Protect the frontend against previous critical errors

         case Nkind (Unit (Library_Unit (W))) is
            when N_Generic_Package_Declaration
               | N_Generic_Subprogram_Declaration
               | N_Package_Declaration
               | N_Subprogram_Declaration
            =>
               null;

            when others =>
               return;
         end case;

         --  Check "use + renamings"

         WEnt := Defining_Unit_Name (Specification (Unit (Library_Unit (W))));
         Spec := Specification (Unit (P));

         Item := First (Visible_Declarations (Spec));
         while Present (Item) loop

            --  Look only at use package clauses

            if Nkind (Item) = N_Use_Package_Clause then

               E := Entity (Name (Item));

               pragma Assert (Present (Parent (E)));

               if Nkind (Parent (E)) = N_Package_Renaming_Declaration
                 and then Renamed_Entity (E) = WEnt
               then
                  --  The unlimited view is visible through use clause and
                  --  renamings. There is no need to generate the error
                  --  message here because Is_Visible_Through_Renamings
                  --  takes care of generating the precise error message.

                  return;

               elsif Nkind (Parent (E)) = N_Package_Specification then

                  --  The use clause may refer to a local package.
                  --  Check all the enclosing scopes.

                  E2 := E;
                  while E2 /= Standard_Standard and then E2 /= WEnt loop
                     E2 := Scope (E2);
                  end loop;

                  if E2 = WEnt then
                     Error_Msg_N
                       ("unlimited view visible through use clause", W);
                     return;
                  end if;
               end if;
            end if;

            Next (Item);
         end loop;

         --  Recursive call to check all the ancestors

         if Is_Child_Spec (Unit (P)) then
            Check_Renamings (P => Parent_Spec (Unit (P)), W => W);
         end if;
      end Check_Renamings;

      ---------------------------------------
      -- Check_Private_Limited_Withed_Unit --
      ---------------------------------------

      procedure Check_Private_Limited_Withed_Unit (Item : Node_Id) is
         Curr_Parent  : Node_Id;
         Child_Parent : Node_Id;
         Curr_Private : Boolean;

      begin
         --  Compilation unit of the parent of the withed library unit

         Child_Parent := Library_Unit (Item);

         --  If the child unit is a public child, then locate its nearest
         --  private ancestor, if any, then Child_Parent will then be set to
         --  the parent of that ancestor.

         if not Private_Present (Library_Unit (Item)) then
            while Present (Child_Parent)
              and then not Private_Present (Child_Parent)
            loop
               Child_Parent := Parent_Spec (Unit (Child_Parent));
            end loop;

            if No (Child_Parent) then
               return;
            end if;
         end if;

         Child_Parent := Parent_Spec (Unit (Child_Parent));

         --  Traverse all the ancestors of the current compilation unit to
         --  check if it is a descendant of named library unit.

         Curr_Parent := Parent (Item);
         Curr_Private := Private_Present (Curr_Parent);

         while Present (Parent_Spec (Unit (Curr_Parent)))
           and then Curr_Parent /= Child_Parent
         loop
            Curr_Parent := Parent_Spec (Unit (Curr_Parent));
            Curr_Private := Curr_Private or else Private_Present (Curr_Parent);
         end loop;

         if Curr_Parent /= Child_Parent then
            Error_Msg_N
              ("unit in with clause is private child unit!", Item);
            Error_Msg_NE
              ("\current unit must also have parent&!",
               Item, Defining_Unit_Name (Specification (Unit (Child_Parent))));

         elsif Private_Present (Parent (Item))
            or else Curr_Private
            or else Private_Present (Item)
            or else Nkind (Unit (Parent (Item))) in
                      N_Package_Body | N_Subprogram_Body | N_Subunit
         then
            --  Current unit is private, of descendant of a private unit

            null;

         else
            Error_Msg_NE
              ("current unit must also be private descendant of&",
               Item, Defining_Unit_Name (Specification (Unit (Child_Parent))));
         end if;
      end Check_Private_Limited_Withed_Unit;

      --------------------------------
      -- Expand_Limited_With_Clause --
      --------------------------------

      procedure Expand_Limited_With_Clause
        (Comp_Unit : Node_Id;
         Nam       : Node_Id;
         N         : Node_Id)
      is
         Loc   : constant Source_Ptr := Sloc (Nam);
         Unum  : Unit_Number_Type;
         Withn : Node_Id;

         function Previous_Withed_Unit (W : Node_Id) return Boolean;
         --  Returns true if the context already includes a with_clause for
         --  this unit. If the with_clause is nonlimited, the unit is fully
         --  visible and an implicit limited_with should not be created. If
         --  there is already a limited_with clause for W, a second one is
         --  simply redundant.

         --------------------------
         -- Previous_Withed_Unit --
         --------------------------

         function Previous_Withed_Unit (W : Node_Id) return Boolean is
            Item : Node_Id;

         begin
            --  A limited with_clause cannot appear in the same context_clause
            --  as a nonlimited with_clause which mentions the same library.

            Item := First (Context_Items (Comp_Unit));
            while Present (Item) loop
               if Nkind (Item) = N_With_Clause
                 and then Library_Unit (Item) = Library_Unit (W)
               then
                  return True;
               end if;

               Next (Item);
            end loop;

            return False;
         end Previous_Withed_Unit;

      --  Start of processing for Expand_Limited_With_Clause

      begin
         if Nkind (Nam) = N_Identifier then

            --  Create node for name of withed unit

            Withn :=
              Make_With_Clause (Loc,
                Name => New_Copy (Nam));

         else pragma Assert (Nkind (Nam) = N_Selected_Component);
            Withn :=
              Make_With_Clause (Loc,
                Name => Make_Selected_Component (Loc,
                  Prefix        => New_Copy_Tree (Prefix (Nam)),
                  Selector_Name => New_Copy (Selector_Name (Nam))));
            Set_Parent (Withn, Parent (N));
         end if;

         Set_First_Name      (Withn);
         Set_Implicit_With   (Withn);
         Set_Limited_Present (Withn);

         Unum :=
           Load_Unit
             (Load_Name  => Get_Spec_Name (Get_Unit_Name (Nam)),
              Required   => True,
              Subunit    => False,
              Error_Node => Nam);

         --  Do not generate a limited_with_clause on the current unit. This
         --  path is taken when a unit has a limited_with clause on one of its
         --  child units.

         if Unum = Current_Sem_Unit then
            return;
         end if;

         Set_Library_Unit (Withn, Cunit (Unum));
         Set_Corresponding_Spec
           (Withn, Specification (Unit (Cunit (Unum))));

         if not Previous_Withed_Unit (Withn) then
            Prepend (Withn, Context_Items (Parent (N)));
            Mark_Rewrite_Insertion (Withn);

            --  Add implicit limited_with_clauses for parents of child units
            --  mentioned in limited_with clauses.

            if Nkind (Nam) = N_Selected_Component then
               Expand_Limited_With_Clause (Comp_Unit, Prefix (Nam), N);
            end if;

            Analyze (Withn);

            if not Limited_View_Installed (Withn) then
               Install_Limited_With_Clause (Withn);
            end if;
         end if;
      end Expand_Limited_With_Clause;

   --  Start of processing for Install_Limited_Context_Clauses

   begin
      Item := First (Context_Items (N));
      while Present (Item) loop
         if Nkind (Item) = N_With_Clause
           and then Limited_Present (Item)
           and then not Error_Posted (Item)
         then
            if Nkind (Name (Item)) = N_Selected_Component then
               Expand_Limited_With_Clause
                 (Comp_Unit => N, Nam => Prefix (Name (Item)), N => Item);
            end if;

            Check_Private_Limited_Withed_Unit (Item);

            if not Implicit_With (Item) and then Is_Child_Spec (Unit (N)) then
               Check_Renamings (Parent_Spec (Unit (N)), Item);
            end if;

            --  A unit may have a limited with on itself if it has a limited
            --  with_clause on one of its child units. In that case it is
            --  already being compiled and it makes no sense to install its
            --  limited view.

            --  If the item is a limited_private_with_clause, install it if the
            --  current unit is a body or if it is a private child. Otherwise
            --  the private clause is installed before analyzing the private
            --  part of the current unit.

            if Library_Unit (Item) /= Cunit (Current_Sem_Unit)
              and then not Limited_View_Installed (Item)
              and then
                not Is_Ancestor_Unit
                      (Library_Unit (Item), Cunit (Current_Sem_Unit))
            then
               if not Private_Present (Item)
                 or else Private_Present (N)
                 or else Nkind (Unit (N)) in
                           N_Package_Body | N_Subprogram_Body | N_Subunit
               then
                  Install_Limited_With_Clause (Item);
               end if;
            end if;
         end if;

         Next (Item);
      end loop;

      --  Ada 2005 (AI-412): Examine visible declarations of a package spec,
      --  looking for incomplete subtype declarations of incomplete types
      --  visible through a limited with clause.

      if Ada_Version >= Ada_2005
        and then Analyzed (N)
        and then Nkind (Unit (N)) = N_Package_Declaration
      then
         declare
            Decl         : Node_Id;
            Def_Id       : Entity_Id;
            Non_Lim_View : Entity_Id;

         begin
            Decl := First (Visible_Declarations (Specification (Unit (N))));
            while Present (Decl) loop
               if Nkind (Decl) = N_Subtype_Declaration
                 and then
                   Ekind (Defining_Identifier (Decl)) = E_Incomplete_Subtype
                 and then
                   From_Limited_With (Defining_Identifier (Decl))
               then
                  Def_Id := Defining_Identifier (Decl);
                  Non_Lim_View := Non_Limited_View (Def_Id);

                  if not Is_Incomplete_Type (Non_Lim_View) then

                     --  Convert an incomplete subtype declaration into a
                     --  corresponding nonlimited view subtype declaration.
                     --  This is usually the case when analyzing a body that
                     --  has regular with clauses,  when the spec has limited
                     --  ones.

                     --  If the nonlimited view is still incomplete, it is
                     --  the dummy entry already created, and the declaration
                     --  cannot be reanalyzed. This is the case when installing
                     --  a parent unit that has limited with-clauses.

                     Set_Subtype_Indication (Decl,
                       New_Occurrence_Of (Non_Lim_View, Sloc (Def_Id)));
                     Set_Etype (Def_Id, Non_Lim_View);
                     Mutate_Ekind
                       (Def_Id, Subtype_Kind (Ekind (Non_Lim_View)));
                     Set_Analyzed (Decl, False);

                     --  Reanalyze the declaration, suppressing the call to
                     --  Enter_Name to avoid duplicate names.

                     Analyze_Subtype_Declaration
                      (N    => Decl,
                       Skip => True);
                  end if;
               end if;

               Next (Decl);
            end loop;
         end;
      end if;
   end Install_Limited_Context_Clauses;

   ---------------------
   -- Install_Parents --
   ---------------------

   procedure Install_Parents
     (Lib_Unit   : Node_Id;
      Is_Private : Boolean;
      Chain      : Boolean := True)
   is
      P      : Node_Id;
      E_Name : Entity_Id;
      P_Name : Entity_Id;
      P_Spec : Node_Id;

   begin
      P := Unit (Parent_Spec (Lib_Unit));
      P_Name := Get_Parent_Entity (P);

      if Etype (P_Name) = Any_Type then
         return;
      end if;

      if Ekind (P_Name) = E_Generic_Package
        and then Nkind (Lib_Unit) not in N_Generic_Declaration
                                       | N_Generic_Renaming_Declaration
      then
         Error_Msg_N
           ("child of a generic package must be a generic unit", Lib_Unit);

      elsif not Is_Package_Or_Generic_Package (P_Name) then
         Error_Msg_N
           ("parent unit must be package or generic package", Lib_Unit);
         raise Unrecoverable_Error;

      elsif Present (Renamed_Object (P_Name)) then
         Error_Msg_N ("parent unit cannot be a renaming", Lib_Unit);
         raise Unrecoverable_Error;

      --  Verify that a child of an instance is itself an instance, or the
      --  renaming of one. Given that an instance that is a unit is replaced
      --  with a package declaration, check against the original node. The
      --  parent may be currently being instantiated, in which case it appears
      --  as a declaration, but the generic_parent is already established
      --  indicating that we deal with an instance.

      elsif Nkind (Original_Node (P)) = N_Package_Instantiation then
         if Nkind (Lib_Unit) in N_Renaming_Declaration
           or else Nkind (Original_Node (Lib_Unit)) in N_Generic_Instantiation
           or else
             (Nkind (Lib_Unit) = N_Package_Declaration
               and then Present (Generic_Parent (Specification (Lib_Unit))))
         then
            null;
         else
            Error_Msg_N
              ("child of an instance must be an instance or renaming",
                Lib_Unit);
         end if;
      end if;

      --  This is the recursive call that ensures all parents are loaded

      if Is_Child_Spec (P) then
         Install_Parents
           (Lib_Unit   => P,
            Is_Private =>
              Is_Private or else Private_Present (Parent (Lib_Unit)),
            Chain      => Chain);
      end if;

      --  Now we can install the context for this parent

      Install_Context_Clauses (Parent_Spec (Lib_Unit), Chain);
      Install_Limited_Context_Clauses (Parent_Spec (Lib_Unit));
      Install_Siblings (P_Name, Parent (Lib_Unit));

      --  The child unit is in the declarative region of the parent. The parent
      --  must therefore appear in the scope stack and be visible, as when
      --  compiling the corresponding body. If the child unit is private or it
      --  is a package body, private declarations must be accessible as well.
      --  Use declarations in the parent must also be installed. Finally, other
      --  child units of the same parent that are in the context are
      --  immediately visible.

      --  Find entity for compilation unit, and set its private descendant
      --  status as needed. Indicate that it is a compilation unit, which is
      --  redundant in general, but needed if this is a generated child spec
      --  for a child body without previous spec.

      E_Name := Defining_Entity (Lib_Unit);

      Set_Is_Child_Unit (E_Name);
      Set_Is_Compilation_Unit (E_Name);

      Set_Is_Private_Descendant (E_Name,
         Is_Private_Descendant (P_Name)
           or else Private_Present (Parent (Lib_Unit)));

      P_Spec := Package_Specification (P_Name);
      Push_Scope (P_Name);

      --  Save current visibility of unit

      Scope_Stack.Table (Scope_Stack.Last).Previous_Visibility :=
        Is_Immediately_Visible (P_Name);
      Set_Is_Immediately_Visible (P_Name);
      Install_Visible_Declarations (P_Name);
      Set_Use (Visible_Declarations (P_Spec));

      --  If the parent is a generic unit, its formal part may contain formal
      --  packages and use clauses for them.

      if Ekind (P_Name) = E_Generic_Package then
         Set_Use (Generic_Formal_Declarations (Parent (P_Spec)));
      end if;

      if Is_Private or else Private_Present (Parent (Lib_Unit)) then
         Install_Private_Declarations (P_Name);
         Install_Private_With_Clauses (P_Name);
         Set_Use (Private_Declarations (P_Spec));
      end if;
   end Install_Parents;

   ----------------------------------
   -- Install_Private_With_Clauses --
   ----------------------------------

   procedure Install_Private_With_Clauses (P : Entity_Id) is
      Decl   : constant Node_Id := Unit_Declaration_Node (P);
      Item   : Node_Id;

   begin
      if Debug_Flag_I then
         Write_Str ("install private with clauses of ");
         Write_Name (Chars (P));
         Write_Eol;
      end if;

      if Nkind (Parent (Decl)) = N_Compilation_Unit then
         Item := First (Context_Items (Parent (Decl)));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause
              and then Private_Present (Item)
            then
               --  If the unit is an ancestor of the current one, it is the
               --  case of a private limited with clause on a child unit, and
               --  the compilation of one of its descendants, In that case the
               --  limited view is errelevant.

               if Limited_Present (Item) then
                  if not Limited_View_Installed (Item)
                    and then
                      not Is_Ancestor_Unit (Library_Unit (Item),
                                            Cunit (Current_Sem_Unit))
                  then
                     Install_Limited_With_Clause (Item);
                  end if;
               else
                  Install_With_Clause (Item, Private_With_OK => True);
               end if;
            end if;

            Next (Item);
         end loop;
      end if;
   end Install_Private_With_Clauses;

   ----------------------
   -- Install_Siblings --
   ----------------------

   procedure Install_Siblings (U_Name : Entity_Id; N : Node_Id) is
      Item : Node_Id;
      Id   : Entity_Id;
      Prev : Entity_Id;

   begin
      --  Iterate over explicit with clauses, and check whether the scope of
      --  each entity is an ancestor of the current unit, in which case it is
      --  immediately visible.

      Item := First (Context_Items (N));
      while Present (Item) loop

         --  Do not install private_with_clauses declaration, unless unit
         --  is itself a private child unit, or is a body. Note that for a
         --  subprogram body the private_with_clause does not take effect
         --  until after the specification.

         if Nkind (Item) /= N_With_Clause
           or else Implicit_With (Item)
           or else Limited_Present (Item)
           or else Error_Posted (Item)

            --  Skip processing malformed trees

           or else (Try_Semantics
                     and then Nkind (Name (Item)) not in N_Has_Entity)
         then
            null;

         elsif not Private_Present (Item)
           or else Private_Present (N)
           or else Nkind (Unit (N)) = N_Package_Body
         then
            Id := Entity (Name (Item));

            if Is_Child_Unit (Id)
              and then Is_Ancestor_Package (Scope (Id), U_Name)
            then
               Set_Is_Immediately_Visible (Id);

               --  Check for the presence of another unit in the context that
               --  may be inadvertently hidden by the child.

               Prev := Current_Entity (Id);

               if Present (Prev)
                 and then Is_Immediately_Visible (Prev)
                 and then not Is_Child_Unit (Prev)
               then
                  declare
                     Clause : Node_Id;

                  begin
                     Clause := First (Context_Items (N));
                     while Present (Clause) loop
                        if Nkind (Clause) = N_With_Clause
                          and then Entity (Name (Clause)) = Prev
                        then
                           Error_Msg_NE
                              ("child unit& hides compilation unit " &
                               "with the same name??",
                                 Name (Item), Id);
                           exit;
                        end if;

                        Next (Clause);
                     end loop;
                  end;
               end if;

            --  The With_Clause may be on a grandchild or one of its further
            --  descendants, which makes a child immediately visible. Examine
            --  ancestry to determine whether such a child exists. For example,
            --  if current unit is A.C, and with_clause is on A.X.Y.Z, then X
            --  is immediately visible.

            elsif Is_Child_Unit (Id) then
               declare
                  Par : Entity_Id;

               begin
                  Par := Scope (Id);
                  while Is_Child_Unit (Par) loop
                     if Is_Ancestor_Package (Scope (Par), U_Name) then
                        Set_Is_Immediately_Visible (Par);
                        exit;
                     end if;

                     Par := Scope (Par);
                  end loop;
               end;
            end if;

         --  If the item is a private with-clause on a child unit, the parent
         --  may have been installed already, but the child unit must remain
         --  invisible until installed in a private part or body, unless there
         --  is already a regular with_clause for it in the current unit.

         elsif Private_Present (Item) then
            Id := Entity (Name (Item));

            if Is_Child_Unit (Id) then
               declare
                  Clause : Node_Id;

                  function In_Context return Boolean;
                  --  Scan context of current unit, to check whether there is
                  --  a with_clause on the same unit as a private with-clause
                  --  on a parent, in which case child unit is visible. If the
                  --  unit is a grandchild, the same applies to its parent.

                  ----------------
                  -- In_Context --
                  ----------------

                  function In_Context return Boolean is
                  begin
                     Clause :=
                       First (Context_Items (Cunit (Current_Sem_Unit)));
                     while Present (Clause) loop
                        if Nkind (Clause) = N_With_Clause
                          and then Comes_From_Source (Clause)
                          and then Is_Entity_Name (Name (Clause))
                          and then not Private_Present (Clause)
                        then
                           if Entity (Name (Clause)) = Id
                             or else
                               (Nkind (Name (Clause)) = N_Expanded_Name
                                 and then Entity (Prefix (Name (Clause))) = Id)
                           then
                              return True;
                           end if;
                        end if;

                        Next (Clause);
                     end loop;

                     return False;
                  end In_Context;

               begin
                  Set_Is_Visible_Lib_Unit (Id, In_Context);
               end;
            end if;
         end if;

         Next (Item);
      end loop;
   end Install_Siblings;

   ---------------------------------
   -- Install_Limited_With_Clause --
   ---------------------------------

   procedure Install_Limited_With_Clause (N : Node_Id) is
      P_Unit           : constant Entity_Id := Unit (Library_Unit (N));
      E                : Entity_Id;
      P                : Entity_Id;
      Is_Child_Package : Boolean := False;
      Lim_Header       : Entity_Id;
      Lim_Typ          : Entity_Id;

      procedure Check_Body_Required;
      --  A unit mentioned in a limited with_clause may not be mentioned in
      --  a regular with_clause, but must still be included in the current
      --  partition. We need to determine whether the unit needs a body, so
      --  that the binder can determine the name of the file to be compiled.
      --  Checking whether a unit needs a body can be done without semantic
      --  analysis, by examining the nature of the declarations in the package.

      function Has_Limited_With_Clause
        (C_Unit : Entity_Id;
         Pack   : Entity_Id) return Boolean;
      --  Determine whether any package in the ancestor chain starting with
      --  C_Unit has a limited with clause for package Pack.

      -------------------------
      -- Check_Body_Required --
      -------------------------

      procedure Check_Body_Required is
         PA : constant List_Id :=
                Pragmas_After (Aux_Decls_Node (Parent (P_Unit)));

         procedure Check_Declarations (Spec : Node_Id);
         --  Recursive procedure that does the work and checks nested packages

         ------------------------
         -- Check_Declarations --
         ------------------------

         procedure Check_Declarations (Spec : Node_Id) is
            Decl             : Node_Id;
            Incomplete_Decls : constant Elist_Id := New_Elmt_List;

            Subp_List        : constant Elist_Id := New_Elmt_List;

            procedure Check_Pragma_Import (P : Node_Id);
            --  If a pragma import applies to a previous subprogram, the
            --  enclosing unit may not need a body. The processing is syntactic
            --  and does not require a declaration to be analyzed. The code
            --  below also handles pragma Import when applied to a subprogram
            --  that renames another. In this case the pragma applies to the
            --  renamed entity.
            --
            --  Chains of multiple renames are not handled by the code below.
            --  It is probably impossible to handle all cases without proper
            --  name resolution. In such cases the algorithm is conservative
            --  and will indicate that a body is needed???

            -------------------------
            -- Check_Pragma_Import --
            -------------------------

            procedure Check_Pragma_Import (P : Node_Id) is
               Arg      : Node_Id;
               Prev_Id  : Elmt_Id;
               Subp_Id  : Elmt_Id;
               Imported : Node_Id;

               procedure Remove_Homonyms (E : Node_Id);
               --  Make one pass over list of subprograms. Called again if
               --  subprogram is a renaming. E is known to be an identifier.

               ---------------------
               -- Remove_Homonyms --
               ---------------------

               procedure Remove_Homonyms (E : Node_Id) is
                  R : Entity_Id := Empty;
                  --  Name of renamed entity, if any

               begin
                  Subp_Id := First_Elmt (Subp_List);
                  while Present (Subp_Id) loop
                     if Chars (Node (Subp_Id)) = Chars (E) then
                        if Nkind (Parent (Parent (Node (Subp_Id))))
                          /= N_Subprogram_Renaming_Declaration
                        then
                           Prev_Id := Subp_Id;
                           Next_Elmt (Subp_Id);
                           Remove_Elmt (Subp_List, Prev_Id);
                        else
                           R := Name (Parent (Parent (Node (Subp_Id))));
                           exit;
                        end if;
                     else
                        Next_Elmt (Subp_Id);
                     end if;
                  end loop;

                  if Present (R) then
                     if Nkind (R) = N_Identifier then
                        Remove_Homonyms (R);

                     elsif Nkind (R) = N_Selected_Component then
                        Remove_Homonyms (Selector_Name (R));

                     --  Renaming of attribute

                     else
                        null;
                     end if;
                  end if;
               end Remove_Homonyms;

            --  Start of processing for Check_Pragma_Import

            begin
               --  Find name of entity in Import pragma. We have not analyzed
               --  the construct, so we must guard against syntax errors.

               Arg := Next (First (Pragma_Argument_Associations (P)));

               if No (Arg)
                 or else Nkind (Expression (Arg)) /= N_Identifier
               then
                  return;
               else
                  Imported := Expression (Arg);
               end if;

               Remove_Homonyms (Imported);
            end Check_Pragma_Import;

         --  Start of processing for Check_Declarations

         begin
            --  Search for Elaborate Body pragma

            Decl := First (Visible_Declarations (Spec));
            while Present (Decl)
              and then Nkind (Decl) = N_Pragma
            loop
               if Get_Pragma_Id (Decl) = Pragma_Elaborate_Body then
                  Set_Body_Required (Library_Unit (N));
                  return;
               end if;

               Next (Decl);
            end loop;

            --  Look for declarations that require the presence of a body. We
            --  have already skipped pragmas at the start of the list.

            while Present (Decl) loop

               --  Subprogram that comes from source means body may be needed.
               --  Save for subsequent examination of import pragmas.

               if Comes_From_Source (Decl)
                 and then (Nkind (Decl) in N_Subprogram_Declaration
                                         | N_Subprogram_Renaming_Declaration
                                         | N_Generic_Subprogram_Declaration)
               then
                  Append_Elmt (Defining_Entity (Decl), Subp_List);

               --  Package declaration of generic package declaration. We need
               --  to recursively examine nested declarations.

               elsif Nkind (Decl) in N_Package_Declaration
                                   | N_Generic_Package_Declaration
               then
                  Check_Declarations (Specification (Decl));

               elsif Nkind (Decl) = N_Pragma
                 and then Pragma_Name (Decl) = Name_Import
               then
                  Check_Pragma_Import (Decl);
               end if;

               Next (Decl);
            end loop;

            --  Same set of tests for private part. In addition to subprograms
            --  detect the presence of Taft Amendment types (incomplete types
            --  completed in the body).

            Decl := First (Private_Declarations (Spec));
            while Present (Decl) loop
               if Comes_From_Source (Decl)
                 and then Nkind (Decl) in N_Subprogram_Declaration
                                        | N_Subprogram_Renaming_Declaration
                                        | N_Generic_Subprogram_Declaration
               then
                  Append_Elmt (Defining_Entity (Decl), Subp_List);

               elsif Nkind (Decl) in N_Package_Declaration
                                   | N_Generic_Package_Declaration
               then
                  Check_Declarations (Specification (Decl));

               --  Collect incomplete type declarations for separate pass

               elsif Nkind (Decl) = N_Incomplete_Type_Declaration then
                  Append_Elmt (Decl, Incomplete_Decls);

               elsif Nkind (Decl) = N_Pragma
                 and then Pragma_Name (Decl) = Name_Import
               then
                  Check_Pragma_Import (Decl);
               end if;

               Next (Decl);
            end loop;

            --  Now check incomplete declarations to locate Taft amendment
            --  types. This can be done by examining the defining identifiers
            --  of  type declarations without real semantic analysis.

            declare
               Inc : Elmt_Id;

            begin
               Inc := First_Elmt (Incomplete_Decls);
               while Present (Inc) loop
                  Decl := Next (Node (Inc));
                  while Present (Decl) loop
                     if Nkind (Decl) = N_Full_Type_Declaration
                       and then Chars (Defining_Identifier (Decl)) =
                                Chars (Defining_Identifier (Node (Inc)))
                     then
                        exit;
                     end if;

                     Next (Decl);
                  end loop;

                  --  If no completion, this is a TAT, and a body is needed

                  if No (Decl) then
                     Set_Body_Required (Library_Unit (N));
                     return;
                  end if;

                  Next_Elmt (Inc);
               end loop;
            end;

            --  Finally, check whether there are subprograms that still require
            --  a body, i.e. are not renamings or null.

            if not Is_Empty_Elmt_List (Subp_List) then
               declare
                  Subp_Id : Elmt_Id;
                  Spec    : Node_Id;

               begin
                  Subp_Id := First_Elmt (Subp_List);
                  Spec    := Parent (Node (Subp_Id));

                  while Present (Subp_Id) loop
                     if Nkind (Parent (Spec))
                        = N_Subprogram_Renaming_Declaration
                     then
                        null;

                     elsif Nkind (Spec) = N_Procedure_Specification
                       and then Null_Present (Spec)
                     then
                        null;

                     else
                        Set_Body_Required (Library_Unit (N));
                        return;
                     end if;

                     Next_Elmt (Subp_Id);
                  end loop;
               end;
            end if;
         end Check_Declarations;

      --  Start of processing for Check_Body_Required

      begin
         --  If this is an imported package (Java and CIL usage) no body is
         --  needed. Scan list of pragmas that may follow a compilation unit
         --  to look for a relevant pragma Import.

         if Present (PA) then
            declare
               Prag : Node_Id;

            begin
               Prag := First (PA);
               while Present (Prag) loop
                  if Nkind (Prag) = N_Pragma
                    and then Get_Pragma_Id (Prag) = Pragma_Import
                  then
                     return;
                  end if;

                  Next (Prag);
               end loop;
            end;
         end if;

         Check_Declarations (Specification (P_Unit));
      end Check_Body_Required;

      -----------------------------
      -- Has_Limited_With_Clause --
      -----------------------------

      function Has_Limited_With_Clause
        (C_Unit : Entity_Id;
         Pack   : Entity_Id) return Boolean
      is
         Par      : Entity_Id;
         Par_Unit : Node_Id;

      begin
         Par := C_Unit;
         while Present (Par) loop
            if Ekind (Par) /= E_Package then
               exit;
            end if;

            --  Retrieve the Compilation_Unit node for Par and determine if
            --  its context clauses contain a limited with for Pack.

            Par_Unit := Parent (Parent (Parent (Par)));

            if Nkind (Par_Unit) = N_Package_Declaration then
               Par_Unit := Parent (Par_Unit);
            end if;

            if Has_With_Clause (Par_Unit, Pack, True) then
               return True;
            end if;

            --  If there are more ancestors, climb up the tree, otherwise we
            --  are done.

            if Is_Child_Unit (Par) then
               Par := Scope (Par);
            else
               exit;
            end if;
         end loop;

         return False;
      end Has_Limited_With_Clause;

   --  Start of processing for Install_Limited_With_Clause

   begin
      pragma Assert (not Limited_View_Installed (N));

      --  In case of limited with_clause on subprograms, generics, instances,
      --  or renamings, the corresponding error was previously posted and we
      --  have nothing to do here. If the file is missing altogether, it has
      --  no source location.

      if Nkind (P_Unit) /= N_Package_Declaration
        or else Sloc (P_Unit) = No_Location
      then
         return;
      end if;

      P := Defining_Unit_Name (Specification (P_Unit));

      --  Handle child packages

      if Nkind (P) = N_Defining_Program_Unit_Name then
         Is_Child_Package := True;
         P := Defining_Identifier (P);
      end if;

      --  Do not install the limited-view if the context of the unit is already
      --  available through a regular with clause.

      if Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Body
        and then Has_With_Clause (Cunit (Current_Sem_Unit), P)
      then
         return;
      end if;

      --  Do not install the limited-view if the full-view is already visible
      --  through renaming declarations.

      if Is_Visible_Through_Renamings (P, N) then
         return;
      end if;

      --  Do not install the limited view if this is the unit being analyzed.
      --  This unusual case will happen when a unit has a limited_with clause
      --  on one of its children. The compilation of the child forces the load
      --  of the parent which tries to install the limited view of the child
      --  again. Installing the limited view must also be disabled when
      --  compiling the body of the child unit.

      if P = Cunit_Entity (Current_Sem_Unit)
        or else (Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Body
                  and then P = Main_Unit_Entity
                  and then Is_Ancestor_Unit
                             (Cunit (Main_Unit), Cunit (Current_Sem_Unit)))
      then
         return;
      end if;

      --  This scenario is similar to the one above, the difference is that the
      --  compilation of sibling Par.Sib forces the load of parent Par which
      --  tries to install the limited view of Lim_Pack [1]. However Par.Sib
      --  has a with clause for Lim_Pack [2] in its body, and thus needs the
      --  nonlimited views of all entities from Lim_Pack.

      --     limited with Lim_Pack;   --  [1]
      --     package Par is ...           package Lim_Pack is ...

      --                                  with Lim_Pack;  --  [2]
      --     package Par.Sib is ...       package body Par.Sib is ...

      --  In this case Main_Unit_Entity is the spec of Par.Sib and Current_
      --  Sem_Unit is the body of Par.Sib.

      if Ekind (P) = E_Package
        and then Ekind (Main_Unit_Entity) = E_Package
        and then Is_Child_Unit (Main_Unit_Entity)

         --  The body has a regular with clause

        and then Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Body
        and then Has_With_Clause (Cunit (Current_Sem_Unit), P)

         --  One of the ancestors has a limited with clause

        and then Nkind (Parent (Parent (Main_Unit_Entity))) =
                                                   N_Package_Specification
        and then Has_Limited_With_Clause (Scope (Main_Unit_Entity), P)
      then
         return;
      end if;

      --  A common use of the limited-with is to have a limited-with in the
      --  package spec, and a normal with in its package body. For example:

      --       limited with X;  -- [1]
      --       package A is ...

      --       with X;          -- [2]
      --       package body A is ...

      --  The compilation of A's body installs the context clauses found at [2]
      --  and then the context clauses of its specification (found at [1]). As
      --  a consequence, at [1] the specification of X has been analyzed and it
      --  is immediately visible. According to the semantics of limited-with
      --  context clauses we don't install the limited view because the full
      --  view of X supersedes its limited view.

      if Analyzed (P_Unit)
        and then
          (Is_Immediately_Visible (P)
            or else (Is_Child_Package and then Is_Visible_Lib_Unit (P)))
      then

         --  The presence of both the limited and the analyzed nonlimited view
         --  may also be an error, such as an illegal context for a limited
         --  with_clause. In that case, do not process the context item at all.

         if Error_Posted (N) then
            return;
         end if;

         if Nkind (Unit (Cunit (Current_Sem_Unit))) = N_Package_Body then
            declare
               Item : Node_Id;
            begin
               Item := First (Context_Items (Cunit (Current_Sem_Unit)));
               while Present (Item) loop
                  if Nkind (Item) = N_With_Clause
                    and then Comes_From_Source (Item)
                    and then Entity (Name (Item)) = P
                  then
                     return;
                  end if;

                  Next (Item);
               end loop;
            end;

            --  If this is a child body, assume that the nonlimited with_clause
            --  appears in an ancestor. Could be refined ???

            if Is_Child_Unit
              (Defining_Entity
                 (Unit (Library_Unit (Cunit (Current_Sem_Unit)))))
            then
               return;
            end if;

         else

            --  If in package declaration, nonlimited view brought in from
            --  parent unit or some error condition.

            return;
         end if;
      end if;

      if Debug_Flag_I then
         Write_Str ("install limited view of ");
         Write_Name (Chars (P));
         Write_Eol;
      end if;

      --  If the unit has not been analyzed and the limited view has not been
      --  already installed then we install it.

      if not Analyzed (P_Unit) then
         if not In_Chain (P) then

            --  Minimum decoration

            Mutate_Ekind (P, E_Package);
            Set_Etype (P, Standard_Void_Type);
            Set_Scope (P, Standard_Standard);
            Set_Is_Visible_Lib_Unit (P);

            if Is_Child_Package then
               Set_Is_Child_Unit (P);
               Set_Scope (P, Defining_Entity (Unit (Parent_Spec (P_Unit))));
            end if;

            --  Place entity on visibility structure

            Set_Homonym (P, Current_Entity (P));
            Set_Current_Entity (P);

            if Debug_Flag_I then
               Write_Str ("   (homonym) chain ");
               Write_Name (Chars (P));
               Write_Eol;
            end if;

            --  Install the incomplete view. The first element of the limited
            --  view is a header (an E_Package entity) used to reference the
            --  first shadow entity in the private part of the package.

            Lim_Header := Limited_View (P);
            Lim_Typ    := First_Entity (Lim_Header);

            while Present (Lim_Typ)
              and then Lim_Typ /= First_Private_Entity (Lim_Header)
            loop
               Set_Homonym (Lim_Typ, Current_Entity (Lim_Typ));
               Set_Current_Entity (Lim_Typ);

               if Debug_Flag_I then
                  Write_Str ("   (homonym) chain ");
                  Write_Name (Chars (Lim_Typ));
                  Write_Eol;
               end if;

               Next_Entity (Lim_Typ);
            end loop;
         end if;

      --  If the unit appears in a previous regular with_clause, the regular
      --  entities of the public part of the withed package must be replaced
      --  by the shadow ones.

      --  This code must be kept synchronized with the code that replaces the
      --  shadow entities by the real entities (see body of Remove_Limited
      --  With_Clause); otherwise the contents of the homonym chains are not
      --  consistent.

      else
         --  Hide all the type entities of the public part of the package to
         --  avoid its usage. This is needed to cover all the subtype decla-
         --  rations because we do not remove them from the homonym chain.

         E := First_Entity (P);
         while Present (E) and then E /= First_Private_Entity (P) loop
            if Is_Type (E) then
               Set_Was_Hidden (E, Is_Hidden (E));
               Set_Is_Hidden (E);
            end if;

            Next_Entity (E);
         end loop;

         --  Replace the real entities by the shadow entities of the limited
         --  view. The first element of the limited view is a header that is
         --  used to reference the first shadow entity in the private part
         --  of the package. Successive elements are the limited views of the
         --  type (including regular incomplete types) declared in the package.

         Lim_Header := Limited_View (P);

         Lim_Typ := First_Entity (Lim_Header);
         while Present (Lim_Typ)
           and then Lim_Typ /= First_Private_Entity (Lim_Header)
         loop
            pragma Assert (not In_Chain (Lim_Typ));

            --  Do not unchain nested packages and child units

            if Ekind (Lim_Typ) /= E_Package
              and then not Is_Child_Unit (Lim_Typ)
            then
               declare
                  Prev : Entity_Id;

               begin
                  Prev := Current_Entity (Lim_Typ);
                  E := Prev;

                  --  Replace E in the homonyms list, so that the limited view
                  --  becomes available.

                  --  If the nonlimited view is a record with an anonymous
                  --  self-referential component, the analysis of the record
                  --  declaration creates an incomplete type with the same name
                  --  in order to define an internal access type. The visible
                  --  entity is now the incomplete type, and that is the one to
                  --  replace in the visibility structure.

                  if E = Non_Limited_View (Lim_Typ)
                    or else
                      (Ekind (E) = E_Incomplete_Type
                        and then Full_View (E) = Non_Limited_View (Lim_Typ))
                  then
                     Set_Homonym (Lim_Typ, Homonym (Prev));
                     Set_Current_Entity (Lim_Typ);

                  else
                     loop
                        E := Homonym (Prev);

                        --  E may have been removed when installing a previous
                        --  limited_with_clause.

                        exit when No (E);
                        exit when E = Non_Limited_View (Lim_Typ);
                        Prev := Homonym (Prev);
                     end loop;

                     if Present (E) then
                        Set_Homonym (Lim_Typ, Homonym (Homonym (Prev)));
                        Set_Homonym (Prev, Lim_Typ);
                     end if;
                  end if;
               end;

               if Debug_Flag_I then
                  Write_Str ("   (homonym) chain ");
                  Write_Name (Chars (Lim_Typ));
                  Write_Eol;
               end if;
            end if;

            Next_Entity (Lim_Typ);
         end loop;
      end if;

      --  The package must be visible while the limited-with clause is active
      --  because references to the type P.T must resolve in the usual way.
      --  In addition, we remember that the limited-view has been installed to
      --  uninstall it at the point of context removal.

      Set_Is_Immediately_Visible (P);
      Set_Limited_View_Installed (N);

      --  If unit has not been analyzed in some previous context, check
      --  (imperfectly ???) whether it might need a body.

      if not Analyzed (P_Unit) then
         Check_Body_Required;
      end if;

      --  If the package in the limited_with clause is a child unit, the clause
      --  is unanalyzed and appears as a selected component. Recast it as an
      --  expanded name so that the entity can be properly set. Use entity of
      --  parent, if available, for higher ancestors in the name.

      if Nkind (Name (N)) = N_Selected_Component then
         declare
            Nam : Node_Id;
            Ent : Entity_Id;

         begin
            Nam := Name (N);
            Ent := P;
            while Nkind (Nam) = N_Selected_Component
              and then Present (Ent)
            loop
               Change_Selected_Component_To_Expanded_Name (Nam);

               --  Set entity of parent identifiers if the unit is a child
               --  unit. This ensures that the tree is properly formed from
               --  semantic point of view. The unit entities are not fully
               --  analyzed, so we need to follow unit links in the tree.

               Set_Entity (Nam, Ent);

               Nam := Prefix (Nam);
               Ent :=
                 Defining_Entity
                   (Unit (Parent_Spec (Unit_Declaration_Node (Ent))));

               --  Set entity of last ancestor

               if Nkind (Nam) = N_Identifier then
                  Set_Entity (Nam, Ent);
               end if;
            end loop;
         end;
      end if;

      Set_Entity (Name (N), P);
      Set_From_Limited_With (P);
   end Install_Limited_With_Clause;

   -------------------------
   -- Install_With_Clause --
   -------------------------

   procedure Install_With_Clause
     (With_Clause     : Node_Id;
      Private_With_OK : Boolean := False)
   is
      Uname : constant Entity_Id := Entity (Name (With_Clause));
      P     : constant Entity_Id := Scope (Uname);

   begin
      --  Ada 2005 (AI-262): Do not install the private withed unit if we are
      --  compiling a package declaration and the Private_With_OK flag was not
      --  set by the caller. These declarations will be installed later (before
      --  analyzing the private part of the package).

      if Private_Present (With_Clause)
        and then Nkind (Unit (Parent (With_Clause)))
                   in N_Package_Declaration | N_Generic_Package_Declaration
        and then not Private_With_OK
      then
         return;
      end if;

      if Debug_Flag_I then
         if Private_Present (With_Clause) then
            Write_Str ("install private withed unit ");
         else
            Write_Str ("install withed unit ");
         end if;

         Write_Name (Chars (Uname));
         Write_Eol;
      end if;

      --  We do not apply the restrictions to an internal unit unless we are
      --  compiling the internal unit as a main unit. This check is also
      --  skipped for dummy units (for missing packages).

      if Sloc (Uname) /= No_Location
        and then (not Is_Internal_Unit (Current_Sem_Unit)
                   or else Current_Sem_Unit = Main_Unit)
      then
         Check_Restricted_Unit
           (Unit_Name (Get_Source_Unit (Uname)), With_Clause);
      end if;

      if P /= Standard_Standard then

         --  If the unit is not analyzed after analysis of the with clause and
         --  it is an instantiation then it awaits a body and is the main unit.
         --  Its appearance in the context of some other unit indicates a
         --  circular dependency (DEC suite perversity).

         if not Analyzed (Uname)
           and then Nkind (Parent (Uname)) = N_Package_Instantiation
         then
            Error_Msg_N
              ("instantiation depends on itself", Name (With_Clause));

         elsif not Analyzed (Uname)
           and then Is_Internal_Unit (Current_Sem_Unit)
           and then not Is_Visible_Lib_Unit (Uname)
           and then No (Scope (Uname))
         then
            if Is_Predefined_Unit (Current_Sem_Unit) then
               Error_Msg_N
                 ("predefined unit depends on itself", Name (With_Clause));
            else
               Error_Msg_N
                 ("GNAT-defined unit depends on itself", Name (With_Clause));
            end if;
            return;

         elsif not Is_Visible_Lib_Unit (Uname) then

            --  Abandon processing in case of previous errors

            if No (Scope (Uname)) then
               Check_Error_Detected;
               return;
            end if;

            Set_Is_Visible_Lib_Unit (Uname);

            --  If the unit is a wrapper package for a compilation unit that is
            --  a subprogram instance, indicate that the instance itself is a
            --  visible unit. This is necessary if the instance is inlined.

            if Is_Wrapper_Package (Uname) then
               Set_Is_Visible_Lib_Unit (Related_Instance (Uname));
            end if;

            --  If the child unit appears in the context of its parent, it is
            --  immediately visible.

            if In_Open_Scopes (Scope (Uname)) then
               Set_Is_Immediately_Visible (Uname);
            end if;

            if Is_Generic_Instance (Uname)
              and then Ekind (Uname) in Subprogram_Kind
            then
               --  Set flag as well on the visible entity that denotes the
               --  instance, which renames the current one.

               Set_Is_Visible_Lib_Unit
                 (Related_Instance
                   (Defining_Entity (Unit (Library_Unit (With_Clause)))));
            end if;

            --  The parent unit may have been installed already, and may have
            --  appeared in a use clause.

            if In_Use (Scope (Uname)) then
               Set_Is_Potentially_Use_Visible (Uname);
            end if;

            Set_Context_Installed (With_Clause);
         end if;

      elsif not Is_Immediately_Visible (Uname) then
         Set_Is_Visible_Lib_Unit (Uname);

         if not Private_Present (With_Clause) or else Private_With_OK then
            Set_Is_Immediately_Visible (Uname);
         end if;

         Set_Context_Installed (With_Clause);
      end if;

      --  A [private] with clause overrides a limited with clause. Restore the
      --  proper view of the package by performing the following actions:
      --
      --    * Remove all shadow entities which hide their corresponding
      --      entities from direct visibility by updating the entity and
      --      homonym chains.
      --
      --    * Enter the corresponding entities back in direct visibility
      --
      --  Note that the original limited with clause which installed its view
      --  is still marked as "active". This effect is undone when the clause
      --  itself is removed, see Remove_Limited_With_Clause.

      if Ekind (Uname) = E_Package and then From_Limited_With (Uname) then
         Remove_Limited_With_Unit (Unit_Declaration_Node (Uname));
      end if;

      --  Ada 2005 (AI-377): it is illegal for a with_clause to name a child
      --  unit if there is a visible homograph for it declared in the same
      --  declarative region. This pathological case can only arise when an
      --  instance I1 of a generic unit G1 has an explicit child unit I1.G2,
      --  G1 has a generic child also named G2, and the context includes with_
      --  clauses for both I1.G2 and for G1.G2, making an implicit declaration
      --  of I1.G2 visible as well. If the child unit is named Standard, do
      --  not apply the check to the Standard package itself.

      if Is_Child_Unit (Uname)
        and then Is_Visible_Lib_Unit (Uname)
        and then Ada_Version >= Ada_2005
      then
         declare
            Decl1 : constant Node_Id := Unit_Declaration_Node (P);
            Decl2 : Node_Id;
            P2    : Entity_Id;
            U2    : Entity_Id;

         begin
            U2 := Homonym (Uname);
            while Present (U2) and then U2 /= Standard_Standard loop
               P2 := Scope (U2);
               Decl2  := Unit_Declaration_Node (P2);

               if Is_Child_Unit (U2) and then Is_Visible_Lib_Unit (U2) then
                  if Is_Generic_Instance (P)
                    and then Nkind (Decl1) = N_Package_Declaration
                    and then Generic_Parent (Specification (Decl1)) = P2
                  then
                     Error_Msg_N ("illegal with_clause", With_Clause);
                     Error_Msg_N
                       ("\child unit has visible homograph" &
                           " (RM 8.3(26), 10.1.1(19))",
                         With_Clause);
                     exit;

                  elsif Is_Generic_Instance (P2)
                    and then Nkind (Decl2) = N_Package_Declaration
                    and then Generic_Parent (Specification (Decl2)) = P
                  then
                     --  With_clause for child unit of instance appears before
                     --  in the context. We want to place the error message on
                     --  it, not on the generic child unit itself.

                     declare
                        Prev_Clause : Node_Id;

                     begin
                        Prev_Clause := First (List_Containing (With_Clause));
                        while Entity (Name (Prev_Clause)) /= U2 loop
                           Next (Prev_Clause);
                        end loop;

                        pragma Assert (Present (Prev_Clause));
                        Error_Msg_N ("illegal with_clause", Prev_Clause);
                        Error_Msg_N
                          ("\child unit has visible homograph" &
                              " (RM 8.3(26), 10.1.1(19))",
                            Prev_Clause);
                        exit;
                     end;
                  end if;
               end if;

               U2 := Homonym (U2);
            end loop;
         end;
      end if;
   end Install_With_Clause;

   -------------------
   -- Is_Child_Spec --
   -------------------

   function Is_Child_Spec (Lib_Unit : Node_Id) return Boolean is
      K : constant Node_Kind := Nkind (Lib_Unit);

   begin
      return (K in N_Generic_Declaration              or else
              K in N_Generic_Instantiation            or else
              K in N_Generic_Renaming_Declaration     or else
              K =  N_Package_Declaration              or else
              K =  N_Package_Renaming_Declaration     or else
              K =  N_Subprogram_Declaration           or else
              K =  N_Subprogram_Renaming_Declaration)
        and then Present (Parent_Spec (Lib_Unit));
   end Is_Child_Spec;

   ------------------------------------
   -- Is_Legal_Shadow_Entity_In_Body --
   ------------------------------------

   function Is_Legal_Shadow_Entity_In_Body (T : Entity_Id) return Boolean is
      C_Unit : constant Node_Id := Cunit (Current_Sem_Unit);
   begin
      return Nkind (Unit (C_Unit)) = N_Package_Body
        and then
          Has_With_Clause
            (C_Unit, Cunit_Entity (Get_Source_Unit (Non_Limited_View (T))));
   end Is_Legal_Shadow_Entity_In_Body;

   ----------------------
   -- Is_Ancestor_Unit --
   ----------------------

   function Is_Ancestor_Unit (U1 : Node_Id; U2 : Node_Id) return Boolean is
      E1 : constant Entity_Id := Defining_Entity (Unit (U1));
      E2 : Entity_Id;
   begin
      if Nkind (Unit (U2)) in N_Package_Body | N_Subprogram_Body then
         E2 := Defining_Entity (Unit (Library_Unit (U2)));
         return Is_Ancestor_Package (E1, E2);
      else
         return False;
      end if;
   end Is_Ancestor_Unit;

   ----------------------------------
   -- Is_Visible_Through_Renamings --
   ----------------------------------

   function Is_Visible_Through_Renamings
     (P          : Entity_Id;
      Error_Node : Node_Id := Empty) return Boolean
   is
      function Is_Limited_Withed_Unit
        (Lib_Unit : Node_Id;
         Pkg_Ent  : Entity_Id) return Boolean;
      --  Return True if Pkg_Ent is a limited-withed package of the given
      --  library unit.

      ----------------------------
      -- Is_Limited_Withed_Unit --
      ----------------------------

      function Is_Limited_Withed_Unit
        (Lib_Unit : Node_Id;
         Pkg_Ent  : Entity_Id) return Boolean
      is
         Item : Node_Id := First (Context_Items (Lib_Unit));

      begin
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause
              and then Limited_Present (Item)
              and then Entity (Name (Item)) = Pkg_Ent
            then
               return True;
            end if;

            Next (Item);
         end loop;

         return False;
      end Is_Limited_Withed_Unit;

      --  Local variables

      Kind     : constant Node_Kind := Nkind (Unit (Cunit (Current_Sem_Unit)));
      Aux_Unit : Node_Id;
      Item     : Node_Id;
      Decl     : Entity_Id;

   begin
      --  Example of the error detected by this subprogram:

      --  package P is
      --    type T is ...
      --  end P;

      --  with P;
      --  package Q is
      --     package Ren_P renames P;
      --  end Q;

      --  with Q;
      --  package R is ...

      --  limited with P; -- ERROR
      --  package R.C is ...

      Aux_Unit := Cunit (Current_Sem_Unit);

      loop
         Item := First (Context_Items (Aux_Unit));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause
              and then not Limited_Present (Item)
              and then Nkind (Unit (Library_Unit (Item))) =
                                               N_Package_Declaration
            then
               Decl :=
                 First (Visible_Declarations
                         (Specification (Unit (Library_Unit (Item)))));
               while Present (Decl) loop
                  if Nkind (Decl) = N_Package_Renaming_Declaration
                    and then Entity (Name (Decl)) = P
                    and then not Is_Limited_Withed_Unit
                                   (Lib_Unit => Library_Unit (Item),
                                    Pkg_Ent  => Entity (Name (Decl)))
                  then
                     --  Generate the error message only if the current unit
                     --  is a package declaration; in case of subprogram
                     --  bodies and package bodies we just return True to
                     --  indicate that the limited view must not be
                     --  installed.

                     if Kind = N_Package_Declaration
                       and then Present (Error_Node)
                     then
                        Error_Msg_N
                          ("simultaneous visibility of the limited and " &
                           "unlimited views not allowed", Error_Node);
                        Error_Msg_Sloc := Sloc (Item);
                        Error_Msg_NE
                          ("\\  unlimited view of & visible through the " &
                           "context clause #", Error_Node, P);
                        Error_Msg_Sloc := Sloc (Decl);
                        Error_Msg_NE ("\\  and the renaming #", Error_Node, P);
                     end if;

                     return True;
                  end if;

                  Next (Decl);
               end loop;
            end if;

            Next (Item);
         end loop;

         --  If it is a body not acting as spec, follow pointer to the
         --  corresponding spec, otherwise follow pointer to parent spec.

         if Present (Library_Unit (Aux_Unit))
           and then Nkind (Unit (Aux_Unit)) in
                      N_Package_Body | N_Subprogram_Body
         then
            if Aux_Unit = Library_Unit (Aux_Unit) then

               --  Aux_Unit is a body that acts as a spec. Clause has
               --  already been flagged as illegal.

               return False;

            else
               Aux_Unit := Library_Unit (Aux_Unit);
            end if;

         else
            Aux_Unit := Parent_Spec (Unit (Aux_Unit));
         end if;

         exit when No (Aux_Unit);
      end loop;

      return False;
   end Is_Visible_Through_Renamings;

   -----------------------
   -- Load_Needed_Body --
   -----------------------

   --  N is a generic unit named in a with clause, or else it is a unit that
   --  contains a generic unit or an inlined function. In order to perform an
   --  instantiation, the body of the unit must be present. If the unit itself
   --  is generic, we assume that an instantiation follows, and load & analyze
   --  the body unconditionally. This forces analysis of the spec as well.

   --  If the unit is not generic, but contains a generic unit, it is loaded on
   --  demand, at the point of instantiation (see ch12).

   procedure Load_Needed_Body
     (N  : Node_Id;
      OK : out Boolean)
   is
      Body_Name : Unit_Name_Type;
      Unum      : Unit_Number_Type;

      Save_Style_Check : constant Boolean := Opt.Style_Check;
      --  The loading and analysis is done with style checks off

   begin
      if not GNAT_Mode then
         Style_Check := False;
      end if;

      Body_Name := Get_Body_Name (Get_Unit_Name (Unit (N)));
      Unum :=
        Load_Unit
          (Load_Name  => Body_Name,
           Required   => False,
           Subunit    => False,
           Error_Node => N,
           Renamings  => True);

      if Unum = No_Unit then
         OK := False;

      else
         Compiler_State := Analyzing; -- reset after load

         if Fatal_Error (Unum) /= Error_Detected or else Try_Semantics then
            if Debug_Flag_L then
               Write_Str ("*** Loaded generic body");
               Write_Eol;
            end if;

            --  We always perform analyses
            Semantics (Cunit (Unum));
         end if;

         OK := True;
      end if;

      Style_Check := Save_Style_Check;
   end Load_Needed_Body;

   -------------------------
   -- Build_Limited_Views --
   -------------------------

   procedure Build_Limited_Views (N : Node_Id) is
      Unum        : constant Unit_Number_Type :=
                      Get_Source_Unit (Library_Unit (N));
      Is_Analyzed : constant Boolean := Analyzed (Cunit (Unum));

      Shadow_Pack : Entity_Id;
      --  The corresponding shadow entity of the withed package. This entity
      --  offers incomplete views of packages and types as well as abstract
      --  views of states and variables declared within.

      Last_Shadow : Entity_Id := Empty;
      --  The last shadow entity created by routine Build_Shadow_Entity

      procedure Build_Shadow_Entity
        (Ent       : Entity_Id;
         Scop      : Entity_Id;
         Shadow    : out Entity_Id;
         Is_Tagged : Boolean := False);
      --  Create a shadow entity that hides Ent and offers an abstract or
      --  incomplete view of Ent. Scop is the proper scope. Flag Is_Tagged
      --  should be set when Ent is a tagged type. The generated entity is
      --  added to Lim_Header. This routine updates the value of Last_Shadow.

      procedure Decorate_Package (Ent : Entity_Id; Scop : Entity_Id);
      --  Perform minimal decoration of a package or its corresponding shadow
      --  entity denoted by Ent. Scop is the proper scope.

      procedure Decorate_State (Ent : Entity_Id; Scop : Entity_Id);
      --  Perform full decoration of an abstract state or its corresponding
      --  shadow entity denoted by Ent. Scop is the proper scope.

      procedure Decorate_Type
        (Ent         : Entity_Id;
         Scop        : Entity_Id;
         Is_Tagged   : Boolean := False;
         Materialize : Boolean := False);
      --  Perform minimal decoration of a type or its corresponding shadow
      --  entity denoted by Ent. Scop is the proper scope. Flag Is_Tagged
      --  should be set when Ent is a tagged type. Flag Materialize should be
      --  set when Ent is a tagged type and its class-wide type needs to appear
      --  in the tree.

      procedure Decorate_Variable (Ent : Entity_Id; Scop : Entity_Id);
      --  Perform minimal decoration of a variable denoted by Ent. Scop is the
      --  proper scope.

      procedure Process_Declarations_And_States
        (Pack  : Entity_Id;
         Decls : List_Id;
         Scop  : Entity_Id;
         Create_Abstract_Views : Boolean);
      --  Inspect the states of package Pack and declarative list Decls. Create
      --  shadow entities for all nested packages, states, types and variables
      --  encountered. Scop is the proper scope. Create_Abstract_Views should
      --  be set when the abstract states and variables need to be processed.

      -------------------------
      -- Build_Shadow_Entity --
      -------------------------

      procedure Build_Shadow_Entity
        (Ent       : Entity_Id;
         Scop      : Entity_Id;
         Shadow    : out Entity_Id;
         Is_Tagged : Boolean := False)
      is
      begin
         Shadow := Make_Temporary (Sloc (Ent), 'Z');

         --  The shadow entity must share the same name and parent as the
         --  entity it hides.

         Set_Chars  (Shadow, Chars (Ent));
         Set_Parent (Shadow, Parent (Ent));

         --  The abstract view of a variable is a state, not another variable

         if Ekind (Ent) = E_Variable then
            Mutate_Ekind (Shadow, E_Abstract_State);
         else
            Mutate_Ekind (Shadow, Ekind (Ent));
         end if;

         Set_Is_Internal       (Shadow);
         Set_From_Limited_With (Shadow);

         --  Add the new shadow entity to the limited view of the package

         Last_Shadow := Shadow;
         Append_Entity (Shadow, Shadow_Pack);

         --  Perform context-specific decoration of the shadow entity

         if Ekind (Ent) = E_Abstract_State then
            Decorate_State       (Shadow, Scop);
            Set_Non_Limited_View (Shadow, Ent);

         elsif Ekind (Ent) = E_Package then
            Decorate_Package (Shadow, Scop);

         elsif Is_Type (Ent) then
            Decorate_Type        (Shadow, Scop, Is_Tagged);
            Set_Non_Limited_View (Shadow, Ent);

            if Is_Tagged then
               Set_Non_Limited_View
                 (Class_Wide_Type (Shadow), Class_Wide_Type (Ent));
            end if;

            if Is_Incomplete_Or_Private_Type (Ent) then
               Set_Private_Dependents (Shadow, New_Elmt_List);
            end if;

         elsif Ekind (Ent) = E_Variable then
            Decorate_State       (Shadow, Scop);
            Set_Non_Limited_View (Shadow, Ent);
         end if;
      end Build_Shadow_Entity;

      ----------------------
      -- Decorate_Package --
      ----------------------

      procedure Decorate_Package (Ent : Entity_Id; Scop : Entity_Id) is
      begin
         Mutate_Ekind (Ent, E_Package);
         Set_Etype (Ent, Standard_Void_Type);
         Set_Scope (Ent, Scop);
      end Decorate_Package;

      --------------------
      -- Decorate_State --
      --------------------

      procedure Decorate_State (Ent : Entity_Id; Scop : Entity_Id) is
      begin
         Mutate_Ekind            (Ent, E_Abstract_State);
         Set_Etype               (Ent, Standard_Void_Type);
         Set_Scope               (Ent, Scop);
         Set_Encapsulating_State (Ent, Empty);
      end Decorate_State;

      -------------------
      -- Decorate_Type --
      -------------------

      procedure Decorate_Type
        (Ent         : Entity_Id;
         Scop        : Entity_Id;
         Is_Tagged   : Boolean := False;
         Materialize : Boolean := False)
      is
         CW_Typ : Entity_Id;

      begin
         --  An unanalyzed type or a shadow entity of a type is treated as an
         --  incomplete type, and carries the corresponding attributes.

         Mutate_Ekind           (Ent, E_Incomplete_Type);
         Set_Etype              (Ent, Ent);
         Set_Full_View          (Ent, Empty);
         Set_Is_First_Subtype   (Ent);
         Set_Scope              (Ent, Scop);
         Set_Stored_Constraint  (Ent, No_Elist);
         Reinit_Size_Align      (Ent);

         if From_Limited_With (Ent) then
            Set_Private_Dependents (Ent, New_Elmt_List);
         end if;

         --  A tagged type and its corresponding shadow entity share one common
         --  class-wide type. The list of primitive operations for the shadow
         --  entity is empty.

         if Is_Tagged then
            Set_Is_Tagged_Type (Ent);
            Set_Direct_Primitive_Operations (Ent, New_Elmt_List);

            CW_Typ :=
              New_External_Entity
                (E_Void, Scope (Ent), Sloc (Ent), Ent, 'C', 0, 'T');

            Set_Class_Wide_Type (Ent, CW_Typ);

            --  Set parent to be the same as the parent of the tagged type.
            --  We need a parent field set, and it is supposed to point to
            --  the declaration of the type. The tagged type declaration
            --  essentially declares two separate types, the tagged type
            --  itself and the corresponding class-wide type, so it is
            --  reasonable for the parent fields to point to the declaration
            --  in both cases.

            Set_Parent (CW_Typ, Parent (Ent));

            Mutate_Ekind                  (CW_Typ, E_Class_Wide_Type);
            Set_Class_Wide_Type           (CW_Typ, CW_Typ);
            Set_Etype                     (CW_Typ, Ent);
            Set_Equivalent_Type           (CW_Typ, Empty);
            Set_From_Limited_With         (CW_Typ, From_Limited_With (Ent));
            Set_Has_Unknown_Discriminants (CW_Typ);
            Set_Is_First_Subtype          (CW_Typ);
            Set_Is_Tagged_Type            (CW_Typ);
            Set_Materialize_Entity        (CW_Typ, Materialize);
            Set_Scope                     (CW_Typ, Scop);
            Reinit_Size_Align             (CW_Typ);
         end if;
      end Decorate_Type;

      -----------------------
      -- Decorate_Variable --
      -----------------------

      procedure Decorate_Variable (Ent : Entity_Id; Scop : Entity_Id) is
      begin
         Mutate_Ekind (Ent, E_Variable);
         Set_Etype (Ent, Standard_Void_Type);
         Set_Scope (Ent, Scop);
      end Decorate_Variable;

      -------------------------------------
      -- Process_Declarations_And_States --
      -------------------------------------

      procedure Process_Declarations_And_States
        (Pack  : Entity_Id;
         Decls : List_Id;
         Scop  : Entity_Id;
         Create_Abstract_Views : Boolean)
      is
         procedure Find_And_Process_States;
         --  Determine whether package Pack defines abstract state either by
         --  using an aspect or a pragma. If this is the case, build shadow
         --  entities for all abstract states of Pack.

         procedure Process_States (States : Elist_Id);
         --  Generate shadow entities for all abstract states in list States

         -----------------------------
         -- Find_And_Process_States --
         -----------------------------

         procedure Find_And_Process_States is
            procedure Process_State (State : Node_Id);
            --  Generate shadow entities for a single abstract state or
            --  multiple states expressed as an aggregate.

            -------------------
            -- Process_State --
            -------------------

            procedure Process_State (State : Node_Id) is
               Loc   : constant Source_Ptr := Sloc (State);
               Decl  : Node_Id;
               Dummy : Entity_Id;
               Elmt  : Node_Id;
               Id    : Entity_Id;

            begin
               --  Multiple abstract states appear as an aggregate

               if Nkind (State) = N_Aggregate then
                  Elmt := First (Expressions (State));
                  while Present (Elmt) loop
                     Process_State (Elmt);
                     Next (Elmt);
                  end loop;

                  return;

               --  A null state has no abstract view

               elsif Nkind (State) = N_Null then
                  return;

               --  State declaration with various options appears as an
               --  extension aggregate.

               elsif Nkind (State) = N_Extension_Aggregate then
                  Decl := Ancestor_Part (State);

               --  Simple state declaration

               elsif Nkind (State) = N_Identifier then
                  Decl := State;

               --  Possibly an illegal state declaration

               else
                  return;
               end if;

               --  Abstract states are elaborated when the related pragma is
               --  elaborated. Since the withed package is not analyzed yet,
               --  the entities of the abstract states are not available. To
               --  overcome this complication, create the entities now and
               --  store them in their respective declarations. The entities
               --  are later used by routine Create_Abstract_State to declare
               --  and enter the states into visibility.

               if No (Entity (Decl)) then
                  Id := Make_Defining_Identifier (Loc, Chars (Decl));

                  Set_Entity     (Decl, Id);
                  Set_Parent     (Id, State);
                  Decorate_State (Id, Scop);

               --  Otherwise the package was previously withed

               else
                  Id := Entity (Decl);
               end if;

               Build_Shadow_Entity (Id, Scop, Dummy);
            end Process_State;

            --  Local variables

            Pack_Decl : constant Node_Id := Unit_Declaration_Node (Pack);
            Asp       : Node_Id;
            Decl      : Node_Id;

         --  Start of processing for Find_And_Process_States

         begin
            --  Find aspect Abstract_State

            Asp := First (Aspect_Specifications (Pack_Decl));
            while Present (Asp) loop
               if Chars (Identifier (Asp)) = Name_Abstract_State then
                  Process_State (Expression (Asp));

                  return;
               end if;

               Next (Asp);
            end loop;

            --  Find pragma Abstract_State by inspecting the declarations

            Decl := First (Decls);
            while Present (Decl) and then Nkind (Decl) = N_Pragma loop
               if Pragma_Name (Decl) = Name_Abstract_State then
                  Process_State
                    (Get_Pragma_Arg
                       (First (Pragma_Argument_Associations (Decl))));

                  return;
               end if;

               Next (Decl);
            end loop;
         end Find_And_Process_States;

         --------------------
         -- Process_States --
         --------------------

         procedure Process_States (States : Elist_Id) is
            Dummy : Entity_Id;
            Elmt  : Elmt_Id;

         begin
            Elmt := First_Elmt (States);
            while Present (Elmt) loop
               Build_Shadow_Entity (Node (Elmt), Scop, Dummy);

               Next_Elmt (Elmt);
            end loop;
         end Process_States;

         --  Local variables

         Is_Tagged : Boolean;
         Decl      : Node_Id;
         Def       : Node_Id;
         Def_Id    : Entity_Id;
         Shadow    : Entity_Id;

      --  Start of processing for Process_Declarations_And_States

      begin
         --  Build abstract views for all states defined in the package

         if Create_Abstract_Views then

            --  When a package has been analyzed, all states are stored in list
            --  Abstract_States. Generate the shadow entities directly.

            if Is_Analyzed then
               if Present (Abstract_States (Pack)) then
                  Process_States (Abstract_States (Pack));
               end if;

            --  The package may declare abstract states by using an aspect or a
            --  pragma. Attempt to locate one of these construct and if found,
            --  build the shadow entities.

            else
               Find_And_Process_States;
            end if;
         end if;

         --  Inspect the declarative list, looking for nested packages, types
         --  and variable declarations.

         Decl := First (Decls);
         while Present (Decl) loop

            --  Packages

            if Nkind (Decl) = N_Package_Declaration then
               Def_Id := Defining_Entity (Decl);

               --  Perform minor decoration when the withed package has not
               --  been analyzed.

               if not Is_Analyzed then
                  Decorate_Package (Def_Id, Scop);
               end if;

               --  Create a shadow entity that offers a limited view of all
               --  visible types declared within.

               Build_Shadow_Entity (Def_Id, Scop, Shadow);

               Process_Declarations_And_States
                 (Pack                  => Def_Id,
                  Decls                 =>
                    Visible_Declarations (Specification (Decl)),
                  Scop                  => Shadow,
                  Create_Abstract_Views => Create_Abstract_Views);

            --  Types

            elsif Nkind (Decl) in N_Full_Type_Declaration
                                | N_Incomplete_Type_Declaration
                                | N_Private_Extension_Declaration
                                | N_Private_Type_Declaration
                                | N_Protected_Type_Declaration
                                | N_Task_Type_Declaration
            then
               Def_Id := Defining_Entity (Decl);

               --  Determine whether the type is tagged. Note that packages
               --  included via a limited with clause are not always analyzed,
               --  hence the tree lookup rather than the use of attribute
               --  Is_Tagged_Type.

               if Nkind (Decl) = N_Full_Type_Declaration then
                  Def := Type_Definition (Decl);

                  Is_Tagged :=
                     (Nkind (Def) = N_Record_Definition
                        and then Tagged_Present (Def))
                    or else
                     (Nkind (Def) = N_Derived_Type_Definition
                        and then Present (Record_Extension_Part (Def)));

               elsif Nkind (Decl) in N_Incomplete_Type_Declaration
                                   | N_Private_Type_Declaration
               then
                  Is_Tagged := Tagged_Present (Decl);

               elsif Nkind (Decl) = N_Private_Extension_Declaration then
                  Is_Tagged := True;

               else
                  Is_Tagged := False;
               end if;

               --  Perform minor decoration when the withed package has not
               --  been analyzed.

               if not Is_Analyzed then
                  Decorate_Type (Def_Id, Scop, Is_Tagged, True);
               end if;

               --  Create a shadow entity that hides the type and offers an
               --  incomplete view of the said type.

               Build_Shadow_Entity (Def_Id, Scop, Shadow, Is_Tagged);

            --  Variables

            elsif Create_Abstract_Views
              and then Nkind (Decl) = N_Object_Declaration
              and then not Constant_Present (Decl)
            then
               Def_Id := Defining_Entity (Decl);

               --  Perform minor decoration when the withed package has not
               --  been analyzed.

               if not Is_Analyzed then
                  Decorate_Variable (Def_Id, Scop);
               end if;

               --  Create a shadow entity that hides the variable and offers an
               --  abstract view of the said variable.

               Build_Shadow_Entity (Def_Id, Scop, Shadow);
            end if;

            Next (Decl);
         end loop;
      end Process_Declarations_And_States;

      --  Local variables

      Nam  : constant Node_Id   := Name (N);
      Pack : constant Entity_Id := Cunit_Entity (Unum);

      Last_Public_Shadow : Entity_Id := Empty;
      Private_Shadow     : Entity_Id;
      Spec               : Node_Id;

   --  Start of processing for Build_Limited_Views

   begin
      pragma Assert (Limited_Present (N));

      --  A library_item mentioned in a limited_with_clause is a package
      --  declaration, not a subprogram declaration, generic declaration,
      --  generic instantiation, or package renaming declaration.

      case Nkind (Unit (Library_Unit (N))) is
         when N_Package_Declaration =>
            null;

         when N_Subprogram_Declaration =>
            Error_Msg_N
              ("subprogram not allowed in `LIMITED WITH` clause", N);
            return;

         when N_Generic_Declaration =>
            Error_Msg_N ("generic not allowed in `LIMITED WITH` clause", N);
            return;

         when N_Generic_Instantiation =>
            Error_Msg_N
              ("generic instantiation not allowed in `LIMITED WITH` clause",
               N);
            return;

         when N_Generic_Renaming_Declaration =>
            Error_Msg_N
              ("generic renaming not allowed in `LIMITED WITH` clause", N);
            return;

         when N_Subprogram_Renaming_Declaration =>
            Error_Msg_N
              ("renamed subprogram not allowed in `LIMITED WITH` clause", N);
            return;

         when N_Package_Renaming_Declaration =>
            Error_Msg_N
              ("renamed package not allowed in `LIMITED WITH` clause", N);
            return;

         when others =>
            raise Program_Error;
      end case;

      --  The withed unit may not be analyzed, but the with calause itself
      --  must be minimally decorated. This ensures that the checks on unused
      --  with clauses also process limieted withs.

      Mutate_Ekind (Pack, E_Package);
      Set_Etype (Pack, Standard_Void_Type);

      if Is_Entity_Name (Nam) then
         Set_Entity (Nam, Pack);

      elsif Nkind (Nam) = N_Selected_Component then
         Set_Entity (Selector_Name (Nam), Pack);
      end if;

      --  Check if the chain is already built

      Spec := Specification (Unit (Library_Unit (N)));

      if Limited_View_Installed (Spec) then
         return;
      end if;

      --  Create the shadow package wich hides the withed unit and provides
      --  incomplete view of all types and packages declared within.

      Shadow_Pack := Make_Temporary (Sloc (N), 'Z');
      Mutate_Ekind     (Shadow_Pack, E_Package);
      Set_Is_Internal  (Shadow_Pack);
      Set_Limited_View (Pack, Shadow_Pack);

      --  Inspect the abstract states and visible declarations of the withed
      --  unit and create shadow entities that hide existing packages, states,
      --  variables and types.

      Process_Declarations_And_States
        (Pack                  => Pack,
         Decls                 => Visible_Declarations (Spec),
         Scop                  => Pack,
         Create_Abstract_Views => True);

      Last_Public_Shadow := Last_Shadow;

      --  Ada 2005 (AI-262): Build the limited view of the private declarations
      --  to accommodate limited private with clauses.

      Process_Declarations_And_States
        (Pack                  => Pack,
         Decls                 => Private_Declarations (Spec),
         Scop                  => Pack,
         Create_Abstract_Views => False);

      if Present (Last_Public_Shadow) then
         Private_Shadow := Next_Entity (Last_Public_Shadow);
      else
         Private_Shadow := First_Entity (Shadow_Pack);
      end if;

      Set_First_Private_Entity (Shadow_Pack, Private_Shadow);
      Set_Limited_View_Installed (Spec);
   end Build_Limited_Views;

   ----------------------------
   -- Check_No_Elab_Code_All --
   ----------------------------

   procedure Check_No_Elab_Code_All (N : Node_Id) is
   begin
      if Present (No_Elab_Code_All_Pragma)
        and then In_Extended_Main_Source_Unit (N)
        and then Present (Context_Items (N))
      then
         declare
            CL : constant List_Id := Context_Items (N);
            CI : Node_Id;

         begin
            CI := First (CL);
            while Present (CI) loop
               if Nkind (CI) = N_With_Clause
                 and then not
                   No_Elab_Code_All (Get_Source_Unit (Library_Unit (CI)))

                 --  In GNATprove mode, some runtime units are implicitly
                 --  loaded to make their entities available for analysis. In
                 --  this case, ignore violations of No_Elaboration_Code_All
                 --  for this special analysis mode.

                 and then not
                   (GNATprove_Mode and then Implicit_With (CI))
               then
                  Error_Msg_Sloc := Sloc (No_Elab_Code_All_Pragma);
                  Error_Msg_N
                    ("violation of No_Elaboration_Code_All#", CI);
                  Error_Msg_NE
                    ("\unit& does not have No_Elaboration_Code_All",
                     CI, Entity (Name (CI)));
               end if;

               Next (CI);
            end loop;
         end;
      end if;
   end Check_No_Elab_Code_All;

   -------------------------------
   -- Check_Body_Needed_For_SAL --
   -------------------------------

   procedure Check_Body_Needed_For_SAL (Unit_Name : Entity_Id) is
      function Entity_Needs_Body (E : Entity_Id) return Boolean;
      --  Determine whether use of entity E might require the presence of its
      --  body. For a package this requires a recursive traversal of all nested
      --  declarations.

      -----------------------
      -- Entity_Needs_Body --
      -----------------------

      function Entity_Needs_Body (E : Entity_Id) return Boolean is
         Ent : Entity_Id;

      begin
         if Is_Subprogram (E) and then Has_Pragma_Inline (E) then
            return True;

         elsif Is_Generic_Subprogram (E) then

            --  A generic subprogram always requires the presence of its
            --  body because an instantiation needs both templates. The only
            --  exceptions is a generic subprogram renaming. In this case the
            --  body is needed only when the template is declared outside the
            --  compilation unit being checked.

            if Present (Renamed_Entity (E)) then
               return not Within_Scope (E, Unit_Name);
            else
               return True;
            end if;

         elsif Ekind (E) = E_Generic_Package
           and then
             Nkind (Unit_Declaration_Node (E)) = N_Generic_Package_Declaration
           and then Present (Corresponding_Body (Unit_Declaration_Node (E)))
         then
            return True;

         elsif Ekind (E) = E_Package
           and then Nkind (Unit_Declaration_Node (E)) = N_Package_Declaration
           and then Present (Corresponding_Body (Unit_Declaration_Node (E)))
         then
            Ent := First_Entity (E);
            while Present (Ent) loop
               if Entity_Needs_Body (Ent) then
                  return True;
               end if;

               Next_Entity (Ent);
            end loop;

            return False;

         else
            return False;
         end if;
      end Entity_Needs_Body;

   --  Start of processing for Check_Body_Needed_For_SAL

   begin
      if Ekind (Unit_Name) = E_Generic_Package
        and then Nkind (Unit_Declaration_Node (Unit_Name)) =
                                            N_Generic_Package_Declaration
        and then
          Present (Corresponding_Body (Unit_Declaration_Node (Unit_Name)))
      then
         Set_Body_Needed_For_SAL (Unit_Name);

      elsif Ekind (Unit_Name) in E_Generic_Procedure | E_Generic_Function then
         Set_Body_Needed_For_SAL (Unit_Name);

      elsif Is_Subprogram (Unit_Name)
        and then Nkind (Unit_Declaration_Node (Unit_Name)) =
                                            N_Subprogram_Declaration
        and then Has_Pragma_Inline (Unit_Name)
      then
         Set_Body_Needed_For_SAL (Unit_Name);

      elsif Ekind (Unit_Name) = E_Subprogram_Body then
         Check_Body_Needed_For_SAL
           (Corresponding_Spec (Unit_Declaration_Node (Unit_Name)));

      elsif Ekind (Unit_Name) = E_Package
        and then Entity_Needs_Body (Unit_Name)
      then
         Set_Body_Needed_For_SAL (Unit_Name);

      elsif Ekind (Unit_Name) = E_Package_Body
        and then Nkind (Unit_Declaration_Node (Unit_Name)) = N_Package_Body
      then
         Check_Body_Needed_For_SAL
           (Corresponding_Spec (Unit_Declaration_Node (Unit_Name)));
      end if;
   end Check_Body_Needed_For_SAL;

   --------------------
   -- Remove_Context --
   --------------------

   procedure Remove_Context (N : Node_Id) is
      Lib_Unit : constant Node_Id := Unit (N);

   begin
      --  If this is a child unit, first remove the parent units

      if Is_Child_Spec (Lib_Unit) then
         Remove_Parents (Lib_Unit);
      end if;

      Remove_Context_Clauses (N);
   end Remove_Context;

   ----------------------------
   -- Remove_Context_Clauses --
   ----------------------------

   procedure Remove_Context_Clauses (N : Node_Id) is
      Item      : Node_Id;
      Unit_Name : Entity_Id;

   begin
      --  Ada 2005 (AI-50217): We remove the context clauses in two phases:
      --  limited-views first and regular-views later (to maintain the stack
      --  model).

      --  First Phase: Remove limited_with context clauses

      Item := First (Context_Items (N));
      while Present (Item) loop

         --  We are interested only in with clauses that got installed on entry

         if Nkind (Item) = N_With_Clause
           and then Limited_Present (Item)
         then
            if Limited_View_Installed (Item) then
               Remove_Limited_With_Clause (Item);

            --  An unusual case: If the library unit of the Main_Unit has a
            --  limited with_clause on some unit P and the context somewhere
            --  includes a with_clause on P, P has been analyzed. The entity
            --  for P is still visible, which in general is harmless because
            --  this is the end of the compilation, but it can affect pending
            --  instantiations that may have been generated elsewhere, so it
            --  it is necessary to remove U from visibility so that inlining
            --  and the analysis of instance bodies can proceed cleanly.

            elsif Current_Sem_Unit = Main_Unit
              and then Serious_Errors_Detected = 0
              and then not Implicit_With (Item)
            then
               Set_Is_Immediately_Visible
                 (Defining_Entity (Unit (Library_Unit (Item))), False);
            end if;
         end if;

         Next (Item);
      end loop;

      --  Second Phase: Loop through context items and undo regular
      --  with_clauses and use_clauses.

      Item := First (Context_Items (N));
      while Present (Item) loop

         --  We are interested only in with clauses which got installed on
         --  entry, as indicated by their Context_Installed flag set

         if Nkind (Item) = N_With_Clause
           and then Limited_Present (Item)
           and then Limited_View_Installed (Item)
         then
            null;

         elsif Nkind (Item) = N_With_Clause
           and then Context_Installed (Item)
         then
            --  Remove items from one with'ed unit

            Unit_Name := Entity (Name (Item));
            Remove_Unit_From_Visibility (Unit_Name);
            Set_Context_Installed (Item, False);

         elsif Nkind (Item) = N_Use_Package_Clause then
            End_Use_Package (Item);

         elsif Nkind (Item) = N_Use_Type_Clause then
            End_Use_Type (Item);
         end if;

         Next (Item);
      end loop;
   end Remove_Context_Clauses;

   --------------------------------
   -- Remove_Limited_With_Clause --
   --------------------------------

   procedure Remove_Limited_With_Clause (N : Node_Id) is
      Pack_Decl : constant Entity_Id := Unit (Library_Unit (N));

   begin
      pragma Assert (Limited_View_Installed (N));

      --  Limited with clauses that designate units other than packages are
      --  illegal and are never installed.

      if Nkind (Pack_Decl) = N_Package_Declaration then
         Remove_Limited_With_Unit (Pack_Decl, N);
      end if;

      --  Indicate that the limited views of the clause have been removed

      Set_Limited_View_Installed (N, False);
   end Remove_Limited_With_Clause;

   ------------------------------
   -- Remove_Limited_With_Unit --
   ------------------------------

   procedure Remove_Limited_With_Unit
     (Pack_Decl  : Node_Id;
      Lim_Clause : Node_Id := Empty)
   is
      procedure Remove_Shadow_Entities_From_Visibility (Pack_Id : Entity_Id);
      --  Remove the shadow entities of package Pack_Id from direct visibility

      procedure Remove_Shadow_Entities_With_Restore (Pack_Id : Entity_Id);
      --  Remove the shadow entities of package Pack_Id from direct visibility,
      --  restore the corresponding entities they hide into direct visibility,
      --  and update the entity and homonym chains.

      --------------------------------------------
      -- Remove_Shadow_Entities_From_Visibility --
      --------------------------------------------

      procedure Remove_Shadow_Entities_From_Visibility (Pack_Id : Entity_Id) is
         Lim_Header : constant Entity_Id := Limited_View (Pack_Id);
         Upto       : constant Entity_Id := First_Private_Entity (Lim_Header);

         Shadow : Entity_Id;

      begin
         --  Remove the package from direct visibility

         Unchain (Pack_Id);
         Set_Is_Immediately_Visible (Pack_Id, False);

         --  Remove all shadow entities from direct visibility

         Shadow := First_Entity (Lim_Header);
         while Present (Shadow) and then Shadow /= Upto loop
            Unchain (Shadow);
            Next_Entity (Shadow);
         end loop;
      end Remove_Shadow_Entities_From_Visibility;

      -----------------------------------------
      -- Remove_Shadow_Entities_With_Restore --
      -----------------------------------------

      procedure Remove_Shadow_Entities_With_Restore (Pack_Id : Entity_Id) is
         procedure Restore_Chain_For_Shadow (Shadow : Entity_Id);
         --  Remove shadow entity Shadow by updating the entity and homonym
         --  chains.

         procedure Restore_Chains
           (From : Entity_Id;
            Upto : Entity_Id);
         --  Remove a sequence of shadow entities starting from From and ending
         --  prior to Upto by updating the entity and homonym chains.

         procedure Restore_Type_Visibility
           (From : Entity_Id;
            Upto : Entity_Id);
         --  Restore a sequence of types starting from From and ending prior to
         --  Upto back in direct visibility.

         ------------------------------
         -- Restore_Chain_For_Shadow --
         ------------------------------

         procedure Restore_Chain_For_Shadow (Shadow : Entity_Id) is
            Prev : Entity_Id;
            Typ  : Entity_Id;

         begin
            --  If the package has incomplete types, the limited view of the
            --  incomplete type is in fact never visible (AI05-129) but we
            --  have created a shadow entity E1 for it, that points to E2,
            --  a nonlimited incomplete type. This in turn has a full view
            --  E3 that is the full declaration. There is a corresponding
            --  shadow entity E4. When reinstalling the nonlimited view,
            --  E2 must become the current entity and E3 must be ignored.

            Typ := Non_Limited_View (Shadow);

            --  Shadow is the limited view of a full type declaration that has
            --  a previous incomplete declaration, i.e. E3 from the previous
            --  description. Nothing to insert.

            if Present (Current_Entity (Typ))
              and then Ekind (Current_Entity (Typ)) = E_Incomplete_Type
              and then Full_View (Current_Entity (Typ)) = Typ
            then
               return;
            end if;

            pragma Assert (not In_Chain (Typ));

            Prev := Current_Entity (Shadow);

            if Prev = Shadow then
               Set_Current_Entity (Typ);

            else
               while Present (Prev) and then Homonym (Prev) /= Shadow loop
                  Prev := Homonym (Prev);
               end loop;

               if Present (Prev) then
                  Set_Homonym (Prev, Typ);
               end if;
            end if;

            Set_Homonym (Typ, Homonym (Shadow));
         end Restore_Chain_For_Shadow;

         --------------------
         -- Restore_Chains --
         --------------------

         procedure Restore_Chains
           (From : Entity_Id;
            Upto : Entity_Id)
         is
            Shadow : Entity_Id;

         begin
            Shadow := From;
            while Present (Shadow) and then Shadow /= Upto loop

               --  Do not unchain nested packages and child units

               if Ekind (Shadow) = E_Package then
                  null;

               elsif Is_Child_Unit (Non_Limited_View (Shadow)) then
                  null;

               else
                  Restore_Chain_For_Shadow (Shadow);
               end if;

               Next_Entity (Shadow);
            end loop;
         end Restore_Chains;

         -----------------------------
         -- Restore_Type_Visibility --
         -----------------------------

         procedure Restore_Type_Visibility
           (From : Entity_Id;
            Upto : Entity_Id)
         is
            Typ : Entity_Id;

         begin
            Typ := From;
            while Present (Typ) and then Typ /= Upto loop
               if Is_Type (Typ) then
                  Set_Is_Hidden (Typ, Was_Hidden (Typ));
               end if;

               Next_Entity (Typ);
            end loop;
         end Restore_Type_Visibility;

         --  Local variables

         Lim_Header : constant Entity_Id := Limited_View (Pack_Id);

      --  Start of processing Remove_Shadow_Entities_With_Restore

      begin
         --  The limited view of a package is being uninstalled by removing
         --  the effects of a limited with clause. If the clause appears in a
         --  unit which is not part of the main unit closure, then the related
         --  package must not be visible.

         if Present (Lim_Clause)
           and then not In_Extended_Main_Source_Unit (Lim_Clause)
         then
            Set_Is_Immediately_Visible (Pack_Id, False);

         --  Otherwise a limited view is being overridden by a nonlimited view.
         --  Leave the visibility of the package as is because the unit must be
         --  visible when the nonlimited view is installed.

         else
            null;
         end if;

         --  Remove the shadow entities from visibility by updating the entity
         --  and homonym chains.

         Restore_Chains
           (From => First_Entity (Lim_Header),
            Upto => First_Private_Entity (Lim_Header));

         --  Reinstate the types that were hidden by the shadow entities back
         --  into direct visibility.

         Restore_Type_Visibility
           (From => First_Entity (Pack_Id),
            Upto => First_Private_Entity (Pack_Id));
      end Remove_Shadow_Entities_With_Restore;

      --  Local variables

      Pack_Id : constant Entity_Id := Defining_Entity (Pack_Decl);

   --  Start of processing for Remove_Limited_With_Unit

   begin
      --  Nothing to do when the limited view of the package is not installed

      if not From_Limited_With (Pack_Id) then
         return;
      end if;

      if Debug_Flag_I then
         Write_Str ("remove limited view of ");
         Write_Name (Chars (Pack_Id));
         Write_Str (" from visibility");
         Write_Eol;
      end if;

      --  The package already appears in the compilation closure. As a result,
      --  its shadow entities must be replaced by the real entities they hide
      --  and the previously hidden entities must be entered back into direct
      --  visibility.

      --  WARNING: This code must be kept synchronized with that of routine
      --  Install_Limited_Withed_Clause.

      if Analyzed (Pack_Decl) then
         Remove_Shadow_Entities_With_Restore (Pack_Id);

      --  Otherwise the package is not analyzed and its shadow entities must be
      --  removed from direct visibility.

      else
         Remove_Shadow_Entities_From_Visibility (Pack_Id);
      end if;

      --  Indicate that the limited view of the package is not installed

      Set_From_Limited_With (Pack_Id, False);
   end Remove_Limited_With_Unit;

   --------------------
   -- Remove_Parents --
   --------------------

   procedure Remove_Parents (Lib_Unit : Node_Id) is
      P      : Node_Id;
      P_Name : Entity_Id;
      P_Spec : Node_Id := Empty;
      E      : Entity_Id;
      Vis    : constant Boolean :=
                 Scope_Stack.Table (Scope_Stack.Last).Previous_Visibility;

   begin
      if Is_Child_Spec (Lib_Unit) then
         P_Spec := Parent_Spec (Lib_Unit);

      elsif Nkind (Lib_Unit) = N_Package_Body
        and then Nkind (Original_Node (Lib_Unit)) = N_Package_Instantiation
      then
         P_Spec := Parent_Spec (Original_Node (Lib_Unit));
      end if;

      if Present (P_Spec) then
         P := Unit (P_Spec);
         P_Name := Get_Parent_Entity (P);
         Remove_Context_Clauses (P_Spec);
         End_Package_Scope (P_Name);
         Set_Is_Immediately_Visible (P_Name, Vis);

         --  Remove from visibility the siblings as well, which are directly
         --  visible while the parent is in scope.

         E := First_Entity (P_Name);
         while Present (E) loop
            if Is_Child_Unit (E) then
               Set_Is_Immediately_Visible (E, False);
            end if;

            Next_Entity (E);
         end loop;

         Set_In_Package_Body (P_Name, False);

         --  This is the recursive call to remove the context of any higher
         --  level parent. This recursion ensures that all parents are removed
         --  in the reverse order of their installation.

         Remove_Parents (P);
      end if;
   end Remove_Parents;

   ---------------------------------
   -- Remove_Private_With_Clauses --
   ---------------------------------

   procedure Remove_Private_With_Clauses (Comp_Unit : Node_Id) is
      Item : Node_Id;

      function In_Regular_With_Clause (E : Entity_Id) return Boolean;
      --  Check whether a given unit appears in a regular with_clause. Used to
      --  determine whether a private_with_clause, implicit or explicit, should
      --  be ignored.

      ----------------------------
      -- In_Regular_With_Clause --
      ----------------------------

      function In_Regular_With_Clause (E : Entity_Id) return Boolean is
         Item : Node_Id;

      begin
         Item := First (Context_Items (Comp_Unit));

         while Present (Item) loop
            if Nkind (Item) = N_With_Clause

              --  The following guard is needed to ensure that the name has
              --  been properly analyzed before we go fetching its entity.

              and then Is_Entity_Name (Name (Item))
              and then Entity (Name (Item)) = E
              and then not Private_Present (Item)
            then
               return True;
            end if;

            Next (Item);
         end loop;

         return False;
      end In_Regular_With_Clause;

   --  Start of processing for Remove_Private_With_Clauses

   begin
      Item := First (Context_Items (Comp_Unit));
      while Present (Item) loop
         if Nkind (Item) = N_With_Clause and then Private_Present (Item) then

            --  If private_with_clause is redundant, remove it from context,
            --  as a small optimization to subsequent handling of private_with
            --  clauses in other nested packages. We replace the clause with
            --  a null statement, which is otherwise ignored by the rest of
            --  the compiler.

            if In_Regular_With_Clause (Entity (Name (Item))) then
               declare
                  Nxt : constant Node_Id := Next (Item);
               begin
                  Rewrite (Item, Make_Null_Statement (Sloc (Item)));
                  Analyze (Item);
                  Item := Nxt;
               end;

            elsif Limited_Present (Item) then
               if not Limited_View_Installed (Item) then
                  Remove_Limited_With_Clause (Item);
               end if;

               Next (Item);

            else
               Remove_Unit_From_Visibility (Entity (Name (Item)));
               Set_Context_Installed (Item, False);
               Next (Item);
            end if;

         else
            Next (Item);
         end if;
      end loop;
   end Remove_Private_With_Clauses;

   ---------------------------------
   -- Remove_Unit_From_Visibility --
   ---------------------------------

   procedure Remove_Unit_From_Visibility (Unit_Name : Entity_Id) is
   begin
      if Debug_Flag_I then
         Write_Str ("remove unit ");
         Write_Name (Chars (Unit_Name));
         Write_Str (" from visibility");
         Write_Eol;
      end if;

      Set_Is_Visible_Lib_Unit        (Unit_Name, False);
      Set_Is_Potentially_Use_Visible (Unit_Name, False);
      Set_Is_Immediately_Visible     (Unit_Name, False);

      --  If the unit is a wrapper package, the subprogram instance is
      --  what must be removed from visibility.
      --  Should we use Related_Instance instead???

      if Is_Wrapper_Package (Unit_Name) then
         Set_Is_Immediately_Visible (Current_Entity (Unit_Name), False);
      end if;
   end Remove_Unit_From_Visibility;

   --------
   -- sm --
   --------

   procedure sm is
   begin
      null;
   end sm;

   -------------
   -- Unchain --
   -------------

   procedure Unchain (E : Entity_Id) is
      Prev : Entity_Id;

   begin
      Prev := Current_Entity (E);

      if No (Prev) then
         return;

      elsif Prev = E then
         Set_Name_Entity_Id (Chars (E), Homonym (E));

      else
         while Present (Prev) and then Homonym (Prev) /= E loop
            Prev := Homonym (Prev);
         end loop;

         if Present (Prev) then
            Set_Homonym (Prev, Homonym (E));
         end if;
      end if;

      if Debug_Flag_I then
         Write_Str ("   (homonym) unchain ");
         Write_Name (Chars (E));
         Write_Eol;
      end if;
   end Unchain;

end Sem_Ch10;
