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

with 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 Warnsw;         use Warnsw;

with GNAT.Heap_Sort_G;
with GNAT.HTable;

package body Lib.Xref is

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

   --  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;

   -----------
   -- 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 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)
                             or else Ekind (Obj) = E_Enumeration_Literal
                           then
                              return Empty;
                           end if;
                        else
                           return Obj;
                        end if;
                     end;
                  end loop;
               end;

            when others =>
               return E;

         end case;
      end Get_Through_Renamings;

      ---------------------------
      -- 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;

      --  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
      --  the main source unit, when the object 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_Object (E)
           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

         --  When E itself is an IN OUT parameter mark it referenced

         if Is_Assignable (E)
           and then Ekind (E) = E_In_Out_Parameter
           and then Known_To_Be_Assigned (N)
         then
            Set_Referenced (E);

         --  For the case where the entity is on the left hand side of an
         --  assignment statement, we do nothing here.

         --  The processing for Analyze_Assignment_Statement will set the
         --  Referenced_As_LHS flag.

         elsif Is_Assignable (E)
           and then Known_To_Be_Assigned (N, Only_LHS => True)
         then
            null;

         --  For objects that are renamings, just set as simply referenced.
         --  We do not try to do assignment type tracking in this case.

         elsif Is_Assignable (E)
           and then Present (Renamed_Object (E))
         then
            Set_Referenced (E);

         --  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;

         --  Out parameter case

         elsif Kind = E_Out_Parameter
           and then Is_Assignable (E)
         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 reference.

            else
               Set_Referenced_As_Out_Parameter (E);
               Set_Referenced (E);
            end if;

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

         elsif 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;

         --  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 or use of an out parameter with warnings for
            --  unread out parameters specified (via -gnatw.o).

            --  The reason for treating unread out parameters in a special
            --  way is so that when pragma Unreferenced is specified on such
            --  an out parameter we do not want to issue a warning about the
            --  pragma being unnecessary - because the purpose of the flag
            --  is to warn about them not being read (e.g. unreferenced)
            --  after use.

            elsif (Known_To_Be_Assigned (N, Only_LHS => True)
                    or else (Present (Formal)
                              and then Ekind (Formal) = E_Out_Parameter
                              and then Warn_On_All_Unread_Out_Parameters))
              and then not (Ekind (E) = E_In_Out_Parameter
                             and then Known_To_Be_Assigned (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
                             ("??aspect Unused specified for&!", N, BE);
                        else
                           Error_Msg_NE -- CODEFIX
                             ("??aspect Unreferenced specified 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
                 ("??aspect Unused specified for&!", N, E);
            else
               Error_Msg_NE -- CODEFIX
                 ("??aspect Unreferenced specified 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;

   ----------
   -- 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 := 3 * M (XE.Key.Ent) + 5 * M (abs XE.Key.Loc);
      --  It would be more natural to write:
      --
      --    H : constant M := 3 * M'Mod (XE.Key.Ent) + 5 * 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;

--  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;
