File : lib-xref.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --                             L I B . X R E F                              --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 1998-2016, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  17 -- for  more details.  You should have  received  a copy of the GNU General --
  18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
  19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
  20 --                                                                          --
  21 -- GNAT was originally developed  by the GNAT team at  New York University. --
  22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  23 --                                                                          --
  24 ------------------------------------------------------------------------------
  25 
  26 with Atree;    use Atree;
  27 with Csets;    use Csets;
  28 with Elists;   use Elists;
  29 with Errout;   use Errout;
  30 with Nlists;   use Nlists;
  31 with Opt;      use Opt;
  32 with Restrict; use Restrict;
  33 with Rident;   use Rident;
  34 with Sem;      use Sem;
  35 with Sem_Aux;  use Sem_Aux;
  36 with Sem_Prag; use Sem_Prag;
  37 with Sem_Util; use Sem_Util;
  38 with Sem_Warn; use Sem_Warn;
  39 with Sinfo;    use Sinfo;
  40 with Sinput;   use Sinput;
  41 with Snames;   use Snames;
  42 with Stringt;  use Stringt;
  43 with Stand;    use Stand;
  44 with Table;    use Table;
  45 
  46 with GNAT.Heap_Sort_G;
  47 with GNAT.HTable;
  48 
  49 package body Lib.Xref is
  50 
  51    ------------------
  52    -- Declarations --
  53    ------------------
  54 
  55    --  The Xref table is used to record references. The Loc field is set
  56    --  to No_Location for a definition entry.
  57 
  58    subtype Xref_Entry_Number is Int;
  59 
  60    type Xref_Key is record
  61       --  These are the components of Xref_Entry that participate in hash
  62       --  lookups.
  63 
  64       Ent : Entity_Id;
  65       --  Entity referenced (E parameter to Generate_Reference)
  66 
  67       Loc : Source_Ptr;
  68       --  Location of reference (Original_Location (Sloc field of N parameter
  69       --  to Generate_Reference)). Set to No_Location for the case of a
  70       --  defining occurrence.
  71 
  72       Typ : Character;
  73       --  Reference type (Typ param to Generate_Reference)
  74 
  75       Eun : Unit_Number_Type;
  76       --  Unit number corresponding to Ent
  77 
  78       Lun : Unit_Number_Type;
  79       --  Unit number corresponding to Loc. Value is undefined and not
  80       --  referenced if Loc is set to No_Location.
  81 
  82       --  The following components are only used for SPARK cross-references
  83 
  84       Ref_Scope : Entity_Id;
  85       --  Entity of the closest subprogram or package enclosing the reference
  86 
  87       Ent_Scope : Entity_Id;
  88       --  Entity of the closest subprogram or package enclosing the definition,
  89       --  which should be located in the same file as the definition itself.
  90    end record;
  91 
  92    type Xref_Entry is record
  93       Key : Xref_Key;
  94 
  95       Ent_Scope_File : Unit_Number_Type;
  96       --  File for entity Ent_Scope
  97 
  98       Def : Source_Ptr;
  99       --  Original source location for entity being referenced. Note that these
 100       --  values are used only during the output process, they are not set when
 101       --  the entries are originally built. This is because private entities
 102       --  can be swapped when the initial call is made.
 103 
 104       HTable_Next : Xref_Entry_Number;
 105       --  For use only by Static_HTable
 106    end record;
 107 
 108    package Xrefs is new Table.Table (
 109      Table_Component_Type => Xref_Entry,
 110      Table_Index_Type     => Xref_Entry_Number,
 111      Table_Low_Bound      => 1,
 112      Table_Initial        => Alloc.Xrefs_Initial,
 113      Table_Increment      => Alloc.Xrefs_Increment,
 114      Table_Name           => "Xrefs");
 115 
 116    --------------
 117    -- Xref_Set --
 118    --------------
 119 
 120    --  We keep a set of xref entries, in order to avoid inserting duplicate
 121    --  entries into the above Xrefs table. An entry is in Xref_Set if and only
 122    --  if it is in Xrefs.
 123 
 124    Num_Buckets : constant := 2**16;
 125 
 126    subtype Header_Num is Integer range 0 .. Num_Buckets - 1;
 127    type Null_Type is null record;
 128    pragma Unreferenced (Null_Type);
 129 
 130    function Hash (F : Xref_Entry_Number) return Header_Num;
 131 
 132    function Equal (F1, F2 : Xref_Entry_Number) return Boolean;
 133 
 134    procedure HT_Set_Next (E : Xref_Entry_Number; Next : Xref_Entry_Number);
 135 
 136    function  HT_Next (E : Xref_Entry_Number) return Xref_Entry_Number;
 137 
 138    function Get_Key (E : Xref_Entry_Number) return Xref_Entry_Number;
 139 
 140    pragma Inline (Hash, Equal, HT_Set_Next, HT_Next, Get_Key);
 141 
 142    package Xref_Set is new GNAT.HTable.Static_HTable (
 143      Header_Num,
 144      Element    => Xref_Entry,
 145      Elmt_Ptr   => Xref_Entry_Number,
 146      Null_Ptr   => 0,
 147      Set_Next   => HT_Set_Next,
 148      Next       => HT_Next,
 149      Key        => Xref_Entry_Number,
 150      Get_Key    => Get_Key,
 151      Hash       => Hash,
 152      Equal      => Equal);
 153 
 154    -----------------------------
 155    -- SPARK Xrefs Information --
 156    -----------------------------
 157 
 158    package body SPARK_Specific is separate;
 159 
 160    ------------------------
 161    --  Local Subprograms --
 162    ------------------------
 163 
 164    procedure Add_Entry (Key : Xref_Key; Ent_Scope_File : Unit_Number_Type);
 165    --  Add an entry to the tables of Xref_Entries, avoiding duplicates
 166 
 167    procedure Generate_Prim_Op_References (Typ : Entity_Id);
 168    --  For a tagged type, generate implicit references to its primitive
 169    --  operations, for source navigation. This is done right before emitting
 170    --  cross-reference information rather than at the freeze point of the type
 171    --  in order to handle late bodies that are primitive operations.
 172 
 173    function Lt (T1, T2 : Xref_Entry) return Boolean;
 174    --  Order cross-references
 175 
 176    ---------------
 177    -- Add_Entry --
 178    ---------------
 179 
 180    procedure Add_Entry (Key : Xref_Key; Ent_Scope_File : Unit_Number_Type) is
 181    begin
 182       Xrefs.Increment_Last; -- tentative
 183       Xrefs.Table (Xrefs.Last).Key := Key;
 184 
 185       --  Set the entry in Xref_Set, and if newly set, keep the above
 186       --  tentative increment.
 187 
 188       if Xref_Set.Set_If_Not_Present (Xrefs.Last) then
 189          Xrefs.Table (Xrefs.Last).Ent_Scope_File := Ent_Scope_File;
 190          --  Leave Def and HTable_Next uninitialized
 191 
 192          Set_Has_Xref_Entry (Key.Ent);
 193 
 194       --  It was already in Xref_Set, so throw away the tentatively-added entry
 195 
 196       else
 197          Xrefs.Decrement_Last;
 198       end if;
 199    end Add_Entry;
 200 
 201    -----------
 202    -- Equal --
 203    -----------
 204 
 205    function Equal (F1, F2 : Xref_Entry_Number) return Boolean is
 206       Result : constant Boolean :=
 207                  Xrefs.Table (F1).Key = Xrefs.Table (F2).Key;
 208    begin
 209       return Result;
 210    end Equal;
 211 
 212    -------------------------
 213    -- Generate_Definition --
 214    -------------------------
 215 
 216    procedure Generate_Definition (E : Entity_Id) is
 217    begin
 218       pragma Assert (Nkind (E) in N_Entity);
 219 
 220       --  Note that we do not test Xref_Entity_Letters here. It is too early
 221       --  to do so, since we are often called before the entity is fully
 222       --  constructed, so that the Ekind is still E_Void.
 223 
 224       if Opt.Xref_Active
 225 
 226          --  Definition must come from source
 227 
 228          --  We make an exception for subprogram child units that have no spec.
 229          --  For these we generate a subprogram declaration for library use,
 230          --  and the corresponding entity does not come from source.
 231          --  Nevertheless, all references will be attached to it and we have
 232          --  to treat is as coming from user code.
 233 
 234          and then (Comes_From_Source (E) or else Is_Child_Unit (E))
 235 
 236          --  And must have a reasonable source location that is not
 237          --  within an instance (all entities in instances are ignored)
 238 
 239          and then Sloc (E) > No_Location
 240          and then Instantiation_Location (Sloc (E)) = No_Location
 241 
 242          --  And must be a non-internal name from the main source unit
 243 
 244          and then In_Extended_Main_Source_Unit (E)
 245          and then not Is_Internal_Name (Chars (E))
 246       then
 247          Add_Entry
 248            ((Ent => E,
 249              Loc => No_Location,
 250              Typ => ' ',
 251              Eun => Get_Source_Unit (Original_Location (Sloc (E))),
 252              Lun => No_Unit,
 253              Ref_Scope => Empty,
 254              Ent_Scope => Empty),
 255             Ent_Scope_File => No_Unit);
 256 
 257          if In_Inlined_Body then
 258             Set_Referenced (E);
 259          end if;
 260       end if;
 261    end Generate_Definition;
 262 
 263    ---------------------------------
 264    -- Generate_Operator_Reference --
 265    ---------------------------------
 266 
 267    procedure Generate_Operator_Reference
 268      (N : Node_Id;
 269       T : Entity_Id)
 270    is
 271    begin
 272       if not In_Extended_Main_Source_Unit (N) then
 273          return;
 274       end if;
 275 
 276       --  If the operator is not a Standard operator, then we generate a real
 277       --  reference to the user defined operator.
 278 
 279       if Sloc (Entity (N)) /= Standard_Location then
 280          Generate_Reference (Entity (N), N);
 281 
 282          --  A reference to an implicit inequality operator is also a reference
 283          --  to the user-defined equality.
 284 
 285          if Nkind (N) = N_Op_Ne
 286            and then not Comes_From_Source (Entity (N))
 287            and then Present (Corresponding_Equality (Entity (N)))
 288          then
 289             Generate_Reference (Corresponding_Equality (Entity (N)), N);
 290          end if;
 291 
 292       --  For the case of Standard operators, we mark the result type as
 293       --  referenced. This ensures that in the case where we are using a
 294       --  derived operator, we mark an entity of the unit that implicitly
 295       --  defines this operator as used. Otherwise we may think that no entity
 296       --  of the unit is used. The actual entity marked as referenced is the
 297       --  first subtype, which is the relevant user defined entity.
 298 
 299       --  Note: we only do this for operators that come from source. The
 300       --  generated code sometimes reaches for entities that do not need to be
 301       --  explicitly visible (for example, when we expand the code for
 302       --  comparing two record objects, the fields of the record may not be
 303       --  visible).
 304 
 305       elsif Comes_From_Source (N) then
 306          Set_Referenced (First_Subtype (T));
 307       end if;
 308    end Generate_Operator_Reference;
 309 
 310    ---------------------------------
 311    -- Generate_Prim_Op_References --
 312    ---------------------------------
 313 
 314    procedure Generate_Prim_Op_References (Typ : Entity_Id) is
 315       Base_T    : Entity_Id;
 316       Prim      : Elmt_Id;
 317       Prim_List : Elist_Id;
 318 
 319    begin
 320       --  Handle subtypes of synchronized types
 321 
 322       if Ekind (Typ) = E_Protected_Subtype
 323         or else Ekind (Typ) = E_Task_Subtype
 324       then
 325          Base_T := Etype (Typ);
 326       else
 327          Base_T := Typ;
 328       end if;
 329 
 330       --  References to primitive operations are only relevant for tagged types
 331 
 332       if not Is_Tagged_Type (Base_T)
 333         or else Is_Class_Wide_Type (Base_T)
 334       then
 335          return;
 336       end if;
 337 
 338       --  Ada 2005 (AI-345): For synchronized types generate reference to the
 339       --  wrapper that allow us to dispatch calls through their implemented
 340       --  abstract interface types.
 341 
 342       --  The check for Present here is to protect against previously reported
 343       --  critical errors.
 344 
 345       Prim_List := Primitive_Operations (Base_T);
 346 
 347       if No (Prim_List) then
 348          return;
 349       end if;
 350 
 351       Prim := First_Elmt (Prim_List);
 352       while Present (Prim) loop
 353 
 354          --  If the operation is derived, get the original for cross-reference
 355          --  reference purposes (it is the original for which we want the xref
 356          --  and for which the comes_from_source test must be performed).
 357 
 358          Generate_Reference
 359            (Typ, Ultimate_Alias (Node (Prim)), 'p', Set_Ref => False);
 360          Next_Elmt (Prim);
 361       end loop;
 362    end Generate_Prim_Op_References;
 363 
 364    ------------------------
 365    -- Generate_Reference --
 366    ------------------------
 367 
 368    procedure Generate_Reference
 369      (E       : Entity_Id;
 370       N       : Node_Id;
 371       Typ     : Character := 'r';
 372       Set_Ref : Boolean   := True;
 373       Force   : Boolean   := False)
 374    is
 375       Actual_Typ : Character := Typ;
 376       Call       : Node_Id;
 377       Def        : Source_Ptr;
 378       Ent        : Entity_Id;
 379       Ent_Scope  : Entity_Id;
 380       Formal     : Entity_Id;
 381       Kind       : Entity_Kind;
 382       Nod        : Node_Id;
 383       Ref        : Source_Ptr;
 384       Ref_Scope  : Entity_Id;
 385 
 386       function Get_Through_Renamings (E : Entity_Id) return Entity_Id;
 387       --  Get the enclosing entity through renamings, which may come from
 388       --  source or from the translation of generic instantiations.
 389 
 390       function Is_On_LHS (Node : Node_Id) return Boolean;
 391       --  Used to check if a node is on the left hand side of an assignment.
 392       --  The following cases are handled:
 393       --
 394       --   Variable    Node is a direct descendant of left hand side of an
 395       --               assignment statement.
 396       --
 397       --   Prefix      Of an indexed or selected component that is present in
 398       --               a subtree rooted by an assignment statement. There is
 399       --               no restriction of nesting of components, thus cases
 400       --               such as A.B (C).D are handled properly. However a prefix
 401       --               of a dereference (either implicit or explicit) is never
 402       --               considered as on a LHS.
 403       --
 404       --   Out param   Same as above cases, but OUT parameter
 405 
 406       function OK_To_Set_Referenced return Boolean;
 407       --  Returns True if the Referenced flag can be set. There are a few
 408       --  exceptions where we do not want to set this flag, see body for
 409       --  details of these exceptional cases.
 410 
 411       ---------------------------
 412       -- Get_Through_Renamings --
 413       ---------------------------
 414 
 415       function Get_Through_Renamings (E : Entity_Id) return Entity_Id is
 416          Result : Entity_Id := E;
 417 
 418       begin
 419          while Present (Result)
 420            and then Is_Object (Result)
 421            and then Present (Renamed_Object (Result))
 422          loop
 423             Result := Get_Enclosing_Object (Renamed_Object (Result));
 424          end loop;
 425 
 426          return Result;
 427       end Get_Through_Renamings;
 428 
 429       ---------------
 430       -- Is_On_LHS --
 431       ---------------
 432 
 433       --  ??? There are several routines here and there that perform a similar
 434       --      (but subtly different) computation, which should be factored:
 435 
 436       --      Sem_Util.Is_LHS
 437       --      Sem_Util.May_Be_Lvalue
 438       --      Sem_Util.Known_To_Be_Assigned
 439       --      Exp_Ch2.Expand_Entry_Parameter.In_Assignment_Context
 440       --      Exp_Smem.Is_Out_Actual
 441 
 442       function Is_On_LHS (Node : Node_Id) return Boolean is
 443          N : Node_Id;
 444          P : Node_Id;
 445          K : Node_Kind;
 446 
 447       begin
 448          --  Only identifiers are considered, is this necessary???
 449 
 450          if Nkind (Node) /= N_Identifier then
 451             return False;
 452          end if;
 453 
 454          --  Immediate return if appeared as OUT parameter
 455 
 456          if Kind = E_Out_Parameter then
 457             return True;
 458          end if;
 459 
 460          --  Search for assignment statement subtree root
 461 
 462          N := Node;
 463          loop
 464             P := Parent (N);
 465             K := Nkind (P);
 466 
 467             if K = N_Assignment_Statement then
 468                return Name (P) = N;
 469 
 470             --  Check whether the parent is a component and the current node is
 471             --  its prefix, but return False if the current node has an access
 472             --  type, as in that case the selected or indexed component is an
 473             --  implicit dereference, and the LHS is the designated object, not
 474             --  the access object.
 475 
 476             --  ??? case of a slice assignment?
 477 
 478             elsif (K = N_Selected_Component or else K = N_Indexed_Component)
 479               and then Prefix (P) = N
 480             then
 481                --  Check for access type. First a special test, In some cases
 482                --  this is called too early (see comments in Find_Direct_Name),
 483                --  at a point where the tree is not fully typed yet. In that
 484                --  case we may lack an Etype for N, and we can't check the
 485                --  Etype. For now, we always return False in such a case,
 486                --  but this is clearly not right in all cases ???
 487 
 488                if No (Etype (N)) then
 489                   return False;
 490 
 491                elsif Is_Access_Type (Etype (N)) then
 492                   return False;
 493 
 494                --  Access type case dealt with, keep going
 495 
 496                else
 497                   N := P;
 498                end if;
 499 
 500             --  All other cases, definitely not on left side
 501 
 502             else
 503                return False;
 504             end if;
 505          end loop;
 506       end Is_On_LHS;
 507 
 508       ---------------------------
 509       -- OK_To_Set_Referenced --
 510       ---------------------------
 511 
 512       function OK_To_Set_Referenced return Boolean is
 513          P : Node_Id;
 514 
 515       begin
 516          --  A reference from a pragma Unreferenced or pragma Unmodified or
 517          --  pragma Warnings does not cause the Referenced flag to be set.
 518          --  This avoids silly warnings about things being referenced and
 519          --  not assigned when the only reference is from the pragma.
 520 
 521          if Nkind (N) = N_Identifier then
 522             P := Parent (N);
 523 
 524             if Nkind (P) = N_Pragma_Argument_Association then
 525                P := Parent (P);
 526 
 527                if Nkind (P) = N_Pragma then
 528                   if Nam_In (Pragma_Name (P), Name_Warnings,
 529                                               Name_Unmodified,
 530                                               Name_Unreferenced)
 531                   then
 532                      return False;
 533                   end if;
 534                end if;
 535 
 536             --  A reference to a formal in a named parameter association does
 537             --  not make the formal referenced. Formals that are unused in the
 538             --  subprogram body are properly flagged as such, even if calls
 539             --  elsewhere use named notation.
 540 
 541             elsif Nkind (P) = N_Parameter_Association
 542               and then N = Selector_Name (P)
 543             then
 544                return False;
 545             end if;
 546          end if;
 547 
 548          return True;
 549       end OK_To_Set_Referenced;
 550 
 551    --  Start of processing for Generate_Reference
 552 
 553    begin
 554       pragma Assert (Nkind (E) in N_Entity);
 555       Find_Actual (N, Formal, Call);
 556 
 557       if Present (Formal) then
 558          Kind := Ekind (Formal);
 559       else
 560          Kind := E_Void;
 561       end if;
 562 
 563       --  Check for obsolescent reference to package ASCII. GNAT treats this
 564       --  element of annex J specially since in practice, programs make a lot
 565       --  of use of this feature, so we don't include it in the set of features
 566       --  diagnosed when Warn_On_Obsolescent_Features mode is set. However we
 567       --  are required to note it as a violation of the RM defined restriction.
 568 
 569       if E = Standard_ASCII then
 570          Check_Restriction (No_Obsolescent_Features, N);
 571       end if;
 572 
 573       --  Check for reference to entity marked with Is_Obsolescent
 574 
 575       --  Note that we always allow obsolescent references in the compiler
 576       --  itself and the run time, since we assume that we know what we are
 577       --  doing in such cases. For example the calls in Ada.Characters.Handling
 578       --  to its own obsolescent subprograms are just fine.
 579 
 580       --  In any case we only generate warnings if we are in the extended main
 581       --  source unit, and the entity itself is not in the extended main source
 582       --  unit, since we assume the source unit itself knows what is going on
 583       --  (and for sure we do not want silly warnings, e.g. on the end line of
 584       --  an obsolescent procedure body).
 585 
 586       if Is_Obsolescent (E)
 587         and then not GNAT_Mode
 588         and then not In_Extended_Main_Source_Unit (E)
 589         and then In_Extended_Main_Source_Unit (N)
 590       then
 591          Check_Restriction (No_Obsolescent_Features, N);
 592 
 593          if Warn_On_Obsolescent_Feature then
 594             Output_Obsolescent_Entity_Warnings (N, E);
 595          end if;
 596       end if;
 597 
 598       --  Warn if reference to Ada 2005 entity not in Ada 2005 mode. We only
 599       --  detect real explicit references (modifications and references).
 600 
 601       if Comes_From_Source (N)
 602         and then Is_Ada_2005_Only (E)
 603         and then Ada_Version < Ada_2005
 604         and then Warn_On_Ada_2005_Compatibility
 605         and then (Typ = 'm' or else Typ = 'r' or else Typ = 's')
 606       then
 607          Error_Msg_NE ("& is only defined in Ada 2005?y?", N, E);
 608       end if;
 609 
 610       --  Warn if reference to Ada 2012 entity not in Ada 2012 mode. We only
 611       --  detect real explicit references (modifications and references).
 612 
 613       if Comes_From_Source (N)
 614         and then Is_Ada_2012_Only (E)
 615         and then Ada_Version < Ada_2012
 616         and then Warn_On_Ada_2012_Compatibility
 617         and then (Typ = 'm' or else Typ = 'r')
 618       then
 619          Error_Msg_NE ("& is only defined in Ada 2012?y?", N, E);
 620       end if;
 621 
 622       --  Do not generate references if we are within a postcondition sub-
 623       --  program, because the reference does not comes from source, and the
 624       --  pre-analysis of the aspect has already created an entry for the ALI
 625       --  file at the proper source location.
 626 
 627       if Chars (Current_Scope) = Name_uPostconditions then
 628          return;
 629       end if;
 630 
 631       --  Never collect references if not in main source unit. However, we omit
 632       --  this test if Typ is 'e' or 'k', since these entries are structural,
 633       --  and it is useful to have them in units that reference packages as
 634       --  well as units that define packages. We also omit the test for the
 635       --  case of 'p' since we want to include inherited primitive operations
 636       --  from other packages.
 637 
 638       --  We also omit this test is this is a body reference for a subprogram
 639       --  instantiation. In this case the reference is to the generic body,
 640       --  which clearly need not be in the main unit containing the instance.
 641       --  For the same reason we accept an implicit reference generated for
 642       --  a default in an instance.
 643 
 644       --  We also set the referenced flag in a generic package that is not in
 645       --  then main source unit, when the variable is of a formal private type,
 646       --  to warn in the instance if the corresponding type is not a fully
 647       --  initialized type.
 648 
 649       if not In_Extended_Main_Source_Unit (N) then
 650          if Typ = 'e' or else
 651             Typ = 'I' or else
 652             Typ = 'p' or else
 653             Typ = 'i' or else
 654             Typ = 'k'
 655            or else (Typ = 'b' and then Is_Generic_Instance (E))
 656 
 657             --  Allow the generation of references to reads, writes and calls
 658             --  in SPARK mode when the related context comes from an instance.
 659 
 660            or else
 661              (GNATprove_Mode
 662                and then In_Extended_Main_Code_Unit (N)
 663                and then (Typ = 'm' or else Typ = 'r' or else Typ = 's'))
 664          then
 665             null;
 666 
 667          elsif In_Instance_Body
 668            and then In_Extended_Main_Code_Unit (N)
 669            and then Is_Generic_Type (Etype (E))
 670          then
 671             Set_Referenced (E);
 672             return;
 673 
 674          elsif Inside_A_Generic
 675            and then Is_Generic_Type (Etype (E))
 676          then
 677             Set_Referenced (E);
 678             return;
 679 
 680          else
 681             return;
 682          end if;
 683       end if;
 684 
 685       --  For reference type p, the entity must be in main source unit
 686 
 687       if Typ = 'p' and then not In_Extended_Main_Source_Unit (E) then
 688          return;
 689       end if;
 690 
 691       --  Unless the reference is forced, we ignore references where the
 692       --  reference itself does not come from source.
 693 
 694       if not Force and then not Comes_From_Source (N) then
 695          return;
 696       end if;
 697 
 698       --  Deal with setting entity as referenced, unless suppressed. Note that
 699       --  we still do Set_Referenced on entities that do not come from source.
 700       --  This situation arises when we have a source reference to a derived
 701       --  operation, where the derived operation itself does not come from
 702       --  source, but we still want to mark it as referenced, since we really
 703       --  are referencing an entity in the corresponding package (this avoids
 704       --  wrong complaints that the package contains no referenced entities).
 705 
 706       if Set_Ref then
 707 
 708          --  Assignable object appearing on left side of assignment or as
 709          --  an out parameter.
 710 
 711          if Is_Assignable (E)
 712            and then Is_On_LHS (N)
 713            and then Ekind (E) /= E_In_Out_Parameter
 714          then
 715             --  For objects that are renamings, just set as simply referenced
 716             --  we do not try to do assignment type tracking in this case.
 717 
 718             if Present (Renamed_Object (E)) then
 719                Set_Referenced (E);
 720 
 721             --  Out parameter case
 722 
 723             elsif Kind = E_Out_Parameter then
 724 
 725                --  If warning mode for all out parameters is set, or this is
 726                --  the only warning parameter, then we want to mark this for
 727                --  later warning logic by setting Referenced_As_Out_Parameter
 728 
 729                if Warn_On_Modified_As_Out_Parameter (Formal) then
 730                   Set_Referenced_As_Out_Parameter (E, True);
 731                   Set_Referenced_As_LHS (E, False);
 732 
 733                --  For OUT parameter not covered by the above cases, we simply
 734                --  regard it as a normal reference (in this case we do not
 735                --  want any of the warning machinery for out parameters).
 736 
 737                else
 738                   Set_Referenced (E);
 739                end if;
 740 
 741             --  For the left hand of an assignment case, we do nothing here.
 742             --  The processing for Analyze_Assignment_Statement will set the
 743             --  Referenced_As_LHS flag.
 744 
 745             else
 746                null;
 747             end if;
 748 
 749          --  Check for a reference in a pragma that should not count as a
 750          --  making the variable referenced for warning purposes.
 751 
 752          elsif Is_Non_Significant_Pragma_Reference (N) then
 753             null;
 754 
 755          --  A reference in an attribute definition clause does not count as a
 756          --  reference except for the case of Address. The reason that 'Address
 757          --  is an exception is that it creates an alias through which the
 758          --  variable may be referenced.
 759 
 760          elsif Nkind (Parent (N)) = N_Attribute_Definition_Clause
 761            and then Chars (Parent (N)) /= Name_Address
 762            and then N = Name (Parent (N))
 763          then
 764             null;
 765 
 766          --  Constant completion does not count as a reference
 767 
 768          elsif Typ = 'c'
 769            and then Ekind (E) = E_Constant
 770          then
 771             null;
 772 
 773          --  Record representation clause does not count as a reference
 774 
 775          elsif Nkind (N) = N_Identifier
 776            and then Nkind (Parent (N)) = N_Record_Representation_Clause
 777          then
 778             null;
 779 
 780          --  Discriminants do not need to produce a reference to record type
 781 
 782          elsif Typ = 'd'
 783            and then Nkind (Parent (N)) = N_Discriminant_Specification
 784          then
 785             null;
 786 
 787          --  All other cases
 788 
 789          else
 790             --  Special processing for IN OUT parameters, where we have an
 791             --  implicit assignment to a simple variable.
 792 
 793             if Kind = E_In_Out_Parameter
 794               and then Is_Assignable (E)
 795             then
 796                --  For sure this counts as a normal read reference
 797 
 798                Set_Referenced (E);
 799                Set_Last_Assignment (E, Empty);
 800 
 801                --  We count it as being referenced as an out parameter if the
 802                --  option is set to warn on all out parameters, except that we
 803                --  have a special exclusion for an intrinsic subprogram, which
 804                --  is most likely an instantiation of Unchecked_Deallocation
 805                --  which we do not want to consider as an assignment since it
 806                --  generates false positives. We also exclude the case of an
 807                --  IN OUT parameter if the name of the procedure is Free,
 808                --  since we suspect similar semantics.
 809 
 810                if Warn_On_All_Unread_Out_Parameters
 811                  and then Is_Entity_Name (Name (Call))
 812                  and then not Is_Intrinsic_Subprogram (Entity (Name (Call)))
 813                  and then Chars (Name (Call)) /= Name_Free
 814                then
 815                   Set_Referenced_As_Out_Parameter (E, True);
 816                   Set_Referenced_As_LHS (E, False);
 817                end if;
 818 
 819             --  Don't count a recursive reference within a subprogram as a
 820             --  reference (that allows detection of a recursive subprogram
 821             --  whose only references are recursive calls as unreferenced).
 822 
 823             elsif Is_Subprogram (E)
 824               and then E = Nearest_Dynamic_Scope (Current_Scope)
 825             then
 826                null;
 827 
 828             --  Any other occurrence counts as referencing the entity
 829 
 830             elsif OK_To_Set_Referenced then
 831                Set_Referenced (E);
 832 
 833                --  If variable, this is an OK reference after an assignment
 834                --  so we can clear the Last_Assignment indication.
 835 
 836                if Is_Assignable (E) then
 837                   Set_Last_Assignment (E, Empty);
 838                end if;
 839             end if;
 840          end if;
 841 
 842          --  Check for pragma Unreferenced given and reference is within
 843          --  this source unit (occasion for possible warning to be issued).
 844          --  Note that the entity may be marked as unreferenced by pragma
 845          --  Unused.
 846 
 847          if Has_Unreferenced (E)
 848            and then In_Same_Extended_Unit (E, N)
 849          then
 850             --  A reference as a named parameter in a call does not count
 851             --  as a violation of pragma Unreferenced for this purpose...
 852 
 853             if Nkind (N) = N_Identifier
 854               and then Nkind (Parent (N)) = N_Parameter_Association
 855               and then Selector_Name (Parent (N)) = N
 856             then
 857                null;
 858 
 859             --  ... Neither does a reference to a variable on the left side
 860             --  of an assignment.
 861 
 862             elsif Is_On_LHS (N) then
 863                null;
 864 
 865             --  For entry formals, we want to place the warning message on the
 866             --  corresponding entity in the accept statement. The current scope
 867             --  is the body of the accept, so we find the formal whose name
 868             --  matches that of the entry formal (there is no link between the
 869             --  two entities, and the one in the accept statement is only used
 870             --  for conformance checking).
 871 
 872             elsif Ekind (Scope (E)) = E_Entry then
 873                declare
 874                   BE : Entity_Id;
 875 
 876                begin
 877                   BE := First_Entity (Current_Scope);
 878                   while Present (BE) loop
 879                      if Chars (BE) = Chars (E) then
 880                         if Has_Pragma_Unused (E) then
 881                            Error_Msg_NE -- CODEFIX
 882                              ("??pragma Unused given for&!", N, BE);
 883                         else
 884                            Error_Msg_NE -- CODEFIX
 885                              ("??pragma Unreferenced given for&!", N, BE);
 886                         end if;
 887                         exit;
 888                      end if;
 889 
 890                      Next_Entity (BE);
 891                   end loop;
 892                end;
 893 
 894             --  Here we issue the warning, since this is a real reference
 895 
 896             elsif Has_Pragma_Unused (E) then
 897                Error_Msg_NE -- CODEFIX
 898                  ("??pragma Unused given for&!", N, E);
 899             else
 900                Error_Msg_NE -- CODEFIX
 901                  ("??pragma Unreferenced given for&!", N, E);
 902             end if;
 903          end if;
 904 
 905          --  If this is a subprogram instance, mark as well the internal
 906          --  subprogram in the wrapper package, which may be a visible
 907          --  compilation unit.
 908 
 909          if Is_Overloadable (E)
 910            and then Is_Generic_Instance (E)
 911            and then Present (Alias (E))
 912          then
 913             Set_Referenced (Alias (E));
 914          end if;
 915       end if;
 916 
 917       --  Generate reference if all conditions are met:
 918 
 919       if
 920          --  Cross referencing must be active
 921 
 922          Opt.Xref_Active
 923 
 924          --  The entity must be one for which we collect references
 925 
 926          and then Xref_Entity_Letters (Ekind (E)) /= ' '
 927 
 928          --  Both Sloc values must be set to something sensible
 929 
 930          and then Sloc (E) > No_Location
 931          and then Sloc (N) > No_Location
 932 
 933          --  Ignore references from within an instance. The only exceptions to
 934          --  this are default subprograms, for which we generate an implicit
 935          --  reference and compilations in SPARK mode.
 936 
 937          and then
 938            (Instantiation_Location (Sloc (N)) = No_Location
 939              or else Typ = 'i'
 940              or else GNATprove_Mode)
 941 
 942         --  Ignore dummy references
 943 
 944         and then Typ /= ' '
 945       then
 946          if Nkind_In (N, N_Identifier,
 947                          N_Defining_Identifier,
 948                          N_Defining_Operator_Symbol,
 949                          N_Operator_Symbol,
 950                          N_Defining_Character_Literal)
 951            or else Nkind (N) in N_Op
 952            or else (Nkind (N) = N_Character_Literal
 953                      and then Sloc (Entity (N)) /= Standard_Location)
 954          then
 955             Nod := N;
 956 
 957          elsif Nkind_In (N, N_Expanded_Name, N_Selected_Component) then
 958             Nod := Selector_Name (N);
 959 
 960          else
 961             return;
 962          end if;
 963 
 964          --  Normal case of source entity comes from source
 965 
 966          if Comes_From_Source (E) then
 967             Ent := E;
 968 
 969          --  Because a declaration may be generated for a subprogram body
 970          --  without declaration in GNATprove mode, for inlining, some
 971          --  parameters may end up being marked as not coming from source
 972          --  although they are. Take these into account specially.
 973 
 974          elsif GNATprove_Mode and then Ekind (E) in Formal_Kind then
 975             Ent := E;
 976 
 977          --  Entity does not come from source, but is a derived subprogram and
 978          --  the derived subprogram comes from source (after one or more
 979          --  derivations) in which case the reference is to parent subprogram.
 980 
 981          elsif Is_Overloadable (E)
 982            and then Present (Alias (E))
 983          then
 984             Ent := Alias (E);
 985             while not Comes_From_Source (Ent) loop
 986                if No (Alias (Ent)) then
 987                   return;
 988                end if;
 989 
 990                Ent := Alias (Ent);
 991             end loop;
 992 
 993          --  The internally created defining entity for a child subprogram
 994          --  that has no previous spec has valid references.
 995 
 996          elsif Is_Overloadable (E)
 997            and then Is_Child_Unit (E)
 998          then
 999             Ent := E;
