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

with Atree;          use Atree;
with Csets;          use Csets;
with Einfo;          use Einfo;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Lib.Util;       use Lib.Util;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Prag;       use Sem_Prag;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Stringt;        use Stringt;
with Stand;          use Stand;
with Table;          use Table;

with GNAT.Heap_Sort_G;
with GNAT.HTable;

package body Lib.Xref is

   ------------------
   -- Declarations --
   ------------------

   package Deferred_References is new Table.Table (
     Table_Component_Type => Deferred_Reference_Entry,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => 512,
     Table_Increment      => 200,
     Table_Name           => "Name_Deferred_References");

   --  The Xref table is used to record references. The Loc field is set
   --  to No_Location for a definition entry.

   subtype Xref_Entry_Number is Int;

   type Xref_Key is record
      --  These are the components of Xref_Entry that participate in hash
      --  lookups.

      Ent : Entity_Id;
      --  Entity referenced (E parameter to Generate_Reference)

      Loc : Source_Ptr;
      --  Location of reference (Original_Location (Sloc field of N parameter
      --  to Generate_Reference)). Set to No_Location for the case of a
      --  defining occurrence.

      Typ : Character;
      --  Reference type (Typ param to Generate_Reference)

      Eun : Unit_Number_Type;
      --  Unit number corresponding to Ent

      Lun : Unit_Number_Type;
      --  Unit number corresponding to Loc. Value is undefined and not
      --  referenced if Loc is set to No_Location.

      --  The following components are only used for SPARK cross-references

      Ref_Scope : Entity_Id;
      --  Entity of the closest subprogram or package enclosing the reference

      Ent_Scope : Entity_Id;
      --  Entity of the closest subprogram or package enclosing the definition,
      --  which should be located in the same file as the definition itself.
   end record;

   type Xref_Entry is record
      Key : Xref_Key;

      Ent_Scope_File : Unit_Number_Type;
      --  File for entity Ent_Scope

      Def : Source_Ptr;
      --  Original source location for entity being referenced. Note that these
      --  values are used only during the output process, they are not set when
      --  the entries are originally built. This is because private entities
      --  can be swapped when the initial call is made.

      HTable_Next : Xref_Entry_Number;
      --  For use only by Static_HTable
   end record;

   package Xrefs is new Table.Table (
     Table_Component_Type => Xref_Entry,
     Table_Index_Type     => Xref_Entry_Number,
     Table_Low_Bound      => 1,
     Table_Initial        => Alloc.Xrefs_Initial,
     Table_Increment      => Alloc.Xrefs_Increment,
     Table_Name           => "Xrefs");

   --------------
   -- Xref_Set --
   --------------

   --  We keep a set of xref entries, in order to avoid inserting duplicate
   --  entries into the above Xrefs table. An entry is in Xref_Set if and only
   --  if it is in Xrefs.

   Num_Buckets : constant := 2**16;

   subtype Header_Num is Integer range 0 .. Num_Buckets - 1;
   type Null_Type is null record;
   pragma Unreferenced (Null_Type);

   function Hash (F : Xref_Entry_Number) return Header_Num;

   function Equal (F1, F2 : Xref_Entry_Number) return Boolean;

   procedure HT_Set_Next (E : Xref_Entry_Number; Next : Xref_Entry_Number);

   function  HT_Next (E : Xref_Entry_Number) return Xref_Entry_Number;

   function Get_Key (E : Xref_Entry_Number) return Xref_Entry_Number;

   pragma Inline (Hash, Equal, HT_Set_Next, HT_Next, Get_Key);

   package Xref_Set is new GNAT.HTable.Static_HTable (
     Header_Num,
     Element    => Xref_Entry,
     Elmt_Ptr   => Xref_Entry_Number,
     Null_Ptr   => 0,
     Set_Next   => HT_Set_Next,
     Next       => HT_Next,
     Key        => Xref_Entry_Number,
     Get_Key    => Get_Key,
     Hash       => Hash,
     Equal      => Equal);

   -----------------------------
   -- SPARK Xrefs Information --
   -----------------------------

   package body SPARK_Specific is separate;

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

   procedure Add_Entry (Key : Xref_Key; Ent_Scope_File : Unit_Number_Type);
   --  Add an entry to the tables of Xref_Entries, avoiding duplicates

   procedure Generate_Prim_Op_References (Typ : Entity_Id);
   --  For a tagged type, generate implicit references to its primitive
   --  operations, for source navigation. This is done right before emitting
   --  cross-reference information rather than at the freeze point of the type
   --  in order to handle late bodies that are primitive operations.

   function Lt (T1, T2 : Xref_Entry) return Boolean;
   --  Order cross-references

   ---------------
   -- Add_Entry --
   ---------------

   procedure Add_Entry (Key : Xref_Key; Ent_Scope_File : Unit_Number_Type) is
   begin
      Xrefs.Increment_Last; -- tentative
      Xrefs.Table (Xrefs.Last).Key := Key;

      --  Set the entry in Xref_Set, and if newly set, keep the above
      --  tentative increment.

      if Xref_Set.Set_If_Not_Present (Xrefs.Last) then
         Xrefs.Table (Xrefs.Last).Ent_Scope_File := Ent_Scope_File;
         --  Leave Def and HTable_Next uninitialized

         Set_Has_Xref_Entry (Key.Ent);

      --  It was already in Xref_Set, so throw away the tentatively-added entry

      else
         Xrefs.Decrement_Last;
      end if;
   end Add_Entry;

   ---------------------
   -- Defer_Reference --
   ---------------------

   procedure Defer_Reference (Deferred_Reference : Deferred_Reference_Entry) is
   begin
      --  If Get_Ignore_Errors, then we are in Preanalyze_Without_Errors, and
      --  we should not record cross references, because that will cause
      --  duplicates when we call Analyze.

      if not Get_Ignore_Errors then
         Deferred_References.Append (Deferred_Reference);
      end if;
   end Defer_Reference;

   -----------
   -- Equal --
   -----------

   function Equal (F1, F2 : Xref_Entry_Number) return Boolean is
      Result : constant Boolean :=
                 Xrefs.Table (F1).Key = Xrefs.Table (F2).Key;
   begin
      return Result;
   end Equal;

   -------------------------
   -- Generate_Definition --
   -------------------------

   procedure Generate_Definition (E : Entity_Id) is
   begin
      pragma Assert (Nkind (E) in N_Entity);

      --  Note that we do not test Xref_Entity_Letters here. It is too early
      --  to do so, since we are often called before the entity is fully
      --  constructed, so that the Ekind is still E_Void.

      if Opt.Xref_Active

         --  Definition must come from source

         --  We make an exception for subprogram child units that have no spec.
         --  For these we generate a subprogram declaration for library use,
         --  and the corresponding entity does not come from source.
         --  Nevertheless, all references will be attached to it and we have
         --  to treat is as coming from user code.

         and then (Comes_From_Source (E) or else Is_Child_Unit (E))

         --  And must have a reasonable source location that is not
         --  within an instance (all entities in instances are ignored)

         and then Sloc (E) > No_Location
         and then Instantiation_Location (Sloc (E)) = No_Location

         --  And must be a non-internal name from the main source unit

         and then In_Extended_Main_Source_Unit (E)
         and then not Is_Internal_Name (Chars (E))
      then
         Add_Entry
           ((Ent => E,
             Loc => No_Location,
             Typ => ' ',
             Eun => Get_Source_Unit (Original_Location (Sloc (E))),
             Lun => No_Unit,
             Ref_Scope => Empty,
             Ent_Scope => Empty),
            Ent_Scope_File => No_Unit);

         if In_Inlined_Body then
            Set_Referenced (E);
         end if;
      end if;
   end Generate_Definition;

   ---------------------------------
   -- Generate_Operator_Reference --
   ---------------------------------

   procedure Generate_Operator_Reference
     (N : Node_Id;
      T : Entity_Id)
   is
   begin
      if not In_Extended_Main_Source_Unit (N) then
         return;
      end if;

      --  If the operator is not a Standard operator, then we generate a real
      --  reference to the user defined operator.

      if Sloc (Entity (N)) /= Standard_Location then
         Generate_Reference (Entity (N), N);

         --  A reference to an implicit inequality operator is also a reference
         --  to the user-defined equality.

         if Nkind (N) = N_Op_Ne
           and then not Comes_From_Source (Entity (N))
           and then Present (Corresponding_Equality (Entity (N)))
         then
            Generate_Reference (Corresponding_Equality (Entity (N)), N);
         end if;

      --  For the case of Standard operators, we mark the result type as
      --  referenced. This ensures that in the case where we are using a
      --  derived operator, we mark an entity of the unit that implicitly
      --  defines this operator as used. Otherwise we may think that no entity
      --  of the unit is used. The actual entity marked as referenced is the
      --  first subtype, which is the relevant user defined entity.

      --  Note: we only do this for operators that come from source. The
      --  generated code sometimes reaches for entities that do not need to be
      --  explicitly visible (for example, when we expand the code for
      --  comparing two record objects, the fields of the record may not be
      --  visible).

      elsif Comes_From_Source (N) then
         Set_Referenced (First_Subtype (T));
      end if;
   end Generate_Operator_Reference;

   ---------------------------------
   -- Generate_Prim_Op_References --
   ---------------------------------

   procedure Generate_Prim_Op_References (Typ : Entity_Id) is
      Base_T    : Entity_Id;
      Prim      : Elmt_Id;
      Prim_List : Elist_Id;

   begin
      --  Handle subtypes of synchronized types

      if Ekind (Typ) = E_Protected_Subtype
        or else Ekind (Typ) = E_Task_Subtype
      then
         Base_T := Etype (Typ);
      else
         Base_T := Typ;
      end if;

      --  References to primitive operations are only relevant for tagged types

      if not Is_Tagged_Type (Base_T)
        or else Is_Class_Wide_Type (Base_T)
      then
         return;
      end if;

      --  Ada 2005 (AI-345): For synchronized types generate reference to the
      --  wrapper that allow us to dispatch calls through their implemented
      --  abstract interface types.

      --  The check for Present here is to protect against previously reported
      --  critical errors.

      Prim_List := Primitive_Operations (Base_T);

      if No (Prim_List) then
         return;
      end if;

      Prim := First_Elmt (Prim_List);
      while Present (Prim) loop

         --  If the operation is derived, get the original for cross-reference
         --  reference purposes (it is the original for which we want the xref
         --  and for which the comes_from_source test must be performed).

         Generate_Reference
           (Typ, Ultimate_Alias (Node (Prim)), 'p', Set_Ref => False);
         Next_Elmt (Prim);
      end loop;
   end Generate_Prim_Op_References;

   ------------------------
   -- Generate_Reference --
   ------------------------

   procedure Generate_Reference
     (E       : Entity_Id;
      N       : Node_Id;
      Typ     : Character := 'r';
      Set_Ref : Boolean   := True;
      Force   : Boolean   := False)
   is
      Actual_Typ : Character := Typ;
      Call       : Node_Id;
      Def        : Source_Ptr;
      Ent        : Entity_Id;
      Ent_Scope  : Entity_Id;
      Formal     : Entity_Id;
      Kind       : Entity_Kind;
      Nod        : Node_Id;
      Ref        : Source_Ptr;
      Ref_Scope  : Entity_Id;

      function Get_Through_Renamings (E : Entity_Id) return Entity_Id;
      --  Get the enclosing entity through renamings, which may come from
      --  source or from the translation of generic instantiations.

      function Is_On_LHS (Node : Node_Id) return Boolean;
      --  Used to check if a node is on the left hand side of an assignment.
      --  The following cases are handled:
      --
      --   Variable    Node is a direct descendant of left hand side of an
      --               assignment statement.
      --
      --   Prefix      Of an indexed or selected component that is present in
      --               a subtree rooted by an assignment statement. There is
      --               no restriction of nesting of components, thus cases
      --               such as A.B (C).D are handled properly. However a prefix
      --               of a dereference (either implicit or explicit) is never
      --               considered as on a LHS.
      --
      --   Out param   Same as above cases, but OUT parameter

      function OK_To_Set_Referenced return Boolean;
      --  Returns True if the Referenced flag can be set. There are a few
      --  exceptions where we do not want to set this flag, see body for
      --  details of these exceptional cases.

      ---------------------------
      -- Get_Through_Renamings --
      ---------------------------

      function Get_Through_Renamings (E : Entity_Id) return Entity_Id is
      begin
         case Ekind (E) is

            --  For subprograms we just need to check once if they are have a
            --  Renamed_Entity, because Renamed_Entity is set transitively.

            when Subprogram_Kind =>
               declare
                  Renamed : constant Entity_Id := Renamed_Entity (E);

               begin
                  if Present (Renamed) then
                     return Renamed;
                  else
                     return E;
                  end if;
               end;

            --  For objects we need to repeatedly call Renamed_Object, because
            --  it is not transitive.

            when Object_Kind =>
               declare
                  Obj : Entity_Id := E;

               begin
                  loop
                     pragma Assert (Present (Obj));

                     declare
                        Renamed : constant Entity_Id := Renamed_Object (Obj);

                     begin
                        if Present (Renamed) then
                           Obj := Get_Enclosing_Object (Renamed);

                           --  The renamed expression denotes a non-object,
                           --  e.g. function call, slicing of a function call,
                           --  pointer dereference, etc.

                           if No (Obj) then
                              return Empty;
                           end if;
                        else
                           return Obj;
                        end if;
                     end;
                  end loop;
               end;

            when others =>
               return E;

         end case;
      end Get_Through_Renamings;

      ---------------
      -- Is_On_LHS --
      ---------------

      --  ??? There are several routines here and there that perform a similar
      --      (but subtly different) computation, which should be factored:

      --      Sem_Util.Is_LHS
      --      Sem_Util.May_Be_Lvalue
      --      Sem_Util.Known_To_Be_Assigned
      --      Exp_Ch2.Expand_Entry_Parameter.In_Assignment_Context
      --      Exp_Smem.Is_Out_Actual

      function Is_On_LHS (Node : Node_Id) return Boolean is
         N : Node_Id;
         P : Node_Id;
         K : Node_Kind;

      begin
         --  Only identifiers are considered, is this necessary???

         if Nkind (Node) /= N_Identifier then
            return False;
         end if;

         --  Immediate return if appeared as OUT parameter

         if Kind = E_Out_Parameter then
            return True;
         end if;

         --  Search for assignment statement subtree root

         N := Node;
         loop
            P := Parent (N);
            K := Nkind (P);

            if K = N_Assignment_Statement then
               return Name (P) = N;

            --  Check whether the parent is a component and the current node is
            --  its prefix, but return False if the current node has an access
            --  type, as in that case the selected or indexed component is an
            --  implicit dereference, and the LHS is the designated object, not
            --  the access object.

            --  ??? case of a slice assignment?

            elsif (K = N_Selected_Component or else K = N_Indexed_Component)
              and then Prefix (P) = N
            then
               --  Check for access type. First a special test, In some cases
               --  this is called too early (see comments in Find_Direct_Name),
               --  at a point where the tree is not fully typed yet. In that
               --  case we may lack an Etype for N, and we can't check the
               --  Etype. For now, we always return False in such a case,
               --  but this is clearly not right in all cases ???

               if No (Etype (N)) then
                  return False;

               elsif Is_Access_Type (Etype (N)) then
                  return False;

               --  Access type case dealt with, keep going

               else
                  N := P;
               end if;

            --  All other cases, definitely not on left side

            else
               return False;
            end if;
         end loop;
      end Is_On_LHS;

      ---------------------------
      -- OK_To_Set_Referenced --
      ---------------------------

      function OK_To_Set_Referenced return Boolean is
         P : Node_Id;

      begin
         --  A reference from a pragma Unreferenced or pragma Unmodified or
         --  pragma Warnings does not cause the Referenced flag to be set.
         --  This avoids silly warnings about things being referenced and
         --  not assigned when the only reference is from the pragma.

         if Nkind (N) = N_Identifier then
            P := Parent (N);

            if Nkind (P) = N_Pragma_Argument_Association then
               P := Parent (P);

               if Nkind (P) = N_Pragma then
                  if Pragma_Name_Unmapped (P) in Name_Warnings
                                               | Name_Unmodified
                                               | Name_Unreferenced
                  then
                     return False;
                  end if;
               end if;

            --  A reference to a formal in a named parameter association does
            --  not make the formal referenced. Formals that are unused in the
            --  subprogram body are properly flagged as such, even if calls
            --  elsewhere use named notation.

            elsif Nkind (P) = N_Parameter_Association
              and then N = Selector_Name (P)
            then
               return False;
            end if;
         end if;

         return True;
      end OK_To_Set_Referenced;

   --  Start of processing for Generate_Reference

   begin
      --  If Get_Ignore_Errors, then we are in Preanalyze_Without_Errors, and
      --  we should not record cross references, because that will cause
      --  duplicates when we call Analyze.

      if Get_Ignore_Errors then
         return;
      end if;

      --  May happen in case of severe errors

      if Nkind (E) not in N_Entity then
         return;
      end if;

      Find_Actual (N, Formal, Call);

      if Present (Formal) then
         Kind := Ekind (Formal);
      else
         Kind := E_Void;
      end if;

      --  Check for obsolescent reference to package ASCII. GNAT treats this
      --  element of annex J specially since in practice, programs make a lot
      --  of use of this feature, so we don't include it in the set of features
      --  diagnosed when Warn_On_Obsolescent_Features mode is set. However we
      --  are required to note it as a violation of the RM defined restriction.

      if E = Standard_ASCII then
         Check_Restriction (No_Obsolescent_Features, N);
      end if;

      --  Check for reference to entity marked with Is_Obsolescent

      --  Note that we always allow obsolescent references in the compiler
      --  itself and the run time, since we assume that we know what we are
      --  doing in such cases. For example the calls in Ada.Characters.Handling
      --  to its own obsolescent subprograms are just fine.

      --  In any case we only generate warnings if we are in the extended main
      --  source unit, and the entity itself is not in the extended main source
      --  unit, since we assume the source unit itself knows what is going on
      --  (and for sure we do not want silly warnings, e.g. on the end line of
      --  an obsolescent procedure body).

      if Is_Obsolescent (E)
        and then not GNAT_Mode
        and then not In_Extended_Main_Source_Unit (E)
        and then In_Extended_Main_Source_Unit (N)
      then
         Check_Restriction (No_Obsolescent_Features, N);

         if Warn_On_Obsolescent_Feature then
            Output_Obsolescent_Entity_Warnings (N, E);
         end if;
      end if;

      --  Warn if reference to Ada 2005 entity not in Ada 2005 mode. We only
      --  detect real explicit references (modifications and references).

      if Comes_From_Source (N)
        and then Is_Ada_2005_Only (E)
        and then Ada_Version < Ada_2005
        and then Warn_On_Ada_2005_Compatibility
        and then (Typ = 'm' or else Typ = 'r' or else Typ = 's')
      then
         Error_Msg_NE ("& is only defined in Ada 2005?y?", N, E);
      end if;

      --  Warn if reference to Ada 2012 entity not in Ada 2012 mode. We only
      --  detect real explicit references (modifications and references).

      if Comes_From_Source (N)
        and then Is_Ada_2012_Only (E)
        and then Ada_Version < Ada_2012
        and then Warn_On_Ada_2012_Compatibility
        and then (Typ = 'm' or else Typ = 'r')
      then
         Error_Msg_NE ("& is only defined in Ada 2012?y?", N, E);
      end if;

      --  Warn if reference to Ada 2022 entity not in Ada 2022 mode. We only
      --  detect real explicit references (modifications and references).

      if Comes_From_Source (N)
        and then Is_Ada_2022_Only (E)
        and then not Is_Subprogram (E)
        and then Ada_Version < Ada_2022
        and then Warn_On_Ada_2022_Compatibility
        and then (Typ = 'm' or else Typ = 'r')
      then
         Error_Msg_NE ("& is only defined in Ada 2022?y?", N, E);

      --  Error on static and dispatching calls to Ada 2022 subprograms that
      --  require overriding if we are not in Ada 2022 mode (since overriding
      --  was skipped); warn if the subprogram does not require overriding.

      elsif Comes_From_Source (N)
        and then Is_Ada_2022_Only (E)
        and then Ada_Version < Ada_2022
        and then Is_Subprogram (E)
        and then (Typ = 'r' or else Typ = 's' or else Typ = 'R')
      then
         if Requires_Overriding (E) then
            Error_Msg_NE
              ("& is only defined in Ada 2022 and requires overriding", N, E);

         elsif Warn_On_Ada_2022_Compatibility then
            Error_Msg_NE ("& is only defined in Ada 2022?y?", N, E);
         end if;
      end if;

      --  Do not generate references if we are within a postcondition sub-
      --  program, because the reference does not comes from source, and the
      --  preanalysis of the aspect has already created an entry for the ALI
      --  file at the proper source location.

      if Chars (Current_Scope) = Name_uPostconditions then
         return;
      end if;

      --  Never collect references if not in main source unit. However, we omit
      --  this test if Typ is 'e' or 'k', since these entries are structural,
      --  and it is useful to have them in units that reference packages as
      --  well as units that define packages. We also omit the test for the
      --  case of 'p' since we want to include inherited primitive operations
      --  from other packages.

      --  We also omit this test is this is a body reference for a subprogram
      --  instantiation. In this case the reference is to the generic body,
      --  which clearly need not be in the main unit containing the instance.
      --  For the same reason we accept an implicit reference generated for
      --  a default in an instance.

      --  We also set the referenced flag in a generic package that is not in
      --  then main source unit, when the variable is of a formal private type,
      --  to warn in the instance if the corresponding type is not a fully
      --  initialized type.

      if not In_Extended_Main_Source_Unit (N) then
         if Typ = 'e' or else
            Typ = 'I' or else
            Typ = 'p' or else
            Typ = 'i' or else
            Typ = 'k'
           or else (Typ = 'b' and then Is_Generic_Instance (E))

            --  Allow the generation of references to reads, writes and calls
            --  in SPARK mode when the related context comes from an instance.

           or else
             (GNATprove_Mode
               and then In_Extended_Main_Code_Unit (N)
               and then (Typ = 'm' or else Typ = 'r' or else Typ = 's'))
         then
            null;

         elsif In_Instance_Body
           and then In_Extended_Main_Code_Unit (N)
           and then Is_Generic_Type (Etype (E))
         then
            Set_Referenced (E);
            return;

         elsif Inside_A_Generic
           and then Is_Generic_Type (Etype (E))
         then
            Set_Referenced (E);
            return;

         else
            return;
         end if;
      end if;

      --  For reference type p, the entity must be in main source unit

      if Typ = 'p' and then not In_Extended_Main_Source_Unit (E) then
         return;
      end if;

      --  Unless the reference is forced, we ignore references where the
      --  reference itself does not come from source.

      if not Force and then not Comes_From_Source (N) then
         return;
      end if;

      --  Deal with setting entity as referenced, unless suppressed. Note that
      --  we still do Set_Referenced on entities that do not come from source.
      --  This situation arises when we have a source reference to a derived
      --  operation, where the derived operation itself does not come from
      --  source, but we still want to mark it as referenced, since we really
      --  are referencing an entity in the corresponding package (this avoids
      --  wrong complaints that the package contains no referenced entities).

      if Set_Ref then

         --  Assignable object appearing on left side of assignment or as
         --  an out parameter.

         if Is_Assignable (E)
           and then Is_On_LHS (N)
           and then Ekind (E) /= E_In_Out_Parameter
         then
            --  For objects that are renamings, just set as simply referenced
            --  we do not try to do assignment type tracking in this case.

            if Present (Renamed_Object (E)) then
               Set_Referenced (E);

            --  Out parameter case

            elsif Kind = E_Out_Parameter then

               --  If warning mode for all out parameters is set, or this is
               --  the only warning parameter, then we want to mark this for
               --  later warning logic by setting Referenced_As_Out_Parameter

               if Warn_On_Modified_As_Out_Parameter (Formal) then
                  Set_Referenced_As_Out_Parameter (E, True);
                  Set_Referenced_As_LHS (E, False);

               --  For OUT parameter not covered by the above cases, we simply
               --  regard it as a normal reference (in this case we do not
               --  want any of the warning machinery for out parameters).

               else
                  Set_Referenced (E);
               end if;

            --  For the left hand of an assignment case, we do nothing here.
            --  The processing for Analyze_Assignment will set the
            --  Referenced_As_LHS flag.

            else
               null;
            end if;

         --  Check for a reference in a pragma that should not count as a
         --  making the variable referenced for warning purposes.

         elsif Is_Non_Significant_Pragma_Reference (N) then
            null;

         --  A reference in an attribute definition clause does not count as a
         --  reference except for the case of Address. The reason that 'Address
         --  is an exception is that it creates an alias through which the
         --  variable may be referenced.

         elsif Nkind (Parent (N)) = N_Attribute_Definition_Clause
           and then Chars (Parent (N)) /= Name_Address
           and then N = Name (Parent (N))
         then
            null;

         --  Constant completion does not count as a reference

         elsif Typ = 'c'
           and then Ekind (E) = E_Constant
         then
            null;

         --  Record representation clause does not count as a reference

         elsif Nkind (N) = N_Identifier
           and then Nkind (Parent (N)) = N_Record_Representation_Clause
         then
            null;

         --  Discriminants do not need to produce a reference to record type

         elsif Typ = 'd'
           and then Nkind (Parent (N)) = N_Discriminant_Specification
         then
            null;

         --  All other cases

         else
            --  Special processing for IN OUT parameters, where we have an
            --  implicit assignment to a simple variable.

            if Kind = E_In_Out_Parameter
              and then Is_Assignable (E)
            then
               --  For sure this counts as a normal read reference

               Set_Referenced (E);
               Set_Last_Assignment (E, Empty);

               --  We count it as being referenced as an out parameter if the
               --  option is set to warn on all out parameters, except that we
               --  have a special exclusion for an intrinsic subprogram, which
               --  is most likely an instantiation of Unchecked_Deallocation
               --  which we do not want to consider as an assignment since it
               --  generates false positives. We also exclude the case of an
               --  IN OUT parameter if the name of the procedure is Free,
               --  since we suspect similar semantics.

               if Warn_On_All_Unread_Out_Parameters
                 and then Is_Entity_Name (Name (Call))
                 and then not Is_Intrinsic_Subprogram (Entity (Name (Call)))
                 and then Chars (Name (Call)) /= Name_Free
               then
                  Set_Referenced_As_Out_Parameter (E, True);
                  Set_Referenced_As_LHS (E, False);
               end if;

            --  Don't count a recursive reference within a subprogram as a
            --  reference (that allows detection of a recursive subprogram
            --  whose only references are recursive calls as unreferenced).

            elsif Is_Subprogram (E)
              and then E = Nearest_Dynamic_Scope (Current_Scope)
            then
               null;

            --  Any other occurrence counts as referencing the entity

            elsif OK_To_Set_Referenced then
               Set_Referenced (E);

               --  If variable, this is an OK reference after an assignment
               --  so we can clear the Last_Assignment indication.

               if Is_Assignable (E) then
                  Set_Last_Assignment (E, Empty);
               end if;
            end if;
         end if;

         --  Check for pragma Unreferenced given and reference is within
         --  this source unit (occasion for possible warning to be issued).
         --  Note that the entity may be marked as unreferenced by pragma
         --  Unused.

         if Has_Unreferenced (E)
           and then In_Same_Extended_Unit (E, N)
         then
            --  A reference as a named parameter in a call does not count as a
            --  violation of pragma Unreferenced for this purpose...

            if Nkind (N) = N_Identifier
              and then Nkind (Parent (N)) = N_Parameter_Association
              and then Selector_Name (Parent (N)) = N
            then
               null;

            --  ... Neither does a reference to a variable on the left side of
            --  an assignment.

            elsif Is_On_LHS (N) then
               null;

            --  Do not consider F'Result as a violation of pragma Unreferenced
            --  since the attribute acts as an anonymous alias of the function
            --  result and not as a real reference to the function.

            elsif Ekind (E) in E_Function | E_Generic_Function
              and then Is_Entity_Name (N)
              and then Is_Attribute_Result (Parent (N))
            then
               null;

            --  No warning if the reference is in a call that does not come
            --  from source (e.g. a call to a controlled type primitive).

            elsif not Comes_From_Source (Parent (N))
              and then Nkind (Parent (N)) = N_Procedure_Call_Statement
            then
               null;

            --  For entry formals, we want to place the warning message on the
            --  corresponding entity in the accept statement. The current scope
            --  is the body of the accept, so we find the formal whose name
            --  matches that of the entry formal (there is no link between the
            --  two entities, and the one in the accept statement is only used
            --  for conformance checking).

            elsif Ekind (Scope (E)) = E_Entry then
               declare
                  BE : Entity_Id;

               begin
                  BE := First_Entity (Current_Scope);
                  while Present (BE) loop
                     if Chars (BE) = Chars (E) then
                        if Has_Pragma_Unused (E) then
                           Error_Msg_NE -- CODEFIX
                             ("??pragma Unused given for&!", N, BE);
                        else
                           Error_Msg_NE -- CODEFIX
                             ("??pragma Unreferenced given for&!", N, BE);
                        end if;
                        exit;
                     end if;

                     Next_Entity (BE);
                  end loop;
               end;

            --  Here we issue the warning, since this is a real reference

            elsif Has_Pragma_Unused (E) then
               Error_Msg_NE -- CODEFIX
                 ("??pragma Unused given for&!", N, E);
            else
               Error_Msg_NE -- CODEFIX
                 ("??pragma Unreferenced given for&!", N, E);
            end if;
         end if;

         --  If this is a subprogram instance, mark as well the internal
         --  subprogram in the wrapper package, which may be a visible
         --  compilation unit.

         if Is_Overloadable (E)
           and then Is_Generic_Instance (E)
           and then Present (Alias (E))
         then
            Set_Referenced (Alias (E));
         end if;
      end if;

      --  Generate reference if all conditions are met:

      if
         --  Cross referencing must be active

         Opt.Xref_Active

         --  The entity must be one for which we collect references

         and then Xref_Entity_Letters (Ekind (E)) /= ' '

         --  Both Sloc values must be set to something sensible

         and then Sloc (E) > No_Location
         and then Sloc (N) > No_Location

         --  Ignore references from within an instance. The only exceptions to
         --  this are default subprograms, for which we generate an implicit
         --  reference and compilations in SPARK mode.

         and then
           (Instantiation_Location (Sloc (N)) = No_Location
             or else Typ = 'i'
             or else GNATprove_Mode)

        --  Ignore dummy references

        and then Typ /= ' '
      then
         if Nkind (N) in N_Identifier
                       | N_Defining_Identifier
                       | N_Defining_Operator_Symbol
                       | N_Operator_Symbol
                       | N_Defining_Character_Literal
                       | N_Op
           or else (Nkind (N) = N_Character_Literal
                     and then Sloc (Entity (N)) /= Standard_Location)
         then
            Nod := N;

         elsif Nkind (N) in N_Expanded_Name | N_Selected_Component then
            Nod := Selector_Name (N);

         else
            return;
         end if;

         --  Normal case of source entity comes from source

         if Comes_From_Source (E) then
            Ent := E;

         --  Because a declaration may be generated for a subprogram body
         --  without declaration in GNATprove mode, for inlining, some
         --  parameters may end up being marked as not coming from source
         --  although they are. Take these into account specially.

         elsif GNATprove_Mode and then Is_Formal (E) then
            Ent := E;

         --  Entity does not come from source, but is a derived subprogram and
         --  the derived subprogram comes from source (after one or more
         --  derivations) in which case the reference is to parent subprogram.

         elsif Is_Overloadable (E)
           and then Present (Alias (E))
         then
            Ent := Alias (E);
            while not Comes_From_Source (Ent) loop
               if No (Alias (Ent)) then
                  return;
               end if;

               Ent := Alias (Ent);
            end loop;

         --  The internally created defining entity for a child subprogram
         --  that has no previous spec has valid references.

         elsif Is_Overloadable (E)
           and then Is_Child_Unit (E)
         then
            Ent := E;

         --  Ditto for the formals of such a subprogram

         elsif Is_Overloadable (Scope (E))
           and then Is_Child_Unit (Scope (E))
         then
            Ent := E;

         --  Record components of discriminated subtypes or derived types must
         --  be treated as references to the original component.

         elsif Ekind (E) = E_Component
           and then Comes_From_Source (Original_Record_Component (E))
         then
            Ent := Original_Record_Component (E);

         --  If this is an expanded reference to a discriminant, recover the
         --  original discriminant, which gets the reference.

         elsif Ekind (E) = E_In_Parameter
           and then Present (Discriminal_Link (E))
         then
            Ent := Discriminal_Link (E);
            Set_Referenced (Ent);

         --  Ignore reference to any other entity that is not from source

         else
            return;
         end if;

         --  In SPARK mode, consider the underlying entity renamed instead of
         --  the renaming, which is needed to compute a valid set of effects
         --  (reads, writes) for the enclosing subprogram.

         if GNATprove_Mode then
            Ent := Get_Through_Renamings (Ent);

            --  If no enclosing object, then it could be a reference to any
            --  location not tracked individually, like heap-allocated data.
            --  Conservatively approximate this possibility by generating a
            --  dereference, and return.

            if No (Ent) then
               if Actual_Typ = 'w' then
                  SPARK_Specific.Generate_Dereference (Nod, 'r');
                  SPARK_Specific.Generate_Dereference (Nod, 'w');
               else
                  SPARK_Specific.Generate_Dereference (Nod, 'r');
               end if;

               return;
            end if;
         end if;

         --  Record reference to entity

         if Actual_Typ = 'p'
           and then Is_Subprogram (Nod)
           and then Present (Overridden_Operation (Nod))
         then
            Actual_Typ := 'P';
         end if;

         --  Comment needed here for special SPARK code ???

         if GNATprove_Mode then

            --  Ignore references to an entity which is a Part_Of single
            --  concurrent object. Ideally we would prefer to add it as a
            --  reference to the corresponding concurrent type, but it is quite
            --  difficult (as such references are not currently added even for)
            --  reads/writes of private protected components) and not worth the
            --  effort.

            if Ekind (Ent) in E_Abstract_State | E_Constant | E_Variable
              and then Present (Encapsulating_State (Ent))
              and then Is_Single_Concurrent_Object (Encapsulating_State (Ent))
            then
               return;
            end if;

            Ref := Sloc (Nod);
            Def := Sloc (Ent);

            Ref_Scope :=
              SPARK_Specific.Enclosing_Subprogram_Or_Library_Package (Nod);
            Ent_Scope :=
              SPARK_Specific.Enclosing_Subprogram_Or_Library_Package (Ent);

            --  Since we are reaching through renamings in SPARK mode, we may
            --  end up with standard constants. Ignore those.

            if Sloc (Ent_Scope) <= Standard_Location
              or else Def <= Standard_Location
            then
               return;
            end if;

            Add_Entry
              ((Ent       => Ent,
                Loc       => Ref,
                Typ       => Actual_Typ,
                Eun       => Get_Top_Level_Code_Unit (Def),
                Lun       => Get_Top_Level_Code_Unit (Ref),
                Ref_Scope => Ref_Scope,
                Ent_Scope => Ent_Scope),
               Ent_Scope_File => Get_Top_Level_Code_Unit (Ent));

         else
            Ref := Original_Location (Sloc (Nod));
            Def := Original_Location (Sloc (Ent));

            --  If this is an operator symbol, skip the initial quote for
            --  navigation purposes. This is not done for the end label,
            --  where we want the actual position after the closing quote.

            if Typ = 't' then
               null;

            elsif Nkind (N) = N_Defining_Operator_Symbol
              or else Nkind (Nod) = N_Operator_Symbol
            then
               Ref := Ref + 1;
            end if;

            Add_Entry
              ((Ent       => Ent,
                Loc       => Ref,
                Typ       => Actual_Typ,
                Eun       => Get_Source_Unit (Def),
                Lun       => Get_Source_Unit (Ref),
                Ref_Scope => Empty,
                Ent_Scope => Empty),
               Ent_Scope_File => No_Unit);

            --  Generate reference to the first private entity

            if Typ = 'e'
              and then Comes_From_Source (E)
              and then Nkind (Ent) = N_Defining_Identifier
              and then (Is_Package_Or_Generic_Package (Ent)
                         or else Is_Concurrent_Type (Ent))
              and then Present (First_Private_Entity (E))
              and then In_Extended_Main_Source_Unit (N)
            then
               --  Handle case in which the full-view and partial-view of the
               --  first private entity are swapped.

               declare
                  First_Private : Entity_Id := First_Private_Entity (E);

               begin
                  if Is_Private_Type (First_Private)
                    and then Present (Full_View (First_Private))
                  then
                     First_Private := Full_View (First_Private);
                  end if;

                  Add_Entry
                    ((Ent       => Ent,
                      Loc       => Sloc (First_Private),
                      Typ       => 'E',
                      Eun       => Get_Source_Unit (Def),
                      Lun       => Get_Source_Unit (Ref),
                      Ref_Scope => Empty,
                      Ent_Scope => Empty),
                     Ent_Scope_File => No_Unit);
               end;
            end if;
         end if;
      end if;
   end Generate_Reference;

   -----------------------------------
   -- Generate_Reference_To_Formals --
   -----------------------------------

   procedure Generate_Reference_To_Formals (E : Entity_Id) is
      Formal : Entity_Id;

   begin
      if Is_Access_Subprogram_Type (E) then
         Formal := First_Formal (Designated_Type (E));
      else
         Formal := First_Formal (E);
      end if;

      while Present (Formal) loop
         if Ekind (Formal) = E_In_Parameter then

            if Nkind (Parameter_Type (Parent (Formal))) = N_Access_Definition
            then
               Generate_Reference (E, Formal, '^', False);
            else
               Generate_Reference (E, Formal, '>', False);
            end if;

         elsif Ekind (Formal) = E_In_Out_Parameter then
            Generate_Reference (E, Formal, '=', False);

         else
            Generate_Reference (E, Formal, '<', False);
         end if;

         Next_Formal (Formal);
      end loop;
   end Generate_Reference_To_Formals;

   -------------------------------------------
   -- Generate_Reference_To_Generic_Formals --
   -------------------------------------------

   procedure Generate_Reference_To_Generic_Formals (E : Entity_Id) is
      Formal : Entity_Id;

   begin
      Formal := First_Entity (E);
      while Present (Formal) loop
         if Comes_From_Source (Formal) then
            Generate_Reference (E, Formal, 'z', False);
         end if;

         Next_Entity (Formal);
      end loop;
   end Generate_Reference_To_Generic_Formals;

   -------------
   -- Get_Key --
   -------------

   function Get_Key (E : Xref_Entry_Number) return Xref_Entry_Number is
   begin
      return E;
   end Get_Key;

   ----------------------------
   -- Has_Deferred_Reference --
   ----------------------------

   function Has_Deferred_Reference (Ent : Entity_Id) return Boolean is
   begin
      for J in Deferred_References.First .. Deferred_References.Last loop
         if Deferred_References.Table (J).E = Ent then
            return True;
         end if;
      end loop;

      return False;
   end Has_Deferred_Reference;

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

   function Hash (F : Xref_Entry_Number) return Header_Num is
      --  It is unlikely to have two references to the same entity at the same
      --  source location, so the hash function depends only on the Ent and Loc
      --  fields.

      XE : Xref_Entry renames Xrefs.Table (F);
      type M is mod 2**32;

      H : constant M := M (XE.Key.Ent) + 2 ** 7 * M (abs XE.Key.Loc);
      --  It would be more natural to write:
      --
      --    H : constant M := M'Mod (XE.Key.Ent) + 2**7 * M'Mod (XE.Key.Loc);
      --
      --  But we can't use M'Mod, because it prevents bootstrapping with older
      --  compilers. Loc can be negative, so we do "abs" before converting.
      --  One day this can be cleaned up ???

   begin
      return Header_Num (H mod Num_Buckets);
   end Hash;

   -----------------
   -- HT_Set_Next --
   -----------------

   procedure HT_Set_Next (E : Xref_Entry_Number; Next : Xref_Entry_Number) is
   begin
      Xrefs.Table (E).HTable_Next := Next;
   end HT_Set_Next;

   -------------
   -- HT_Next --
   -------------

   function HT_Next (E : Xref_Entry_Number) return Xref_Entry_Number is
   begin
      return Xrefs.Table (E).HTable_Next;
   end HT_Next;

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

   procedure Initialize is
   begin
      Xrefs.Init;
   end Initialize;

   --------
   -- Lt --
   --------

   function Lt (T1, T2 : Xref_Entry) return Boolean is
   begin
      --  First test: if entity is in different unit, sort by unit

      if T1.Key.Eun /= T2.Key.Eun then
         return Dependency_Num (T1.Key.Eun) < Dependency_Num (T2.Key.Eun);

      --  Second test: within same unit, sort by entity Sloc

      elsif T1.Def /= T2.Def then
         return T1.Def < T2.Def;

      --  Third test: sort definitions ahead of references

      elsif T1.Key.Loc = No_Location then
         return True;

      elsif T2.Key.Loc = No_Location then
         return False;

      --  Fourth test: for same entity, sort by reference location unit

      elsif T1.Key.Lun /= T2.Key.Lun then
         return Dependency_Num (T1.Key.Lun) < Dependency_Num (T2.Key.Lun);

      --  Fifth test: order of location within referencing unit

      elsif T1.Key.Loc /= T2.Key.Loc then
         return T1.Key.Loc < T2.Key.Loc;

      --  Finally, for two locations at the same address, we prefer
      --  the one that does NOT have the type 'r' so that a modification
      --  or extension takes preference, when there are more than one
      --  reference at the same location. As a result, in the case of
      --  entities that are in-out actuals, the read reference follows
      --  the modify reference.

      else
         return T2.Key.Typ = 'r';
      end if;
   end Lt;

   -----------------------
   -- Output_References --
   -----------------------

   procedure Output_References is

      procedure Get_Type_Reference
        (Ent   : Entity_Id;
         Tref  : out Entity_Id;
         Left  : out Character;
         Right : out Character);
      --  Given an Entity_Id Ent, determines whether a type reference is
      --  required. If so, Tref is set to the entity for the type reference
      --  and Left and Right are set to the left/right brackets to be output
      --  for the reference. If no type reference is required, then Tref is
      --  set to Empty, and Left/Right are set to space.

      procedure Output_Import_Export_Info (Ent : Entity_Id);
      --  Output language and external name information for an interfaced
      --  entity, using the format <language, external_name>.

      ------------------------
      -- Get_Type_Reference --
      ------------------------

      procedure Get_Type_Reference
        (Ent   : Entity_Id;
         Tref  : out Entity_Id;
         Left  : out Character;
         Right : out Character)
      is
         Sav : Entity_Id;

      begin
         --  See if we have a type reference

         Tref := Ent;
         Left := '{';
         Right := '}';

         loop
            Sav := Tref;

            --  Processing for types

            if Is_Type (Tref) then

               --  Case of base type

               if Base_Type (Tref) = Tref then

                  --  If derived, then get first subtype

                  if Tref /= Etype (Tref) then
                     Tref := First_Subtype (Etype (Tref));

                     --  Set brackets for derived type, but don't override
                     --  pointer case since the fact that something is a
                     --  pointer is more important.

                     if Left /= '(' then
                        Left := '<';
                        Right := '>';
                     end if;

                  --  If the completion of a private type is itself a derived
                  --  type, we need the parent of the full view.

                  elsif Is_Private_Type (Tref)
                    and then Present (Full_View (Tref))
                    and then Etype (Full_View (Tref)) /= Full_View (Tref)
                  then
                     Tref := Etype (Full_View (Tref));

                     if Left /= '(' then
                        Left := '<';
                        Right := '>';
                     end if;

                  --  If non-derived pointer, get directly designated type.
                  --  If the type has a full view, all references are on the
                  --  partial view that is seen first.

                  elsif Is_Access_Type (Tref) then
                     Tref := Directly_Designated_Type (Tref);
                     Left := '(';
                     Right := ')';

                  elsif Is_Private_Type (Tref)
                    and then Present (Full_View (Tref))
                  then
                     if Is_Access_Type (Full_View (Tref)) then
                        Tref := Directly_Designated_Type (Full_View (Tref));
                        Left := '(';
                        Right := ')';

                     --  If the full view is an array type, we also retrieve
                     --  the corresponding component type, because the ali
                     --  entry already indicates that this is an array.

                     elsif Is_Array_Type (Full_View (Tref)) then
                        Tref := Component_Type (Full_View (Tref));
                        Left := '(';
                        Right := ')';
                     end if;

                  --  If non-derived array, get component type. Skip component
                  --  type for case of String or Wide_String, saves worthwhile
                  --  space.

                  elsif Is_Array_Type (Tref)
                    and then Tref /= Standard_String
                    and then Tref /= Standard_Wide_String
                  then
                     Tref := Component_Type (Tref);
                     Left := '(';
                     Right := ')';

                  --  For other non-derived base types, nothing

                  else
                     exit;
                  end if;

               --  For a subtype, go to ancestor subtype

               else
                  Tref := Ancestor_Subtype (Tref);

                  --  If no ancestor subtype, go to base type

                  if No (Tref) then
                     Tref := Base_Type (Sav);
                  end if;
               end if;

            --  For objects, functions, enum literals, just get type from
            --  Etype field.

            elsif Is_Object (Tref)
              or else Ekind (Tref) = E_Enumeration_Literal
              or else Ekind (Tref) = E_Function
              or else Ekind (Tref) = E_Operator
            then
               Tref := Etype (Tref);

               --  Another special case: an object of a classwide type
               --  initialized with a tag-indeterminate call gets a subtype
               --  of the classwide type during expansion. See if the original
               --  type in the declaration is named, and return it instead
               --  of going to the root type. The expression may be a class-
               --  wide function call whose result is on the secondary stack,
               --  which forces the declaration to be rewritten as a renaming,
               --  so examine the source declaration.

               if Ekind (Tref) = E_Class_Wide_Subtype then
                  declare
                     Decl : constant Node_Id := Original_Node (Parent (Ent));
                  begin
                     if Nkind (Decl) = N_Object_Declaration
                       and then Is_Entity_Name
                                  (Original_Node (Object_Definition (Decl)))
                     then
                        Tref :=
                          Entity (Original_Node (Object_Definition (Decl)));
                     end if;
                  end;

               --  For a function that returns a class-wide type, Tref is
               --  already correct.

               elsif Is_Overloadable (Ent)
                 and then Is_Class_Wide_Type (Tref)
               then
                  return;
               end if;

            --  For anything else, exit

            else
               exit;
            end if;

            --  Exit if no type reference, or we are stuck in some loop trying
            --  to find the type reference, or if the type is standard void
            --  type (the latter is an implementation artifact that should not
            --  show up in the generated cross-references).

            exit when No (Tref)
              or else Tref = Sav
              or else Tref = Standard_Void_Type;

            --  If we have a usable type reference, return, otherwise keep
            --  looking for something useful (we are looking for something
            --  that either comes from source or standard)

            if Sloc (Tref) = Standard_Location
              or else Comes_From_Source (Tref)
            then
               --  If the reference is a subtype created for a generic actual,
               --  go actual directly, the inner subtype is not user visible.

               if Nkind (Parent (Tref)) = N_Subtype_Declaration
                 and then not Comes_From_Source (Parent (Tref))
                 and then
                  (Is_Wrapper_Package (Scope (Tref))
                     or else Is_Generic_Instance (Scope (Tref)))
               then
                  Tref := First_Subtype (Base_Type (Tref));
               end if;

               return;
            end if;
         end loop;

         --  If we fall through the loop, no type reference

         Tref := Empty;
         Left := ' ';
         Right := ' ';
      end Get_Type_Reference;

      -------------------------------
      -- Output_Import_Export_Info --
      -------------------------------

      procedure Output_Import_Export_Info (Ent : Entity_Id) is
         Language_Name : Name_Id;
         Conv          : constant Convention_Id := Convention (Ent);

      begin
         --  Generate language name from convention

         if Conv = Convention_C or else Conv in Convention_C_Variadic then
            Language_Name := Name_C;

         elsif Conv = Convention_CPP then
            Language_Name := Name_CPP;

         elsif Conv = Convention_Ada then
            Language_Name := Name_Ada;

         else
            --  For the moment we ignore all other cases ???

            return;
         end if;

         Write_Info_Char ('<');
         Get_Unqualified_Name_String (Language_Name);

         for J in 1 .. Name_Len loop
            Write_Info_Char (Name_Buffer (J));
         end loop;

         if Present (Interface_Name (Ent)) then
            Write_Info_Char (',');
            String_To_Name_Buffer (Strval (Interface_Name (Ent)));

            for J in 1 .. Name_Len loop
               Write_Info_Char (Name_Buffer (J));
            end loop;
         end if;

         Write_Info_Char ('>');
      end Output_Import_Export_Info;

   --  Start of processing for Output_References

   begin
      --  First we add references to the primitive operations of tagged types
      --  declared in the main unit.

      Handle_Prim_Ops : declare
         Ent  : Entity_Id;

      begin
         for J in 1 .. Xrefs.Last loop
            Ent := Xrefs.Table (J).Key.Ent;

            if Is_Type (Ent)
              and then Is_Tagged_Type (Ent)
              and then Is_Base_Type (Ent)
              and then In_Extended_Main_Source_Unit (Ent)
            then
               Generate_Prim_Op_References (Ent);
            end if;
         end loop;
      end Handle_Prim_Ops;

      --  Before we go ahead and output the references we have a problem
      --  that needs dealing with. So far we have captured things that are
      --  definitely referenced by the main unit, or defined in the main
      --  unit. That's because we don't want to clutter up the ali file
      --  for this unit with definition lines for entities in other units
      --  that are not referenced.

      --  But there is a glitch. We may reference an entity in another unit,
      --  and it may have a type reference to an entity that is not directly
      --  referenced in the main unit, which may mean that there is no xref
      --  entry for this entity yet in the list of references.

      --  If we don't do something about this, we will end with an orphan type
      --  reference, i.e. it will point to an entity that does not appear
      --  within the generated references in the ali file. That is not good for
      --  tools using the xref information.

      --  To fix this, we go through the references adding definition entries
      --  for any unreferenced entities that can be referenced in a type
      --  reference. There is a recursion problem here, and that is dealt with
      --  by making sure that this traversal also traverses any entries that
      --  get added by the traversal.

      Handle_Orphan_Type_References : declare
         J    : Nat;
         Tref : Entity_Id;
         Ent  : Entity_Id;

         L, R : Character;
         pragma Warnings (Off, L);
         pragma Warnings (Off, R);

         procedure New_Entry (E : Entity_Id);
         --  Make an additional entry into the Xref table for a type entity
         --  that is related to the current entity (parent, type ancestor,
         --  progenitor, etc.).

         ----------------
         -- New_Entry --
         ----------------

         procedure New_Entry (E : Entity_Id) is
         begin
            pragma Assert (Present (E));

            if not Has_Xref_Entry (Implementation_Base_Type (E))
              and then Sloc (E) > No_Location
            then
               Add_Entry
                 ((Ent       => E,
                   Loc       => No_Location,
                   Typ       => Character'First,
                   Eun       => Get_Source_Unit (Original_Location (Sloc (E))),
                   Lun       => No_Unit,
                   Ref_Scope => Empty,
                   Ent_Scope => Empty),
                  Ent_Scope_File => No_Unit);
            end if;
         end New_Entry;

      --  Start of processing for Handle_Orphan_Type_References

      begin
         --  Note that this is not a for loop for a very good reason. The
         --  processing of items in the table can add new items to the table,
         --  and they must be processed as well.

         J := 1;
         while J <= Xrefs.Last loop
            Ent := Xrefs.Table (J).Key.Ent;

            --  Do not generate reference information for an ignored Ghost
            --  entity because neither the entity nor its references will
            --  appear in the final tree.

            if Is_Ignored_Ghost_Entity (Ent) then
               goto Orphan_Continue;
            end if;

            Get_Type_Reference (Ent, Tref, L, R);

            if Present (Tref)
              and then not Has_Xref_Entry (Tref)
              and then Sloc (Tref) > No_Location
            then
               New_Entry (Tref);

               if Is_Record_Type (Ent)
                 and then Present (Interfaces (Ent))
               then
                  --  Add an entry for each one of the given interfaces
                  --  implemented by type Ent.

                  declare
                     Elmt : Elmt_Id := First_Elmt (Interfaces (Ent));
                  begin
                     while Present (Elmt) loop
                        New_Entry (Node (Elmt));
                        Next_Elmt (Elmt);
                     end loop;
                  end;
               end if;
            end if;

            --  Collect inherited primitive operations that may be declared in
            --  another unit and have no visible reference in the current one.

            if Is_Type (Ent)
              and then Is_Tagged_Type (Ent)
              and then Is_Derived_Type (Ent)
              and then Is_Base_Type (Ent)
              and then In_Extended_Main_Source_Unit (Ent)
            then
               declare
                  Op_List : constant Elist_Id := Primitive_Operations (Ent);
                  Op      : Elmt_Id;
                  Prim    : Entity_Id;

                  function Parent_Op (E : Entity_Id) return Entity_Id;
                  --  Find original operation, which may be inherited through
                  --  several derivations.

                  function Parent_Op (E : Entity_Id) return Entity_Id is
                     Orig_Op : constant Entity_Id := Alias (E);

                  begin
                     if No (Orig_Op) then
                        return Empty;

                     elsif not Comes_From_Source (E)
                       and then not Has_Xref_Entry (Orig_Op)
                       and then Comes_From_Source (Orig_Op)
                     then
                        return Orig_Op;
                     else
                        return Parent_Op (Orig_Op);
                     end if;
                  end Parent_Op;

               begin
                  Op := First_Elmt (Op_List);
                  while Present (Op) loop
                     Prim := Parent_Op (Node (Op));

                     if Present (Prim) then
                        Add_Entry
                          ((Ent       => Prim,
                            Loc       => No_Location,
                            Typ       => Character'First,
                            Eun       => Get_Source_Unit (Sloc (Prim)),
                            Lun       => No_Unit,
                            Ref_Scope => Empty,
                            Ent_Scope => Empty),
                           Ent_Scope_File => No_Unit);
                     end if;

                     Next_Elmt (Op);
                  end loop;
               end;
            end if;

            <<Orphan_Continue>>
            J := J + 1;
         end loop;
      end Handle_Orphan_Type_References;

      --  Now we have all the references, including those for any embedded type
      --  references, so we can sort them, and output them.

      Output_Refs : declare
         Nrefs : constant Nat := Xrefs.Last;
         --  Number of references in table

         Rnums : array (0 .. Nrefs) of Nat;
         --  This array contains numbers of references in the Xrefs table.
         --  This list is sorted in output order. The extra 0'th entry is
         --  convenient for the call to sort. When we sort the table, we
         --  move the entries in Rnums around, but we do not move the
         --  original table entries.

         Curxu : Unit_Number_Type;
         --  Current xref unit

         Curru : Unit_Number_Type;
         --  Current reference unit for one entity

         Curent : Entity_Id;
         --  Current entity

         Curnam : String (1 .. Name_Buffer'Length);
         Curlen : Natural;
         --  Simple name and length of current entity

         Curdef : Source_Ptr;
         --  Original source location for current entity

         Crloc : Source_Ptr;
         --  Current reference location

         Ctyp : Character;
         --  Entity type character

         Prevt : Character;
         --  reference kind of previous reference

         Tref : Entity_Id;
         --  Type reference

         Rref : Node_Id;
         --  Renaming reference

         Trunit : Unit_Number_Type;
         --  Unit number for type reference

         function Lt (Op1, Op2 : Natural) return Boolean;
         --  Comparison function for Sort call

         function Name_Change (X : Entity_Id) return Boolean;
         --  Determines if entity X has a different simple name from Curent

         procedure Move (From : Natural; To : Natural);
         --  Move procedure for Sort call

         package Sorting is new GNAT.Heap_Sort_G (Move, Lt);

         --------
         -- Lt --
         --------

         function Lt (Op1, Op2 : Natural) return Boolean is
            T1 : Xref_Entry renames Xrefs.Table (Rnums (Nat (Op1)));
            T2 : Xref_Entry renames Xrefs.Table (Rnums (Nat (Op2)));

         begin
            return Lt (T1, T2);
         end Lt;

         ----------
         -- Move --
         ----------

         procedure Move (From : Natural; To : Natural) is
         begin
            Rnums (Nat (To)) := Rnums (Nat (From));
         end Move;

         -----------------
         -- Name_Change --
         -----------------

         --  Why a string comparison here??? Why not compare Name_Id values???

         function Name_Change (X : Entity_Id) return Boolean is
         begin
            Get_Unqualified_Name_String (Chars (X));

            if Name_Len /= Curlen then
               return True;
            else
               return Name_Buffer (1 .. Curlen) /= Curnam (1 .. Curlen);
            end if;
         end Name_Change;

      --  Start of processing for Output_Refs

      begin
         --  Capture the definition Sloc values. We delay doing this till now,
         --  since at the time the reference or definition is made, private
         --  types may be swapped, and the Sloc value may be incorrect. We
         --  also set up the pointer vector for the sort.

         --  For user-defined operators we need to skip the initial quote and
         --  point to the first character of the name, for navigation purposes.

         for J in 1 .. Nrefs loop
            declare
               E   : constant Entity_Id  := Xrefs.Table (J).Key.Ent;
               Loc : constant Source_Ptr := Original_Location (Sloc (E));

            begin
               Rnums (J) := J;

               if Nkind (E) = N_Defining_Operator_Symbol then
                  Xrefs.Table (J).Def := Loc + 1;
               else
                  Xrefs.Table (J).Def := Loc;
               end if;
            end;
         end loop;

         --  Sort the references

         Sorting.Sort (Integer (Nrefs));

         --  Initialize loop through references

         Curxu  := No_Unit;
         Curent := Empty;
         Curdef := No_Location;
         Curru  := No_Unit;
         Crloc  := No_Location;
         Prevt  := 'm';

         --  Loop to output references

         for Refno in 1 .. Nrefs loop
            Output_One_Ref : declare
               Ent : Entity_Id;

               XE : Xref_Entry renames Xrefs.Table (Rnums (Refno));
               --  The current entry to be accessed

               Left  : Character;
               Right : Character;
               --  Used for {} or <> or () for type reference

               procedure Check_Type_Reference
                 (Ent            : Entity_Id;
                  List_Interface : Boolean;
                  Is_Component   : Boolean := False);
               --  Find whether there is a meaningful type reference for
               --  Ent, and display it accordingly. If List_Interface is
               --  true, then Ent is a progenitor interface of the current
               --  type entity being listed. In that case list it as is,
               --  without looking for a type reference for it. Flag is also
               --  used for index types of an array type, where the caller
               --  supplies the intended type reference. Is_Component serves
               --  the same purpose, to display the component type of a
               --  derived array type, for which only the parent type has
               --  ben displayed so far.

               procedure Output_Instantiation_Refs (Loc : Source_Ptr);
               --  Recursive procedure to output instantiation references for
               --  the given source ptr in [file|line[...]] form. No output
               --  if the given location is not a generic template reference.

               procedure Output_Overridden_Op (Old_E : Entity_Id);
               --  For a subprogram that is overriding, display information
               --  about the inherited operation that it overrides.

               --------------------------
               -- Check_Type_Reference --
               --------------------------

               procedure Check_Type_Reference
                 (Ent            : Entity_Id;
                  List_Interface : Boolean;
                  Is_Component   : Boolean := False)
               is
               begin
                  if List_Interface then

                     --  This is a progenitor interface of the type for which
                     --  xref information is being generated.

                     Tref  := Ent;
                     Left  := '<';
                     Right := '>';

                  --  The following is not documented in lib-xref.ads ???

                  elsif Is_Component then
                     Tref  := Ent;
                     Left  := '(';
                     Right := ')';

                  else
                     Get_Type_Reference (Ent, Tref, Left, Right);
                  end if;

                  if Present (Tref) then

                     --  Case of standard entity, output name

                     if Sloc (Tref) = Standard_Location then
                        Write_Info_Char (Left);
                        Write_Info_Name (Chars (Tref));
                        Write_Info_Char (Right);

                     --  Case of source entity, output location

                     else
                        Write_Info_Char (Left);
                        Trunit := Get_Source_Unit (Sloc (Tref));

                        if Trunit /= Curxu then
                           Write_Info_Nat (Dependency_Num (Trunit));
                           Write_Info_Char ('|');
                        end if;

                        Write_Info_Nat
                          (Int (Get_Logical_Line_Number (Sloc (Tref))));

                        declare
                           Ent  : Entity_Id;
                           Ctyp : Character;

                        begin
                           Ent := Tref;
                           Ctyp := Xref_Entity_Letters (Ekind (Ent));

                           if Ctyp = '+'
                             and then Present (Full_View (Ent))
                           then
                              Ent := Underlying_Type (Ent);

                              if Present (Ent) then
                                 Ctyp := Xref_Entity_Letters (Ekind (Ent));
                              end if;
                           end if;

                           Write_Info_Char (Ctyp);
                        end;

                        Write_Info_Nat
                          (Int (Get_Column_Number (Sloc (Tref))));

                        --  If the type comes from an instantiation, add the
                        --  corresponding info.

                        Output_Instantiation_Refs (Sloc (Tref));
                        Write_Info_Char (Right);
                     end if;
                  end if;
               end Check_Type_Reference;

               -------------------------------
               -- Output_Instantiation_Refs --
               -------------------------------

               procedure Output_Instantiation_Refs (Loc : Source_Ptr) is
                  Iloc : constant Source_Ptr := Instantiation_Location (Loc);
                  Lun  : Unit_Number_Type;
                  Cu   : constant Unit_Number_Type := Curru;

               begin
                  --  Nothing to do if this is not an instantiation

                  if Iloc = No_Location then
                     return;
                  end if;

                  --  Output instantiation reference

                  Write_Info_Char ('[');
                  Lun := Get_Source_Unit (Iloc);

                  if Lun /= Curru then
                     Curru := Lun;
                     Write_Info_Nat (Dependency_Num (Curru));
                     Write_Info_Char ('|');
                  end if;

                  Write_Info_Nat (Int (Get_Logical_Line_Number (Iloc)));

                  --  Recursive call to get nested instantiations

                  Output_Instantiation_Refs (Iloc);

                  --  Output final ] after call to get proper nesting

                  Write_Info_Char (']');
                  Curru := Cu;
                  return;
               end Output_Instantiation_Refs;

               --------------------------
               -- Output_Overridden_Op --
               --------------------------

               procedure Output_Overridden_Op (Old_E : Entity_Id) is
                  Op : Entity_Id;

               begin
                  --  The overridden operation has an implicit declaration
                  --  at the point of derivation. What we want to display
                  --  is the original operation, which has the actual body
                  --  (or abstract declaration) that is being overridden.
                  --  The overridden operation is not always set, e.g. when
                  --  it is a predefined operator.

                  if No (Old_E) then
                     return;

                  --  Follow alias chain if one is present

                  elsif Present (Alias (Old_E)) then

                     --  The subprogram may have been implicitly inherited
                     --  through several levels of derivation, so find the
                     --  ultimate (source) ancestor.

                     Op := Ultimate_Alias (Old_E);

                  --  Normal case of no alias present. We omit generated
                  --  primitives like tagged equality, that have no source
                  --  representation.

                  else
                     Op := Old_E;
                  end if;

                  if Present (Op)
                    and then Sloc (Op) /= Standard_Location
                    and then Comes_From_Source (Op)
                  then
                     declare
                        Loc      : constant Source_Ptr := Sloc (Op);
                        Par_Unit : constant Unit_Number_Type :=
                                     Get_Source_Unit (Loc);

                     begin
                        Write_Info_Char ('<');

                        if Par_Unit /= Curxu then
                           Write_Info_Nat (Dependency_Num (Par_Unit));
                           Write_Info_Char ('|');
                        end if;

                        Write_Info_Nat (Int (Get_Logical_Line_Number (Loc)));
                        Write_Info_Char ('p');
                        Write_Info_Nat (Int (Get_Column_Number (Loc)));
                        Write_Info_Char ('>');
                     end;
                  end if;
               end Output_Overridden_Op;

            --  Start of processing for Output_One_Ref

            begin
               Ent := XE.Key.Ent;

               --  Do not generate reference information for an ignored Ghost
               --  entity because neither the entity nor its references will
               --  appear in the final tree.

               if Is_Ignored_Ghost_Entity (Ent) then
                  goto Continue;
               end if;

               Ctyp := Xref_Entity_Letters (Ekind (Ent));

               --  Skip reference if it is the only reference to an entity,
               --  and it is an END line reference, and the entity is not in
               --  the current extended source. This prevents junk entries
               --  consisting only of packages with END lines, where no
               --  entity from the package is actually referenced.

               if XE.Key.Typ = 'e'
                 and then Ent /= Curent
                 and then (Refno = Nrefs
                            or else
                              Ent /= Xrefs.Table (Rnums (Refno + 1)).Key.Ent)
                 and then not In_Extended_Main_Source_Unit (Ent)
               then
                  goto Continue;
               end if;

               --  For private type, get full view type

               if Ctyp = '+'
                 and then Present (Full_View (XE.Key.Ent))
               then
                  Ent := Underlying_Type (Ent);

                  if Present (Ent) then
                     Ctyp := Xref_Entity_Letters (Ekind (Ent));
                  end if;
               end if;

               --  Special exception for Boolean

               if Ctyp = 'E' and then Is_Boolean_Type (Ent) then
                  Ctyp := 'B';
               end if;

               --  For variable reference, get corresponding type

               if Ctyp = '*' then
                  Ent := Etype (XE.Key.Ent);
                  Ctyp := Fold_Lower (Xref_Entity_Letters (Ekind (Ent)));

                  --  If variable is private type, get full view type

                  if Ctyp = '+'
                    and then Present (Full_View (Etype (XE.Key.Ent)))
                  then
                     Ent := Underlying_Type (Etype (XE.Key.Ent));

                     if Present (Ent) then
                        Ctyp := Fold_Lower (Xref_Entity_Letters (Ekind (Ent)));
                     end if;

                  elsif Is_Generic_Type (Ent) then

                     --  If the type of the entity is a generic private type,
                     --  there is no usable full view, so retain the indication
                     --  that this is an object.

                     Ctyp := '*';
                  end if;

                  --  Special handling for access parameters and objects and
                  --  components of an anonymous access type.

                  if Ekind (Etype (XE.Key.Ent)) in
                               E_Anonymous_Access_Type
                             | E_Anonymous_Access_Subprogram_Type
                             | E_Anonymous_Access_Protected_Subprogram_Type
                  then
                     if Is_Formal (XE.Key.Ent)
                       or else
                         Ekind (XE.Key.Ent) in
                           E_Variable | E_Constant | E_Component
                     then
                        Ctyp := 'p';
                     end if;

                     --  Special handling for Boolean

                  elsif Ctyp = 'e' and then Is_Boolean_Type (Ent) then
                     Ctyp := 'b';
                  end if;
               end if;

               --  Special handling for abstract types and operations

               if Is_Overloadable (XE.Key.Ent)
                 and then Is_Abstract_Subprogram (XE.Key.Ent)
               then
                  if Ctyp = 'U' then
                     Ctyp := 'x';            --  Abstract procedure

                  elsif Ctyp = 'V' then
                     Ctyp := 'y';            --  Abstract function
                  end if;

               elsif Is_Type (XE.Key.Ent)
                 and then Is_Abstract_Type (XE.Key.Ent)
               then
                  if Is_Interface (XE.Key.Ent) then
                     Ctyp := 'h';

                  elsif Ctyp = 'R' then
                     Ctyp := 'H';            --  Abstract type
                  end if;
               end if;

               --  Only output reference if interesting type of entity

               if Ctyp = ' '

               --  Suppress references to object definitions, used for local
               --  references.

                 or else XE.Key.Typ = 'D'
                 or else XE.Key.Typ = 'I'

               --  Suppress self references, except for bodies that act as
               --  specs.

                 or else (XE.Key.Loc = XE.Def
                           and then
                             (XE.Key.Typ /= 'b'
                               or else not Is_Subprogram (XE.Key.Ent)))

               --  Also suppress definitions of body formals (we only
               --  treat these as references, and the references were
               --  separately recorded).

                 or else (Is_Formal (XE.Key.Ent)
                           and then Present (Spec_Entity (XE.Key.Ent)))
               then
                  null;

               else
                  --  Start new Xref section if new xref unit

                  if XE.Key.Eun /= Curxu then
                     if Write_Info_Col > 1 then
                        Write_Info_EOL;
                     end if;

                     Curxu := XE.Key.Eun;

                     Write_Info_Initiate ('X');
                     Write_Info_Char (' ');
                     Write_Info_Nat (Dependency_Num (XE.Key.Eun));
                     Write_Info_Char (' ');
                     Write_Info_Name
                       (Reference_Name (Source_Index (XE.Key.Eun)));
                  end if;

                  --  Start new Entity line if new entity. Note that we
                  --  consider two entities the same if they have the same
                  --  name and source location. This causes entities in
                  --  instantiations to be treated as though they referred
                  --  to the template.

                  if No (Curent)
                    or else
                      (XE.Key.Ent /= Curent
                         and then
                           (Name_Change (XE.Key.Ent) or else XE.Def /= Curdef))
                  then
                     Curent := XE.Key.Ent;
                     Curdef := XE.Def;

                     Get_Unqualified_Name_String (Chars (XE.Key.Ent));
                     Curlen := Name_Len;
                     Curnam (1 .. Curlen) := Name_Buffer (1 .. Curlen);

                     if Write_Info_Col > 1 then
                        Write_Info_EOL;
                     end if;

                     --  Write column number information

                     Write_Info_Nat (Int (Get_Logical_Line_Number (XE.Def)));
                     Write_Info_Char (Ctyp);
                     Write_Info_Nat (Int (Get_Column_Number (XE.Def)));

                     --  Write level information

                     Write_Level_Info : declare
                        function Is_Visible_Generic_Entity
                          (E : Entity_Id) return Boolean;
                        --  Check whether E is declared in the visible part
                        --  of a generic package. For source navigation
                        --  purposes, treat this as a visible entity.

                        function Is_Private_Record_Component
                          (E : Entity_Id) return Boolean;
                        --  Check whether E is a non-inherited component of a
                        --  private extension. Even if the enclosing record is
                        --  public, we want to treat the component as private
                        --  for navigation purposes.

                        ---------------------------------
                        -- Is_Private_Record_Component --
                        ---------------------------------

                        function Is_Private_Record_Component
                          (E : Entity_Id) return Boolean
                        is
                           S : constant Entity_Id := Scope (E);
                        begin
                           return
                             Ekind (E) = E_Component
                               and then Nkind (Declaration_Node (S)) =
                                 N_Private_Extension_Declaration
                               and then Original_Record_Component (E) = E;
                        end Is_Private_Record_Component;

                        -------------------------------
                        -- Is_Visible_Generic_Entity --
                        -------------------------------

                        function Is_Visible_Generic_Entity
                          (E : Entity_Id) return Boolean
                        is
                           Par : Node_Id;

                        begin
                           --  The Present check here is an error defense

                           if Present (Scope (E))
                             and then Ekind (Scope (E)) /= E_Generic_Package
                           then
                              return False;
                           end if;

                           Par := Parent (E);
                           while Present (Par) loop
                              if
                                Nkind (Par) = N_Generic_Package_Declaration
                              then
                                 --  Entity is a generic formal

                                 return False;

                              elsif
                                Nkind (Parent (Par)) = N_Package_Specification
                              then
                                 return
                                   Is_List_Member (Par)
                                     and then List_Containing (Par) =
                                       Visible_Declarations (Parent (Par));
                              else
                                 Par := Parent (Par);
                              end if;
                           end loop;

                           return False;
                        end Is_Visible_Generic_Entity;

                     --  Start of processing for Write_Level_Info

                     begin
                        if Is_Hidden (Curent)
                          or else Is_Private_Record_Component (Curent)
                        then
                           Write_Info_Char (' ');

                        elsif
                           Is_Public (Curent)
                             or else Is_Visible_Generic_Entity (Curent)
                        then
                           Write_Info_Char ('*');

                        else
                           Write_Info_Char (' ');
                        end if;
                     end Write_Level_Info;

                     --  Output entity name. We use the occurrence from the
                     --  actual source program at the definition point.

                     declare
                        Ent_Name : constant String :=
                                     Exact_Source_Name (Sloc (XE.Key.Ent));
                     begin
                        for C in Ent_Name'Range loop
                           Write_Info_Char (Ent_Name (C));
                        end loop;
                     end;

                     --  See if we have a renaming reference

                     if Is_Object (XE.Key.Ent)
                       and then Present (Renamed_Object (XE.Key.Ent))
                     then
                        Rref := Renamed_Object (XE.Key.Ent);

                     elsif Is_Overloadable (XE.Key.Ent)
                       and then Nkind (Parent (Declaration_Node (XE.Key.Ent)))
                                           = N_Subprogram_Renaming_Declaration
                     then
                        Rref := Name (Parent (Declaration_Node (XE.Key.Ent)));

                     elsif Ekind (XE.Key.Ent) = E_Package
                       and then Nkind (Declaration_Node (XE.Key.Ent)) =
                                         N_Package_Renaming_Declaration
                     then
                        Rref := Name (Declaration_Node (XE.Key.Ent));

                     else
                        Rref := Empty;
                     end if;

                     if Present (Rref) then
                        if Nkind (Rref) = N_Expanded_Name then
                           Rref := Selector_Name (Rref);
                        end if;

                        if Nkind (Rref) = N_Identifier
                          or else Nkind (Rref) = N_Operator_Symbol
                        then
                           null;

                        --  For renamed array components, use the array name
                        --  for the renamed entity, which reflect the fact that
                        --  in general the whole array is aliased.

                        elsif Nkind (Rref) = N_Indexed_Component then
                           if Nkind (Prefix (Rref)) = N_Identifier then
                              Rref := Prefix (Rref);
                           elsif Nkind (Prefix (Rref)) = N_Expanded_Name then
                              Rref := Selector_Name (Prefix (Rref));
                           else
                              Rref := Empty;
                           end if;

                        else
                           Rref := Empty;
                        end if;
                     end if;

                     --  Write out renaming reference if we have one

                     if Present (Rref) then
                        Write_Info_Char ('=');
                        Write_Info_Nat
                          (Int (Get_Logical_Line_Number (Sloc (Rref))));
                        Write_Info_Char (':');
                        Write_Info_Nat
                          (Int (Get_Column_Number (Sloc (Rref))));
                     end if;

                     --  Indicate that the entity is in the unit of the current
                     --  xref section.

                     Curru := Curxu;

                     --  Write out information about generic parent, if entity
                     --  is an instance.

                     if Is_Generic_Instance (XE.Key.Ent) then
                        declare
                           Gen_Par : constant Entity_Id :=
                                       Generic_Parent
                                         (Specification
                                            (Unit_Declaration_Node
                                               (XE.Key.Ent)));
                           Loc     : constant Source_Ptr := Sloc (Gen_Par);
                           Gen_U   : constant Unit_Number_Type :=
                                       Get_Source_Unit (Loc);

                        begin
                           Write_Info_Char ('[');

                           if Curru /= Gen_U then
                              Write_Info_Nat (Dependency_Num (Gen_U));
                              Write_Info_Char ('|');
                           end if;

                           Write_Info_Nat
                             (Int (Get_Logical_Line_Number (Loc)));
                           Write_Info_Char (']');
                        end;
                     end if;

                     --  See if we have a type reference and if so output

                     Check_Type_Reference (XE.Key.Ent, False);

                     --  Additional information for types with progenitors,
                     --  including synchronized tagged types.

                     declare
                        Typ  : constant Entity_Id := XE.Key.Ent;
                        Elmt : Elmt_Id;

                     begin
                        if Is_Record_Type (Typ)
                          and then Present (Interfaces (Typ))
                        then
                           Elmt := First_Elmt (Interfaces (Typ));

                        elsif Is_Concurrent_Type (Typ)
                          and then Present (Corresponding_Record_Type (Typ))
                          and then Present (
                            Interfaces (Corresponding_Record_Type (Typ)))
                        then
                           Elmt :=
                             First_Elmt (
                              Interfaces (Corresponding_Record_Type (Typ)));

                        else
                           Elmt := No_Elmt;
                        end if;

                        while Present (Elmt) loop
                           Check_Type_Reference (Node (Elmt), True);
                           Next_Elmt (Elmt);
                        end loop;
                     end;

                     --  For array types, list index types as well. (This is
                     --  not C, indexes have distinct types).

                     if Is_Array_Type (XE.Key.Ent) then
                        declare
                           A_Typ : constant Entity_Id := XE.Key.Ent;
                           Indx : Node_Id;

                        begin
                           --  If this is a derived array type, we have
                           --  output the parent type, so add the component
                           --  type now.

                           if Is_Derived_Type (A_Typ) then
                              Check_Type_Reference
                                (Component_Type (A_Typ), False, True);
                           end if;

                           --  Add references to index types.

                           Indx := First_Index (XE.Key.Ent);
                           while Present (Indx) loop
                              Check_Type_Reference
                                (First_Subtype (Etype (Indx)), True);
                              Next_Index (Indx);
                           end loop;
                        end;
                     end if;

                     --  If the entity is an overriding operation, write info
                     --  on operation that was overridden.

                     if Is_Subprogram (XE.Key.Ent)
                       and then Present (Overridden_Operation (XE.Key.Ent))
                     then
                        Output_Overridden_Op
                          (Overridden_Operation (XE.Key.Ent));
                     end if;

                     --  End of processing for entity output

                     Crloc := No_Location;
                  end if;

                  --  Output the reference if it is not as the same location
                  --  as the previous one, or it is a read-reference that
                  --  indicates that the entity is an in-out actual in a call.

                  if XE.Key.Loc /= No_Location
                    and then
                      (XE.Key.Loc /= Crloc
                        or else (Prevt = 'm' and then XE.Key.Typ = 'r'))
                  then
                     Crloc := XE.Key.Loc;
                     Prevt := XE.Key.Typ;

                     --  Start continuation if line full, else blank

                     if Write_Info_Col > 72 then
                        Write_Info_EOL;
                        Write_Info_Initiate ('.');
                     end if;

                     Write_Info_Char (' ');

                     --  Output file number if changed

                     if XE.Key.Lun /= Curru then
                        Curru := XE.Key.Lun;
                        Write_Info_Nat (Dependency_Num (Curru));
                        Write_Info_Char ('|');
                     end if;

                     Write_Info_Nat
                       (Int (Get_Logical_Line_Number (XE.Key.Loc)));
                     Write_Info_Char (XE.Key.Typ);

                     if Is_Overloadable (XE.Key.Ent) then
                        if (Is_Imported (XE.Key.Ent) and then XE.Key.Typ = 'b')
                             or else
                           (Is_Exported (XE.Key.Ent) and then XE.Key.Typ = 'i')
                        then
                           Output_Import_Export_Info (XE.Key.Ent);
                        end if;
                     end if;

                     Write_Info_Nat (Int (Get_Column_Number (XE.Key.Loc)));

                     Output_Instantiation_Refs (Sloc (XE.Key.Ent));
                  end if;
               end if;
            end Output_One_Ref;

         <<Continue>>
            null;
         end loop;

         Write_Info_EOL;
      end Output_Refs;
   end Output_References;

   ---------------------------------
   -- Process_Deferred_References --
   ---------------------------------

   procedure Process_Deferred_References is
   begin
      for J in Deferred_References.First .. Deferred_References.Last loop
         declare
            D : Deferred_Reference_Entry renames Deferred_References.Table (J);

         begin
            case Is_LHS (D.N) is
               when Yes =>
                  Generate_Reference (D.E, D.N, 'm');

               when No =>
                  Generate_Reference (D.E, D.N, 'r');

               --  Not clear if Unknown can occur at this stage, but if it
               --  does we will treat it as a normal reference.

               when Unknown =>
                  Generate_Reference (D.E, D.N, 'r');
            end case;
         end;
      end loop;

      --  Clear processed entries from table

      Deferred_References.Init;
   end Process_Deferred_References;

--  Start of elaboration for Lib.Xref

begin
   --  Reset is necessary because Elmt_Ptr does not default to Null_Ptr,
   --  because it's not an access type.

   Xref_Set.Reset;
end Lib.Xref;
