------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                B I N D E                                 --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2023, 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 Binderr; use Binderr;
with Butil;   use Butil;
with Debug;   use Debug;
with Fname;   use Fname;
with Opt;     use Opt;
with Osint;
with Output;  use Output;
with Table;
with Types;   use Types;

with System.Case_Util; use System.Case_Util;
with System.HTable;

package body Binde is
   use Unit_Id_Tables;

   --  We now have Elab_New, a new elaboration-order algorithm.
   --
   --  However, any change to elaboration order can break some programs.
   --  Therefore, we are keeping the old algorithm in place, to be selected
   --  by switches.
   --
   --  The new algorithm has the following interesting properties:
   --
   --    * The static and dynamic models use the same elaboration order. The
   --      static model might get an error, but if it does not, it will use
   --      the same order as the dynamic model.
   --
   --    * Each SCC (see below) is elaborated together; that is, units from
   --      different SCCs are not interspersed.
   --
   --    * In particular, this implies that if an SCC contains just a spec and
   --      the corresponding body, and nothing else, the body will be
   --      elaborated immediately after the spec. This is expected to result
   --      in a better elaboration order for most programs, because in this
   --      case, a call from outside the library unit cannot get ABE.
   --
   --    * Pragmas Elaborate_All (explicit and implicit) are ignored. Instead,
   --      we behave as if every legal pragma Elaborate_All were present. That
   --      is, if it would be legal to have "pragma Elaborate_All(Y);" on X,
   --      then we behave as if such a pragma exists, even if it does not.

   Do_Old : constant Boolean := False;
   Do_New : constant Boolean := True;
   --  True to enable the old and new algorithms, respectively. Used for
   --  debugging/experimentation.

   Doing_New : Boolean := False;
   --  True if we are currently doing the new algorithm. Print certain
   --  messages only when doing the "new" elab order algorithm, so we don't get
   --  duplicates. And use different heuristics in Better_Choice_Optimistic.

   --  The following data structures are used to represent the graph that is
   --  used to determine the elaboration order (using a topological sort).

   --  The following structures are used to record successors. If B is a
   --  successor of A in this table, it means that A must be elaborated before
   --  B is elaborated. For example, if Y (body) says "with X;", then Y (body)
   --  will be a successor of X (spec), and X (spec) will be a predecessor of
   --  Y (body).
   --
   --  Note that we store the successors of each unit explicitly. We don't
   --  store the predecessors, but we store a count of them.
   --
   --  The basic algorithm is to first compute a directed graph of units (type
   --  Unit_Node_Record, below), with successors as edges. A unit is "ready"
   --  (to be chosen as the next to be elaborated) if it has no predecessors
   --  that have not yet been chosen. We use heuristics to decide which of the
   --  ready units should be elaborated next, and "choose" that one (which
   --  means we append it to the elaboration-order table).

   type Successor_Id is new Nat;
   --  Identification of single successor entry

   No_Successor : constant Successor_Id := 0;
   --  Used to indicate end of list of successors

   type Elab_All_Id is new Nat;
   --  Identification of Elab_All entry link

   No_Elab_All_Link : constant Elab_All_Id := 0;
   --  Used to indicate end of list

   --  Succ_Reason indicates the reason for a particular elaboration link

   type Succ_Reason is
     (Withed,
      --  After directly with's Before, so the spec of Before must be
      --  elaborated before After is elaborated.

      Forced,
      --  Before and After come from a pair of lines in the forced-elaboration-
      --  order file.

      Elab,
      --  After directly mentions Before in a pragma Elaborate, so the body of
      --  Before must be elaborated before After is elaborated.

      Elab_All,
      --  After either mentions Before directly in a pragma Elaborate_All, or
      --  mentions a third unit, X, which itself requires that Before be
      --  elaborated before unit X is elaborated. The Elab_All_Link list traces
      --  the dependencies in the latter case.

      Elab_All_Desirable,
      --  This is just like Elab_All, except that the Elaborate_All was not
      --  explicitly present in the source, but rather was created by the front
      --  end, which decided that it was "desirable".

      Elab_Desirable,
      --  This is just like Elab, except that the Elaborate was not explicitly
      --  present in the source, but rather was created by the front end, which
      --  decided that it was "desirable".

      Spec_First);
      --  After is a body, and Before is the corresponding spec

   --  Successor_Link contains the information for one link

   type Successor_Link is record
      Before : Unit_Id;
      --  Predecessor unit

      After : Unit_Id;
      --  Successor unit

      Next : Successor_Id;
      --  Next successor on this list

      Reason : Succ_Reason;
      --  Reason for this link

      Elab_Body : Boolean;
      --  Set True if this link is needed for the special Elaborate_Body
      --  processing described below.

      Reason_Unit : Unit_Id;
      --  For Reason = Elab, or Elab_All or Elab_Desirable, records the unit
      --  containing the pragma leading to the link.

      Elab_All_Link : Elab_All_Id;
      --  If Reason = Elab_All or Elab_Desirable, then this points to the
      --  first element in a list of Elab_All entries that record the with
      --  chain resulting in this particular dependency.
   end record;

   --  Note on handling of Elaborate_Body. Basically, if we have a pragma
   --  Elaborate_Body in a unit, it means that the spec and body have to be
   --  handled as a single entity from the point of view of determining an
   --  elaboration order. What we do is to essentially remove the body from
   --  consideration completely, and transfer all its links (other than the
   --  spec link) to the spec. Then when the spec gets chosen, we choose the
   --  body right afterwards. We mark the links that get moved from the body to
   --  the spec by setting their Elab_Body flag True, so that we can understand
   --  what is going on.

   Succ_First : constant := 1;

   package Succ is new Table.Table
     (Table_Component_Type => Successor_Link,
      Table_Index_Type     => Successor_Id,
      Table_Low_Bound      => Succ_First,
      Table_Initial        => 500,
      Table_Increment      => 200,
      Table_Name           => "Succ");

   --  For the case of Elaborate_All, the following table is used to record
   --  chains of with relationships that lead to the Elab_All link. These are
   --  used solely for diagnostic purposes

   type Elab_All_Entry is record
      Needed_By : Unit_Name_Type;
      --  Name of unit from which referencing unit was with'ed or otherwise
      --  needed as a result of Elaborate_All or Elaborate_Desirable.

      Next_Elab : Elab_All_Id;
      --  Link to next entry on chain (No_Elab_All_Link marks end of list)
   end record;

   package Elab_All_Entries is new Table.Table
     (Table_Component_Type => Elab_All_Entry,
      Table_Index_Type     => Elab_All_Id,
      Table_Low_Bound      => 1,
      Table_Initial        => 2000,
      Table_Increment      => 200,
      Table_Name           => "Elab_All_Entries");

   type Unit_Id_Array_Ptr is access Unit_Id_Array;

   --  A Unit_Node_Record is built for each active unit

   type Unit_Node_Record is record
      Successors : Successor_Id;
      --  Pointer to list of links for successor nodes

      Num_Pred : Int;
      --  Number of predecessors for this unit that have not yet been chosen.
      --  Normally non-negative, but can go negative in the case of units
      --  chosen by the diagnose error procedure (when cycles are being removed
      --  from the graph).

      Nextnp : Unit_Id;
      --  Forward pointer for list of units with no predecessors

      Visited : Boolean;
      --  Used in computing transitive closure for Elaborate_All and also in
      --  locating cycles and paths in the diagnose routines.

      Elab_Position : Nat;
      --  Initialized to zero. Set non-zero when a unit is chosen and placed in
      --  the elaboration order. The value represents the ordinal position in
      --  the elaboration order.

      --  The following are for Elab_New. We compute the strongly connected
      --  components (SCCs) of the directed graph of units. The edges are the
      --  Successors, which do not include pragmas Elaborate_All (explicit or
      --  implicit) in Elab_New. In addition, we assume there is a edge
      --  pointing from a body to its corresponding spec; this edge is not
      --  included in Successors, because of course a spec is elaborated BEFORE
      --  its body, not after.

      SCC_Root : Unit_Id;
      --  Each unit points to the root of its SCC, which is just an arbitrary
      --  member of the SCC. Two units are in the same SCC if and only if their
      --  SCC_Roots are equal. U is the root of its SCC if and only if
      --  SCC(U)=U.

      Nodes : Unit_Id_Array_Ptr;
      --  Present only in the root of an SCC. This is the set of units in the
      --  SCC, in no particular order.

      SCC_Num_Pred : Int;
      --  Present only in the root of an SCC. This is the number of predecessor
      --  units of the SCC that are in other SCCs, and that have not yet been
      --  chosen.

      Validate_Seen : Boolean := False;
      --  See procedure Validate below
   end record;

   package UNR is new Table.Table
     (Table_Component_Type => Unit_Node_Record,
      Table_Index_Type     => Unit_Id,
      Table_Low_Bound      => First_Unit_Entry,
      Table_Initial        => 500,
      Table_Increment      => 200,
      Table_Name           => "UNR");

   No_Pred : Unit_Id;
   --  Head of list of items with no predecessors

   Num_Left : Int;
   --  Number of entries not yet dealt with

   Cur_Unit : Unit_Id;
   --  Current unit, set by Gather_Dependencies, and picked up in Build_Link to
   --  set the Reason_Unit field of the created dependency link.

   Num_Chosen : Nat;
   --  Number of units chosen in the elaboration order so far

   Diagnose_Elaboration_Problem_Called : Boolean := False;
   --  True if Diagnose_Elaboration_Problem was called. Used in an assertion.

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

   function Debug_Flag_Older return Boolean;
   function Debug_Flag_Old return Boolean;
   --  True if debug flags select the old or older algorithms. Pretty much any
   --  change to elaboration order can break some programs. For example,
   --  programs can depend on elaboration order even without failing
   --  access-before-elaboration checks. A trivial example is a program that
   --  prints text during elaboration. Therefore, we have flags to revert to
   --  the old(er) algorithms.

   procedure Validate (Order : Unit_Id_Array; Doing_New : Boolean);
   --  Assert that certain properties are true

   function Better_Choice_Optimistic
     (U1 : Unit_Id;
      U2 : Unit_Id) return Boolean;
   --  U1 and U2 are both permitted candidates for selection as the next unit
   --  to be elaborated. This function determines whether U1 is a better choice
   --  than U2, i.e. should be elaborated in preference to U2, based on a set
   --  of heuristics that establish a friendly and predictable order (see body
   --  for details). The result is True if U1 is a better choice than U2, and
   --  False if it is a worse choice, or there is no preference between them.

   function Better_Choice_Pessimistic
     (U1 : Unit_Id;
      U2 : Unit_Id) return Boolean;
   --  This is like Better_Choice_Optimistic, and has the same interface, but
   --  returns true if U1 is a worse choice than U2 in the sense of the -p
   --  (pessimistic elaboration order) switch. We still have to obey Ada rules,
   --  so it is not quite the direct inverse of Better_Choice_Optimistic.

   function Better_Choice (U1 : Unit_Id; U2 : Unit_Id) return Boolean;
   --  Calls Better_Choice_Optimistic or Better_Choice_Pessimistic as
   --  appropriate. Also takes care of the U2 = No_Unit_Id case.

   procedure Build_Link
     (Before : Unit_Id;
      After  : Unit_Id;
      R      : Succ_Reason;
      Ea_Id  : Elab_All_Id := No_Elab_All_Link);
   --  Establish a successor link, Before must be elaborated before After, and
   --  the reason for the link is R. Ea_Id is the contents to be placed in the
   --  Elab_All_Link of the entry.

   procedure Choose
     (Elab_Order : in out Unit_Id_Table;
      Chosen     : Unit_Id;
      Msg        : String);
   --  Chosen is the next entry chosen in the elaboration order. This procedure
   --  updates all data structures appropriately.

   function Corresponding_Body (U : Unit_Id) return Unit_Id;
   pragma Inline (Corresponding_Body);
   --  Given a unit that is a spec for which there is a separate body, return
   --  the unit id of the body. It is an error to call this routine with a unit
   --  that is not a spec, or that does not have a separate body.

   function Corresponding_Spec (U : Unit_Id) return Unit_Id;
   pragma Inline (Corresponding_Spec);
   --  Given a unit that is a body for which there is a separate spec, return
   --  the unit id of the spec. It is an error to call this routine with a unit
   --  that is not a body, or that does not have a separate spec.

   procedure Diagnose_Elaboration_Problem
     (Elab_Order : in out Unit_Id_Table);
   pragma No_Return (Diagnose_Elaboration_Problem);
   --  Called when no elaboration order can be found. Outputs an appropriate
   --  diagnosis of the problem, and then abandons the bind.

   procedure Elab_All_Links
     (Before : Unit_Id;
      After  : Unit_Id;
      Reason : Succ_Reason;
      Link   : Elab_All_Id);
   --  Used to compute the transitive closure of elaboration links for an
   --  Elaborate_All pragma (Reason = Elab_All) or for an indication of
   --  Elaborate_All_Desirable (Reason = Elab_All_Desirable). Unit After has a
   --  pragma Elaborate_All or the front end has determined that a reference
   --  probably requires Elaborate_All, and unit Before must be previously
   --  elaborated. First a link is built making sure that unit Before is
   --  elaborated before After, then a recursive call ensures that we also
   --  build links for any units needed by Before (i.e. these units must/should
   --  also be elaborated before After). Link is used to build a chain of
   --  Elab_All_Entries to explain the reason for a link. The value passed is
   --  the chain so far.

   procedure Elab_Error_Msg (S : Successor_Id);
   --  Given a successor link, outputs an error message of the form
   --  "$ must be elaborated before $ ..." where ... is the reason.

   procedure Force_Elab_Order;
   --  Gather dependencies from the forced-elaboration-order file (-f switch)

   procedure Gather_Dependencies;
   --  Compute dependencies, building the Succ and UNR tables

   procedure Init;
   --  Initialize global data structures in this package body

   function Is_Body_Unit (U : Unit_Id) return Boolean;
   pragma Inline (Is_Body_Unit);
   --  Determines if given unit is a body

   function Is_Pure_Or_Preelab_Unit (U : Unit_Id) return Boolean;
   --  Returns True if corresponding unit is Pure or Preelaborate. Includes
   --  dealing with testing flags on spec if it is given a body.

   function Is_Waiting_Body (U : Unit_Id) return Boolean;
   pragma Inline (Is_Waiting_Body);
   --  Determines if U is a waiting body, defined as a body that has
   --  not been elaborated, but whose spec has been elaborated.

   function Make_Elab_All_Entry
     (Unam : Unit_Name_Type;
      Link : Elab_All_Id) return Elab_All_Id;
   --  Make an Elab_All_Entries table entry with the given Unam and Link

   function Unit_Id_Of (Uname : Unit_Name_Type) return Unit_Id;
   --  This function uses the Info field set in the names table to obtain
   --  the unit Id of a unit, given its name id value.

   procedure Write_Closure (Order : Unit_Id_Array);
   --  Write the closure. This is for the -R and -Ra switches, "list closure
   --  display".

   procedure Write_Dependencies;
   --  Write out dependencies (called only if appropriate option is set)

   procedure Write_Elab_All_Chain (S : Successor_Id);
   --  If the reason for the link S is Elaborate_All or Elaborate_Desirable,
   --  then this routine will output the "needed by" explanation chain.

   procedure Write_Elab_Order (Order : Unit_Id_Array; Title : String);
   --  Display elaboration order. This is for the -l switch. Title is a heading
   --  to print; an empty string is passed to indicate Zero_Formatting.

   package Elab_New is

      --  Implementation of the new algorithm

      procedure Write_SCC (U : Unit_Id);
      --  Write the unit names of the units in the SCC in which U lives

      procedure Find_Elab_Order (Elab_Order : out Unit_Id_Table);

      Elab_Cycle_Found : Boolean := False;
      --  Set True if Find_Elab_Order found a cycle (usually an illegal pragma
      --  Elaborate_All, explicit or implicit).

      function SCC (U : Unit_Id) return Unit_Id;
      --  The root of the strongly connected component containing U

      function SCC_Num_Pred (U : Unit_Id) return Int;
      --  The SCC_Num_Pred of the SCC in which U lives

      function Nodes (U : Unit_Id) return Unit_Id_Array_Ptr;
      --  The nodes of the strongly connected component containing U

   end Elab_New;

   use Elab_New;

   package Elab_Old is

      --  Implementation of the old algorithm

      procedure Find_Elab_Order (Elab_Order : out Unit_Id_Table);

   end Elab_Old;

   --  Most of the code is shared between old and new; such code is outside
   --  packages Elab_Old and Elab_New.

   -------------------
   -- Better_Choice --
   -------------------

   function Better_Choice (U1 : Unit_Id; U2 : Unit_Id) return Boolean is
      pragma Assert (U1 /= No_Unit_Id);
   begin
      if U2 = No_Unit_Id then
         return True;
      end if;

      if Pessimistic_Elab_Order then
         return Better_Choice_Pessimistic (U1, U2);
      else
         return Better_Choice_Optimistic (U1, U2);
      end if;
   end Better_Choice;

   ------------------------------
   -- Better_Choice_Optimistic --
   ------------------------------

   function Better_Choice_Optimistic
     (U1 : Unit_Id;
      U2 : Unit_Id) return Boolean
   is
      UT1 : Unit_Record renames Units.Table (U1);
      UT2 : Unit_Record renames Units.Table (U2);

   begin
      if Debug_Flag_B then
         Write_Str ("Better_Choice_Optimistic (");
         Write_Unit_Name (UT1.Uname);
         Write_Str (", ");
         Write_Unit_Name (UT2.Uname);
         Write_Line (")");
      end if;

      --  Note: the checks here are applied in sequence, and the ordering is
      --  significant (i.e. the more important criteria are applied first).

      --  Prefer a waiting body to one that is not a waiting body

      if Is_Waiting_Body (U1) and then not Is_Waiting_Body (U2) then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is waiting body, u2 is not");
         end if;

         return True;

      elsif Is_Waiting_Body (U2) and then not Is_Waiting_Body (U1) then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is waiting body, u1 is not");
         end if;

         return False;

      --  Prefer a predefined unit to a non-predefined unit

      elsif UT1.Predefined and then not UT2.Predefined then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is predefined, u2 is not");
         end if;

         return True;

      elsif UT2.Predefined and then not UT1.Predefined then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is predefined, u1 is not");
         end if;

         return False;

      --  Prefer an internal unit to a non-internal unit

      elsif UT1.Internal and then not UT2.Internal then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is internal, u2 is not");
         end if;
         return True;

      elsif UT2.Internal and then not UT1.Internal then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is internal, u1 is not");
         end if;

         return False;

      --  Prefer a pure or preelaborated unit to one that is not. Pure should
      --  come before preelaborated.

      elsif Is_Pure_Or_Preelab_Unit (U1)
              and then not
            Is_Pure_Or_Preelab_Unit (U2)
      then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is pure/preelab, u2 is not");
         end if;

         return True;

      elsif Is_Pure_Or_Preelab_Unit (U2)
              and then not
            Is_Pure_Or_Preelab_Unit (U1)
      then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is pure/preelab, u1 is not");
         end if;

         return False;

      --  Prefer a body to a spec

      elsif Is_Body_Unit (U1) and then not Is_Body_Unit (U2) then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is body, u2 is not");
         end if;

         return True;

      elsif Is_Body_Unit (U2) and then not Is_Body_Unit (U1) then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is body, u1 is not");
         end if;

         return False;

      --  If both are waiting bodies, then prefer the one whose spec is more
      --  recently elaborated. Consider the following:

      --     spec of A
      --     spec of B
      --     body of A or B?

      --  The normal waiting body preference would have placed the body of A
      --  before the spec of B if it could. Since it could not, then it must be
      --  the case that A depends on B. It is therefore a good idea to put the
      --  body of B first.

      elsif Is_Waiting_Body (U1) and then Is_Waiting_Body (U2) then
         declare
            Result : constant Boolean :=
                       UNR.Table (Corresponding_Spec (U1)).Elab_Position >
                       UNR.Table (Corresponding_Spec (U2)).Elab_Position;
         begin
            if Debug_Flag_B then
               if Result then
                  Write_Line ("  True: based on waiting body elab positions");
               else
                  Write_Line ("  False: based on waiting body elab positions");
               end if;
            end if;

            return Result;
         end;
      end if;

      --  Remaining choice rules are disabled by Debug flag -do

      if not Debug_Flag_Older then

         --  The following deal with the case of specs that have been marked
         --  as Elaborate_Body_Desirable. We generally want to delay these
         --  specs as long as possible, so that the bodies have a better chance
         --  of being elaborated closer to the specs.

         --  If we have two units, one of which is a spec for which this flag
         --  is set, and the other is not, we prefer to delay the spec for
         --  which the flag is set.

         if not UT1.Elaborate_Body_Desirable
           and then UT2.Elaborate_Body_Desirable
         then
            if Debug_Flag_B then
               Write_Line ("  True: u1 is elab body desirable, u2 is not");
            end if;

            return True;

         elsif not UT2.Elaborate_Body_Desirable
           and then UT1.Elaborate_Body_Desirable
         then
            if Debug_Flag_B then
               Write_Line ("  False: u1 is elab body desirable, u2 is not");
            end if;

            return False;

            --  If we have two specs that are both marked as Elaborate_Body
            --  desirable, we prefer the one whose body is nearer to being able
            --  to be elaborated, based on the Num_Pred count. This helps to
            --  ensure bodies are as close to specs as possible.

         elsif UT1.Elaborate_Body_Desirable
           and then UT2.Elaborate_Body_Desirable
         then
            declare
               Result : constant Boolean :=
                          UNR.Table (Corresponding_Body (U1)).Num_Pred <
                          UNR.Table (Corresponding_Body (U2)).Num_Pred;
            begin
               if Debug_Flag_B then
                  if Result then
                     Write_Line ("  True based on Num_Pred compare");
                  else
                     Write_Line ("  False based on Num_Pred compare");
                  end if;
               end if;

               return Result;
            end;
         end if;
      end if;

      --  If we have two specs in the same SCC, choose the one whose body is
      --  closer to being ready.

      if Doing_New
        and then SCC (U1) = SCC (U2)
        and then Units.Table (U1).Utype = Is_Spec
        and then Units.Table (U2).Utype = Is_Spec
        and then UNR.Table (Corresponding_Body (U1)).Num_Pred /=
                 UNR.Table (Corresponding_Body (U2)).Num_Pred
      then
         if UNR.Table (Corresponding_Body (U1)).Num_Pred <
           UNR.Table (Corresponding_Body (U2)).Num_Pred
         then
            if Debug_Flag_B then
               Write_Str ("  True: same SCC; ");
               Write_Int (UNR.Table (Corresponding_Body (U1)).Num_Pred);
               Write_Str (" < ");
               Write_Int (UNR.Table (Corresponding_Body (U2)).Num_Pred);
               Write_Eol;
            end if;

            return True;
         else
            if Debug_Flag_B then
               Write_Str ("  False: same SCC; ");
               Write_Int (UNR.Table (Corresponding_Body (U1)).Num_Pred);
               Write_Str (" > ");
               Write_Int (UNR.Table (Corresponding_Body (U2)).Num_Pred);
               Write_Eol;
            end if;

            return False;
         end if;
      end if;

      --  If we fall through, it means that no preference rule applies, so we
      --  use alphabetical order to at least give a deterministic result.

      if Debug_Flag_B then
         Write_Line ("  choose on alpha order");
      end if;

      return Uname_Less (UT1.Uname, UT2.Uname);
   end Better_Choice_Optimistic;

   -------------------------------
   -- Better_Choice_Pessimistic --
   -------------------------------

   function Better_Choice_Pessimistic
     (U1 : Unit_Id;
      U2 : Unit_Id) return Boolean
   is
      UT1 : Unit_Record renames Units.Table (U1);
      UT2 : Unit_Record renames Units.Table (U2);

   begin
      if Debug_Flag_B then
         Write_Str ("Better_Choice_Pessimistic (");
         Write_Unit_Name (UT1.Uname);
         Write_Str (", ");
         Write_Unit_Name (UT2.Uname);
         Write_Line (")");
      end if;

      --  Note: the checks here are applied in sequence, and the ordering is
      --  significant (i.e. the more important criteria are applied first).

      --  If either unit is predefined or internal, then we use the normal
      --  Better_Choice_Optimistic rule, since we don't want to disturb the
      --  elaboration rules of the language with -p; same treatment for
      --  Pure/Preelab.

      --  Prefer a predefined unit to a non-predefined unit

      if UT1.Predefined and then not UT2.Predefined then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is predefined, u2 is not");
         end if;

         return True;

      elsif UT2.Predefined and then not UT1.Predefined then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is predefined, u1 is not");
         end if;

         return False;

      --  Prefer an internal unit to a non-internal unit

      elsif UT1.Internal and then not UT2.Internal then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is internal, u2 is not");
         end if;

         return True;

      elsif UT2.Internal and then not UT1.Internal then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is internal, u1 is not");
         end if;

         return False;

      --  Prefer a pure or preelaborated unit to one that is not

      elsif Is_Pure_Or_Preelab_Unit (U1)
              and then not
            Is_Pure_Or_Preelab_Unit (U2)
      then
         if Debug_Flag_B then
            Write_Line ("  True: u1 is pure/preelab, u2 is not");
         end if;

         return True;

      elsif Is_Pure_Or_Preelab_Unit (U2)
              and then not
            Is_Pure_Or_Preelab_Unit (U1)
      then
         if Debug_Flag_B then
            Write_Line ("  False: u2 is pure/preelab, u1 is not");
         end if;

         return False;

      --  Prefer anything else to a waiting body. We want to make bodies wait
      --  as long as possible, till we are forced to choose them.

      elsif Is_Waiting_Body (U1) and then not Is_Waiting_Body (U2) then
         if Debug_Flag_B then
            Write_Line ("  False: u1 is waiting body, u2 is not");
         end if;

         return False;

      elsif Is_Waiting_Body (U2) and then not Is_Waiting_Body (U1) then
         if Debug_Flag_B then
            Write_Line ("  True: u2 is waiting body, u1 is not");
         end if;

         return True;

      --  Prefer a spec to a body (this is mandatory)

      elsif Is_Body_Unit (U1) and then not Is_Body_Unit (U2) then
         if Debug_Flag_B then
            Write_Line ("  False: u1 is body, u2 is not");
         end if;

         return False;

      elsif Is_Body_Unit (U2) and then not Is_Body_Unit (U1) then
         if Debug_Flag_B then
            Write_Line ("  True: u2 is body, u1 is not");
         end if;

         return True;

      --  If both are waiting bodies, then prefer the one whose spec is less
      --  recently elaborated. Consider the following:

      --     spec of A
      --     spec of B
      --     body of A or B?

      --  The normal waiting body preference would have placed the body of A
      --  before the spec of B if it could. Since it could not, then it must be
      --  the case that A depends on B. It is therefore a good idea to put the
      --  body of B last so that if there is an elaboration order problem, we
      --  will find it (that's what pessimistic order is about).

      elsif Is_Waiting_Body (U1) and then Is_Waiting_Body (U2) then
         declare
            Result : constant Boolean :=
                       UNR.Table (Corresponding_Spec (U1)).Elab_Position <
                       UNR.Table (Corresponding_Spec (U2)).Elab_Position;
         begin
            if Debug_Flag_B then
               if Result then
                  Write_Line ("  True: based on waiting body elab positions");
               else
                  Write_Line ("  False: based on waiting body elab positions");
               end if;
            end if;

            return Result;
         end;
      end if;

      --  Remaining choice rules are disabled by Debug flag -do

      if not Debug_Flag_Older then

         --  The following deal with the case of specs that have been marked as
         --  Elaborate_Body_Desirable. In the normal case, we generally want to
         --  delay the elaboration of these specs as long as possible, so that
         --  bodies have better chance of being elaborated closer to the specs.
         --  Better_Choice_Pessimistic as usual wants to do the opposite and
         --  elaborate such specs as early as possible.

         --  If we have two units, one of which is a spec for which this flag
         --  is set, and the other is not, we normally prefer to delay the spec
         --  for which the flag is set, so again Better_Choice_Pessimistic does
         --  the opposite.

         if not UT1.Elaborate_Body_Desirable
           and then UT2.Elaborate_Body_Desirable
         then
            if Debug_Flag_B then
               Write_Line ("  False: u1 is elab body desirable, u2 is not");
            end if;

            return False;

         elsif not UT2.Elaborate_Body_Desirable
           and then UT1.Elaborate_Body_Desirable
         then
            if Debug_Flag_B then
               Write_Line ("  True: u1 is elab body desirable, u2 is not");
            end if;

            return True;

            --  If we have two specs that are both marked as Elaborate_Body
            --  desirable, we normally prefer the one whose body is nearer to
            --  being able to be elaborated, based on the Num_Pred count. This
            --  helps to ensure bodies are as close to specs as possible. As
            --  usual, Better_Choice_Pessimistic does the opposite.

         elsif UT1.Elaborate_Body_Desirable
           and then UT2.Elaborate_Body_Desirable
         then
            declare
               Result : constant Boolean :=
                          UNR.Table (Corresponding_Body (U1)).Num_Pred >=
                          UNR.Table (Corresponding_Body (U2)).Num_Pred;
            begin
               if Debug_Flag_B then
                  if Result then
                     Write_Line ("  True based on Num_Pred compare");
                  else
                     Write_Line ("  False based on Num_Pred compare");
                  end if;
               end if;

               return Result;
            end;
         end if;
      end if;

      --  If we fall through, it means that no preference rule applies, so we
      --  use alphabetical order to at least give a deterministic result. Since
      --  Better_Choice_Pessimistic is in the business of stirring up the
      --  order, we will use reverse alphabetical ordering.

      if Debug_Flag_B then
         Write_Line ("  choose on reverse alpha order");
      end if;

      return Uname_Less (UT2.Uname, UT1.Uname);
   end Better_Choice_Pessimistic;

   ----------------
   -- Build_Link --
   ----------------

   procedure Build_Link
     (Before : Unit_Id;
      After  : Unit_Id;
      R      : Succ_Reason;
      Ea_Id  : Elab_All_Id := No_Elab_All_Link)
   is
      Cspec : Unit_Id;

   begin
      Succ.Append
        ((Before        => Before,
          After         => No_Unit_Id, -- filled in below
          Next          => UNR.Table (Before).Successors,
          Reason        => R,
          Elab_Body     => False, -- set correctly below
          Reason_Unit   => Cur_Unit,
          Elab_All_Link => Ea_Id));
      UNR.Table (Before).Successors := Succ.Last;

      --  Deal with special Elab_Body case. If the After of this link is
      --  a body whose spec has Elaborate_All set, and this is not the link
      --  directly from the body to the spec, then we make the After of the
      --  link reference its spec instead, marking the link appropriately.

      if Units.Table (After).Utype = Is_Body then
         Cspec := Corresponding_Spec (After);

         if Units.Table (Cspec).Elaborate_Body
           and then Cspec /= Before
         then
            Succ.Table (Succ.Last).After     := Cspec;
            Succ.Table (Succ.Last).Elab_Body := True;
            UNR.Table (Cspec).Num_Pred       := UNR.Table (Cspec).Num_Pred + 1;
            return;
         end if;
      end if;

      --  Fall through on normal case

      Succ.Table (Succ.Last).After     := After;
      Succ.Table (Succ.Last).Elab_Body := False;
      UNR.Table (After).Num_Pred       := UNR.Table (After).Num_Pred + 1;
   end Build_Link;

   ------------
   -- Choose --
   ------------

   procedure Choose
     (Elab_Order : in out Unit_Id_Table;
      Chosen     : Unit_Id;
      Msg        : String)
   is
      pragma Assert (Chosen /= No_Unit_Id);
      S : Successor_Id;
      U : Unit_Id;

   begin
      if Debug_Flag_C then
         Write_Str ("Choosing Unit ");
         Write_Unit_Name (Units.Table (Chosen).Uname);
         Write_Str (Msg);
      end if;

      --  We shouldn't be choosing something with unelaborated predecessors,
      --  and we shouldn't call this twice on the same unit. But that's not
      --  true when this is called from Diagnose_Elaboration_Problem.

      if Errors_Detected = 0 then
         pragma Assert (UNR.Table (Chosen).Num_Pred = 0);
         pragma Assert (UNR.Table (Chosen).Elab_Position = 0);
         pragma Assert (not Doing_New or else SCC_Num_Pred (Chosen) = 0);
         null;
      end if;

      --  Add to elaboration order. Note that units having no elaboration code
      --  are not treated specially yet. The special casing of this is in
      --  Bindgen, where Gen_Elab_Calls skips over them. Meanwhile we need them
      --  here, because the object file list is also driven by the contents of
      --  the Elab_Order table.

      Append (Elab_Order, Chosen);

      --  Remove from No_Pred list. This is a little inefficient and may be we
      --  should doubly link the list, but it will do for now.

      if No_Pred = Chosen then
         No_Pred := UNR.Table (Chosen).Nextnp;
      else
         U := No_Pred;
         while U /= No_Unit_Id loop
            if UNR.Table (U).Nextnp = Chosen then
               UNR.Table (U).Nextnp := UNR.Table (Chosen).Nextnp;
               goto Done_Removal;
            end if;

            U := UNR.Table (U).Nextnp;
         end loop;

         --  Here if we didn't find it on the No_Pred list. This can happen
         --  only in calls from the Diagnose_Elaboration_Problem routine,
         --  where cycles are being removed arbitrarily from the graph.

         pragma Assert (Errors_Detected > 0);
         <<Done_Removal>> null;
      end if;

      --  For all successors, decrement the number of predecessors, and if it
      --  becomes zero, then add to no-predecessor list.

      S := UNR.Table (Chosen).Successors;
      pragma Annotate (CodePeer, Modified, S);

      while S /= No_Successor loop
         U := Succ.Table (S).After;
         UNR.Table (U).Num_Pred := UNR.Table (U).Num_Pred - 1;

         if Debug_Flag_N then
            Write_Str ("  decrementing Num_Pred for unit ");
            Write_Unit_Name (Units.Table (U).Uname);
            Write_Str (" new value = ");
            Write_Int (UNR.Table (U).Num_Pred);
            Write_Eol;
         end if;

         if UNR.Table (U).Num_Pred = 0 then
            UNR.Table (U).Nextnp := No_Pred;
            No_Pred := U;
         end if;

         if Doing_New and then SCC (U) /= SCC (Chosen) then
            UNR.Table (SCC (U)).SCC_Num_Pred :=
              UNR.Table (SCC (U)).SCC_Num_Pred - 1;

            if Debug_Flag_N then
               Write_Str ("  decrementing SCC_Num_Pred for unit ");
               Write_Unit_Name (Units.Table (U).Uname);
               Write_Str (" new value = ");
               Write_Int (SCC_Num_Pred (U));
               Write_Eol;
            end if;
         end if;

         S := Succ.Table (S).Next;
      end loop;

      --  All done, adjust number of units left count and set elaboration pos

      Num_Left   := Num_Left   - 1;
      Num_Chosen := Num_Chosen + 1;

      pragma Assert
        (Errors_Detected > 0 or else Num_Chosen = Last (Elab_Order));
      pragma Assert (Units.Last = UNR.Last);
      pragma Assert (Num_Chosen + Num_Left = Int (UNR.Last));

      if Debug_Flag_C then
         Write_Str (" ");
         Write_Int (Int (Num_Chosen));
         Write_Str ("+");
         Write_Int (Num_Left);
         Write_Str ("=");
         Write_Int (Int (UNR.Last));
         Write_Eol;
      end if;

      UNR.Table (Chosen).Elab_Position := Num_Chosen;

      --  If we just chose a spec with Elaborate_Body set, then we must
      --  immediately elaborate the body, before any other units.

      if Units.Table (Chosen).Elaborate_Body then

         --  If the unit is a spec only, then there is no body. This is a bit
         --  odd given that Elaborate_Body is here, but it is valid in an RCI
         --  unit, where we only have the interface in the stub bind.

         if Units.Table (Chosen).Utype = Is_Spec_Only
           and then Units.Table (Chosen).RCI
         then
            null;

         --  If this unit is an interface to a stand-alone library, then we
         --  don't want to elaborate the body -- that will happen as part of
         --  the library.

         elsif Units.Table (Chosen).SAL_Interface then
            null;

         else
            Choose
              (Elab_Order => Elab_Order,
               Chosen     => Corresponding_Body (Chosen),
               Msg        => " [Elaborate_Body]");
         end if;
      end if;
   end Choose;

   ------------------------
   -- Corresponding_Body --
   ------------------------

   --  Currently if the body and spec are separate, then they appear as two
   --  separate units in the same ALI file, with the body appearing first and
   --  the spec appearing second.

   function Corresponding_Body (U : Unit_Id) return Unit_Id is
   begin
      pragma Assert (Units.Table (U).Utype = Is_Spec);
      return U - 1;
   end Corresponding_Body;

   ------------------------
   -- Corresponding_Spec --
   ------------------------

   --  Currently if the body and spec are separate, then they appear as two
   --  separate units in the same ALI file, with the body appearing first and
   --  the spec appearing second.

   function Corresponding_Spec (U : Unit_Id) return Unit_Id is
   begin
      pragma Assert (Units.Table (U).Utype = Is_Body);
      return U + 1;
   end Corresponding_Spec;

   --------------------
   -- Debug_Flag_Old --
   --------------------

   function Debug_Flag_Old return Boolean is
   begin
      --  If the user specified both flags, we want to use the older algorithm,
      --  rather than some confusing mix of the two.

      return Debug_Flag_P and not Debug_Flag_O;
   end Debug_Flag_Old;

   ----------------------
   -- Debug_Flag_Older --
   ----------------------

   function Debug_Flag_Older return Boolean is
   begin
      return Debug_Flag_O;
   end Debug_Flag_Older;

   ----------------------------------
   -- Diagnose_Elaboration_Problem --
   ----------------------------------

   procedure Diagnose_Elaboration_Problem
     (Elab_Order : in out Unit_Id_Table)
   is
      function Find_Path
        (Ufrom : Unit_Id;
         Uto   : Unit_Id;
         ML    : Nat) return Boolean;
      --  Recursive routine used to find a path from node Ufrom to node Uto.
      --  If a path exists, returns True and outputs an appropriate set of
      --  error messages giving the path. Also calls Choose for each of the
      --  nodes so that they get removed from the remaining set. There are
      --  two cases of calls, either Ufrom = Uto for an attempt to find a
      --  cycle, or Ufrom is a spec and Uto the corresponding body for the
      --  case of an unsatisfiable Elaborate_Body pragma. ML is the minimum
      --  acceptable length for a path.

      ---------------
      -- Find_Path --
      ---------------

      function Find_Path
        (Ufrom : Unit_Id;
         Uto   : Unit_Id;
         ML    : Nat) return Boolean
      is
         function Find_Link (U : Unit_Id; PL : Nat) return Boolean;
         --  This is the inner recursive routine, it determines if a path
         --  exists from U to Uto, and if so returns True and outputs the
         --  appropriate set of error messages. PL is the path length

         ---------------
         -- Find_Link --
         ---------------

         function Find_Link (U : Unit_Id; PL : Nat) return Boolean is
            S : Successor_Id;

         begin
            --  Recursion ends if we are at terminating node and the path is
            --  sufficiently long, generate error message and return True.

            if U = Uto and then PL >= ML then
               Choose (Elab_Order, U, " [Find_Link: base]");
               return True;

            --  All done if already visited

            elsif UNR.Table (U).Visited then
               return False;

            --  Otherwise mark as visited and look at all successors

            else
               UNR.Table (U).Visited := True;

               S := UNR.Table (U).Successors;
               while S /= No_Successor loop
                  if Find_Link (Succ.Table (S).After, PL + 1) then
                     Elab_Error_Msg (S);
                     Choose (Elab_Order, U, " [Find_Link: recursive]");
                     return True;
                  end if;

                  S := Succ.Table (S).Next;
               end loop;

               --  Falling through means this does not lead to a path

               return False;
            end if;
         end Find_Link;

      --  Start of processing for Find_Path

      begin
         --  Initialize all non-chosen nodes to not visited yet

         for U in Units.First .. Units.Last loop
            UNR.Table (U).Visited := UNR.Table (U).Elab_Position /= 0;
         end loop;

         --  Now try to find the path

         return Find_Link (Ufrom, 0);
      end Find_Path;

   --  Start of processing for Diagnose_Elaboration_Problem

   begin
      Diagnose_Elaboration_Problem_Called := True;
      Set_Standard_Error;

      --  Output state of things if debug flag N set

      if Debug_Flag_N then
         declare
            NP : Int;

         begin
            Write_Eol;
            Write_Eol;
            Write_Line ("Diagnose_Elaboration_Problem called");
            Write_Line ("List of remaining unchosen units and predecessors");

            for U in Units.First .. Units.Last loop
               if UNR.Table (U).Elab_Position = 0 then
                  NP := UNR.Table (U).Num_Pred;
                  Write_Eol;
                  Write_Str ("  Unchosen unit: #");
                  Write_Int (Int (U));
                  Write_Str ("  ");
                  Write_Unit_Name (Units.Table (U).Uname);
                  Write_Str (" (Num_Pred = ");
                  Write_Int (NP);
                  Write_Line (")");

                  if NP = 0 then
                     if Units.Table (U).Elaborate_Body then
                        Write_Line
                          ("    (not chosen because of Elaborate_Body)");
                     else
                        Write_Line ("  ****************** why not chosen?");
                     end if;
                  end if;

                  --  Search links list to find unchosen predecessors

                  for S in Succ.First .. Succ.Last loop
                     declare
                        SL : Successor_Link renames Succ.Table (S);

                     begin
                        if SL.After = U
                          and then UNR.Table (SL.Before).Elab_Position = 0
                        then
                           Write_Str ("    unchosen predecessor: #");
                           Write_Int (Int (SL.Before));
                           Write_Str ("  ");
                           Write_Unit_Name (Units.Table (SL.Before).Uname);
                           Write_Eol;
                           NP := NP - 1;
                        end if;
                     end;
                  end loop;

                  if NP /= 0 then
                     Write_Line ("  **************** Num_Pred value wrong!");
                  end if;
               end if;
            end loop;
         end;
      end if;

      --  Output the header for the error, and manually increment the error
      --  count. We are using Error_Msg_Output rather than Error_Msg here for
      --  two reasons:

      --    This is really only one error, not one for each line
      --    We want this output on standard output since it is voluminous

      --  But we do need to deal with the error count manually in this case

      Errors_Detected := Errors_Detected + 1;
      Error_Msg_Output ("elaboration circularity detected", Info => False);

      --  Try to find cycles starting with any of the remaining nodes that have
      --  not yet been chosen. There must be at least one (there is some reason
      --  we are being called).

      for U in Units.First .. Units.Last loop
         if UNR.Table (U).Elab_Position = 0 then
            if Find_Path (U, U, 1) then
               raise Unrecoverable_Error;
            end if;
         end if;
      end loop;

      --  We should never get here, since we were called for some reason, and
      --  we should have found and eliminated at least one bad path.

      raise Program_Error;
   end Diagnose_Elaboration_Problem;

   --------------------
   -- Elab_All_Links --
   --------------------

   procedure Elab_All_Links
     (Before : Unit_Id;
      After  : Unit_Id;
      Reason : Succ_Reason;
      Link   : Elab_All_Id)
   is
   begin
      if UNR.Table (Before).Visited then
         return;
      end if;

      --  Build the direct link for Before

      UNR.Table (Before).Visited := True;
      Build_Link (Before, After, Reason, Link);

      --  Process all units with'ed by Before recursively

      for W in Units.Table (Before).First_With ..
               Units.Table (Before).Last_With
      loop
         --  Skip if this with is an interface to a stand-alone library. Skip
         --  also if no ALI file for this WITH, happens for language defined
         --  generics while bootstrapping the compiler (see body of routine
         --  Lib.Writ.Write_With_Lines). Finally, skip if it is a limited with
         --  clause, which does not impose an elaboration link.

         if not Withs.Table (W).SAL_Interface
           and then Withs.Table (W).Afile /= No_File
           and then not Withs.Table (W).Limited_With
         then
            declare
               Info : constant Int :=
                 Get_Name_Table_Int (Withs.Table (W).Uname);

            begin
               --  If the unit is unknown, for some unknown reason, fail
               --  graciously explaining that the unit is unknown. Without
               --  this check, gnatbind will crash in Unit_Id_Of.

               if Info = 0 or else Unit_Id (Info) = No_Unit_Id then
                  declare
                     Withed       : String  :=
                                      Get_Name_String (Withs.Table (W).Uname);
                     Last_Withed  : Natural := Withed'Last;
                     Withing      : String  :=
                                      Get_Name_String
                                        (Units.Table (Before).Uname);
                     Last_Withing : Natural := Withing'Last;
                     Spec_Body    : String  := " (Spec)";

                  begin
                     To_Mixed (Withed);
                     To_Mixed (Withing);

                     if Last_Withed > 2
                       and then Withed (Last_Withed - 1) = '%'
                     then
                        Last_Withed := Last_Withed - 2;
                     end if;

                     if Last_Withing > 2
                       and then Withing (Last_Withing - 1) = '%'
                     then
                        Last_Withing := Last_Withing - 2;
                     end if;

                     if Units.Table (Before).Utype = Is_Body
                       or else Units.Table (Before).Utype = Is_Body_Only
                     then
                        Spec_Body := " (Body)";
                     end if;

                     Osint.Fail
                       ("could not find unit "
                        & Withed (Withed'First .. Last_Withed) & " needed by "
                        & Withing (Withing'First .. Last_Withing) & Spec_Body);
                  end;
               end if;

               Elab_All_Links
                 (Unit_Id_Of (Withs.Table (W).Uname),
                  After,
                  Reason,
                  Make_Elab_All_Entry (Withs.Table (W).Uname, Link));
            end;
         end if;
      end loop;

      --  Process corresponding body, if there is one

      if Units.Table (Before).Utype = Is_Spec then
         Elab_All_Links
           (Corresponding_Body (Before),
            After, Reason,
            Make_Elab_All_Entry
              (Units.Table (Corresponding_Body (Before)).Uname, Link));
      end if;
   end Elab_All_Links;

   --------------------
   -- Elab_Error_Msg --
   --------------------

   procedure Elab_Error_Msg (S : Successor_Id) is
      SL : Successor_Link renames Succ.Table (S);

   begin
      --  Nothing to do if internal unit involved and no -da flag

      if not Debug_Flag_A
        and then
          (Is_Internal_File_Name (Units.Table (SL.Before).Sfile)
            or else
           Is_Internal_File_Name (Units.Table (SL.After).Sfile))
      then
         return;
      end if;

      --  Here we want to generate output

      Error_Msg_Unit_1 := Units.Table (SL.Before).Uname;

      if SL.Elab_Body then
         Error_Msg_Unit_2 := Units.Table (Corresponding_Body (SL.After)).Uname;
      else
         Error_Msg_Unit_2 := Units.Table (SL.After).Uname;
      end if;

      Error_Msg_Output ("  $ must be elaborated before $", Info => True);

      Error_Msg_Unit_1 := Units.Table (SL.Reason_Unit).Uname;

      case SL.Reason is
         when Withed =>
            Error_Msg_Output
              ("     reason: with clause",
               Info => True);

         when Forced =>
            Error_Msg_Output
              ("     reason: forced by -f switch",
               Info => True);

         when Elab =>
            Error_Msg_Output
              ("     reason: pragma Elaborate in unit $",
               Info => True);

         when Elab_All =>
            Error_Msg_Output
              ("     reason: pragma Elaborate_All in unit $",
               Info => True);

         when Elab_All_Desirable =>
            Error_Msg_Output
              ("     reason: implicit Elaborate_All in unit $",
               Info => True);

            Error_Msg_Output
              ("     recompile $ with -gnatel for full details",
               Info => True);

         when Elab_Desirable =>
            Error_Msg_Output
              ("     reason: implicit Elaborate in unit $",
               Info => True);

            Error_Msg_Output
              ("     recompile $ with -gnatel for full details",
               Info => True);

         when Spec_First =>
            Error_Msg_Output
              ("     reason: spec always elaborated before body",
               Info => True);
      end case;

      Write_Elab_All_Chain (S);

      if SL.Elab_Body then
         Error_Msg_Unit_1 := Units.Table (SL.Before).Uname;
         Error_Msg_Unit_2 := Units.Table (SL.After).Uname;
         Error_Msg_Output
           ("  $ must therefore be elaborated before $", True);

         Error_Msg_Unit_1 := Units.Table (SL.After).Uname;
         Error_Msg_Output
           ("     (because $ has a pragma Elaborate_Body)", True);
      end if;

      if not Zero_Formatting then
         Write_Eol;
      end if;
   end Elab_Error_Msg;

   ---------------------
   -- Find_Elab_Order --
   ---------------------

   procedure Find_Elab_Order
     (Elab_Order          : out Unit_Id_Table;
      First_Main_Lib_File : File_Name_Type)
   is
      function Num_Spec_Body_Pairs (Order : Unit_Id_Array) return Nat;
      --  Number of cases where the body of a unit immediately follows the
      --  corresponding spec. Such cases are good, because calls to that unit
      --  from outside can't get ABE.

      -------------------------
      -- Num_Spec_Body_Pairs --
      -------------------------

      function Num_Spec_Body_Pairs (Order : Unit_Id_Array) return Nat is
         Result : Nat := 0;

      begin
         for J in Order'First + 1 .. Order'Last loop
            if Units.Table (Order (J - 1)).Utype = Is_Spec
              and then Units.Table (Order (J)).Utype = Is_Body
              and then Corresponding_Spec (Order (J)) = Order (J - 1)
            then
               Result := Result + 1;
            end if;
         end loop;

         return Result;
      end Num_Spec_Body_Pairs;

      --  Local variables

      Old_Elab_Order : Unit_Id_Table;

   --  Start of processing for Find_Elab_Order

   begin
      --  Output warning if -p used with no -gnatE units

      if Pessimistic_Elab_Order
        and not Dynamic_Elaboration_Checks_Specified
      then
         Error_Msg ("?use of -p switch questionable");
         Error_Msg ("?since all units compiled with static elaboration model");
      end if;

      if Do_New and not Debug_Flag_Old and not Debug_Flag_Older then
         if Debug_Flag_V then
            Write_Line ("Doing new...");
         end if;

         Doing_New := True;
         Init;
         Elab_New.Find_Elab_Order (Elab_Order);
      end if;

      --  Elab_New does not support the pessimistic order, so if that was
      --  requested, use the old results. Use Elab_Old if -dp or -do was
      --  selected. Elab_New does not yet give proper error messages for
      --  illegal Elaborate_Alls, so if there is one, run Elab_Old.

      if Do_Old
        or Pessimistic_Elab_Order
        or Debug_Flag_Old
        or Debug_Flag_Older
        or Elab_Cycle_Found
      then
         if Debug_Flag_V then
            Write_Line ("Doing old...");
         end if;

         Doing_New := False;
         Init;
         Elab_Old.Find_Elab_Order (Old_Elab_Order);
      end if;

      pragma Assert (Elab_Cycle_Found <= -- implies
                       Diagnose_Elaboration_Problem_Called);

      declare
         Old_Order : Unit_Id_Array renames
                       Old_Elab_Order.Table (1 .. Last (Old_Elab_Order));
      begin
         if Do_Old and Do_New then
            declare
               New_Order : Unit_Id_Array renames
                             Elab_Order.Table (1 .. Last (Elab_Order));
               Old_Pairs : constant Nat := Num_Spec_Body_Pairs (Old_Order);
               New_Pairs : constant Nat := Num_Spec_Body_Pairs (New_Order);

            begin
               Write_Line (Get_Name_String (First_Main_Lib_File));

               pragma Assert (Old_Order'Length = New_Order'Length);
               pragma Debug (Validate (Old_Order, Doing_New => False));
               pragma Debug (Validate (New_Order, Doing_New => True));

               --  Misc debug printouts that can be used for experimentation by
               --  changing the 'if's below.

               if True then
                  if New_Order = Old_Order then
                     Write_Line ("Elab_New: same order.");
                  else
                     Write_Line ("Elab_New: diff order.");
                  end if;
               end if;

               if New_Order /= Old_Order and then False then
                  Write_Line ("Elaboration orders differ:");
                  Write_Elab_Order
                    (Old_Order, Title => "OLD ELABORATION ORDER");
                  Write_Elab_Order
                    (New_Order, Title => "NEW ELABORATION ORDER");
               end if;

               if True then
                  Write_Str ("Pairs: ");
                  Write_Int (Old_Pairs);

                  if Old_Pairs = New_Pairs then
                     Write_Str (" = ");
                  elsif Old_Pairs < New_Pairs then
                     Write_Str (" < ");
                  else
                     Write_Str (" > ");
                  end if;

                  Write_Int (New_Pairs);
                  Write_Eol;
               end if;

               if Old_Pairs /= New_Pairs and then False then
                  Write_Str ("Pairs: ");
                  Write_Int (Old_Pairs);

                  if Old_Pairs < New_Pairs then
                     Write_Str (" < ");
                  else
                     Write_Str (" > ");
                  end if;

                  Write_Int (New_Pairs);
                  Write_Eol;

                  if Old_Pairs /= New_Pairs and then Debug_Flag_V then
                     Write_Elab_Order
                       (Old_Order, Title => "OLD ELABORATION ORDER");
                     Write_Elab_Order
                       (New_Order, Title => "NEW ELABORATION ORDER");
                     pragma Assert (New_Pairs >= Old_Pairs);
                  end if;
               end if;
            end;
         end if;

         --  The Elab_New algorithm doesn't implement the -p switch, so if that
         --  was used, use the results from the old algorithm. Likewise if the
         --  user has requested the old algorithm.

         if Pessimistic_Elab_Order or Debug_Flag_Old or Debug_Flag_Older then
            pragma Assert
              (Last (Elab_Order) = 0
                or else Last (Elab_Order) = Old_Order'Last);

            Init (Elab_Order);
            Append_All (Elab_Order, Old_Order);
         end if;

         --  Now set the Elab_Positions in the Units table. It is important to
         --  do this late, in case we're running both Elab_New and Elab_Old.

         declare
            New_Order : Unit_Id_Array renames
                          Elab_Order.Table (1 .. Last (Elab_Order));
            Units_Array : Units.Table_Type renames
                            Units.Table (Units.First .. Units.Last);
         begin
            for J in New_Order'Range loop
               pragma Assert
                 (UNR.Table (New_Order (J)).Elab_Position = J);
               Units_Array  (New_Order (J)).Elab_Position := J;
            end loop;

            if Errors_Detected = 0 then

               --  Display elaboration order if -l was specified

               if Elab_Order_Output then
                  if Zero_Formatting then
                     Write_Elab_Order (New_Order, Title => "");
                  else
                     Write_Elab_Order
                       (New_Order, Title => "ELABORATION ORDER");
                  end if;
               end if;

               --  Display list of sources in the closure (except predefined
               --  sources) if -R was used. Include predefined sources if -Ra
               --  was used.

               if List_Closure then
                  Write_Closure (New_Order);
               end if;
            end if;
         end;
      end;
   end Find_Elab_Order;

   ----------------------
   -- Force_Elab_Order --
   ----------------------

   procedure Force_Elab_Order is
      subtype Header_Num is Unit_Name_Type'Base range 0 .. 2**16 - 1;

      function Hash (N : Unit_Name_Type) return Header_Num;

      package Name_Map is new System.HTable.Simple_HTable
        (Header_Num => Header_Num,
         Element    => Logical_Line_Number,
         No_Element => No_Line_Number,
         Key        => Unit_Name_Type,
         Hash       => Hash,
         Equal      => "=");
      --  Name_Map contains an entry for each file name seen, mapped to the
      --  line number where we saw it first. This is used to give an error for
      --  duplicates.

      ----------
      -- Hash --
      ----------

      function Hash (N : Unit_Name_Type) return Header_Num is
         --  Name_Ids are already widely dispersed; no need for any actual
         --  hashing. Just subtract to make it zero based, and "mod" to
         --  bring it in range.
      begin
         return (N - Unit_Name_Type'First) mod (Header_Num'Last + 1);
      end Hash;

      --  Local variables

      Cur_Line_Number : Logical_Line_Number;
      Error           : Boolean := False;
      Iter            : Forced_Units_Iterator;
      Prev_Unit       : Unit_Id := No_Unit_Id;
      Uname           : Unit_Name_Type;

   --  Start of processing for Force_Elab_Order

   begin
      Iter := Iterate_Forced_Units;
      while Has_Next (Iter) loop
         Next (Iter, Uname, Cur_Line_Number);

         declare
            Dup : constant Logical_Line_Number := Name_Map.Get (Uname);
         begin
            if Dup = No_Line_Number then
               Name_Map.Set (Uname, Cur_Line_Number);

               --  We don't need to give the "not present" message in the case
               --  of "duplicate unit", because we would have already given the
               --  "not present" message on the first occurrence.

               if Get_Name_Table_Int (Uname) = 0
                 or else Unit_Id (Get_Name_Table_Int (Uname)) = No_Unit_Id
               then
                  Error := True;
                  if Doing_New then
                     Write_Line
                       ("""" & Get_Name_String (Uname)
                        & """: not present; ignored");
                  end if;
               end if;

            else
               Error := True;
               if Doing_New then
                  Error_Msg_Nat_1  := Nat (Cur_Line_Number);
                  Error_Msg_Unit_1 := Uname;
                  Error_Msg_Nat_2  := Nat (Dup);
                  Error_Msg
                    (Force_Elab_Order_File.all
                     & ":#: duplicate unit name $ from line #");
               end if;
            end if;
         end;

         if not Error then
            declare
               Cur_Unit : constant Unit_Id := Unit_Id_Of (Uname);
            begin
               if Is_Internal_File_Name (Units.Table (Cur_Unit).Sfile) then
                  if Doing_New then
                     Write_Line
                       ("""" & Get_Name_String (Uname)
                        & """: predefined unit ignored");
                  end if;

               else
                  if Prev_Unit /= No_Unit_Id then
                     if Doing_New then
                        Write_Unit_Name (Units.Table (Prev_Unit).Uname);
                        Write_Str (" <-- ");
                        Write_Unit_Name (Units.Table (Cur_Unit).Uname);
                        Write_Eol;
                     end if;

                     Build_Link
                       (Before => Prev_Unit,
                        After  => Cur_Unit,
                        R      => Forced);
                  end if;

                  Prev_Unit := Cur_Unit;
               end if;
            end;
         end if;
      end loop;
   end Force_Elab_Order;

   -------------------------
   -- Gather_Dependencies --
   -------------------------

   procedure Gather_Dependencies is
      Withed_Unit : Unit_Id;

   begin
      --  Loop through all units

      for U in Units.First .. Units.Last loop
         Cur_Unit := U;

         --  If this is not an interface to a stand-alone library and there is
         --  a body and a spec, then spec must be elaborated first. Note that
         --  the corresponding spec immediately follows the body.

         if not Units.Table (U).SAL_Interface
           and then Units.Table (U).Utype = Is_Body
         then
            Build_Link (Corresponding_Spec (U), U, Spec_First);
         end if;

         --  If this unit is not an interface to a stand-alone library, process
         --  WITH references for this unit ignoring interfaces to stand-alone
         --  libraries.

         if not Units.Table (U).SAL_Interface then
            for W in Units.Table (U).First_With ..
                     Units.Table (U).Last_With
            loop
               if Withs.Table (W).Sfile /= No_File
                 and then not Withs.Table (W).SAL_Interface
               then
                  --  Check for special case of withing a unit that does not
                  --  exist any more. If the unit was completely missing we
                  --  would already have detected this, but a nasty case arises
                  --  when we have a subprogram body with no spec, and some
                  --  obsolete unit with's a previous (now disappeared) spec.

                  if Get_Name_Table_Int (Withs.Table (W).Uname) = 0 then
                     if Doing_New then
                        Error_Msg_File_1 := Units.Table (U).Sfile;
                        Error_Msg_Unit_1 := Withs.Table (W).Uname;
                        Error_Msg ("{ depends on $ which no longer exists");
                     end if;

                     goto Next_With;
                  end if;

                  Withed_Unit := Unit_Id_Of (Withs.Table (W).Uname);

                  --  Pragma Elaborate_All case, for this we use the recursive
                  --  Elab_All_Links procedure to establish the links.

                  --  Elab_New ignores Elaborate_All and Elab_All_Desirable,
                  --  except for error messages.

                  if Withs.Table (W).Elaborate_All and then not Doing_New then

                     --  Reset flags used to stop multiple visits to a given
                     --  node.

                     for Uref in UNR.First .. UNR.Last loop
                        UNR.Table (Uref).Visited := False;
                     end loop;

                     --  Now establish all the links we need

                     Elab_All_Links
                       (Withed_Unit, U, Elab_All,
                        Make_Elab_All_Entry
                          (Withs.Table (W).Uname, No_Elab_All_Link));

                  --  Elaborate_All_Desirable case, for this we establish the
                  --  same links as above, but with a different reason.

                  elsif Withs.Table (W).Elab_All_Desirable
                    and then not Doing_New
                  then
                     --  Reset flags used to stop multiple visits to a given
                     --  node.

                     for Uref in UNR.First .. UNR.Last loop
                        UNR.Table (Uref).Visited := False;
                     end loop;

                     --  Now establish all the links we need

                     Elab_All_Links
                       (Withed_Unit, U, Elab_All_Desirable,
                        Make_Elab_All_Entry
                          (Withs.Table (W).Uname, No_Elab_All_Link));

                  --  Pragma Elaborate case. We must build a link for the
                  --  withed unit itself, and also the corresponding body if
                  --  there is one.

                  --  However, skip this processing if there is no ALI file for
                  --  the WITH entry, because this means it is a generic (even
                  --  when we fix the generics so that an ALI file is present,
                  --  we probably still will have no ALI file for unchecked and
                  --  other special cases).

                  elsif Withs.Table (W).Elaborate
                    and then Withs.Table (W).Afile /= No_File
                  then
                     Build_Link (Withed_Unit, U, Withed);

                     if Units.Table (Withed_Unit).Utype = Is_Spec then
                        Build_Link
                          (Corresponding_Body (Withed_Unit), U, Elab);
                     end if;

                  --  Elaborate_Desirable case, for this we establish the same
                  --  links as above, but with a different reason.

                  elsif Withs.Table (W).Elab_Desirable then
                     Build_Link (Withed_Unit, U, Withed);

                     if Units.Table (Withed_Unit).Utype = Is_Spec then
                        Build_Link
                          (Corresponding_Body (Withed_Unit),
                           U, Elab_Desirable);
                     end if;

                  --  A limited_with does not establish an elaboration
                  --  dependence (that's the whole point).

                  elsif Withs.Table (W).Limited_With then
                     null;

                  --  Case of normal WITH with no elaboration pragmas, just
                  --  build the single link to the directly referenced unit

                  else
                     Build_Link (Withed_Unit, U, Withed);
                  end if;
               end if;

               <<Next_With>>
               null;
            end loop;
         end if;
      end loop;

      --  If -f<elab_order> switch was given, take into account dependences
      --  specified in the file <elab_order>.

      if Force_Elab_Order_File /= null then
         Force_Elab_Order;
      end if;

      --  Output elaboration dependencies if option is set

      if Elab_Dependency_Output or Debug_Flag_E then
         if Doing_New then
            Write_Dependencies;
         end if;
      end if;
   end Gather_Dependencies;

   ----------
   -- Init --
   ----------

   procedure Init is
   begin
      Num_Chosen := 0;
      Num_Left := Int (Units.Last - Units.First + 1);
      Succ.Init;
      Elab_All_Entries.Init;
      UNR.Init;

      --  Initialize unit table for elaboration control

      for U in Units.First .. Units.Last loop
         UNR.Append
           ((Successors    => No_Successor,
             Num_Pred      => 0,
             Nextnp        => No_Unit_Id,
             Visited       => False,
             Elab_Position => 0,
             SCC_Root      => No_Unit_Id,
             Nodes         => null,
             SCC_Num_Pred  => 0,
             Validate_Seen => False));
      end loop;
   end Init;

   ------------------
   -- Is_Body_Unit --
   ------------------

   function Is_Body_Unit (U : Unit_Id) return Boolean is
   begin
      return
        Units.Table (U).Utype = Is_Body
          or else Units.Table (U).Utype = Is_Body_Only;
   end Is_Body_Unit;

   -----------------------------
   -- Is_Pure_Or_Preelab_Unit --
   -----------------------------

   function Is_Pure_Or_Preelab_Unit (U : Unit_Id) return Boolean is
   begin
      --  If we have a body with separate spec, test flags on the spec

      if Units.Table (U).Utype = Is_Body then
         return
           Units.Table (Corresponding_Spec (U)).Preelab
             or else Units.Table (Corresponding_Spec (U)).Pure;

      --  Otherwise we have a spec or body acting as spec, test flags on unit

      else
         return Units.Table (U).Preelab or else Units.Table (U).Pure;
      end if;
   end Is_Pure_Or_Preelab_Unit;

   ---------------------
   -- Is_Waiting_Body --
   ---------------------

   function Is_Waiting_Body (U : Unit_Id) return Boolean is
   begin
      return
        Units.Table (U).Utype = Is_Body
          and then UNR.Table (Corresponding_Spec (U)).Elab_Position /= 0;
   end Is_Waiting_Body;

   -------------------------
   -- Make_Elab_All_Entry --
   -------------------------

   function Make_Elab_All_Entry
     (Unam : Unit_Name_Type;
      Link : Elab_All_Id) return Elab_All_Id
   is
   begin
      Elab_All_Entries.Append ((Needed_By => Unam, Next_Elab => Link));
      return Elab_All_Entries.Last;
   end Make_Elab_All_Entry;

   ----------------
   -- Unit_Id_Of --
   ----------------

   function Unit_Id_Of (Uname : Unit_Name_Type) return Unit_Id is
      Info : constant Int := Get_Name_Table_Int (Uname);

   begin
      pragma Assert (Info /= 0 and then Unit_Id (Info) /= No_Unit_Id);
      return Unit_Id (Info);
   end Unit_Id_Of;

   --------------
   -- Validate --
   --------------

   procedure Validate (Order : Unit_Id_Array; Doing_New : Boolean) is
      Cur_SCC : Unit_Id := No_Unit_Id;
      OK      : Boolean := True;
      Msg     : String := "Old: ";

   begin
      if Doing_New then
         Msg := "New: ";
      end if;

      --  For each unit, assert that its successors are elaborated after it

      for J in Order'Range loop
         declare
            U : constant Unit_Id := Order (J);
            S : Successor_Id := UNR.Table (U).Successors;

         begin
            while S /= No_Successor loop
               if UNR.Table (Succ.Table (S).After).Elab_Position <=
                    UNR.Table (U).Elab_Position
               then
                  OK := False;
                  Write_Line (Msg & " elab order failed");
               end if;

               S := Succ.Table (S).Next;
            end loop;
         end;
      end loop;

      --  An SCC of size 2 units necessarily consists of a spec and the
      --  corresponding body. Assert that the body is elaborated immediately
      --  after the spec, with nothing in between. (We only have SCCs in the
      --  new algorithm.)

      if Doing_New then
         for J in Order'Range loop
            declare
               U : constant Unit_Id := Order (J);

            begin
               if Nodes (U)'Length = 2 then
                  if Units.Table (U).Utype = Is_Spec then
                     if Order (J + 1) /= Corresponding_Body (U) then
                        OK := False;
                        Write_Line (Msg & "Bad spec with SCC of size 2:");
                        Write_SCC (SCC (U));
                     end if;
                  end if;

                  if Units.Table (U).Utype = Is_Body then
                     if Order (J - 1) /= Corresponding_Spec (U) then
                        OK := False;
                        Write_Line (Msg & "Bad body with SCC of size 2:");
                        Write_SCC (SCC (U));
                     end if;
                  end if;
               end if;
            end;
         end loop;

         --  Assert that all units of an SCC are elaborated together, with no
         --  units from other SCCs in between. The above spec/body case is a
         --  special case of this general rule.

         for J in Order'Range loop
            declare
               U : constant Unit_Id := Order (J);

            begin
               if SCC (U) /= Cur_SCC then
                  Cur_SCC := SCC (U);
                  if UNR.Table (Cur_SCC).Validate_Seen then
                     OK := False;
                     Write_Line (Msg & "SCC not elaborated together:");
                     Write_SCC (Cur_SCC);
                  end if;

                  UNR.Table (Cur_SCC).Validate_Seen := True;
               end if;
            end;
         end loop;
      end if;

      pragma Assert (OK);
   end Validate;

   -------------------
   -- Write_Closure --
   -------------------

   procedure Write_Closure (Order : Unit_Id_Array) is
      package Closure_Sources is new Table.Table
        (Table_Component_Type => File_Name_Type,
         Table_Index_Type     => Natural,
         Table_Low_Bound      => 1,
         Table_Initial        => 10,
         Table_Increment      => 100,
         Table_Name           => "Gnatbind.Closure_Sources");
      --  Table to record the sources in the closure, to avoid duplications

      function Put_In_Sources (S : File_Name_Type) return Boolean;
      --  Check if S is already in table Sources and put in Sources if it is
      --  not. Return False if the source is already in Sources, and True if
      --  it is added.

      --------------------
      -- Put_In_Sources --
      --------------------

      function Put_In_Sources (S : File_Name_Type) return Boolean is
      begin
         for J in 1 .. Closure_Sources.Last loop
            if Closure_Sources.Table (J) = S then
               return False;
            end if;
         end loop;

         Closure_Sources.Append (S);
         return True;
      end Put_In_Sources;

      --  Local variables

      Source : File_Name_Type;

   --  Start of processing for Write_Closure

   begin
      Closure_Sources.Init;

      if not Zero_Formatting then
         Write_Eol;
         Write_Line ("REFERENCED SOURCES");
      end if;

      for J in reverse Order'Range loop
         Source := Units.Table (Order (J)).Sfile;

         --  Do not include same source more than once

         if Put_In_Sources (Source)

           --  Do not include run-time units unless -Ra switch set

           and then (List_Closure_All
                      or else not Is_Internal_File_Name (Source))
         then
            if not Zero_Formatting then
               Write_Str ("   ");
            end if;

            Write_Line (Get_Name_String (Source));
         end if;
      end loop;

      --  Subunits do not appear in the elaboration table because they are
      --  subsumed by their parent units, but we need to list them for other
      --  tools. For now they are listed after other files, rather than right
      --  after their parent, since there is no easy link between the
      --  elaboration table and the ALIs table. As subunits may appear
      --  repeatedly in the list, if the parent unit appears in the context of
      --  several units in the closure, duplicates are suppressed.

      for J in Sdep.First .. Sdep.Last loop
         Source := Sdep.Table (J).Sfile;

         if Sdep.Table (J).Subunit_Name /= No_Name
           and then Put_In_Sources (Source)
           and then not Is_Internal_File_Name (Source)
         then
            if not Zero_Formatting then
               Write_Str ("   ");
            end if;

            Write_Line (Get_Name_String (Source));
         end if;
      end loop;

      if not Zero_Formatting then
         Write_Eol;
      end if;
   end Write_Closure;

   ------------------------
   -- Write_Dependencies --
   ------------------------

   procedure Write_Dependencies is
   begin
      if not Zero_Formatting then
         Write_Eol;
         Write_Line ("                 ELABORATION ORDER DEPENDENCIES");
         Write_Eol;
      end if;

      Info_Prefix_Suppress := True;

      for S in Succ_First .. Succ.Last loop
         Elab_Error_Msg (S);
      end loop;

      Info_Prefix_Suppress := False;

      if not Zero_Formatting then
         Write_Eol;
      end if;
   end Write_Dependencies;

   --------------------------
   -- Write_Elab_All_Chain --
   --------------------------

   procedure Write_Elab_All_Chain (S : Successor_Id) is
      ST     : constant Successor_Link := Succ.Table (S);
      After  : constant Unit_Name_Type := Units.Table (ST.After).Uname;

      L   : Elab_All_Id;
      Nam : Unit_Name_Type;

      First_Name : Boolean := True;

   begin
      if ST.Reason in Elab_All .. Elab_All_Desirable then
         L := ST.Elab_All_Link;
         pragma Annotate (CodePeer, Modified, L);

         while L /= No_Elab_All_Link loop
            Nam := Elab_All_Entries.Table (L).Needed_By;
            Error_Msg_Unit_1 := Nam;
            Error_Msg_Output ("        $", Info => True);

            Get_Name_String (Nam);

            if Name_Buffer (Name_Len) = 'b' then
               if First_Name then
                  Error_Msg_Output
                    ("           must be elaborated along with its spec:",
                     Info => True);

               else
                  Error_Msg_Output
                    ("           which must be elaborated along with its "
                     & "spec:",
                     Info => True);
               end if;

            else
               if First_Name then
                  Error_Msg_Output
                    ("           is withed by:",
                     Info => True);

               else
                  Error_Msg_Output
                    ("           which is withed by:",
                     Info => True);
               end if;
            end if;

            First_Name := False;

            L := Elab_All_Entries.Table (L).Next_Elab;
         end loop;

         Error_Msg_Unit_1 := After;
         Error_Msg_Output ("        $", Info => True);
      end if;
   end Write_Elab_All_Chain;

   ----------------------
   -- Write_Elab_Order --
   ----------------------

   procedure Write_Elab_Order
     (Order : Unit_Id_Array; Title : String)
   is
   begin
      if Title /= "" then
         Write_Eol;
         Write_Line (Title);
      end if;

      for J in Order'Range loop
         if not Units.Table (Order (J)).SAL_Interface then
            if not Zero_Formatting then
               Write_Str ("   ");
            end if;

            Write_Unit_Name (Units.Table (Order (J)).Uname);
            Write_Eol;
         end if;
      end loop;

      if Title /= "" then
         Write_Eol;
      end if;
   end Write_Elab_Order;

   --------------
   -- Elab_New --
   --------------

   package body Elab_New is

      generic
         type Node is (<>);
         First_Node : Node;
         Last_Node  : Node;
         type Node_Array is array (Pos range <>) of Node;
         with function Successors (N : Node) return Node_Array;
         with procedure Create_SCC (Root : Node; Nodes : Node_Array);

      procedure Compute_Strongly_Connected_Components;
      --  Compute SCCs for a directed graph. The nodes in the graph are all
      --  values of type Node in the range First_Node .. Last_Node.
      --  Successors(N) returns the nodes pointed to by the edges emanating
      --  from N. Create_SCC is a callback that is called once for each SCC,
      --  passing in the Root node for that SCC (which is an arbitrary node in
      --  the SCC used as a representative of that SCC), and the set of Nodes
      --  in that SCC.
      --
      --  This is generic, in case we want to use it elsewhere; then we could
      --  move this into a separate library unit. Unfortunately, it's not as
      --  generic as one might like. Ideally, we would have "type Node is
      --  private;", and pass in iterators to iterate over all nodes, and over
      --  the successors of a given node. However, that leads to using advanced
      --  features of Ada that are not allowed in the compiler and binder for
      --  bootstrapping reasons. It also leads to trampolines, which are not
      --  allowed in the compiler and binder. Restricting Node to be discrete
      --  allows us to iterate over all nodes with a 'for' loop, and allows us
      --  to attach temporary information to nodes by having an array indexed
      --  by Node.

      procedure Compute_Unit_SCCs;
      --  Use the above generic procedure to compute the SCCs for the graph of
      --  units. Store in each Unit_Node_Record the SCC_Root and Nodes
      --  components. Also initialize the SCC_Num_Pred components.

      procedure Find_Elab_All_Errors;
      --  Generate an error for illegal Elaborate_All pragmas (explicit or
      --  implicit). A pragma Elaborate_All (Y) on unit X is legal if and only
      --  if X and Y are in different SCCs.

      -------------------------------------------
      -- Compute_Strongly_Connected_Components --
      -------------------------------------------

      procedure Compute_Strongly_Connected_Components is

         --  This uses Tarjan's algorithm for finding SCCs. Comments here are
         --  intended to tell what it does, but if you want to know how it
         --  works, you have to look it up. Please do not modify this code
         --  without reading up on Tarjan's algorithm.

         subtype Node_Index is Nat;
         No_Index : constant Node_Index := 0;

         Num_Nodes : constant Nat :=
                       Node'Pos (Last_Node) - Node'Pos (First_Node) + 1;
         Stack : Node_Array (1 .. Num_Nodes);
         Top   : Node_Index := 0;
         --  Stack of nodes, pushed when first visited. All nodes of an SCC are
         --  popped at once when the SCC is found.

         subtype Valid_Node is Node range First_Node .. Last_Node;
         Node_Indices : array (Valid_Node) of Node_Index :=
                          (others => No_Index);
         --  Each node has an "index", which is the sequential number in the
         --  order in which they are visited in the recursive walk. No_Index
         --  means "not yet visited"; we want to avoid walking any node more
         --  than once.

         Index : Node_Index := 1;
         --  Next value to be assigned to a node index

         Low_Links : array (Valid_Node) of Node_Index;
         --  Low_Links (N) is the smallest index of nodes reachable from N

         On_Stack : array (Valid_Node) of Boolean := (others => False);
         --  True if the node is currently on the stack

         procedure Walk (N : Valid_Node);
         --  Recursive depth-first graph walk, with the node index used to
         --  avoid visiting a node more than once.

         ----------
         -- Walk --
         ----------

         procedure Walk (N : Valid_Node) is
            Stack_Position_Of_N : constant Pos := Top + 1;
            S : constant Node_Array := Successors (N);

         begin
            --  Assign the index and low link, increment Index for next call to
            --  Walk.

            Node_Indices (N) := Index;
            Low_Links (N) := Index;
            Index := Index + 1;

            --  Push it on the stack:

            Top := Stack_Position_Of_N;
            Stack (Top) := N;
            On_Stack (N) := True;

            --  Walk not-yet-visited subnodes, and update low link for visited
            --  ones as appropriate.

            for J in S'Range loop
               if Node_Indices (S (J)) = No_Index then
                  Walk (S (J));
                  Low_Links (N) :=
                    Node_Index'Min (Low_Links (N), Low_Links (S (J)));
               elsif On_Stack (S (J)) then
                  Low_Links (N) :=
                    Node_Index'Min (Low_Links (N), Node_Indices (S (J)));
               end if;
            end loop;

            --  If the index is (still) equal to the low link, we've found an
            --  SCC. Pop the whole SCC off the stack, and call Create_SCC.

            if Low_Links (N) = Node_Indices (N) then
               declare
                  SCC : Node_Array renames
                    Stack (Stack_Position_Of_N .. Top);
                  pragma Assert (SCC'Length >= 1);
                  pragma Assert (SCC (SCC'First) = N);

               begin
                  for J in SCC'Range loop
                     On_Stack (SCC (J)) := False;
                  end loop;

                  Create_SCC (Root => N, Nodes => SCC);
                  pragma Assert (Top - SCC'Length = Stack_Position_Of_N - 1);
                  Top := Stack_Position_Of_N - 1; -- pop all
               end;
            end if;
         end Walk;

      --  Start of processing for Compute_Strongly_Connected_Components

      begin
         --  Walk all the nodes that have not yet been walked

         for N in Valid_Node loop
            if Node_Indices (N) = No_Index then
               Walk (N);
            end if;
         end loop;
      end Compute_Strongly_Connected_Components;

      -----------------------
      -- Compute_Unit_SCCs --
      -----------------------

      procedure Compute_Unit_SCCs is
         function Successors (U : Unit_Id) return Unit_Id_Array;
         --  Return all the units that must be elaborated after U. In addition,
         --  if U is a body, include the corresponding spec; this ensures that
         --  a spec/body pair are always in the same SCC.

         procedure Create_SCC (Root : Unit_Id; Nodes : Unit_Id_Array);
         --  Set Nodes of the Root, and set SCC_Root of all the Nodes

         procedure Init_SCC_Num_Pred (U : Unit_Id);
         --  Initialize the SCC_Num_Pred fields, so that the root of each SCC
         --  has a count of the number of successors of all the units in the
         --  SCC, but only for successors outside the SCC.

         procedure Compute_SCCs is new Compute_Strongly_Connected_Components
           (Node       => Unit_Id,
            First_Node => Units.First,
            Last_Node  => Units.Last,
            Node_Array => Unit_Id_Array,
            Successors => Successors,
            Create_SCC => Create_SCC);

         ----------------
         -- Create_SCC --
         ----------------

         procedure Create_SCC (Root : Unit_Id; Nodes : Unit_Id_Array) is
         begin
            if Debug_Flag_V then
               Write_Str ("Root = ");
               Write_Int (Int (Root));
               Write_Str (" ");
               Write_Unit_Name (Units.Table (Root).Uname);
               Write_Str (" -- ");
               Write_Int (Nodes'Length);
               Write_Line (" units:");

               for J in Nodes'Range loop
                  Write_Str ("   ");
                  Write_Int (Int (Nodes (J)));
                  Write_Str (" ");
                  Write_Unit_Name (Units.Table (Nodes (J)).Uname);
                  Write_Eol;
               end loop;
            end if;

            pragma Assert (Nodes (Nodes'First) = Root);
            pragma Assert (UNR.Table (Root).Nodes = null);
            UNR.Table (Root).Nodes := new Unit_Id_Array'(Nodes);

            for J in Nodes'Range loop
               pragma Assert (SCC (Nodes (J)) = No_Unit_Id);
               UNR.Table (Nodes (J)).SCC_Root := Root;
            end loop;
         end Create_SCC;

         ----------------
         -- Successors --
         ----------------

         function Successors (U : Unit_Id) return Unit_Id_Array is
            S   : Successor_Id := UNR.Table (U).Successors;
            Tab : Unit_Id_Table;

         begin
            --  Pretend that a spec is a successor of its body (even though it
            --  isn't), just so both get included.

            if Units.Table (U).Utype = Is_Body then
               Append (Tab, Corresponding_Spec (U));
            end if;

            --  Now include the real successors

            while S /= No_Successor loop
               pragma Assert (Succ.Table (S).Before = U);
               Append (Tab, Succ.Table (S).After);
               S := Succ.Table (S).Next;
            end loop;

            declare
               Result : constant Unit_Id_Array := Tab.Table (1 .. Last (Tab));

            begin
               Free (Tab);
               return Result;
            end;
         end Successors;

         -----------------------
         -- Init_SCC_Num_Pred --
         -----------------------

         procedure Init_SCC_Num_Pred (U : Unit_Id) is
         begin
            if UNR.Table (U).Visited then
               return;
            end if;

            UNR.Table (U).Visited := True;

            declare
               S : Successor_Id := UNR.Table (U).Successors;

            begin
               while S /= No_Successor loop
                  pragma Assert (Succ.Table (S).Before = U);
                  Init_SCC_Num_Pred (Succ.Table (S).After);

                  if SCC (U) /= SCC (Succ.Table (S).After) then
                     UNR.Table (SCC (Succ.Table (S).After)).SCC_Num_Pred :=
                       UNR.Table (SCC (Succ.Table (S).After)).SCC_Num_Pred + 1;
                  end if;

                  S := Succ.Table (S).Next;
               end loop;
            end;
         end Init_SCC_Num_Pred;

      --  Start of processing for Compute_Unit_SCCs

      begin
         Compute_SCCs;

         for Uref in UNR.First .. UNR.Last loop
            pragma Assert (not UNR.Table (Uref).Visited);
            null;
         end loop;

         for Uref in UNR.First .. UNR.Last loop
            Init_SCC_Num_Pred (Uref);
         end loop;

         --  Assert that SCC_Root of all units has been set to a valid unit,
         --  and that SCC_Num_Pred has not been modified in non-root units.

         for Uref in UNR.First .. UNR.Last loop
            pragma Assert (UNR.Table (Uref).SCC_Root /= No_Unit_Id);
            pragma Assert (UNR.Table (Uref).SCC_Root in UNR.First .. UNR.Last);

            if SCC (Uref) /= Uref then
               pragma Assert (UNR.Table (Uref).SCC_Num_Pred = 0);
               null;
            end if;
         end loop;
      end Compute_Unit_SCCs;

      --------------------------
      -- Find_Elab_All_Errors --
      --------------------------

      procedure Find_Elab_All_Errors is
         Withed_Unit : Unit_Id;

      begin
         for U in Units.First .. Units.Last loop

            --  If this unit is not an interface to a stand-alone library,
            --  process WITH references for this unit ignoring interfaces to
            --  stand-alone libraries.

            if not Units.Table (U).SAL_Interface then
               for W in Units.Table (U).First_With ..
                        Units.Table (U).Last_With
               loop
                  if Withs.Table (W).Sfile /= No_File
                    and then not Withs.Table (W).SAL_Interface
                  then
                     --  Check for special case of withing a unit that does not
                     --  exist any more.

                     if Get_Name_Table_Int (Withs.Table (W).Uname) = 0 then
                        goto Next_With;
                     end if;

                     Withed_Unit := Unit_Id_Of (Withs.Table (W).Uname);

                     --  If it's Elaborate_All or Elab_All_Desirable, check
                     --  that the withER and withEE are not in the same SCC.

                     if Withs.Table (W).Elaborate_All
                       or else Withs.Table (W).Elab_All_Desirable
                     then
                        if SCC (U) = SCC (Withed_Unit) then
                           Elab_Cycle_Found := True;

                           --  We could probably give better error messages
                           --  than Elab_Old here, but for now, to avoid
                           --  disruption, we don't give any error here.
                           --  Instead, we set the Elab_Cycle_Found flag above,
                           --  and then run the Elab_Old algorithm to issue the
                           --  error message. Ideally, we would like to print
                           --  multiple errors rather than stopping after the
                           --  first cycle.

                           if False then
                              Error_Msg_Output
                                ("illegal pragma Elaborate_All",
                                 Info => False);
                           end if;
                        end if;
                     end if;
                  end if;

                  <<Next_With>>
                  null;
               end loop;
            end if;
         end loop;
      end Find_Elab_All_Errors;

      ---------------------
      -- Find_Elab_Order --
      ---------------------

      procedure Find_Elab_Order (Elab_Order : out Unit_Id_Table) is
         Best_So_Far : Unit_Id;
         U           : Unit_Id;

      begin
         --  Gather dependencies and output them if option set

         Gather_Dependencies;

         Compute_Unit_SCCs;

         --  Initialize the no-predecessor list

         No_Pred := No_Unit_Id;
         for U in UNR.First .. UNR.Last loop
            if UNR.Table (U).Num_Pred = 0 then
               UNR.Table (U).Nextnp := No_Pred;
               No_Pred := U;
            end if;
         end loop;

         --  OK, now we determine the elaboration order proper. All we do is to
         --  select the best choice from the no-predecessor list until all the
         --  nodes have been chosen.

         Outer : loop
            if Debug_Flag_N then
               Write_Line ("Outer loop");
            end if;

            --  If there are no nodes with predecessors, then either we are
            --  done, as indicated by Num_Left being set to zero, or we have a
            --  circularity. In the latter case, diagnose the circularity,
            --  removing it from the graph and
            --  continue. Diagnose_Elaboration_Problem always raises an
            --  exception, so the loop never goes around more than once.

            Get_No_Pred : while No_Pred = No_Unit_Id loop
               exit Outer when Num_Left < 1;
               Diagnose_Elaboration_Problem (Elab_Order);
            end loop Get_No_Pred;

            U := No_Pred;
            Best_So_Far := No_Unit_Id;

            --  Loop to choose best entry in No_Pred list

            No_Pred_Search : loop
               if Debug_Flag_N then
                  Write_Str ("  considering choice of ");
                  Write_Unit_Name (Units.Table (U).Uname);
                  Write_Eol;

                  if Units.Table (U).Elaborate_Body then
                     Write_Str
                       ("    Elaborate_Body = True, Num_Pred for body = ");
                     Write_Int
                       (UNR.Table (Corresponding_Body (U)).Num_Pred);
                  else
                     Write_Str
                       ("    Elaborate_Body = False");
                  end if;

                  Write_Eol;
               end if;

               --  Don't even consider units whose SCC is not ready. This
               --  ensures that all units of an SCC will be elaborated
               --  together, with no other units in between.

               if SCC_Num_Pred (U) = 0
                 and then Better_Choice (U, Best_So_Far)
               then
                  if Debug_Flag_N then
                     Write_Line ("    tentatively chosen (best so far)");
                  end if;

                  Best_So_Far := U;
               else
                  if Debug_Flag_N then
                     Write_Line ("    SCC not ready");
                  end if;
               end if;

               U := UNR.Table (U).Nextnp;
               exit No_Pred_Search when U = No_Unit_Id;
            end loop No_Pred_Search;

            --  If there are no units on the No_Pred list whose SCC is ready,
            --  there must be a cycle. Defer to Elab_Old to print an error
            --  message.

            if Best_So_Far = No_Unit_Id then
               Elab_Cycle_Found := True;
               return;
            end if;

            --  Choose the best candidate found

            Choose (Elab_Order, Best_So_Far, " [Best_So_Far]");

            --  If it's a spec with a body, and the body is not yet chosen,
            --  choose the body if possible. The case where the body is
            --  already chosen is Elaborate_Body; the above call to Choose
            --  the spec will also Choose the body.

            if Units.Table (Best_So_Far).Utype = Is_Spec
              and then UNR.Table
                         (Corresponding_Body (Best_So_Far)).Elab_Position = 0
            then
               declare
                  Choose_The_Body : constant Boolean :=
                                      UNR.Table (Corresponding_Body
                                        (Best_So_Far)).Num_Pred = 0;

               begin
                  if Debug_Flag_B then
                     Write_Str ("Can we choose the body?... ");

                     if Choose_The_Body then
                        Write_Line ("Yes!");
                     else
                        Write_Line ("No.");
                     end if;
                  end if;

                  if Choose_The_Body then
                     Choose
                       (Elab_Order => Elab_Order,
                        Chosen     => Corresponding_Body (Best_So_Far),
                        Msg        => " [body]");
                  end if;
               end;
            end if;

            --  Finally, choose all the rest of the units in the same SCC as
            --  Best_So_Far. If it hasn't been chosen (Elab_Position = 0), and
            --  it's ready to be chosen (Num_Pred = 0), then we can choose it.

            loop
               declare
                  Chose_One_Or_More : Boolean := False;
                  SCC : Unit_Id_Array renames Nodes (Best_So_Far).all;

               begin
                  for J in SCC'Range loop
                     if UNR.Table (SCC (J)).Elab_Position = 0
                       and then UNR.Table (SCC (J)).Num_Pred = 0
                     then
                        Chose_One_Or_More := True;
                        Choose (Elab_Order, SCC (J), " [same SCC]");
                     end if;
                  end loop;

                  exit when not Chose_One_Or_More;
               end;
            end loop;
         end loop Outer;

         Find_Elab_All_Errors;
      end Find_Elab_Order;

      -----------
      -- Nodes --
      -----------

      function Nodes (U : Unit_Id) return Unit_Id_Array_Ptr is
      begin
         return UNR.Table (SCC (U)).Nodes;
      end Nodes;

      ---------
      -- SCC --
      ---------

      function SCC (U : Unit_Id) return Unit_Id is
      begin
         return UNR.Table (U).SCC_Root;
      end SCC;

      ------------------
      -- SCC_Num_Pred --
      ------------------

      function SCC_Num_Pred (U : Unit_Id) return Int is
      begin
         return UNR.Table (SCC (U)).SCC_Num_Pred;
      end SCC_Num_Pred;

      ---------------
      -- Write_SCC --
      ---------------

      procedure Write_SCC (U : Unit_Id) is
         pragma Assert (SCC (U) = U);
      begin
         for J in Nodes (U)'Range loop
            Write_Int (UNR.Table (Nodes (U) (J)).Elab_Position);
            Write_Str (". ");
            Write_Unit_Name (Units.Table (Nodes (U) (J)).Uname);
            Write_Eol;
         end loop;

         Write_Eol;
      end Write_SCC;

   end Elab_New;

   --------------
   -- Elab_Old --
   --------------

   package body Elab_Old is

      ---------------------
      -- Find_Elab_Order --
      ---------------------

      procedure Find_Elab_Order (Elab_Order : out Unit_Id_Table) is
         Best_So_Far : Unit_Id;
         U           : Unit_Id;

      begin
         --  Gather dependencies and output them if option set

         Gather_Dependencies;

         --  Initialize the no-predecessor list

         No_Pred := No_Unit_Id;
         for U in UNR.First .. UNR.Last loop
            if UNR.Table (U).Num_Pred = 0 then
               UNR.Table (U).Nextnp := No_Pred;
               No_Pred := U;
            end if;
         end loop;

         --  OK, now we determine the elaboration order proper. All we do is to
         --  select the best choice from the no-predecessor list until all the
         --  nodes have been chosen.

         Outer : loop

            --  If there are no nodes with predecessors, then either we are
            --  done, as indicated by Num_Left being set to zero, or we have a
            --  circularity. In the latter case, diagnose the circularity,
            --  removing it from the graph and continue.
            --  Diagnose_Elaboration_Problem always raises an exception, so the
            --  loop never goes around more than once.

            Get_No_Pred : while No_Pred = No_Unit_Id loop
               exit Outer when Num_Left < 1;
               Diagnose_Elaboration_Problem (Elab_Order);
            end loop Get_No_Pred;

            U := No_Pred;
            Best_So_Far := No_Unit_Id;

            --  Loop to choose best entry in No_Pred list

            No_Pred_Search : loop
               if Debug_Flag_N then
                  Write_Str ("  considering choice of ");
                  Write_Unit_Name (Units.Table (U).Uname);
                  Write_Eol;

                  if Units.Table (U).Elaborate_Body then
                     Write_Str
                       ("    Elaborate_Body = True, Num_Pred for body = ");
                     Write_Int
                       (UNR.Table (Corresponding_Body (U)).Num_Pred);
                  else
                     Write_Str
                       ("    Elaborate_Body = False");
                  end if;

                  Write_Eol;
               end if;

               --  This is a candididate to be considered for choice

               if Better_Choice (U, Best_So_Far) then
                  if Debug_Flag_N then
                     Write_Line ("    tentatively chosen (best so far)");
                  end if;

                  Best_So_Far := U;
               end if;

               U := UNR.Table (U).Nextnp;
               exit No_Pred_Search when U = No_Unit_Id;
            end loop No_Pred_Search;

            --  Choose the best candidate found

            Choose (Elab_Order, Best_So_Far, " [Elab_Old Best_So_Far]");
         end loop Outer;
      end Find_Elab_Order;

   end Elab_Old;

end Binde;