1000 
1001          --  Ditto for the formals of such a subprogram
1002 
1003          elsif Is_Overloadable (Scope (E))
1004            and then Is_Child_Unit (Scope (E))
1005          then
1006             Ent := E;
1007 
1008          --  Record components of discriminated subtypes or derived types must
1009          --  be treated as references to the original component.
1010 
1011          elsif Ekind (E) = E_Component
1012            and then Comes_From_Source (Original_Record_Component (E))
1013          then
1014             Ent := Original_Record_Component (E);
1015 
1016          --  If this is an expanded reference to a discriminant, recover the
1017          --  original discriminant, which gets the reference.
1018 
1019          elsif Ekind (E) = E_In_Parameter
1020            and then  Present (Discriminal_Link (E))
1021          then
1022             Ent := Discriminal_Link (E);
1023             Set_Referenced (Ent);
1024 
1025          --  Ignore reference to any other entity that is not from source
1026 
1027          else
1028             return;
1029          end if;
1030 
1031          --  In SPARK mode, consider the underlying entity renamed instead of
1032          --  the renaming, which is needed to compute a valid set of effects
1033          --  (reads, writes) for the enclosing subprogram.
1034 
1035          if GNATprove_Mode then
1036             Ent := Get_Through_Renamings (Ent);
1037 
1038             --  If no enclosing object, then it could be a reference to any
1039             --  location not tracked individually, like heap-allocated data.
1040             --  Conservatively approximate this possibility by generating a
1041             --  dereference, and return.
1042 
1043             if No (Ent) then
1044                if Actual_Typ = 'w' then
1045                   SPARK_Specific.Generate_Dereference (Nod, 'r');
1046                   SPARK_Specific.Generate_Dereference (Nod, 'w');
1047                else
1048                   SPARK_Specific.Generate_Dereference (Nod, 'r');
1049                end if;
1050 
1051                return;
1052             end if;
1053          end if;
1054 
1055          --  Record reference to entity
1056 
1057          if Actual_Typ = 'p'
1058            and then Is_Subprogram (Nod)
1059            and then Present (Overridden_Operation (Nod))
1060          then
1061             Actual_Typ := 'P';
1062          end if;
1063 
1064          --  Comment needed here for special SPARK code ???
1065 
1066          if GNATprove_Mode then
1067             Ref := Sloc (Nod);
1068             Def := Sloc (Ent);
1069 
1070             Ref_Scope :=
1071               SPARK_Specific.Enclosing_Subprogram_Or_Library_Package (Nod);
1072             Ent_Scope :=
1073               SPARK_Specific.Enclosing_Subprogram_Or_Library_Package (Ent);
1074 
1075             --  Since we are reaching through renamings in SPARK mode, we may
1076             --  end up with standard constants. Ignore those.
1077 
1078             if Sloc (Ent_Scope) <= Standard_Location
1079               or else Def <= Standard_Location
1080             then
1081                return;
1082             end if;
1083 
1084             Add_Entry
1085               ((Ent       => Ent,
1086                 Loc       => Ref,
1087                 Typ       => Actual_Typ,
1088                 Eun       => Get_Top_Level_Code_Unit (Def),
1089                 Lun       => Get_Top_Level_Code_Unit (Ref),
1090                 Ref_Scope => Ref_Scope,
1091                 Ent_Scope => Ent_Scope),
1092                Ent_Scope_File => Get_Top_Level_Code_Unit (Ent));
1093 
1094          else
1095             Ref := Original_Location (Sloc (Nod));
1096             Def := Original_Location (Sloc (Ent));
1097 
1098             --  If this is an operator symbol, skip the initial quote for
1099             --  navigation purposes. This is not done for the end label,
1100             --  where we want the actual position after the closing quote.
1101 
1102             if Typ = 't' then
1103                null;
1104 
1105             elsif Nkind (N) = N_Defining_Operator_Symbol
1106               or else Nkind (Nod) = N_Operator_Symbol
1107             then
1108                Ref := Ref + 1;
1109             end if;
1110 
1111             Add_Entry
1112               ((Ent       => Ent,
1113                 Loc       => Ref,
1114                 Typ       => Actual_Typ,
1115                 Eun       => Get_Source_Unit (Def),
1116                 Lun       => Get_Source_Unit (Ref),
1117                 Ref_Scope => Empty,
1118                 Ent_Scope => Empty),
1119                Ent_Scope_File => No_Unit);
1120 
1121             --  Generate reference to the first private entity
1122 
1123             if Typ = 'e'
1124               and then Comes_From_Source (E)
1125               and then Nkind (Ent) = N_Defining_Identifier
1126               and then (Is_Package_Or_Generic_Package (Ent)
1127                          or else Is_Concurrent_Type (Ent))
1128               and then Present (First_Private_Entity (E))
1129               and then In_Extended_Main_Source_Unit (N)
1130             then
1131                --  Handle case in which the full-view and partial-view of the
1132                --  first private entity are swapped.
1133 
1134                declare
1135                   First_Private : Entity_Id := First_Private_Entity (E);
1136 
1137                begin
1138                   if Is_Private_Type (First_Private)
1139                     and then Present (Full_View (First_Private))
1140                   then
1141                      First_Private := Full_View (First_Private);
1142                   end if;
1143 
1144                   Add_Entry
1145                     ((Ent       => Ent,
1146                       Loc       => Sloc (First_Private),
1147                       Typ       => 'E',
1148                       Eun       => Get_Source_Unit (Def),
1149                       Lun       => Get_Source_Unit (Ref),
1150                       Ref_Scope => Empty,
1151                       Ent_Scope => Empty),
1152                      Ent_Scope_File => No_Unit);
1153                end;
1154             end if;
1155          end if;
1156       end if;
1157    end Generate_Reference;
1158 
1159    -----------------------------------
1160    -- Generate_Reference_To_Formals --
1161    -----------------------------------
1162 
1163    procedure Generate_Reference_To_Formals (E : Entity_Id) is
1164       Formal : Entity_Id;
1165 
1166    begin
1167       if Is_Generic_Subprogram (E) then
1168          Formal := First_Entity (E);
1169 
1170          while Present (Formal)
1171            and then not Is_Formal (Formal)
1172          loop
1173             Next_Entity (Formal);
1174          end loop;
1175 
1176       elsif Ekind (E) in Access_Subprogram_Kind then
1177          Formal := First_Formal (Designated_Type (E));
1178 
1179       else
1180          Formal := First_Formal (E);
1181       end if;
1182 
1183       while Present (Formal) loop
1184          if Ekind (Formal) = E_In_Parameter then
1185 
1186             if Nkind (Parameter_Type (Parent (Formal))) = N_Access_Definition
1187             then
1188                Generate_Reference (E, Formal, '^', False);
1189             else
1190                Generate_Reference (E, Formal, '>', False);
1191             end if;
1192 
1193          elsif Ekind (Formal) = E_In_Out_Parameter then
1194             Generate_Reference (E, Formal, '=', False);
1195 
1196          else
1197             Generate_Reference (E, Formal, '<', False);
1198          end if;
1199 
1200          Next_Formal (Formal);
1201       end loop;
1202    end Generate_Reference_To_Formals;
1203 
1204    -------------------------------------------
1205    -- Generate_Reference_To_Generic_Formals --
1206    -------------------------------------------
1207 
1208    procedure Generate_Reference_To_Generic_Formals (E : Entity_Id) is
1209       Formal : Entity_Id;
1210 
1211    begin
1212       Formal := First_Entity (E);
1213       while Present (Formal) loop
1214          if Comes_From_Source (Formal) then
1215             Generate_Reference (E, Formal, 'z', False);
1216          end if;
1217 
1218          Next_Entity (Formal);
1219       end loop;
1220    end Generate_Reference_To_Generic_Formals;
1221 
1222    -------------
1223    -- Get_Key --
1224    -------------
1225 
1226    function Get_Key (E : Xref_Entry_Number) return Xref_Entry_Number is
1227    begin
1228       return E;
1229    end Get_Key;
1230 
1231    ----------------------------
1232    -- Has_Deferred_Reference --
1233    ----------------------------
1234 
1235    function Has_Deferred_Reference (Ent : Entity_Id) return Boolean is
1236    begin
1237       for J in Deferred_References.First .. Deferred_References.Last loop
1238          if Deferred_References.Table (J).E = Ent then
1239             return True;
1240          end if;
1241       end loop;
1242 
1243       return False;
1244    end Has_Deferred_Reference;
1245 
1246    ----------
1247    -- Hash --
1248    ----------
1249 
1250    function Hash (F : Xref_Entry_Number) return Header_Num is
1251       --  It is unlikely to have two references to the same entity at the same
1252       --  source location, so the hash function depends only on the Ent and Loc
1253       --  fields.
1254 
1255       XE : Xref_Entry renames Xrefs.Table (F);
1256       type M is mod 2**32;
1257 
1258       H : constant M := M (XE.Key.Ent) + 2 ** 7 * M (abs XE.Key.Loc);
1259       --  It would be more natural to write:
1260       --
1261       --    H : constant M := M'Mod (XE.Key.Ent) + 2**7 * M'Mod (XE.Key.Loc);
1262       --
1263       --  But we can't use M'Mod, because it prevents bootstrapping with older
1264       --  compilers. Loc can be negative, so we do "abs" before converting.
1265       --  One day this can be cleaned up ???
1266 
1267    begin
1268       return Header_Num (H mod Num_Buckets);
1269    end Hash;
1270 
1271    -----------------
1272    -- HT_Set_Next --
1273    -----------------
1274 
1275    procedure HT_Set_Next (E : Xref_Entry_Number; Next : Xref_Entry_Number) is
1276    begin
1277       Xrefs.Table (E).HTable_Next := Next;
1278    end HT_Set_Next;
1279 
1280    -------------
1281    -- HT_Next --
1282    -------------
1283 
1284    function HT_Next (E : Xref_Entry_Number) return Xref_Entry_Number is
1285    begin
1286       return Xrefs.Table (E).HTable_Next;
1287    end HT_Next;
1288 
1289    ----------------
1290    -- Initialize --
1291    ----------------
1292 
1293    procedure Initialize is
1294    begin
1295       Xrefs.Init;
1296    end Initialize;
1297 
1298    --------
1299    -- Lt --
1300    --------
1301 
1302    function Lt (T1, T2 : Xref_Entry) return Boolean is
1303    begin
1304       --  First test: if entity is in different unit, sort by unit
1305 
1306       if T1.Key.Eun /= T2.Key.Eun then
1307          return Dependency_Num (T1.Key.Eun) < Dependency_Num (T2.Key.Eun);
1308 
1309       --  Second test: within same unit, sort by entity Sloc
1310 
1311       elsif T1.Def /= T2.Def then
1312          return T1.Def < T2.Def;
1313 
1314       --  Third test: sort definitions ahead of references
1315 
1316       elsif T1.Key.Loc = No_Location then
1317          return True;
1318 
1319       elsif T2.Key.Loc = No_Location then
1320          return False;
1321 
1322       --  Fourth test: for same entity, sort by reference location unit
1323 
1324       elsif T1.Key.Lun /= T2.Key.Lun then
1325          return Dependency_Num (T1.Key.Lun) < Dependency_Num (T2.Key.Lun);
1326 
1327       --  Fifth test: order of location within referencing unit
1328 
1329       elsif T1.Key.Loc /= T2.Key.Loc then
1330          return T1.Key.Loc < T2.Key.Loc;
1331 
1332       --  Finally, for two locations at the same address, we prefer
1333       --  the one that does NOT have the type 'r' so that a modification
1334       --  or extension takes preference, when there are more than one
1335       --  reference at the same location. As a result, in the case of
1336       --  entities that are in-out actuals, the read reference follows
1337       --  the modify reference.
1338 
1339       else
1340          return T2.Key.Typ = 'r';
1341       end if;
1342    end Lt;
1343 
1344    -----------------------
1345    -- Output_References --
1346    -----------------------
1347 
1348    procedure Output_References is
1349 
1350       procedure Get_Type_Reference
1351         (Ent   : Entity_Id;
1352          Tref  : out Entity_Id;
1353          Left  : out Character;
1354          Right : out Character);
1355       --  Given an Entity_Id Ent, determines whether a type reference is
1356       --  required. If so, Tref is set to the entity for the type reference
1357       --  and Left and Right are set to the left/right brackets to be output
1358       --  for the reference. If no type reference is required, then Tref is
1359       --  set to Empty, and Left/Right are set to space.
1360 
1361       procedure Output_Import_Export_Info (Ent : Entity_Id);
1362       --  Output language and external name information for an interfaced
1363       --  entity, using the format <language, external_name>.
1364 
1365       ------------------------
1366       -- Get_Type_Reference --
1367       ------------------------
1368 
1369       procedure Get_Type_Reference
1370         (Ent   : Entity_Id;
1371          Tref  : out Entity_Id;
1372          Left  : out Character;
1373          Right : out Character)
1374       is
1375          Sav : Entity_Id;
1376 
1377       begin
1378          --  See if we have a type reference
1379 
1380          Tref := Ent;
1381          Left := '{';
1382          Right := '}';
1383 
1384          loop
1385             Sav := Tref;
1386 
1387             --  Processing for types
1388 
1389             if Is_Type (Tref) then
1390 
1391                --  Case of base type
1392 
1393                if Base_Type (Tref) = Tref then
1394 
1395                   --  If derived, then get first subtype
1396 
1397                   if Tref /= Etype (Tref) then
1398                      Tref := First_Subtype (Etype (Tref));
1399 
1400                      --  Set brackets for derived type, but don't override
1401                      --  pointer case since the fact that something is a
1402                      --  pointer is more important.
1403 
1404                      if Left /= '(' then
1405                         Left := '<';
1406                         Right := '>';
1407                      end if;
1408 
1409                   --  If the completion of a private type is itself a derived
1410                   --  type, we need the parent of the full view.
1411 
1412                   elsif Is_Private_Type (Tref)
1413                     and then Present (Full_View (Tref))
1414                     and then Etype (Full_View (Tref)) /= Full_View (Tref)
1415                   then
1416                      Tref := Etype (Full_View (Tref));
1417 
1418                      if Left /= '(' then
1419                         Left := '<';
1420                         Right := '>';
1421                      end if;
1422 
1423                   --  If non-derived pointer, get directly designated type.
1424                   --  If the type has a full view, all references are on the
1425                   --  partial view that is seen first.
1426 
1427                   elsif Is_Access_Type (Tref) then
1428                      Tref := Directly_Designated_Type (Tref);
1429                      Left := '(';
1430                      Right := ')';
1431 
1432                   elsif Is_Private_Type (Tref)
1433                     and then Present (Full_View (Tref))
1434                   then
1435                      if Is_Access_Type (Full_View (Tref)) then
1436                         Tref := Directly_Designated_Type (Full_View (Tref));
1437                         Left := '(';
1438                         Right := ')';
1439 
1440                      --  If the full view is an array type, we also retrieve
1441                      --  the corresponding component type, because the ali
1442                      --  entry already indicates that this is an array.
1443 
1444                      elsif Is_Array_Type (Full_View (Tref)) then
1445                         Tref := Component_Type (Full_View (Tref));
1446                         Left := '(';
1447                         Right := ')';
1448                      end if;
1449 
1450                   --  If non-derived array, get component type. Skip component
1451                   --  type for case of String or Wide_String, saves worthwhile
1452                   --  space.
1453 
1454                   elsif Is_Array_Type (Tref)
1455                     and then Tref /= Standard_String
1456                     and then Tref /= Standard_Wide_String
1457                   then
1458                      Tref := Component_Type (Tref);
1459                      Left := '(';
1460                      Right := ')';
1461 
1462                   --  For other non-derived base types, nothing
1463 
1464                   else
1465                      exit;
1466                   end if;
1467 
1468                --  For a subtype, go to ancestor subtype
1469 
1470                else
1471                   Tref := Ancestor_Subtype (Tref);
1472 
1473                   --  If no ancestor subtype, go to base type
1474 
1475                   if No (Tref) then
1476                      Tref := Base_Type (Sav);
1477                   end if;
1478                end if;
1479 
1480             --  For objects, functions, enum literals, just get type from
1481             --  Etype field.
1482 
1483             elsif Is_Object (Tref)
1484               or else Ekind (Tref) = E_Enumeration_Literal
1485               or else Ekind (Tref) = E_Function
1486               or else Ekind (Tref) = E_Operator
1487             then
1488                Tref := Etype (Tref);
1489 
1490                --  Another special case: an object of a classwide type
1491                --  initialized with a tag-indeterminate call gets a subtype
1492                --  of the classwide type during expansion. See if the original
1493                --  type in the declaration is named, and return it instead
1494                --  of going to the root type. The expression may be a class-
1495                --  wide function call whose result is on the secondary stack,
1496                --  which forces the declaration to be rewritten as a renaming,
1497                --  so examine the source declaration.
1498 
1499                if Ekind (Tref) = E_Class_Wide_Subtype then
1500                   declare
1501                      Decl : constant Node_Id := Original_Node (Parent (Ent));
1502                   begin
1503                      if Nkind (Decl) = N_Object_Declaration
1504                        and then Is_Entity_Name
1505                                   (Original_Node (Object_Definition (Decl)))
1506                      then
1507                         Tref :=
1508                           Entity (Original_Node (Object_Definition (Decl)));
1509                      end if;
1510                   end;
1511                end if;
1512 
1513             --  For anything else, exit
1514 
1515             else
1516                exit;
1517             end if;
1518 
1519             --  Exit if no type reference, or we are stuck in some loop trying
1520             --  to find the type reference, or if the type is standard void
1521             --  type (the latter is an implementation artifact that should not
1522             --  show up in the generated cross-references).
1523 
1524             exit when No (Tref)
1525               or else Tref = Sav
1526               or else Tref = Standard_Void_Type;
1527 
1528             --  If we have a usable type reference, return, otherwise keep
1529             --  looking for something useful (we are looking for something
1530             --  that either comes from source or standard)
1531 
1532             if Sloc (Tref) = Standard_Location
1533               or else Comes_From_Source (Tref)
1534             then
1535                --  If the reference is a subtype created for a generic actual,
1536                --  go actual directly, the inner subtype is not user visible.
1537 
1538                if Nkind (Parent (Tref)) = N_Subtype_Declaration
1539                  and then not Comes_From_Source (Parent (Tref))
1540                  and then
1541                   (Is_Wrapper_Package (Scope (Tref))
1542                      or else Is_Generic_Instance (Scope (Tref)))
1543                then
1544                   Tref := First_Subtype (Base_Type (Tref));
1545                end if;
1546 
1547                return;
1548             end if;
1549          end loop;
1550 
1551          --  If we fall through the loop, no type reference
1552 
1553          Tref := Empty;
1554          Left := ' ';
1555          Right := ' ';
1556       end Get_Type_Reference;
1557 
1558       -------------------------------
1559       -- Output_Import_Export_Info --
1560       -------------------------------
1561 
1562       procedure Output_Import_Export_Info (Ent : Entity_Id) is
1563          Language_Name : Name_Id;
1564          Conv          : constant Convention_Id := Convention (Ent);
1565 
1566       begin
1567          --  Generate language name from convention
1568 
1569          if Conv  = Convention_C then
1570             Language_Name := Name_C;
1571 
1572          elsif Conv = Convention_CPP then
1573             Language_Name := Name_CPP;
1574 
1575          elsif Conv = Convention_Ada then
1576             Language_Name := Name_Ada;
1577 
1578          else
1579             --  For the moment we ignore all other cases ???
1580 
1581             return;
1582          end if;
1583 
1584          Write_Info_Char ('<');
1585          Get_Unqualified_Name_String (Language_Name);
1586 
1587          for J in 1 .. Name_Len loop
1588             Write_Info_Char (Name_Buffer (J));
1589          end loop;
1590 
1591          if Present (Interface_Name (Ent)) then
1592             Write_Info_Char (',');
1593             String_To_Name_Buffer (Strval (Interface_Name (Ent)));
1594 
1595             for J in 1 .. Name_Len loop
1596                Write_Info_Char (Name_Buffer (J));
1597             end loop;
1598          end if;
1599 
1600          Write_Info_Char ('>');
1601       end Output_Import_Export_Info;
1602 
1603    --  Start of processing for Output_References
1604 
1605    begin
1606       --  First we add references to the primitive operations of tagged types
1607       --  declared in the main unit.
1608 
1609       Handle_Prim_Ops : declare
1610          Ent  : Entity_Id;
1611 
1612       begin
1613          for J in 1 .. Xrefs.Last loop
1614             Ent := Xrefs.Table (J).Key.Ent;
1615 
1616             if Is_Type (Ent)
1617               and then Is_Tagged_Type (Ent)
1618               and then Is_Base_Type (Ent)
1619               and then In_Extended_Main_Source_Unit (Ent)
1620             then
1621                Generate_Prim_Op_References (Ent);
1622             end if;
1623          end loop;
1624       end Handle_Prim_Ops;
1625 
1626       --  Before we go ahead and output the references we have a problem
1627       --  that needs dealing with. So far we have captured things that are
1628       --  definitely referenced by the main unit, or defined in the main
1629       --  unit. That's because we don't want to clutter up the ali file
1630       --  for this unit with definition lines for entities in other units
1631       --  that are not referenced.
1632 
1633       --  But there is a glitch. We may reference an entity in another unit,
1634       --  and it may have a type reference to an entity that is not directly
1635       --  referenced in the main unit, which may mean that there is no xref
1636       --  entry for this entity yet in the list of references.
1637 
1638       --  If we don't do something about this, we will end with an orphan type
1639       --  reference, i.e. it will point to an entity that does not appear
1640       --  within the generated references in the ali file. That is not good for
1641       --  tools using the xref information.
1642 
1643       --  To fix this, we go through the references adding definition entries
1644       --  for any unreferenced entities that can be referenced in a type
1645       --  reference. There is a recursion problem here, and that is dealt with
1646       --  by making sure that this traversal also traverses any entries that
1647       --  get added by the traversal.
1648 
1649       Handle_Orphan_Type_References : declare
1650          J    : Nat;
1651          Tref : Entity_Id;
1652          Ent  : Entity_Id;
1653 
1654          L, R : Character;
1655          pragma Warnings (Off, L);
1656          pragma Warnings (Off, R);
1657 
1658          procedure New_Entry (E : Entity_Id);
1659          --  Make an additional entry into the Xref table for a type entity
1660          --  that is related to the current entity (parent, type ancestor,
1661          --  progenitor, etc.).
1662 
1663          ----------------
1664          -- New_Entry --
1665          ----------------
1666 
1667          procedure New_Entry (E : Entity_Id) is
1668          begin
1669             pragma Assert (Present (E));
1670 
1671             if not Has_Xref_Entry (Implementation_Base_Type (E))
1672               and then Sloc (E) > No_Location
1673             then
1674                Add_Entry
1675                  ((Ent       => E,
1676                    Loc       => No_Location,
1677                    Typ       => Character'First,
1678                    Eun       => Get_Source_Unit (Original_Location (Sloc (E))),
1679                    Lun       => No_Unit,
1680                    Ref_Scope => Empty,
1681                    Ent_Scope => Empty),
1682                   Ent_Scope_File => No_Unit);
1683             end if;
1684          end New_Entry;
1685 
1686       --  Start of processing for Handle_Orphan_Type_References
1687 
1688       begin
1689          --  Note that this is not a for loop for a very good reason. The
1690          --  processing of items in the table can add new items to the table,
1691          --  and they must be processed as well.
1692 
1693          J := 1;
1694          while J <= Xrefs.Last loop
1695             Ent := Xrefs.Table (J).Key.Ent;
1696 
1697             --  Do not generate reference information for an ignored Ghost
1698             --  entity because neither the entity nor its references will
1699             --  appear in the final tree.
1700 
1701             if Is_Ignored_Ghost_Entity (Ent) then
1702                goto Orphan_Continue;
1703             end if;
1704 
1705             Get_Type_Reference (Ent, Tref, L, R);
1706 
1707             if Present (Tref)
1708               and then not Has_Xref_Entry (Tref)
1709               and then Sloc (Tref) > No_Location
1710             then
1711                New_Entry (Tref);
1712 
1713                if Is_Record_Type (Ent)
1714                  and then Present (Interfaces (Ent))
1715                then
1716                   --  Add an entry for each one of the given interfaces
1717                   --  implemented by type Ent.
1718 
1719                   declare
1720                      Elmt : Elmt_Id := First_Elmt (Interfaces (Ent));
1721                   begin
1722                      while Present (Elmt) loop
1723                         New_Entry (Node (Elmt));
1724                         Next_Elmt (Elmt);
1725                      end loop;
1726                   end;
1727                end if;
1728             end if;
1729 
1730             --  Collect inherited primitive operations that may be declared in
1731             --  another unit and have no visible reference in the current one.
1732 
1733             if Is_Type (Ent)
1734               and then Is_Tagged_Type (Ent)
1735               and then Is_Derived_Type (Ent)
1736               and then Is_Base_Type (Ent)
1737               and then In_Extended_Main_Source_Unit (Ent)
1738             then
1739                declare
1740                   Op_List : constant Elist_Id := Primitive_Operations (Ent);
1741                   Op      : Elmt_Id;
1742                   Prim    : Entity_Id;
1743 
1744                   function Parent_Op (E : Entity_Id) return Entity_Id;
1745                   --  Find original operation, which may be inherited through
1746                   --  several derivations.
1747 
1748                   function Parent_Op (E : Entity_Id) return Entity_Id is
1749                      Orig_Op : constant Entity_Id := Alias (E);
1750 
1751                   begin
1752                      if No (Orig_Op) then
1753                         return Empty;
1754 
1755                      elsif not Comes_From_Source (E)
1756                        and then not Has_Xref_Entry (Orig_Op)
1757                        and then Comes_From_Source (Orig_Op)
1758                      then
1759                         return Orig_Op;
1760                      else
1761                         return Parent_Op (Orig_Op);
1762                      end if;
1763                   end Parent_Op;
1764 
1765                begin
1766                   Op := First_Elmt (Op_List);
1767                   while Present (Op) loop
1768                      Prim := Parent_Op (Node (Op));
1769 
1770                      if Present (Prim) then
1771                         Add_Entry
1772                           ((Ent       => Prim,
1773                             Loc       => No_Location,
1774                             Typ       => Character'First,
1775                             Eun       => Get_Source_Unit (Sloc (Prim)),
1776                             Lun       => No_Unit,
1777                             Ref_Scope => Empty,
1778                             Ent_Scope => Empty),
1779                            Ent_Scope_File => No_Unit);
1780                      end if;
1781 
1782                      Next_Elmt (Op);
1783                   end loop;
1784                end;
1785             end if;
1786 
1787             <<Orphan_Continue>>
1788             J := J + 1;
1789          end loop;
1790       end Handle_Orphan_Type_References;
1791 
1792       --  Now we have all the references, including those for any embedded type
1793       --  references, so we can sort them, and output them.
1794 
1795       Output_Refs : declare
1796          Nrefs : constant Nat := Xrefs.Last;
1797          --  Number of references in table
1798 
1799          Rnums : array (0 .. Nrefs) of Nat;
1800          --  This array contains numbers of references in the Xrefs table.
1801          --  This list is sorted in output order. The extra 0'th entry is
1802          --  convenient for the call to sort. When we sort the table, we
1803          --  move the entries in Rnums around, but we do not move the
1804          --  original table entries.
1805 
1806          Curxu : Unit_Number_Type;
1807          --  Current xref unit
1808 
1809          Curru : Unit_Number_Type;
1810          --  Current reference unit for one entity
1811 
1812          Curent : Entity_Id;
1813          --  Current entity
1814 
1815          Curnam : String (1 .. Name_Buffer'Length);
1816          Curlen : Natural;
1817          --  Simple name and length of current entity
1818 
1819          Curdef : Source_Ptr;
1820          --  Original source location for current entity
1821 
1822          Crloc : Source_Ptr;
1823          --  Current reference location
1824 
1825          Ctyp : Character;
1826          --  Entity type character
1827 
1828          Prevt : Character;
1829          --  reference kind of previous reference
1830 
1831          Tref : Entity_Id;
1832          --  Type reference
1833 
1834          Rref : Node_Id;
1835          --  Renaming reference
1836 
1837          Trunit : Unit_Number_Type;
1838          --  Unit number for type reference
1839 
1840          function Lt (Op1, Op2 : Natural) return Boolean;
1841          --  Comparison function for Sort call
1842 
1843          function Name_Change (X : Entity_Id) return Boolean;
1844          --  Determines if entity X has a different simple name from Curent
1845 
1846          procedure Move (From : Natural; To : Natural);
1847          --  Move procedure for Sort call
1848 
1849          package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
1850 
1851          --------
1852          -- Lt --
1853          --------
1854 
1855          function Lt (Op1, Op2 : Natural) return Boolean is
1856             T1 : Xref_Entry renames Xrefs.Table (Rnums (Nat (Op1)));
1857             T2 : Xref_Entry renames Xrefs.Table (Rnums (Nat (Op2)));
1858 
1859          begin
1860             return Lt (T1, T2);
1861          end Lt;
1862 
1863          ----------
1864          -- Move --
1865          ----------
1866 
1867          procedure Move (From : Natural; To : Natural) is
1868          begin
1869             Rnums (Nat (To)) := Rnums (Nat (From));
1870          end Move;
1871 
1872          -----------------
1873          -- Name_Change --
1874          -----------------
1875 
1876          --  Why a string comparison here??? Why not compare Name_Id values???
1877 
1878          function Name_Change (X : Entity_Id) return Boolean is
1879          begin
1880             Get_Unqualified_Name_String (Chars (X));
1881 
1882             if Name_Len /= Curlen then
1883                return True;
1884             else
1885                return Name_Buffer (1 .. Curlen) /= Curnam (1 .. Curlen);
1886             end if;
1887          end Name_Change;
1888 
1889       --  Start of processing for Output_Refs
1890 
1891       begin
1892          --  Capture the definition Sloc values. We delay doing this till now,
1893          --  since at the time the reference or definition is made, private
1894          --  types may be swapped, and the Sloc value may be incorrect. We
1895          --  also set up the pointer vector for the sort.
1896 
1897          --  For user-defined operators we need to skip the initial quote and
1898          --  point to the first character of the name, for navigation purposes.
1899 
1900          for J in 1 .. Nrefs loop
1901             declare
1902                E   : constant Entity_Id  := Xrefs.Table (J).Key.Ent;
1903                Loc : constant Source_Ptr := Original_Location (Sloc (E));
1904 
1905             begin
1906                Rnums (J) := J;
1907 
1908                if Nkind (E) = N_Defining_Operator_Symbol then
1909                   Xrefs.Table (J).Def := Loc + 1;
1910                else
1911                   Xrefs.Table (J).Def := Loc;
1912                end if;
1913             end;
1914          end loop;
1915 
1916          --  Sort the references
1917 
1918          Sorting.Sort (Integer (Nrefs));
1919 
1920          --  Initialize loop through references
1921 
1922          Curxu  := No_Unit;
1923          Curent := Empty;
1924          Curdef := No_Location;
1925          Curru  := No_Unit;
1926          Crloc  := No_Location;
1927          Prevt  := 'm';
1928 
1929          --  Loop to output references
1930 
1931          for Refno in 1 .. Nrefs loop
1932             Output_One_Ref : declare
1933                Ent : Entity_Id;
1934 
1935                XE : Xref_Entry renames Xrefs.Table (Rnums (Refno));
1936                --  The current entry to be accessed
1937 
1938                Left  : Character;
1939                Right : Character;
1940                --  Used for {} or <> or () for type reference
1941 
1942                procedure Check_Type_Reference
1943                  (Ent            : Entity_Id;
1944                   List_Interface : Boolean;
1945                   Is_Component   : Boolean := False);
1946                --  Find whether there is a meaningful type reference for
1947                --  Ent, and display it accordingly. If List_Interface is
1948                --  true, then Ent is a progenitor interface of the current
1949                --  type entity being listed. In that case list it as is,
1950                --  without looking for a type reference for it. Flag is also
1951                --  used for index types of an array type, where the caller
1952                --  supplies the intended type reference. Is_Component serves
1953                --  the same purpose, to display the component type of a
1954                --  derived array type, for which only the parent type has
1955                --  ben displayed so far.
1956 
1957                procedure Output_Instantiation_Refs (Loc : Source_Ptr);
1958                --  Recursive procedure to output instantiation references for
1959                --  the given source ptr in [file|line[...]] form. No output
1960                --  if the given location is not a generic template reference.
1961 
1962                procedure Output_Overridden_Op (Old_E : Entity_Id);
1963                --  For a subprogram that is overriding, display information
1964                --  about the inherited operation that it overrides.
1965 
1966                --------------------------
1967                -- Check_Type_Reference --
1968                --------------------------
1969 
1970                procedure Check_Type_Reference
1971                  (Ent            : Entity_Id;
1972                   List_Interface : Boolean;
1973                   Is_Component   : Boolean := False)
1974                is
1975                begin
1976                   if List_Interface then
1977 
1978                      --  This is a progenitor interface of the type for which
1979                      --  xref information is being generated.
1980 
1981                      Tref  := Ent;
1982                      Left  := '<';
1983                      Right := '>';
1984 
1985                   --  The following is not documented in lib-xref.ads ???
1986 
1987                   elsif Is_Component then
1988                      Tref  := Ent;
1989                      Left  := '(';
1990                      Right := ')';
1991 
1992                   else
1993                      Get_Type_Reference (Ent, Tref, Left, Right);
1994                   end if;
1995 
1996                   if Present (Tref) then
1997 
1998                      --  Case of standard entity, output name
1999 
2000                      if Sloc (Tref) = Standard_Location then
2001                         Write_Info_Char (Left);
2002                         Write_Info_Name (Chars (Tref));
2003                         Write_Info_Char (Right);
2004 
2005                      --  Case of source entity, output location
2006 
2007                      else
2008                         Write_Info_Char (Left);
2009                         Trunit := Get_Source_Unit (Sloc (Tref));
2010 
2011                         if Trunit /= Curxu then
2012                            Write_Info_Nat (Dependency_Num (Trunit));
2013                            Write_Info_Char ('|');
2014                         end if;
2015 
2016                         Write_Info_Nat
2017                           (Int (Get_Logical_Line_Number (Sloc (Tref))));
2018 
2019                         declare
2020                            Ent  : Entity_Id;
2021                            Ctyp : Character;
2022 
2023                         begin
2024                            Ent := Tref;
2025                            Ctyp := Xref_Entity_Letters (Ekind (Ent));
2026 
2027                            if Ctyp = '+'
2028                              and then Present (Full_View (Ent))
2029                            then
2030                               Ent := Underlying_Type (Ent);
2031 
2032                               if Present (Ent) then
2033                                  Ctyp := Xref_Entity_Letters (Ekind (Ent));
2034                               end if;
2035                            end if;
2036 
2037                            Write_Info_Char (Ctyp);
2038                         end;
2039 
2040                         Write_Info_Nat
2041                           (Int (Get_Column_Number (Sloc (Tref))));
2042 
2043                         --  If the type comes from an instantiation, add the
2044                         --  corresponding info.
2045 
2046                         Output_Instantiation_Refs (Sloc (Tref));
2047                         Write_Info_Char (Right);
2048                      end if;
2049                   end if;
2050                end Check_Type_Reference;
2051 
2052                -------------------------------
2053                -- Output_Instantiation_Refs --
2054                -------------------------------
2055 
2056                procedure Output_Instantiation_Refs (Loc : Source_Ptr) is
2057                   Iloc : constant Source_Ptr := Instantiation_Location (Loc);
2058                   Lun  : Unit_Number_Type;
2059                   Cu   : constant Unit_Number_Type := Curru;
2060 
2061                begin
2062                   --  Nothing to do if this is not an instantiation
2063 
2064                   if Iloc = No_Location then
2065                      return;
2066                   end if;
2067 
2068                   --  Output instantiation reference
2069 
2070                   Write_Info_Char ('[');
2071                   Lun := Get_Source_Unit (Iloc);
2072 
2073                   if Lun /= Curru then
2074                      Curru := Lun;
2075                      Write_Info_Nat (Dependency_Num (Curru));
2076                      Write_Info_Char ('|');
2077                   end if;
2078 
2079                   Write_Info_Nat (Int (Get_Logical_Line_Number (Iloc)));
2080 
2081                   --  Recursive call to get nested instantiations
2082 
2083                   Output_Instantiation_Refs (Iloc);
2084 
2085                   --  Output final ] after call to get proper nesting
2086 
2087                   Write_Info_Char (']');
2088                   Curru := Cu;
2089                   return;
2090                end Output_Instantiation_Refs;
2091 
2092                --------------------------
2093                -- Output_Overridden_Op --
2094                --------------------------
2095 
2096                procedure Output_Overridden_Op (Old_E : Entity_Id) is
2097                   Op : Entity_Id;
2098 
2099                begin
2100                   --  The overridden operation has an implicit declaration
2101                   --  at the point of derivation. What we want to display
2102                   --  is the original operation, which has the actual body
2103                   --  (or abstract declaration) that is being overridden.
2104                   --  The overridden operation is not always set, e.g. when
2105                   --  it is a predefined operator.
2106 
2107                   if No (Old_E) then
2108                      return;
2109 
2110                   --  Follow alias chain if one is present
2111 
2112                   elsif Present (Alias (Old_E)) then
2113 
2114                      --  The subprogram may have been implicitly inherited
2115                      --  through several levels of derivation, so find the
2116                      --  ultimate (source) ancestor.
2117 
2118                      Op := Ultimate_Alias (Old_E);
2119 
2120                   --  Normal case of no alias present. We omit generated
2121                   --  primitives like tagged equality, that have no source
2122                   --  representation.
2123 
2124                   else
2125                      Op := Old_E;
2126                   end if;
2127 
2128                   if Present (Op)
2129                     and then Sloc (Op) /= Standard_Location
2130                     and then Comes_From_Source (Op)
2131                   then
2132                      declare
2133                         Loc      : constant Source_Ptr := Sloc (Op);
2134                         Par_Unit : constant Unit_Number_Type :=
2135                                      Get_Source_Unit (Loc);
2136 
2137                      begin
2138                         Write_Info_Char ('<');
2139 
2140                         if Par_Unit /= Curxu then
2141                            Write_Info_Nat (Dependency_Num (Par_Unit));
2142                            Write_Info_Char ('|');
2143                         end if;
2144 
2145                         Write_Info_Nat (Int (Get_Logical_Line_Number (Loc)));
2146                         Write_Info_Char ('p');
2147                         Write_Info_Nat (Int (Get_Column_Number (Loc)));
2148                         Write_Info_Char ('>');
2149                      end;
2150                   end if;
2151                end Output_Overridden_Op;
2152 
2153             --  Start of processing for Output_One_Ref
2154 
2155             begin
2156                Ent := XE.Key.Ent;
2157 
2158                --  Do not generate reference information for an ignored Ghost
2159                --  entity because neither the entity nor its references will
2160                --  appear in the final tree.
2161 
2162                if Is_Ignored_Ghost_Entity (Ent) then
2163                   goto Continue;
2164                end if;
2165 
2166                Ctyp := Xref_Entity_Letters (Ekind (Ent));
2167 
2168                --  Skip reference if it is the only reference to an entity,
2169                --  and it is an END line reference, and the entity is not in
2170                --  the current extended source. This prevents junk entries
2171                --  consisting only of packages with END lines, where no
2172                --  entity from the package is actually referenced.
2173 
2174                if XE.Key.Typ = 'e'
2175                  and then Ent /= Curent
2176                  and then (Refno = Nrefs
2177                             or else
2178                               Ent /= Xrefs.Table (Rnums (Refno + 1)).Key.Ent)
2179                  and then not In_Extended_Main_Source_Unit (Ent)
2180                then
2181                   goto Continue;
2182                end if;
2183 
2184                --  For private type, get full view type
2185 
2186                if Ctyp = '+'
2187                  and then Present (Full_View (XE.Key.Ent))
2188                then
2189                   Ent := Underlying_Type (Ent);
2190 
2191                   if Present (Ent) then
2192                      Ctyp := Xref_Entity_Letters (Ekind (Ent));
2193                   end if;
2194                end if;
2195 
2196                --  Special exception for Boolean
2197 
2198                if Ctyp = 'E' and then Is_Boolean_Type (Ent) then
2199                   Ctyp := 'B';
2200                end if;
2201 
2202                --  For variable reference, get corresponding type
2203 
2204                if Ctyp = '*' then
2205                   Ent := Etype (XE.Key.Ent);
2206                   Ctyp := Fold_Lower (Xref_Entity_Letters (Ekind (Ent)));
2207 
2208                   --  If variable is private type, get full view type
2209 
2210                   if Ctyp = '+'
2211                     and then Present (Full_View (Etype (XE.Key.Ent)))
2212                   then
2213                      Ent := Underlying_Type (Etype (XE.Key.Ent));
2214 
2215                      if Present (Ent) then
2216                         Ctyp := Fold_Lower (Xref_Entity_Letters (Ekind (Ent)));
2217                      end if;
2218 
2219                   elsif Is_Generic_Type (Ent) then
2220 
2221                      --  If the type of the entity is a generic private type,
2222                      --  there is no usable full view, so retain the indication
2223                      --  that this is an object.
2224 
2225                      Ctyp := '*';
2226                   end if;
2227 
2228                   --  Special handling for access parameters and objects and
2229                   --  components of an anonymous access type.
2230 
2231                   if Ekind_In (Etype (XE.Key.Ent),
2232                                E_Anonymous_Access_Type,
2233                                E_Anonymous_Access_Subprogram_Type,
2234                                E_Anonymous_Access_Protected_Subprogram_Type)
2235                   then
2236                      if Is_Formal (XE.Key.Ent)
2237                        or else
2238                          Ekind_In
2239                            (XE.Key.Ent, E_Variable, E_Constant, E_Component)
2240                      then
2241                         Ctyp := 'p';
2242                      end if;
2243 
2244                      --  Special handling for Boolean
2245 
2246                   elsif Ctyp = 'e' and then Is_Boolean_Type (Ent) then
2247                      Ctyp := 'b';
2248                   end if;
2249                end if;
2250 
2251                --  Special handling for abstract types and operations
2252 
2253                if Is_Overloadable (XE.Key.Ent)
2254                  and then Is_Abstract_Subprogram (XE.Key.Ent)
2255                then
2256                   if Ctyp = 'U' then
2257                      Ctyp := 'x';            --  Abstract procedure
2258 
2259                   elsif Ctyp = 'V' then
2260                      Ctyp := 'y';            --  Abstract function
2261                   end if;
2262 
2263                elsif Is_Type (XE.Key.Ent)
2264                  and then Is_Abstract_Type (XE.Key.Ent)
2265                then
2266                   if Is_Interface (XE.Key.Ent) then
2267                      Ctyp := 'h';
2268 
2269                   elsif Ctyp = 'R' then
2270                      Ctyp := 'H';            --  Abstract type
2271                   end if;
2272                end if;
2273 
2274                --  Only output reference if interesting type of entity
2275 
2276                if Ctyp = ' '
2277 
2278                --  Suppress references to object definitions, used for local
2279                --  references.
2280 
2281                  or else XE.Key.Typ = 'D'
2282                  or else XE.Key.Typ = 'I'
2283 
2284                --  Suppress self references, except for bodies that act as
2285                --  specs.
2286 
2287                  or else (XE.Key.Loc = XE.Def
2288                            and then
2289                              (XE.Key.Typ /= 'b'
2290                                or else not Is_Subprogram (XE.Key.Ent)))
2291 
2292                --  Also suppress definitions of body formals (we only
2293                --  treat these as references, and the references were
2294                --  separately recorded).
2295 
2296                  or else (Is_Formal (XE.Key.Ent)
2297                            and then Present (Spec_Entity (XE.Key.Ent)))
2298                then
2299                   null;
2300 
2301                else
2302                   --  Start new Xref section if new xref unit
2303 
2304                   if XE.Key.Eun /= Curxu then
2305                      if Write_Info_Col > 1 then
2306                         Write_Info_EOL;
2307                      end if;
2308 
2309                      Curxu := XE.Key.Eun;
2310 
2311                      Write_Info_Initiate ('X');
2312                      Write_Info_Char (' ');
2313                      Write_Info_Nat (Dependency_Num (XE.Key.Eun));
2314                      Write_Info_Char (' ');
2315                      Write_Info_Name
2316                        (Reference_Name (Source_Index (XE.Key.Eun)));
2317                   end if;
2318 
2319                   --  Start new Entity line if new entity. Note that we
2320                   --  consider two entities the same if they have the same
2321                   --  name and source location. This causes entities in
2322                   --  instantiations to be treated as though they referred
2323                   --  to the template.
2324 
2325                   if No (Curent)
2326                     or else
2327                       (XE.Key.Ent /= Curent
2328                          and then
2329                            (Name_Change (XE.Key.Ent) or else XE.Def /= Curdef))
2330                   then
2331                      Curent := XE.Key.Ent;
2332                      Curdef := XE.Def;
2333 
2334                      Get_Unqualified_Name_String (Chars (XE.Key.Ent));
2335                      Curlen := Name_Len;
2336                      Curnam (1 .. Curlen) := Name_Buffer (1 .. Curlen);
2337 
2338                      if Write_Info_Col > 1 then
2339                         Write_Info_EOL;
2340                      end if;
2341 
2342                      --  Write column number information
2343 
2344                      Write_Info_Nat (Int (Get_Logical_Line_Number (XE.Def)));
2345                      Write_Info_Char (Ctyp);
2346                      Write_Info_Nat (Int (Get_Column_Number (XE.Def)));
2347 
2348                      --  Write level information
2349 
2350                      Write_Level_Info : declare
2351                         function Is_Visible_Generic_Entity
2352                           (E : Entity_Id) return Boolean;
2353                         --  Check whether E is declared in the visible part
2354                         --  of a generic package. For source navigation
2355                         --  purposes, treat this as a visible entity.
2356 
2357                         function Is_Private_Record_Component
2358                           (E : Entity_Id) return Boolean;
2359                         --  Check whether E is a non-inherited component of a
2360                         --  private extension. Even if the enclosing record is
2361                         --  public, we want to treat the component as private
2362                         --  for navigation purposes.
2363 
2364                         ---------------------------------
2365                         -- Is_Private_Record_Component --
2366                         ---------------------------------
2367 
2368                         function Is_Private_Record_Component
2369                           (E : Entity_Id) return Boolean
2370                         is
2371                            S : constant Entity_Id := Scope (E);
2372                         begin
2373                            return
2374                              Ekind (E) = E_Component
2375                                and then Nkind (Declaration_Node (S)) =
2376                                  N_Private_Extension_Declaration
2377                                and then Original_Record_Component (E) = E;
2378                         end Is_Private_Record_Component;
2379 
2380                         -------------------------------
2381                         -- Is_Visible_Generic_Entity --
2382                         -------------------------------
2383 
2384                         function Is_Visible_Generic_Entity
2385                           (E : Entity_Id) return Boolean
2386                         is
2387                            Par : Node_Id;
2388 
2389                         begin
2390                            --  The Present check here is an error defense
2391 
2392                            if Present (Scope (E))
2393                              and then Ekind (Scope (E)) /= E_Generic_Package
2394                            then
2395                               return False;
2396                            end if;
2397 
2398                            Par := Parent (E);
2399                            while Present (Par) loop
2400                               if
2401                                 Nkind (Par) = N_Generic_Package_Declaration
2402                               then
2403                                  --  Entity is a generic formal
2404 
2405                                  return False;
2406 
2407                               elsif
2408                                 Nkind (Parent (Par)) = N_Package_Specification
2409                               then
2410                                  return
2411                                    Is_List_Member (Par)
2412                                      and then List_Containing (Par) =
2413                                        Visible_Declarations (Parent (Par));
2414                               else
2415                                  Par := Parent (Par);
2416                               end if;
2417                            end loop;
2418 
2419                            return False;
2420                         end Is_Visible_Generic_Entity;
2421 
2422                      --  Start of processing for Write_Level_Info
2423 
2424                      begin
2425                         if Is_Hidden (Curent)
2426                           or else Is_Private_Record_Component (Curent)
2427                         then
2428                            Write_Info_Char (' ');
2429 
2430                         elsif
2431                            Is_Public (Curent)
2432                              or else Is_Visible_Generic_Entity (Curent)
2433                         then
2434                            Write_Info_Char ('*');
2435 
2436                         else
2437                            Write_Info_Char (' ');
2438                         end if;
2439                      end Write_Level_Info;
2440 
2441                      --  Output entity name. We use the occurrence from the
2442                      --  actual source program at the definition point.
2443 
2444                      declare
2445                         Ent_Name : constant String :=
2446                                      Exact_Source_Name (Sloc (XE.Key.Ent));
2447                      begin
2448                         for C in Ent_Name'Range loop
2449                            Write_Info_Char (Ent_Name (C));
2450                         end loop;
2451                      end;
2452 
2453                      --  See if we have a renaming reference
2454 
2455                      if Is_Object (XE.Key.Ent)
2456                        and then Present (Renamed_Object (XE.Key.Ent))
2457                      then
2458                         Rref := Renamed_Object (XE.Key.Ent);
2459 
2460                      elsif Is_Overloadable (XE.Key.Ent)
2461                        and then Nkind (Parent (Declaration_Node (XE.Key.Ent)))
2462                                            = N_Subprogram_Renaming_Declaration
2463                      then
2464                         Rref := Name (Parent (Declaration_Node (XE.Key.Ent)));
2465 
2466                      elsif Ekind (XE.Key.Ent) = E_Package
2467                        and then Nkind (Declaration_Node (XE.Key.Ent)) =
2468                                          N_Package_Renaming_Declaration
2469                      then
2470                         Rref := Name (Declaration_Node (XE.Key.Ent));
2471 
2472                      else
2473                         Rref := Empty;
2474                      end if;
2475 
2476                      if Present (Rref) then
2477                         if Nkind (Rref) = N_Expanded_Name then
2478                            Rref := Selector_Name (Rref);
2479                         end if;
2480 
2481                         if Nkind (Rref) = N_Identifier
2482                           or else Nkind (Rref) = N_Operator_Symbol
2483                         then
2484                            null;
2485 
2486                         --  For renamed array components, use the array name
2487                         --  for the renamed entity, which reflect the fact that
2488                         --  in general the whole array is aliased.
2489 
2490                         elsif Nkind (Rref) = N_Indexed_Component then
2491                            if Nkind (Prefix (Rref)) = N_Identifier then
2492                               Rref := Prefix (Rref);
2493                            elsif Nkind (Prefix (Rref)) = N_Expanded_Name then
2494                               Rref := Selector_Name (Prefix (Rref));
2495                            else
2496                               Rref := Empty;
2497                            end if;
2498 
2499                         else
2500                            Rref := Empty;
2501                         end if;
2502                      end if;
2503 
2504                      --  Write out renaming reference if we have one
2505 
2506                      if Present (Rref) then
2507                         Write_Info_Char ('=');
2508                         Write_Info_Nat
2509                           (Int (Get_Logical_Line_Number (Sloc (Rref))));
2510                         Write_Info_Char (':');
2511                         Write_Info_Nat
2512                           (Int (Get_Column_Number (Sloc (Rref))));
2513                      end if;
2514 
2515                      --  Indicate that the entity is in the unit of the current
2516                      --  xref section.
2517 
2518                      Curru := Curxu;
2519 
2520                      --  Write out information about generic parent, if entity
2521                      --  is an instance.
2522 
2523                      if Is_Generic_Instance (XE.Key.Ent) then
2524                         declare
2525                            Gen_Par : constant Entity_Id :=
2526                                        Generic_Parent
2527                                          (Specification
2528                                             (Unit_Declaration_Node
2529                                                (XE.Key.Ent)));
2530                            Loc     : constant Source_Ptr := Sloc (Gen_Par);
2531                            Gen_U   : constant Unit_Number_Type :=
2532                                        Get_Source_Unit (Loc);
2533 
2534                         begin
2535                            Write_Info_Char ('[');
2536 
2537                            if Curru /= Gen_U then
2538                               Write_Info_Nat (Dependency_Num (Gen_U));
2539                               Write_Info_Char ('|');
2540                            end if;
2541 
2542                            Write_Info_Nat
2543                              (Int (Get_Logical_Line_Number (Loc)));
2544                            Write_Info_Char (']');
2545                         end;
2546                      end if;
2547 
2548                      --  See if we have a type reference and if so output
2549 
2550                      Check_Type_Reference (XE.Key.Ent, False);
2551 
2552                      --  Additional information for types with progenitors,
2553                      --  including synchronized tagged types.
2554 
2555                      declare
2556                         Typ  : constant Entity_Id := XE.Key.Ent;
2557                         Elmt : Elmt_Id;
2558 
2559                      begin
2560                         if Is_Record_Type (Typ)
2561                           and then Present (Interfaces (Typ))
2562                         then
2563                            Elmt := First_Elmt (Interfaces (Typ));
2564 
2565                         elsif Is_Concurrent_Type (Typ)
2566                           and then Present (Corresponding_Record_Type (Typ))
2567                           and then Present (
2568                             Interfaces (Corresponding_Record_Type (Typ)))
2569                         then
2570                            Elmt :=
2571                              First_Elmt (
2572                               Interfaces (Corresponding_Record_Type (Typ)));
2573 
2574                         else
2575                            Elmt := No_Elmt;
2576                         end if;
2577 
2578                         while Present (Elmt) loop
2579                            Check_Type_Reference (Node (Elmt), True);
2580                            Next_Elmt (Elmt);
2581                         end loop;
2582                      end;
2583 
2584                      --  For array types, list index types as well. (This is
2585                      --  not C, indexes have distinct types).
2586 
2587                      if Is_Array_Type (XE.Key.Ent) then
2588                         declare
2589                            A_Typ : constant Entity_Id := XE.Key.Ent;
2590                            Indx : Node_Id;
2591 
2592                         begin
2593                            --  If this is a derived array type, we have
2594                            --  output the parent type, so add the component
2595                            --  type now.
2596 
2597                            if Is_Derived_Type (A_Typ) then
2598                               Check_Type_Reference
2599                                 (Component_Type (A_Typ), False, True);
2600                            end if;
2601 
2602                            --  Add references to index types.
2603 
2604                            Indx := First_Index (XE.Key.Ent);
2605                            while Present (Indx) loop
2606                               Check_Type_Reference
2607                                 (First_Subtype (Etype (Indx)), True);
2608                               Next_Index (Indx);
2609                            end loop;
2610                         end;
2611                      end if;
2612 
2613                      --  If the entity is an overriding operation, write info
2614                      --  on operation that was overridden.
2615 
2616                      if Is_Subprogram (XE.Key.Ent)
2617                        and then Present (Overridden_Operation (XE.Key.Ent))
2618                      then
2619                         Output_Overridden_Op
2620                           (Overridden_Operation (XE.Key.Ent));
2621                      end if;
2622 
2623                      --  End of processing for entity output
2624 
2625                      Crloc := No_Location;
2626                   end if;
2627 
2628                   --  Output the reference if it is not as the same location
2629                   --  as the previous one, or it is a read-reference that
2630                   --  indicates that the entity is an in-out actual in a call.
2631 
2632                   if XE.Key.Loc /= No_Location
2633                     and then
2634                       (XE.Key.Loc /= Crloc
2635                         or else (Prevt = 'm' and then  XE.Key.Typ = 'r'))
2636                   then
2637                      Crloc := XE.Key.Loc;
2638                      Prevt := XE.Key.Typ;
2639 
2640                      --  Start continuation if line full, else blank
2641 
2642                      if Write_Info_Col > 72 then
2643                         Write_Info_EOL;
2644                         Write_Info_Initiate ('.');
2645                      end if;
2646 
2647                      Write_Info_Char (' ');
2648 
2649                      --  Output file number if changed
2650 
2651                      if XE.Key.Lun /= Curru then
2652                         Curru := XE.Key.Lun;
2653                         Write_Info_Nat (Dependency_Num (Curru));
2654                         Write_Info_Char ('|');
2655                      end if;
2656 
2657                      Write_Info_Nat
2658                        (Int (Get_Logical_Line_Number (XE.Key.Loc)));
2659                      Write_Info_Char (XE.Key.Typ);
2660 
2661                      if Is_Overloadable (XE.Key.Ent) then
2662                         if (Is_Imported (XE.Key.Ent) and then XE.Key.Typ = 'b')
2663                              or else
2664                            (Is_Exported (XE.Key.Ent) and then XE.Key.Typ = 'i')
2665                         then
2666                            Output_Import_Export_Info (XE.Key.Ent);
2667                         end if;
2668                      end if;
2669 
2670                      Write_Info_Nat (Int (Get_Column_Number (XE.Key.Loc)));
2671 
2672                      Output_Instantiation_Refs (Sloc (XE.Key.Ent));
2673                   end if;
2674                end if;
2675             end Output_One_Ref;
2676 
2677          <<Continue>>
2678             null;
2679          end loop;
2680 
2681          Write_Info_EOL;
2682       end Output_Refs;
2683    end Output_References;
2684 
2685    ---------------------------------
2686    -- Process_Deferred_References --
2687    ---------------------------------
2688 
2689    procedure Process_Deferred_References is
2690    begin
2691       for J in Deferred_References.First .. Deferred_References.Last loop
2692          declare
2693             D : Deferred_Reference_Entry renames Deferred_References.Table (J);
2694 
2695          begin
2696             case Is_LHS (D.N) is
2697                when Yes =>
2698                   Generate_Reference (D.E, D.N, 'm');
2699 
2700                when No =>
2701                   Generate_Reference (D.E, D.N, 'r');
2702 
2703                --  Not clear if Unknown can occur at this stage, but if it
2704                --  does we will treat it as a normal reference.
2705 
2706                when Unknown =>
2707                   Generate_Reference (D.E, D.N, 'r');
2708             end case;
2709          end;
2710       end loop;
2711 
2712       --  Clear processed entries from table
2713 
2714       Deferred_References.Init;
2715    end Process_Deferred_References;
2716 
2717 --  Start of elaboration for Lib.Xref
2718 
2719 begin
2720    --  Reset is necessary because Elmt_Ptr does not default to Null_Ptr,
2721    --  because it's not an access type.
2722 
2723    Xref_Set.Reset;
2724 end Lib.Xref;