------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                  L I B                                   --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2004 Free Software Foundation, Inc.          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

pragma Style_Checks (All_Checks);
--  Subprogram ordering not enforced in this unit
--  (because of some logical groupings).

with Atree;   use Atree;
with Einfo;   use Einfo;
with Fname;   use Fname;
with Namet;   use Namet;
with Namet;   use Namet;
with Output;  use Output;
with Sinfo;   use Sinfo;
with Sinput;  use Sinput;
with Stand;   use Stand;
with Stringt; use Stringt;
with Tree_IO; use Tree_IO;
with Uname;   use Uname;

package body Lib is

   Switch_Storing_Enabled : Boolean := True;
   --  Set to False by Disable_Switch_Storing

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

   type SEU_Result is (
      Yes_Before, -- S1 is in same extended unit as S2 and appears before it
      Yes_Same,   -- S1 is in same extended unit as S2, Slocs are the same
      Yes_After,  -- S1 is in same extended unit as S2, and appears after it
      No);        -- S2 is not in same extended unit as S2

   function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result;
   --  Used by In_Same_Extended_Unit and Earlier_In_Extended_Unit. Returns
   --  value as described above.

   --------------------------------------------
   -- Access Functions for Unit Table Fields --
   --------------------------------------------

   function Cunit (U : Unit_Number_Type) return Node_Id is
   begin
      return Units.Table (U).Cunit;
   end Cunit;

   function Cunit_Entity (U : Unit_Number_Type) return Entity_Id is
   begin
      return Units.Table (U).Cunit_Entity;
   end Cunit_Entity;

   function Dependency_Num (U : Unit_Number_Type) return Nat is
   begin
      return Units.Table (U).Dependency_Num;
   end Dependency_Num;

   function Dynamic_Elab (U : Unit_Number_Type) return Boolean is
   begin
      return Units.Table (U).Dynamic_Elab;
   end Dynamic_Elab;

   function Error_Location (U : Unit_Number_Type) return Source_Ptr is
   begin
      return Units.Table (U).Error_Location;
   end Error_Location;

   function Expected_Unit (U : Unit_Number_Type) return Unit_Name_Type is
   begin
      return Units.Table (U).Expected_Unit;
   end Expected_Unit;

   function Fatal_Error (U : Unit_Number_Type) return Boolean is
   begin
      return Units.Table (U).Fatal_Error;
   end Fatal_Error;

   function Generate_Code (U : Unit_Number_Type) return Boolean is
   begin
      return Units.Table (U).Generate_Code;
   end Generate_Code;

   function Has_RACW (U : Unit_Number_Type) return Boolean is
   begin
      return Units.Table (U).Has_RACW;
   end Has_RACW;

   function Ident_String (U : Unit_Number_Type) return Node_Id is
   begin
      return Units.Table (U).Ident_String;
   end Ident_String;

   function Loading (U : Unit_Number_Type) return Boolean is
   begin
      return Units.Table (U).Loading;
   end Loading;

   function Main_Priority (U : Unit_Number_Type) return Int is
   begin
      return Units.Table (U).Main_Priority;
   end Main_Priority;

   function Munit_Index (U : Unit_Number_Type) return Nat is
   begin
      return Units.Table (U).Munit_Index;
   end Munit_Index;

   function Source_Index (U : Unit_Number_Type) return Source_File_Index is
   begin
      return Units.Table (U).Source_Index;
   end Source_Index;

   function Unit_File_Name (U : Unit_Number_Type) return File_Name_Type is
   begin
      return Units.Table (U).Unit_File_Name;
   end Unit_File_Name;

   function Unit_Name (U : Unit_Number_Type) return Unit_Name_Type is
   begin
      return Units.Table (U).Unit_Name;
   end Unit_Name;

   ------------------------------------------
   -- Subprograms to Set Unit Table Fields --
   ------------------------------------------

   procedure Set_Cunit (U : Unit_Number_Type; N : Node_Id) is
   begin
      Units.Table (U).Cunit := N;
   end Set_Cunit;

   procedure Set_Cunit_Entity (U : Unit_Number_Type; E : Entity_Id) is
   begin
      Units.Table (U).Cunit_Entity := E;
      Set_Is_Compilation_Unit (E);
   end Set_Cunit_Entity;

   procedure Set_Dynamic_Elab (U : Unit_Number_Type; B : Boolean := True) is
   begin
      Units.Table (U).Dynamic_Elab := B;
   end Set_Dynamic_Elab;

   procedure Set_Error_Location (U : Unit_Number_Type; W : Source_Ptr) is
   begin
      Units.Table (U).Error_Location := W;
   end Set_Error_Location;

   procedure Set_Fatal_Error (U : Unit_Number_Type; B : Boolean := True) is
   begin
      Units.Table (U).Fatal_Error := B;
   end Set_Fatal_Error;

   procedure Set_Generate_Code (U : Unit_Number_Type; B : Boolean := True) is
   begin
      Units.Table (U).Generate_Code := B;
   end Set_Generate_Code;

   procedure Set_Has_RACW (U : Unit_Number_Type; B : Boolean := True) is
   begin
      Units.Table (U).Has_RACW := B;
   end Set_Has_RACW;

   procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id) is
   begin
      Units.Table (U).Ident_String := N;
   end Set_Ident_String;

   procedure Set_Loading (U : Unit_Number_Type; B : Boolean := True) is
   begin
      Units.Table (U).Loading := B;
   end Set_Loading;

   procedure Set_Main_Priority (U : Unit_Number_Type; P : Int) is
   begin
      Units.Table (U).Main_Priority := P;
   end Set_Main_Priority;

   procedure Set_Unit_Name (U : Unit_Number_Type; N : Unit_Name_Type) is
   begin
      Units.Table (U).Unit_Name := N;
   end Set_Unit_Name;

   ------------------------------
   -- Check_Same_Extended_Unit --
   ------------------------------

   function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result is
      Sloc1  : Source_Ptr;
      Sloc2  : Source_Ptr;
      Sind1  : Source_File_Index;
      Sind2  : Source_File_Index;
      Inst1  : Source_Ptr;
      Inst2  : Source_Ptr;
      Unum1  : Unit_Number_Type;
      Unum2  : Unit_Number_Type;
      Unit1  : Node_Id;
      Unit2  : Node_Id;
      Depth1 : Nat;
      Depth2 : Nat;

   begin
      if S1 = No_Location or else S2 = No_Location then
         return No;

      elsif S1 = Standard_Location then
         if S2 = Standard_Location then
            return Yes_Same;
         else
            return No;
         end if;

      elsif S2 = Standard_Location then
         return No;
      end if;

      Sloc1 := S1;
      Sloc2 := S2;
      Unum1 := Get_Code_Unit (Sloc1);
      Unum2 := Get_Code_Unit (Sloc2);

      loop
         Sind1 := Get_Source_File_Index (Sloc1);
         Sind2 := Get_Source_File_Index (Sloc2);

         if Sind1 = Sind2 then
            if Sloc1 < Sloc2 then
               return Yes_Before;
            elsif Sloc1 > Sloc2 then
               return Yes_After;
            else
               return Yes_Same;
            end if;
         end if;

         --  OK, the two nodes are in separate source elements, but this is not
         --  decisive, because of the issue of subunits and instantiations.

         --  First we deal with subunits, since if the subunit is in an
         --  instantiation, we know that the parent is in the corresponding
         --  instantiation, since that is the only way we can have a subunit
         --  that is part of an instantiation.

         Unit1 := Unit (Cunit (Unum1));
         Unit2 := Unit (Cunit (Unum2));

         if Nkind (Unit1) = N_Subunit
           and then Present (Corresponding_Stub (Unit1))
         then
            --  Both in subunits. They could have a common ancestor. If they
            --  do, then the deeper one must have a longer unit name. Replace
            --  the deeper one with its corresponding stub, in order to find
            --  nearest common ancestor, if any.

            if Nkind (Unit2) = N_Subunit
              and then Present (Corresponding_Stub (Unit2))
            then
               if Length_Of_Name (Unit_Name (Unum1)) <
                  Length_Of_Name (Unit_Name (Unum2))
               then
                  Sloc2 := Sloc (Corresponding_Stub (Unit2));
                  Unum2 := Get_Source_Unit (Sloc2);
                  goto Continue;

               else
                  Sloc1 := Sloc (Corresponding_Stub (Unit1));
                  Unum1 := Get_Source_Unit (Sloc1);
                  goto Continue;
               end if;

            --  Nod1 in subunit, Nod2 not

            else
               Sloc1 := Sloc (Corresponding_Stub (Unit1));
               Unum1 := Get_Source_Unit (Sloc1);
               goto Continue;
            end if;

         --  Nod2 in subunit, Nod1 not

         elsif Nkind (Unit2) = N_Subunit
           and then Present (Corresponding_Stub (Unit2))
         then
            Sloc2 := Sloc (Corresponding_Stub (Unit2));
            Unum2 := Get_Source_Unit (Sloc2);
            goto Continue;
         end if;

         --  At this stage we know that neither is a subunit, so we deal
         --  with instantiations, since we culd have a common ancestor

         Inst1 := Instantiation (Sind1);
         Inst2 := Instantiation (Sind2);

         if Inst1 /= No_Location then

            --  Both are instantiations

            if Inst2 /= No_Location then

               Depth1 := Instantiation_Depth (Sloc1);
               Depth2 := Instantiation_Depth (Sloc2);

               if Depth1 < Depth2 then
                  Sloc2 := Inst2;
                  Unum2 := Get_Source_Unit (Sloc2);
                  goto Continue;

               elsif Depth1 > Depth2 then
                  Sloc1 := Inst1;
                  Unum1 := Get_Source_Unit (Sloc1);
                  goto Continue;

               else
                  Sloc1 := Inst1;
                  Sloc2 := Inst2;
                  Unum1 := Get_Source_Unit (Sloc1);
                  Unum2 := Get_Source_Unit (Sloc2);
                  goto Continue;
               end if;

            --  Only first node is in instantiation

            else
               Sloc1 := Inst1;
               Unum1 := Get_Source_Unit (Sloc1);
               goto Continue;
            end if;

         --  Only second node is instantiation

         elsif Inst2 /= No_Location then
            Sloc2 := Inst2;
            Unum2 := Get_Source_Unit (Sloc2);
            goto Continue;
         end if;

         --  No instantiations involved, so we are not in the same unit
         --  However, there is one case still to check, namely the case
         --  where one location is in the spec, and the other in the
         --  corresponding body (the spec location is earlier).

         if Nkind (Unit1) = N_Subprogram_Body
              or else
            Nkind (Unit1) = N_Package_Body
         then
            if Library_Unit (Cunit (Unum1)) = Cunit (Unum2) then
               return Yes_After;
            end if;

         elsif Nkind (Unit2) = N_Subprogram_Body
                 or else
               Nkind (Unit2) = N_Package_Body
         then
            if Library_Unit (Cunit (Unum2)) = Cunit (Unum1) then
               return Yes_Before;
            end if;
         end if;

         --  If that special case does not occur, then we are certain that
         --  the two locations are really in separate units.

         return No;

         <<Continue>>
            null;
      end loop;
   end Check_Same_Extended_Unit;

   -------------------------------
   -- Compilation_Switches_Last --
   -------------------------------

   function Compilation_Switches_Last return Nat is
   begin
      return Compilation_Switches.Last;
   end Compilation_Switches_Last;

   procedure Disable_Switch_Storing is
   begin
      Switch_Storing_Enabled := False;
   end Disable_Switch_Storing;

   ------------------------------
   -- Earlier_In_Extended_Unit --
   ------------------------------

   function Earlier_In_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is
   begin
      return Check_Same_Extended_Unit (S1, S2) = Yes_Before;
   end Earlier_In_Extended_Unit;

   ----------------------------
   -- Entity_Is_In_Main_Unit --
   ----------------------------

   function Entity_Is_In_Main_Unit (E : Entity_Id) return Boolean is
      S : Entity_Id;

   begin
      S := Scope (E);

      while S /= Standard_Standard loop
         if S = Main_Unit_Entity then
            return True;
         elsif Ekind (S) = E_Package and then Is_Child_Unit (S) then
            return False;
         else
            S := Scope (S);
         end if;
      end loop;

      return False;
   end Entity_Is_In_Main_Unit;

   ---------------------------------
   -- Generic_Separately_Compiled --
   ---------------------------------

   function Generic_Separately_Compiled (E : Entity_Id) return Boolean is
   begin
      --  We do not generate object files for internal generics, because
      --  the only thing they would contain is the elaboration boolean, and
      --  we are careful to elaborate all predefined units first anyway, so
      --  this boolean is not needed.

      if Is_Internal_File_Name
          (Fname => Unit_File_Name (Get_Source_Unit (E)),
           Renamings_Included => True)
      then
         return False;

      --  All other generic units do generate object files

      else
         return True;
      end if;
   end Generic_Separately_Compiled;

   function Generic_Separately_Compiled
     (Sfile : File_Name_Type) return Boolean
   is
   begin
      --  Exactly the same as previous function, but works directly on a file
      --  name.

      if Is_Internal_File_Name
          (Fname              => Sfile,
           Renamings_Included => True)
      then
         return False;

      --  All other generic units do generate object files

      else
         return True;
      end if;
   end Generic_Separately_Compiled;

   -------------------
   -- Get_Code_Unit --
   -------------------

   function Get_Code_Unit (S : Source_Ptr) return Unit_Number_Type is
   begin
      --  Search table unless we have No_Location, which can happen if the
      --  relevant location has not been set yet. Happens for example when
      --  we obtain Sloc (Cunit (Main_Unit)) before it is set.

      if S /= No_Location then
         declare
            Source_File : constant Source_File_Index :=
                            Get_Source_File_Index (Top_Level_Location (S));

         begin
            for U in Units.First .. Units.Last loop
               if Source_Index (U) = Source_File then
                  return U;
               end if;
            end loop;
         end;
      end if;

      --  If S was No_Location, or was not in the table, we must be in the
      --  main source unit (and the value has not been placed in the table yet)

      return Main_Unit;
   end Get_Code_Unit;

   function Get_Code_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
   begin
      return Get_Code_Unit (Sloc (N));
   end Get_Code_Unit;

   ----------------------------
   -- Get_Compilation_Switch --
   ----------------------------

   function Get_Compilation_Switch (N : Pos) return String_Ptr is
   begin
      if N <= Compilation_Switches.Last then
         return Compilation_Switches.Table (N);

      else
         return null;
      end if;
   end Get_Compilation_Switch;

   ----------------------------------
   -- Get_Cunit_Entity_Unit_Number --
   ----------------------------------

   function Get_Cunit_Entity_Unit_Number
     (E : Entity_Id) return Unit_Number_Type
   is
   begin
      for U in Units.First .. Units.Last loop
         if Cunit_Entity (U) = E then
            return U;
         end if;
      end loop;

      --  If not in the table, must be the main source unit, and we just
      --  have not got it put into the table yet.

      return Main_Unit;
   end Get_Cunit_Entity_Unit_Number;

   ---------------------------
   -- Get_Cunit_Unit_Number --
   ---------------------------

   function Get_Cunit_Unit_Number (N : Node_Id) return Unit_Number_Type is
   begin
      for U in Units.First .. Units.Last loop
         if Cunit (U) = N then
            return U;
         end if;
      end loop;

      --  If not in the table, must be the main source unit, and we just
      --  have not got it put into the table yet.

      return Main_Unit;
   end Get_Cunit_Unit_Number;

   ---------------------
   -- Get_Source_Unit --
   ---------------------

   function Get_Source_Unit (S : Source_Ptr) return Unit_Number_Type is
   begin
      --  Search table unless we have No_Location, which can happen if the
      --  relevant location has not been set yet. Happens for example when
      --  we obtain Sloc (Cunit (Main_Unit)) before it is set.

      if S /= No_Location then
         declare
            Source_File : Source_File_Index :=
                            Get_Source_File_Index (Top_Level_Location (S));

         begin
            Source_File := Get_Source_File_Index (S);
            while Template (Source_File) /= No_Source_File loop
               Source_File := Template (Source_File);
            end loop;

            for U in Units.First .. Units.Last loop
               if Source_Index (U) = Source_File then
                  return U;
               end if;
            end loop;
         end;
      end if;

      --  If S was No_Location, or was not in the table, we must be in the
      --  main source unit (and the value has not got put into the table yet)

      return Main_Unit;
   end Get_Source_Unit;

   function Get_Source_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
   begin
      return Get_Source_Unit (Sloc (N));
   end Get_Source_Unit;

   --------------------------------
   -- In_Extended_Main_Code_Unit --
   --------------------------------

   function In_Extended_Main_Code_Unit
     (N : Node_Or_Entity_Id) return Boolean
   is
   begin
      if Sloc (N) = Standard_Location then
         return True;

      elsif Sloc (N) = No_Location then
         return False;

      --  Special case Itypes to test the Sloc of the associated node. The
      --  reason we do this is for possible calls from gigi after -gnatD
      --  processing is complete in sprint. This processing updates the
      --  sloc fields of all nodes in the tree, but itypes are not in the
      --  tree so their slocs do not get updated.

      elsif Nkind (N) = N_Defining_Identifier
        and then Is_Itype (N)
      then
         return In_Extended_Main_Code_Unit (Associated_Node_For_Itype (N));

      --  Otherwise see if we are in the main unit

      elsif Get_Code_Unit (Sloc (N)) = Get_Code_Unit (Cunit (Main_Unit)) then
         return True;

      --  Node may be in spec (or subunit etc) of main unit

      else
         return
           In_Same_Extended_Unit (N, Cunit (Main_Unit));
      end if;
   end In_Extended_Main_Code_Unit;

   function In_Extended_Main_Code_Unit (Loc : Source_Ptr) return Boolean is
   begin
      if Loc = Standard_Location then
         return True;

      elsif Loc = No_Location then
         return False;

      --  Otherwise see if we are in the main unit

      elsif Get_Code_Unit (Loc) = Get_Code_Unit (Cunit (Main_Unit)) then
         return True;

      --  Location may be in spec (or subunit etc) of main unit

      else
         return
           In_Same_Extended_Unit (Loc, Sloc (Cunit (Main_Unit)));
      end if;
   end In_Extended_Main_Code_Unit;

   ----------------------------------
   -- In_Extended_Main_Source_Unit --
   ----------------------------------

   function In_Extended_Main_Source_Unit
     (N : Node_Or_Entity_Id) return Boolean
   is
      Nloc : constant Source_Ptr := Sloc (N);
      Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit));

   begin
      --  If Mloc is not set, it means we are still parsing the main unit,
      --  so everything so far is in the extended main source unit.

      if Mloc = No_Location then
         return True;

      --  Special value cases

      elsif Nloc = Standard_Location then
         return True;

      elsif Nloc = No_Location then
         return False;

      --  Special case Itypes to test the Sloc of the associated node. The
      --  reason we do this is for possible calls from gigi after -gnatD
      --  processing is complete in sprint. This processing updates the
      --  sloc fields of all nodes in the tree, but itypes are not in the
      --  tree so their slocs do not get updated.

      elsif Nkind (N) = N_Defining_Identifier
        and then Is_Itype (N)
      then
         return In_Extended_Main_Source_Unit (Associated_Node_For_Itype (N));

      --  Otherwise compare original locations to see if in same unit

      else
         return
           In_Same_Extended_Unit
             (Original_Location (Nloc), Original_Location (Mloc));
      end if;
   end In_Extended_Main_Source_Unit;

   function In_Extended_Main_Source_Unit
     (Loc : Source_Ptr) return Boolean
   is
      Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit));

   begin
      --  If Mloc is not set, it means we are still parsing the main unit,
      --  so everything so far is in the extended main source unit.

      if Mloc = No_Location then
         return True;

      --  Special value cases

      elsif Loc = Standard_Location then
         return True;

      elsif Loc = No_Location then
         return False;

      --  Otherwise compare original locations to see if in same unit

      else
         return
           In_Same_Extended_Unit
             (Original_Location (Loc), Original_Location (Mloc));
      end if;
   end In_Extended_Main_Source_Unit;

   -----------------------
   -- In_Same_Code_Unit --
   -----------------------

   function In_Same_Code_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is
      S1 : constant Source_Ptr := Sloc (N1);
      S2 : constant Source_Ptr := Sloc (N2);

   begin
      if S1 = No_Location or else S2 = No_Location then
         return False;

      elsif S1 = Standard_Location then
         return S2 = Standard_Location;

      elsif S2 = Standard_Location then
         return False;
      end if;

      return Get_Code_Unit (N1) = Get_Code_Unit (N2);
   end In_Same_Code_Unit;

   ---------------------------
   -- In_Same_Extended_Unit --
   ---------------------------

   function In_Same_Extended_Unit
     (N1, N2 : Node_Or_Entity_Id) return Boolean
   is
   begin
      return Check_Same_Extended_Unit (Sloc (N1), Sloc (N2)) /= No;
   end In_Same_Extended_Unit;

   function In_Same_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is
   begin
      return Check_Same_Extended_Unit (S1, S2) /= No;
   end In_Same_Extended_Unit;

   -------------------------
   -- In_Same_Source_Unit --
   -------------------------

   function In_Same_Source_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is
      S1 : constant Source_Ptr := Sloc (N1);
      S2 : constant Source_Ptr := Sloc (N2);

   begin
      if S1 = No_Location or else S2 = No_Location then
         return False;

      elsif S1 = Standard_Location then
         return S2 = Standard_Location;

      elsif S2 = Standard_Location then
         return False;
      end if;

      return Get_Source_Unit (N1) = Get_Source_Unit (N2);
   end In_Same_Source_Unit;

   -----------------------------
   -- Increment_Serial_Number --
   -----------------------------

   function Increment_Serial_Number return Nat is
      TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
   begin
      TSN := TSN + 1;
      return TSN;
   end Increment_Serial_Number;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      Linker_Option_Lines.Init;
      Load_Stack.Init;
      Units.Init;
      Unit_Exception_Table_Present := False;
      Compilation_Switches.Init;
   end Initialize;

   ---------------
   -- Is_Loaded --
   ---------------

   function Is_Loaded (Uname : Unit_Name_Type) return Boolean is
   begin
      for Unum in Units.First .. Units.Last loop
         if Uname = Unit_Name (Unum) then
            return True;
         end if;
      end loop;

      return False;
   end Is_Loaded;

   ---------------
   -- Last_Unit --
   ---------------

   function Last_Unit return Unit_Number_Type is
   begin
      return Units.Last;
   end Last_Unit;

   ----------
   -- List --
   ----------

   procedure List (File_Names_Only : Boolean := False) is separate;

   ----------
   -- Lock --
   ----------

   procedure Lock is
   begin
      Linker_Option_Lines.Locked := True;
      Load_Stack.Locked := True;
      Units.Locked := True;
      Linker_Option_Lines.Release;
      Load_Stack.Release;
      Units.Release;
   end Lock;

   ---------------
   -- Num_Units --
   ---------------

   function Num_Units return Nat is
   begin
      return Int (Units.Last) - Int (Main_Unit) + 1;
   end Num_Units;

   -----------------
   -- Remove_Unit --
   -----------------

   procedure Remove_Unit (U : Unit_Number_Type) is
   begin
      if U = Units.Last then
         Units.Decrement_Last;
      end if;
   end Remove_Unit;

   ----------------------------------
   -- Replace_Linker_Option_String --
   ----------------------------------

   procedure Replace_Linker_Option_String
     (S : String_Id; Match_String : String)
   is
   begin
      if Match_String'Length > 0 then
         for J in 1 .. Linker_Option_Lines.Last loop
            String_To_Name_Buffer (Linker_Option_Lines.Table (J).Option);

            if Match_String = Name_Buffer (1 .. Match_String'Length) then
               Linker_Option_Lines.Table (J).Option := S;
               return;
            end if;
         end loop;
      end if;

      Store_Linker_Option_String (S);
   end Replace_Linker_Option_String;

   ----------
   -- Sort --
   ----------

   procedure Sort (Tbl : in out Unit_Ref_Table) is separate;

   ------------------------------
   -- Store_Compilation_Switch --
   ------------------------------

   procedure Store_Compilation_Switch (Switch : String) is
   begin
      if Switch_Storing_Enabled then
         Compilation_Switches.Increment_Last;
         Compilation_Switches.Table (Compilation_Switches.Last) :=
           new String'(Switch);

         --  Fix up --RTS flag which has been transformed by the gcc driver
         --  into -fRTS

         if Switch'Last >= Switch'First + 4
           and then Switch (Switch'First .. Switch'First + 4) = "-fRTS"
         then
            Compilation_Switches.Table
              (Compilation_Switches.Last) (Switch'First + 1) := '-';
         end if;
      end if;
   end Store_Compilation_Switch;

   --------------------------------
   -- Store_Linker_Option_String --
   --------------------------------

   procedure Store_Linker_Option_String (S : String_Id) is
   begin
      Linker_Option_Lines.Increment_Last;
      Linker_Option_Lines.Table (Linker_Option_Lines.Last) :=
        (Option => S, Unit => Current_Sem_Unit);
   end Store_Linker_Option_String;

   -------------------------------
   -- Synchronize_Serial_Number --
   -------------------------------

   procedure Synchronize_Serial_Number is
      TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
   begin
      TSN := TSN + 1;
   end Synchronize_Serial_Number;

   ---------------
   -- Tree_Read --
   ---------------

   procedure Tree_Read is
      N : Nat;
      S : String_Ptr;

   begin
      Units.Tree_Read;

      --  Read Compilation_Switches table

      Tree_Read_Int (N);
      Compilation_Switches.Set_Last (N);

      for J in 1 .. N loop
         Tree_Read_Str (S);
         Compilation_Switches.Table (J) := S;
      end loop;
   end Tree_Read;

   ----------------
   -- Tree_Write --
   ----------------

   procedure Tree_Write is
   begin
      Units.Tree_Write;

      --  Write Compilation_Switches table

      Tree_Write_Int (Compilation_Switches.Last);

      for J in 1 .. Compilation_Switches.Last loop
         Tree_Write_Str (Compilation_Switches.Table (J));
      end loop;
   end Tree_Write;

   -----------------
   -- Version_Get --
   -----------------

   function Version_Get (U : Unit_Number_Type) return Word_Hex_String is
   begin
      return Get_Hex_String (Units.Table (U).Version);
   end Version_Get;

   ------------------------
   -- Version_Referenced --
   ------------------------

   procedure Version_Referenced (S : String_Id) is
   begin
      Version_Ref.Append (S);
   end Version_Referenced;

end Lib;
