------------------------------------------------------------------------------
--                                                                          --
--                            GNATELIM COMPONENTS                           --
--                                                                          --
--                       G N A T E L I M . E N T I T I E S                  --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--            Copyright (c) 1997-1999, Free Software Foundation, Inc.       --
--                                                                          --
-- Gnatelim is free software; you can redistribute it and/or modify it      --
-- under terms of the  GNU General Public License  as published by the Free --
-- Software Foundation;  either version 2,  or  (at your option)  any later --
-- version. Gnatelim is distributed  in the hope  that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MER-      --
-- CHANTABILITY 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.                                              --
--                                                                          --
-- Gnatelim is distributed as a part of the ASIS implementation for GNAT    --
-- (ASIS-for-GNAT).                                                         --
--                                                                          --
-- Gnatelim was originally developed by Alain Le Guennec                    --
--                                                                          --
-- Gnatelim  is  now  maintained  by  Ada  Core  Technologies  Inc          --
-- (http://www.gnat.com).                                                   --
------------------------------------------------------------------------------

with Asis;

package GNATELIM.Entities is

   type Entity_Id is private;
   type Entity_Id_List is array (Natural range <>) of Entity_Id;


   No_Entity : constant Entity_Id;


   function No (Entity : Entity_Id) return Boolean;
   pragma Inline (No);
   --  Returns True if Entity = No_Entity.


   function Present (Entity : Entity_Id) return Boolean;
   pragma Inline (Present);
   --  Returns True if Entity /= No_Entity.


   Already_Registered : exception;
   --  Raised when trying to register an entity that was already registered.


   function  New_Entity (Element  : Asis.Element;
                         Instance : Entity_Id;
                         Name     : Wide_String;
                         Scope    : Entity_Id)
                         return Entity_Id;
   --  Creates (and inserts in a Table) a new Entity.
   --  This is the only function that creates a _new_ Entity_Id.


   function  Get_Element (Entity  : Entity_Id)
                          return Asis.Element;
   --  Returns the (ASIS.)Element corresponding to the Entity.
   --  Get_Element (No_Entity) = Asis.Nil_Element.


   function  Get_Name (Entity : Entity_Id) return Wide_String;
   --  Returns the defining name of the Entity.
   --  Get_Name (No_Entity) = "".


   function  Get_Instance (Entity  : Entity_Id)
                           return Entity_Id;
   --  Returns the Instance in which Entity is declared.
   --  Returns No_Entity for Entities that are not part of any instance.
   --  Get_Instance (No_Entity) = No_Entity.


   function  Get_Scope (Entity  : Entity_Id)
                        return Entity_Id;
   --  Returns the Scope in which Entity is declared.
   --  Get_Scope (No_Entity) = No_Entity.


   function  Corresponding_Declaration (Entity  : Entity_Id)
                                        return Asis.Declaration;
   --  Returns the declaration Element corresponding to Entity.
   --  If the Entity is not based on a defining name, return Nil_element.


   function  First_Homonym (Entity : Entity_Id) return Entity_Id;
   --  Returns the first homonym of Entity (same scope & name.)


   function  Next_Homonym  (Entity : Entity_Id) return Entity_Id;
   --  Returns the next homonym of Entity.


   function  Corresponding_Entity  (Element  : Asis.Element;
                                    Instance : Entity_Id)
                                    return Entity_Id;
   --  Returns the Entity (a element of the Table) corresponding
   --  to the (ASIS.)Element, and declared in the given Instance.
   --  If the Entity is not part of any instance, use No_Entity
   --  as the actual value for Instance.
   --  NOTE: If the expected result had not been registered before,
   --  a No_Entity is returned.


   function  Renamed_Entity (Renaming : Entity_Id) return Entity_Id;
   --  Returns the entity renamed by the Renaming.


   function  Unwind_Renamings (Entity : Entity_Id) return Entity_Id;
   --  Unwinds all renamings and returns the last renamed Entity.


   procedure Note_Use (Entity : Entity_Id; Used_By : Entity_Id);
   --  Marks a given entity as used by transitivity by another one.
   --  If Used_By is the No_Entity,
   --  the Entity can not be eliminated
   --  (ie. Is_Used (Entity) will be True.)


   function  Is_A_Master (Entity : Entity_Id) return Boolean;
   --  Returns True if the Entity is a master.


   function  Is_An_Instance (Entity : Entity_Id) return Boolean;
   --  Returns True if the Entity is a generic instantiation.


   function  Is_Used  (Entity : Entity_Id) return Boolean;
   --  Returns True if the Entity can't be eliminated.


   procedure Perform_Transitive_Closure;
   --  Performs the transitive closure on the whole call-graph.
   --  After this is done, it is possible to check if a given
   --  Entity can be eliminated by using the Is_Used function.


   generic
      with procedure Action (Entity   : in     Entity_Id;
                             Continue : in out Boolean);
   procedure Iterate;
   --  Apply the Action procedure to all registered entities.
   --  If Action sets Continue to False, then the iteration is aborted
   --  (Action is called with Continue set to True.)

private

   type Entity_Id is new Natural;
   --  Used to index the Entity_Information table.

   No_Entity : constant Entity_Id := 0;


   --  Boolean flags to characterize entities.
   Nb_Available_Flags : constant := 4;
   type Flag_Range is new Natural range 1 .. Nb_Available_Flags;
   Nb_Allocated_Flags : Flag_Range'Base := 0;

   generic
   package Boolean_Flag is
      procedure Set_Flag (Id : Entity_Id; Flag : Boolean);
      function  Get_Flag (Id : Entity_Id) return Boolean;
   end Boolean_Flag;


   --  Static links to connect entities with other entities.
   Nb_Available_Links : constant := 5;
   type Link_Range is new Natural range 1 .. Nb_Available_Links;
   Nb_Allocated_Links : Link_Range'Base := 0;

   generic
   package Static_Link is
      procedure Set_Link (Id : Entity_Id; Next : Entity_Id);
      function  Get_Link (Id : Entity_Id) return Entity_Id;
   end Static_Link;

end GNATELIM.Entities;