make.adb: (Kill): New procedure (__gnat_kill imported)
[platform/upstream/gcc.git] / gcc / ada / 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-2007, 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 Lib.Util; use Lib.Util;
31 with Nlists;   use Nlists;
32 with Opt;      use Opt;
33 with Restrict; use Restrict;
34 with Rident;   use Rident;
35 with Sem;      use Sem;
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 with Widechar; use Widechar;
46
47 with GNAT.Heap_Sort_A;
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_Entry is record
61       Ent : Entity_Id;
62       --  Entity referenced (E parameter to Generate_Reference)
63
64       Def : Source_Ptr;
65       --  Original source location for entity being referenced. Note that these
66       --  values are used only during the output process, they are not set when
67       --  the entries are originally built. This is because private entities
68       --  can be swapped when the initial call is made.
69
70       Loc : Source_Ptr;
71       --  Location of reference (Original_Location (Sloc field of N parameter
72       --  to Generate_Reference). Set to No_Location for the case of a
73       --  defining occurrence.
74
75       Typ : Character;
76       --  Reference type (Typ param to Generate_Reference)
77
78       Eun : Unit_Number_Type;
79       --  Unit number corresponding to Ent
80
81       Lun : Unit_Number_Type;
82       --  Unit number corresponding to Loc. Value is undefined and not
83       --  referenced if Loc is set to No_Location.
84
85    end record;
86
87    package Xrefs is new Table.Table (
88      Table_Component_Type => Xref_Entry,
89      Table_Index_Type     => Xref_Entry_Number,
90      Table_Low_Bound      => 1,
91      Table_Initial        => Alloc.Xrefs_Initial,
92      Table_Increment      => Alloc.Xrefs_Increment,
93      Table_Name           => "Xrefs");
94
95    -------------------------
96    -- Generate_Definition --
97    -------------------------
98
99    procedure Generate_Definition (E : Entity_Id) is
100       Loc  : Source_Ptr;
101       Indx : Nat;
102
103    begin
104       pragma Assert (Nkind (E) in N_Entity);
105
106       --  Note that we do not test Xref_Entity_Letters here. It is too early
107       --  to do so, since we are often called before the entity is fully
108       --  constructed, so that the Ekind is still E_Void.
109
110       if Opt.Xref_Active
111
112          --  Definition must come from source
113
114          --  We make an exception for subprogram child units that have no spec.
115          --  For these we generate a subprogram declaration for library use,
116          --  and the corresponding entity does not come from source.
117          --  Nevertheless, all references will be attached to it and we have
118          --  to treat is as coming from user code.
119
120          and then (Comes_From_Source (E) or else Is_Child_Unit (E))
121
122          --  And must have a reasonable source location that is not
123          --  within an instance (all entities in instances are ignored)
124
125          and then Sloc (E) > No_Location
126          and then Instantiation_Location (Sloc (E)) = No_Location
127
128          --  And must be a non-internal name from the main source unit
129
130          and then In_Extended_Main_Source_Unit (E)
131          and then not Is_Internal_Name (Chars (E))
132       then
133          Xrefs.Increment_Last;
134          Indx := Xrefs.Last;
135          Loc  := Original_Location (Sloc (E));
136
137          Xrefs.Table (Indx).Ent := E;
138          Xrefs.Table (Indx).Def := No_Location;
139          Xrefs.Table (Indx).Loc := No_Location;
140          Xrefs.Table (Indx).Typ := ' ';
141          Xrefs.Table (Indx).Eun := Get_Source_Unit (Loc);
142          Xrefs.Table (Indx).Lun := No_Unit;
143          Set_Has_Xref_Entry (E);
144
145          if In_Inlined_Body then
146             Set_Referenced (E);
147          end if;
148       end if;
149    end Generate_Definition;
150
151    ---------------------------------
152    -- Generate_Operator_Reference --
153    ---------------------------------
154
155    procedure Generate_Operator_Reference
156      (N : Node_Id;
157       T : Entity_Id)
158    is
159    begin
160       if not In_Extended_Main_Source_Unit (N) then
161          return;
162       end if;
163
164       --  If the operator is not a Standard operator, then we generate a real
165       --  reference to the user defined operator.
166
167       if Sloc (Entity (N)) /= Standard_Location then
168          Generate_Reference (Entity (N), N);
169
170          --  A reference to an implicit inequality operator is a also a
171          --  reference to the user-defined equality.
172
173          if Nkind (N) = N_Op_Ne
174            and then not Comes_From_Source (Entity (N))
175            and then Present (Corresponding_Equality (Entity (N)))
176          then
177             Generate_Reference (Corresponding_Equality (Entity (N)), N);
178          end if;
179
180       --  For the case of Standard operators, we mark the result type as
181       --  referenced. This ensures that in the case where we are using a
182       --  derived operator, we mark an entity of the unit that implicitly
183       --  defines this operator as used. Otherwise we may think that no entity
184       --  of the unit is used. The actual entity marked as referenced is the
185       --  first subtype, which is the relevant user defined entity.
186
187       --  Note: we only do this for operators that come from source. The
188       --  generated code sometimes reaches for entities that do not need to be
189       --  explicitly visible (for example, when we expand the code for
190       --  comparing two record objects, the fields of the record may not be
191       --  visible).
192
193       elsif Comes_From_Source (N) then
194          Set_Referenced (First_Subtype (T));
195       end if;
196    end Generate_Operator_Reference;
197
198    ------------------------
199    -- Generate_Reference --
200    ------------------------
201
202    procedure Generate_Reference
203      (E       : Entity_Id;
204       N       : Node_Id;
205       Typ     : Character := 'r';
206       Set_Ref : Boolean   := True;
207       Force   : Boolean   := False)
208    is
209       Indx : Nat;
210       Nod  : Node_Id;
211       Ref  : Source_Ptr;
212       Def  : Source_Ptr;
213       Ent  : Entity_Id;
214
215       function Is_On_LHS (Node : Node_Id) return Boolean;
216       --  Used to check if a node is on the left hand side of an assignment.
217       --  The following cases are handled:
218       --
219       --   Variable  Node is a direct descendant of an assignment statement.
220       --
221       --   Prefix    Of an indexed or selected component that is present in a
222       --             subtree rooted by an assignment statement. There is no
223       --             restriction of nesting of components, thus cases such as
224       --             A.B (C).D are handled properly.
225       --             However a prefix of a dereference (either implicit or
226       --             explicit) is never considered as on a LHS.
227
228       ---------------
229       -- Is_On_LHS --
230       ---------------
231
232       --  ??? There are several routines here and there that perform a similar
233       --      (but subtly different) computation, which should be factored:
234
235       --      Sem_Util.May_Be_Lvalue
236       --      Sem_Util.Known_To_Be_Assigned
237       --      Exp_Ch2.Expand_Entry_Parameter.In_Assignment_Context
238
239       function Is_On_LHS (Node : Node_Id) return Boolean is
240          N : Node_Id := Node;
241
242       begin
243          --  Only identifiers are considered, is this necessary???
244
245          if Nkind (N) /= N_Identifier then
246             return False;
247          end if;
248
249          --  Reach the assignment statement subtree root. In the case of a
250          --  variable being a direct descendant of an assignment statement,
251          --  the loop is skiped.
252
253          while Nkind (Parent (N)) /= N_Assignment_Statement loop
254
255             --  Check whether the parent is a component and the current node
256             --  is its prefix, but return False if the current node has an
257             --  access type, as in that case the selected or indexed component
258             --  is an implicit dereference, and the LHS is the designated
259             --  object, not the access object.
260
261             --  ??? case of a slice assignment?
262
263             --  ??? Note that in some cases this is called too early
264             --  (see comments in Sem_Ch8.Find_Direct_Name), at a point where
265             --  the tree is not fully typed yet. In that case we may lack
266             --  an Etype for N, and we must disable the check for an implicit
267             --  dereference. If the dereference is on an LHS, this causes a
268             --  false positive.
269
270             if (Nkind (Parent (N)) = N_Selected_Component
271                   or else
272                 Nkind (Parent (N)) = N_Indexed_Component)
273               and then Prefix (Parent (N)) = N
274               and then not (Present (Etype (N))
275                               and then
276                             Is_Access_Type (Etype (N)))
277             then
278                N := Parent (N);
279             else
280                return False;
281             end if;
282          end loop;
283
284          --  Parent (N) is assignment statement, check whether N is its name
285
286          return Name (Parent (N)) = N;
287       end Is_On_LHS;
288
289    --  Start of processing for Generate_Reference
290
291    begin
292       pragma Assert (Nkind (E) in N_Entity);
293
294       --  Check for obsolescent reference to package ASCII. GNAT treats this
295       --  element of annex J specially since in practice, programs make a lot
296       --  of use of this feature, so we don't include it in the set of features
297       --  diagnosed when Warn_On_Obsolescent_Features mode is set. However we
298       --  are required to note it as a violation of the RM defined restriction.
299
300       if E = Standard_ASCII then
301          Check_Restriction (No_Obsolescent_Features, N);
302       end if;
303
304       --  Check for reference to entity marked with Is_Obsolescent
305
306       --  Note that we always allow obsolescent references in the compiler
307       --  itself and the run time, since we assume that we know what we are
308       --  doing in such cases. For example the calls in Ada.Characters.Handling
309       --  to its own obsolescent subprograms are just fine.
310
311       --  In any case we do not generate warnings within the extended source
312       --  unit of the entity in question, since we assume the source unit
313       --  itself knows what is going on (and for sure we do not want silly
314       --  warnings, e.g. on the end line of an obsolescent procedure body).
315
316       if Is_Obsolescent (E)
317         and then not GNAT_Mode
318         and then not In_Extended_Main_Source_Unit (E)
319       then
320          Check_Restriction (No_Obsolescent_Features, N);
321
322          if Warn_On_Obsolescent_Feature then
323             Output_Obsolescent_Entity_Warnings (N, E);
324          end if;
325       end if;
326
327       --  Warn if reference to Ada 2005 entity not in Ada 2005 mode. We only
328       --  detect real explicit references (modifications and references).
329
330       if Comes_From_Source (N)
331         and then Is_Ada_2005_Only (E)
332         and then Ada_Version < Ada_05
333         and then Warn_On_Ada_2005_Compatibility
334         and then (Typ = 'm' or else Typ = 'r')
335       then
336          Error_Msg_NE ("& is only defined in Ada 2005?", N, E);
337       end if;
338
339       --  Never collect references if not in main source unit. However, we omit
340       --  this test if Typ is 'e' or 'k', since these entries are structural,
341       --  and it is useful to have them in units that reference packages as
342       --  well as units that define packages. We also omit the test for the
343       --  case of 'p' since we want to include inherited primitive operations
344       --  from other packages.
345
346       --  We also omit this test is this is a body reference for a subprogram
347       --  instantiation. In this case the reference is to the generic body,
348       --  which clearly need not be in the main unit containing the instance.
349       --  For the same reason we accept an implicit reference generated for
350       --  a default in an instance.
351
352       if not In_Extended_Main_Source_Unit (N) then
353          if Typ = 'e'
354            or else Typ = 'p'
355            or else Typ = 'i'
356            or else Typ = 'k'
357            or else (Typ = 'b' and then Is_Generic_Instance (E))
358          then
359             null;
360          else
361             return;
362          end if;
363       end if;
364
365       --  For reference type p, the entity must be in main source unit
366
367       if Typ = 'p' and then not In_Extended_Main_Source_Unit (E) then
368          return;
369       end if;
370
371       --  Unless the reference is forced, we ignore references where the
372       --  reference itself does not come from source.
373
374       if not Force and then not Comes_From_Source (N) then
375          return;
376       end if;
377
378       --  Deal with setting entity as referenced, unless suppressed. Note that
379       --  we still do Set_Referenced on entities that do not come from source.
380       --  This situation arises when we have a source reference to a derived
381       --  operation, where the derived operation itself does not come from
382       --  source, but we still want to mark it as referenced, since we really
383       --  are referencing an entity in the corresponding package (this avoids
384       --  wrong complaints that the package contains no referenced entities).
385
386       if Set_Ref then
387
388          --  For a variable that appears on the left side of an assignment
389          --  statement, we set the Referenced_As_LHS flag since this is indeed
390          --  a left hand side. We also set the Referenced_As_LHS flag of a
391          --  prefix of selected or indexed component.
392
393          if (Ekind (E) = E_Variable or else Is_Formal (E))
394            and then Is_On_LHS (N)
395          then
396             Set_Referenced_As_LHS (E);
397
398          --  Check for a reference in a pragma that should not count as a
399          --  making the variable referenced for warning purposes.
400
401          elsif Is_Non_Significant_Pragma_Reference (N) then
402             null;
403
404          --  A reference in an attribute definition clause does not count as a
405          --  reference except for the case of Address. The reason that 'Address
406          --  is an exception is that it creates an alias through which the
407          --  variable may be referenced.
408
409          elsif Nkind (Parent (N)) = N_Attribute_Definition_Clause
410            and then Chars (Parent (N)) /= Name_Address
411            and then N = Name (Parent (N))
412          then
413             null;
414
415          --  Constant completion does not count as a reference
416
417          elsif Typ = 'c'
418            and then Ekind (E) = E_Constant
419          then
420             null;
421
422          --  Record representation clause does not count as a reference
423
424          elsif Nkind (N) = N_Identifier
425            and then Nkind (Parent (N)) = N_Record_Representation_Clause
426          then
427             null;
428
429          --  Discriminants do not need to produce a reference to record type
430
431          elsif Typ = 'd'
432            and then Nkind (Parent (N)) = N_Discriminant_Specification
433          then
434             null;
435
436          --  Any other occurrence counts as referencing the entity
437
438          else
439             Set_Referenced (E);
440
441             if Ekind (E) = E_Variable then
442                Set_Last_Assignment (E, Empty);
443             end if;
444          end if;
445
446          --  Check for pragma Unreferenced given and reference is within
447          --  this source unit (occasion for possible warning to be issued).
448
449          if Has_Pragma_Unreferenced (E)
450            and then In_Same_Extended_Unit (E, N)
451          then
452             --  A reference as a named parameter in a call does not count
453             --  as a violation of pragma Unreferenced for this purpose...
454
455             if Nkind (N) = N_Identifier
456               and then Nkind (Parent (N)) = N_Parameter_Association
457               and then Selector_Name (Parent (N)) = N
458             then
459                null;
460
461             --  ... Neither does a reference to a variable on the left side
462             --  of an assignment.
463
464             elsif Is_On_LHS (N) then
465                null;
466
467             --  For entry formals, we want to place the warning message on the
468             --  corresponding entity in the accept statement. The current scope
469             --  is the body of the accept, so we find the formal whose name
470             --  matches that of the entry formal (there is no link between the
471             --  two entities, and the one in the accept statement is only used
472             --  for conformance checking).
473
474             elsif Ekind (Scope (E)) = E_Entry then
475                declare
476                   BE : Entity_Id;
477
478                begin
479                   BE := First_Entity (Current_Scope);
480                   while Present (BE) loop
481                      if Chars (BE) = Chars (E) then
482                         Error_Msg_NE
483                           ("?pragma Unreferenced given for&", N, BE);
484                         exit;
485                      end if;
486
487                      Next_Entity (BE);
488                   end loop;
489                end;
490
491             --  Here we issue the warning, since this is a real reference
492
493             else
494                Error_Msg_NE ("?pragma Unreferenced given for&", N, E);
495             end if;
496          end if;
497
498          --  If this is a subprogram instance, mark as well the internal
499          --  subprogram in the wrapper package, which may be a visible
500          --  compilation unit.
501
502          if Is_Overloadable (E)
503            and then Is_Generic_Instance (E)
504            and then Present (Alias (E))
505          then
506             Set_Referenced (Alias (E));
507          end if;
508       end if;
509
510       --  Generate reference if all conditions are met:
511
512       if
513          --  Cross referencing must be active
514
515          Opt.Xref_Active
516
517          --  The entity must be one for which we collect references
518
519          and then Xref_Entity_Letters (Ekind (E)) /= ' '
520
521          --  Both Sloc values must be set to something sensible
522
523          and then Sloc (E) > No_Location
524          and then Sloc (N) > No_Location
525
526          --  We ignore references from within an instance
527
528          and then Instantiation_Location (Sloc (N)) = No_Location
529
530          --  Ignore dummy references
531
532         and then Typ /= ' '
533       then
534          if Nkind (N) = N_Identifier
535               or else
536             Nkind (N) = N_Defining_Identifier
537               or else
538             Nkind (N) in N_Op
539               or else
540             Nkind (N) = N_Defining_Operator_Symbol
541               or else
542             Nkind (N) = N_Operator_Symbol
543               or else
544             (Nkind (N) = N_Character_Literal
545               and then Sloc (Entity (N)) /= Standard_Location)
546               or else
547             Nkind (N) = N_Defining_Character_Literal
548          then
549             Nod := N;
550
551          elsif Nkind (N) = N_Expanded_Name
552                  or else
553                Nkind (N) = N_Selected_Component
554          then
555             Nod := Selector_Name (N);
556
557          else
558             return;
559          end if;
560
561          --  Normal case of source entity comes from source
562
563          if Comes_From_Source (E) then
564             Ent := E;
565
566          --  Entity does not come from source, but is a derived subprogram and
567          --  the derived subprogram comes from source (after one or more
568          --  derivations) in which case the reference is to parent subprogram.
569
570          elsif Is_Overloadable (E)
571            and then Present (Alias (E))
572          then
573             Ent := Alias (E);
574             while not Comes_From_Source (Ent) loop
575                if No (Alias (Ent)) then
576                   return;
577                end if;
578
579                Ent := Alias (Ent);
580             end loop;
581
582          --  The internally created defining entity for a child subprogram
583          --  that has no previous spec has valid references.
584
585          elsif Is_Overloadable (E)
586            and then Is_Child_Unit (E)
587          then
588             Ent := E;
589
590          --  Record components of discriminated subtypes or derived types must
591          --  be treated as references to the original component.
592
593          elsif Ekind (E) = E_Component
594            and then Comes_From_Source (Original_Record_Component (E))
595          then
596             Ent := Original_Record_Component (E);
597
598          --  Ignore reference to any other entity that is not from source
599
600          else
601             return;
602          end if;
603
604          --  Record reference to entity
605
606          Ref := Original_Location (Sloc (Nod));
607          Def := Original_Location (Sloc (Ent));
608
609          Xrefs.Increment_Last;
610          Indx := Xrefs.Last;
611
612          Xrefs.Table (Indx).Loc := Ref;
613
614          --  Overriding operations are marked with 'P'
615
616          if Typ = 'p'
617            and then Is_Subprogram (N)
618            and then Is_Overriding_Operation (N)
619          then
620             Xrefs.Table (Indx).Typ := 'P';
621          else
622             Xrefs.Table (Indx).Typ := Typ;
623          end if;
624
625          Xrefs.Table (Indx).Eun := Get_Source_Unit (Def);
626          Xrefs.Table (Indx).Lun := Get_Source_Unit (Ref);
627          Xrefs.Table (Indx).Ent := Ent;
628          Set_Has_Xref_Entry (Ent);
629       end if;
630    end Generate_Reference;
631
632    -----------------------------------
633    -- Generate_Reference_To_Formals --
634    -----------------------------------
635
636    procedure Generate_Reference_To_Formals (E : Entity_Id) is
637       Formal : Entity_Id;
638
639    begin
640       if Is_Generic_Subprogram (E) then
641          Formal := First_Entity (E);
642
643          while Present (Formal)
644            and then not Is_Formal (Formal)
645          loop
646             Next_Entity (Formal);
647          end loop;
648
649       else
650          Formal := First_Formal (E);
651       end if;
652
653       while Present (Formal) loop
654          if Ekind (Formal) = E_In_Parameter then
655
656             if Nkind (Parameter_Type (Parent (Formal)))
657               = N_Access_Definition
658             then
659                Generate_Reference (E, Formal, '^', False);
660             else
661                Generate_Reference (E, Formal, '>', False);
662             end if;
663
664          elsif Ekind (Formal) = E_In_Out_Parameter then
665             Generate_Reference (E, Formal, '=', False);
666
667          else
668             Generate_Reference (E, Formal, '<', False);
669          end if;
670
671          Next_Formal (Formal);
672       end loop;
673    end Generate_Reference_To_Formals;
674
675    -------------------------------------------
676    -- Generate_Reference_To_Generic_Formals --
677    -------------------------------------------
678
679    procedure Generate_Reference_To_Generic_Formals (E : Entity_Id) is
680       Formal : Entity_Id;
681
682    begin
683       Formal := First_Entity (E);
684       while Present (Formal) loop
685          if Comes_From_Source (Formal) then
686             Generate_Reference (E, Formal, 'z', False);
687          end if;
688
689          Next_Entity (Formal);
690       end loop;
691    end Generate_Reference_To_Generic_Formals;
692
693    ----------------
694    -- Initialize --
695    ----------------
696
697    procedure Initialize is
698    begin
699       Xrefs.Init;
700    end Initialize;
701
702    -----------------------
703    -- Output_References --
704    -----------------------
705
706    procedure Output_References is
707
708       procedure Get_Type_Reference
709         (Ent   : Entity_Id;
710          Tref  : out Entity_Id;
711          Left  : out Character;
712          Right : out Character);
713       --  Given an Entity_Id Ent, determines whether a type reference is
714       --  required. If so, Tref is set to the entity for the type reference
715       --  and Left and Right are set to the left/right brackets to be output
716       --  for the reference. If no type reference is required, then Tref is
717       --  set to Empty, and Left/Right are set to space.
718
719       procedure Output_Import_Export_Info (Ent : Entity_Id);
720       --  Ouput language and external name information for an interfaced
721       --  entity, using the format <language, external_name>,
722
723       ------------------------
724       -- Get_Type_Reference --
725       ------------------------
726
727       procedure Get_Type_Reference
728         (Ent   : Entity_Id;
729          Tref  : out Entity_Id;
730          Left  : out Character;
731          Right : out Character)
732       is
733          Sav : Entity_Id;
734
735       begin
736          --  See if we have a type reference
737
738          Tref := Ent;
739          Left := '{';
740          Right := '}';
741
742          loop
743             Sav := Tref;
744
745             --  Processing for types
746
747             if Is_Type (Tref) then
748
749                --  Case of base type
750
751                if Base_Type (Tref) = Tref then
752
753                   --  If derived, then get first subtype
754
755                   if Tref /= Etype (Tref) then
756                      Tref := First_Subtype (Etype (Tref));
757
758                      --  Set brackets for derived type, but don't override
759                      --  pointer case since the fact that something is a
760                      --  pointer is more important.
761
762                      if Left /= '(' then
763                         Left := '<';
764                         Right := '>';
765                      end if;
766
767                   --  If non-derived ptr, get directly designated type.
768                   --  If the type has a full view, all references are on the
769                   --  partial view, that is seen first.
770
771                   elsif Is_Access_Type (Tref) then
772                      Tref := Directly_Designated_Type (Tref);
773                      Left := '(';
774                      Right := ')';
775
776                   elsif Is_Private_Type (Tref)
777                     and then Present (Full_View (Tref))
778                   then
779                      if Is_Access_Type (Full_View (Tref)) then
780                         Tref := Directly_Designated_Type (Full_View (Tref));
781                         Left := '(';
782                         Right := ')';
783
784                      --  If the full view is an array type, we also retrieve
785                      --  the corresponding component type, because the ali
786                      --  entry already indicates that this is an array.
787
788                      elsif Is_Array_Type (Full_View (Tref)) then
789                         Tref := Component_Type (Full_View (Tref));
790                         Left := '(';
791                         Right := ')';
792                      end if;
793
794                   --  If non-derived array, get component type. Skip component
795                   --  type for case of String or Wide_String, saves worthwhile
796                   --  space.
797
798                   elsif Is_Array_Type (Tref)
799                     and then Tref /= Standard_String
800                     and then Tref /= Standard_Wide_String
801                   then
802                      Tref := Component_Type (Tref);
803                      Left := '(';
804                      Right := ')';
805
806                   --  For other non-derived base types, nothing
807
808                   else
809                      exit;
810                   end if;
811
812                --  For a subtype, go to ancestor subtype
813
814                else
815                   Tref := Ancestor_Subtype (Tref);
816
817                   --  If no ancestor subtype, go to base type
818
819                   if No (Tref) then
820                      Tref := Base_Type (Sav);
821                   end if;
822                end if;
823
824             --  For objects, functions, enum literals, just get type from
825             --  Etype field.
826
827             elsif Is_Object (Tref)
828               or else Ekind (Tref) = E_Enumeration_Literal
829               or else Ekind (Tref) = E_Function
830               or else Ekind (Tref) = E_Operator
831             then
832                Tref := Etype (Tref);
833
834             --  For anything else, exit
835
836             else
837                exit;
838             end if;
839
840             --  Exit if no type reference, or we are stuck in some loop trying
841             --  to find the type reference, or if the type is standard void
842             --  type (the latter is an implementation artifact that should not
843             --  show up in the generated cross-references).
844
845             exit when No (Tref)
846               or else Tref = Sav
847               or else Tref = Standard_Void_Type;
848
849             --  If we have a usable type reference, return, otherwise keep
850             --  looking for something useful (we are looking for something
851             --  that either comes from source or standard)
852
853             if Sloc (Tref) = Standard_Location
854               or else Comes_From_Source (Tref)
855             then
856                --  If the reference is a subtype created for a generic actual,
857                --  go actual directly, the inner subtype is not user visible.
858
859                if Nkind (Parent (Tref)) = N_Subtype_Declaration
860                  and then not Comes_From_Source (Parent (Tref))
861                  and then
862                   (Is_Wrapper_Package (Scope (Tref))
863                      or else Is_Generic_Instance (Scope (Tref)))
864                then
865                   Tref := First_Subtype (Base_Type (Tref));
866                end if;
867
868                return;
869             end if;
870          end loop;
871
872          --  If we fall through the loop, no type reference
873
874          Tref := Empty;
875          Left := ' ';
876          Right := ' ';
877       end Get_Type_Reference;
878
879       -------------------------------
880       -- Output_Import_Export_Info --
881       -------------------------------
882
883       procedure Output_Import_Export_Info (Ent : Entity_Id) is
884          Language_Name : Name_Id;
885          Conv          : constant Convention_Id := Convention (Ent);
886
887       begin
888          --  Generate language name from convention
889
890          if Conv  = Convention_C then
891             Language_Name := Name_C;
892
893          elsif Conv = Convention_CPP then
894             Language_Name := Name_CPP;
895
896          elsif Conv = Convention_Ada then
897             Language_Name := Name_Ada;
898
899          else
900             --  For the moment we ignore all other cases ???
901
902             return;
903          end if;
904
905          Write_Info_Char ('<');
906          Get_Unqualified_Name_String (Language_Name);
907
908          for J in 1 .. Name_Len loop
909             Write_Info_Char (Name_Buffer (J));
910          end loop;
911
912          if Present (Interface_Name (Ent)) then
913             Write_Info_Char (',');
914             String_To_Name_Buffer (Strval (Interface_Name (Ent)));
915
916             for J in 1 .. Name_Len loop
917                Write_Info_Char (Name_Buffer (J));
918             end loop;
919          end if;
920
921          Write_Info_Char ('>');
922       end Output_Import_Export_Info;
923
924    --  Start of processing for Output_References
925
926    begin
927       if not Opt.Xref_Active then
928          return;
929       end if;
930
931       --  Before we go ahead and output the references we have a problem
932       --  that needs dealing with. So far we have captured things that are
933       --  definitely referenced by the main unit, or defined in the main
934       --  unit. That's because we don't want to clutter up the ali file
935       --  for this unit with definition lines for entities in other units
936       --  that are not referenced.
937
938       --  But there is a glitch. We may reference an entity in another unit,
939       --  and it may have a type reference to an entity that is not directly
940       --  referenced in the main unit, which may mean that there is no xref
941       --  entry for this entity yet in the list of references.
942
943       --  If we don't do something about this, we will end with an orphan type
944       --  reference, i.e. it will point to an entity that does not appear
945       --  within the generated references in the ali file. That is not good for
946       --  tools using the xref information.
947
948       --  To fix this, we go through the references adding definition entries
949       --  for any unreferenced entities that can be referenced in a type
950       --  reference. There is a recursion problem here, and that is dealt with
951       --  by making sure that this traversal also traverses any entries that
952       --  get added by the traversal.
953
954       Handle_Orphan_Type_References : declare
955          J    : Nat;
956          Tref : Entity_Id;
957          L, R : Character;
958          Indx : Nat;
959          Ent  : Entity_Id;
960          Loc  : Source_Ptr;
961
962          procedure New_Entry (E : Entity_Id);
963          --  Make an additional entry into the Xref table for a type entity
964          --  that is related to the current entity (parent, type ancestor,
965          --  progenitor, etc.).
966
967          ----------------
968          -- New_Entry --
969          ----------------
970
971          procedure New_Entry (E : Entity_Id) is
972          begin
973             if Present (E)
974               and then not Has_Xref_Entry (E)
975               and then Sloc (E) > No_Location
976             then
977                Xrefs.Increment_Last;
978                Indx := Xrefs.Last;
979                Loc  := Original_Location (Sloc (E));
980                Xrefs.Table (Indx).Ent := E;
981                Xrefs.Table (Indx).Loc := No_Location;
982                Xrefs.Table (Indx).Eun := Get_Source_Unit (Loc);
983                Xrefs.Table (Indx).Lun := No_Unit;
984                Set_Has_Xref_Entry (E);
985             end if;
986          end New_Entry;
987
988       --  Start of processing for Handle_Orphan_Type_References
989
990       begin
991          --  Note that this is not a for loop for a very good reason. The
992          --  processing of items in the table can add new items to the table,
993          --  and they must be processed as well.
994
995          J := 1;
996          while J <= Xrefs.Last loop
997             Ent := Xrefs.Table (J).Ent;
998             Get_Type_Reference (Ent, Tref, L, R);
999
1000             if Present (Tref)
1001               and then not Has_Xref_Entry (Tref)
1002               and then Sloc (Tref) > No_Location
1003             then
1004                New_Entry (Tref);
1005
1006                if Is_Record_Type (Ent)
1007                  and then Present (Abstract_Interfaces (Ent))
1008                then
1009                   --  Add an entry for each one of the given interfaces
1010                   --  implemented by type Ent.
1011
1012                   declare
1013                      Elmt : Elmt_Id;
1014
1015                   begin
1016                      Elmt := First_Elmt (Abstract_Interfaces (Ent));
1017                      while Present (Elmt) loop
1018                         New_Entry (Node (Elmt));
1019                         Next_Elmt (Elmt);
1020                      end loop;
1021                   end;
1022                end if;
1023             end if;
1024
1025             --  Collect inherited primitive operations that may be declared in
1026             --  another unit and have no visible reference in the current one.
1027
1028             if Is_Type (Ent)
1029               and then Is_Tagged_Type (Ent)
1030               and then Is_Derived_Type (Ent)
1031               and then Ent = Base_Type (Ent)
1032               and then In_Extended_Main_Source_Unit (Ent)
1033             then
1034                declare
1035                   Op_List : constant Elist_Id := Primitive_Operations (Ent);
1036                   Op      : Elmt_Id;
1037                   Prim    : Entity_Id;
1038
1039                   function Parent_Op (E : Entity_Id) return Entity_Id;
1040                   --  Find original operation, which may be inherited through
1041                   --  several derivations.
1042
1043                   function Parent_Op (E : Entity_Id) return Entity_Id is
1044                      Orig_Op : constant Entity_Id := Alias (E);
1045                   begin
1046                      if No (Orig_Op) then
1047                         return Empty;
1048                      elsif not Comes_From_Source (E)
1049                        and then not Has_Xref_Entry (Orig_Op)
1050                        and then Comes_From_Source (Orig_Op)
1051                      then
1052                         return Orig_Op;
1053                      else
1054                         return Parent_Op (Orig_Op);
1055                      end if;
1056                   end Parent_Op;
1057
1058                begin
1059                   Op := First_Elmt (Op_List);
1060                   while Present (Op) loop
1061                      Prim := Parent_Op (Node (Op));
1062
1063                      if Present (Prim) then
1064                         Xrefs.Increment_Last;
1065                         Indx := Xrefs.Last;
1066                         Loc  := Original_Location (Sloc (Prim));
1067                         Xrefs.Table (Indx).Ent := Prim;
1068                         Xrefs.Table (Indx).Loc := No_Location;
1069                         Xrefs.Table (Indx).Eun :=
1070                           Get_Source_Unit (Sloc (Prim));
1071                         Xrefs.Table (Indx).Lun := No_Unit;
1072                         Set_Has_Xref_Entry (Prim);
1073                      end if;
1074
1075                      Next_Elmt (Op);
1076                   end loop;
1077                end;
1078             end if;
1079
1080             J := J + 1;
1081          end loop;
1082       end Handle_Orphan_Type_References;
1083
1084       --  Now we have all the references, including those for any embedded
1085       --  type references, so we can sort them, and output them.
1086
1087       Output_Refs : declare
1088
1089          Nrefs : Nat := Xrefs.Last;
1090          --  Number of references in table. This value may get reset (reduced)
1091          --  when we eliminate duplicate reference entries.
1092
1093          Rnums : array (0 .. Nrefs) of Nat;
1094          --  This array contains numbers of references in the Xrefs table.
1095          --  This list is sorted in output order. The extra 0'th entry is
1096          --  convenient for the call to sort. When we sort the table, we
1097          --  move the entries in Rnums around, but we do not move the
1098          --  original table entries.
1099
1100          Curxu : Unit_Number_Type;
1101          --  Current xref unit
1102
1103          Curru : Unit_Number_Type;
1104          --  Current reference unit for one entity
1105
1106          Cursrc : Source_Buffer_Ptr;
1107          --  Current xref unit source text
1108
1109          Curent : Entity_Id;
1110          --  Current entity
1111
1112          Curnam : String (1 .. Name_Buffer'Length);
1113          Curlen : Natural;
1114          --  Simple name and length of current entity
1115
1116          Curdef : Source_Ptr;
1117          --  Original source location for current entity
1118
1119          Crloc : Source_Ptr;
1120          --  Current reference location
1121
1122          Ctyp : Character;
1123          --  Entity type character
1124
1125          Tref : Entity_Id;
1126          --  Type reference
1127
1128          Rref : Node_Id;
1129          --  Renaming reference
1130
1131          Trunit : Unit_Number_Type;
1132          --  Unit number for type reference
1133
1134          function Lt (Op1, Op2 : Natural) return Boolean;
1135          --  Comparison function for Sort call
1136
1137          function Name_Change (X : Entity_Id) return Boolean;
1138          --  Determines if entity X has a different simple name from Curent
1139
1140          procedure Move (From : Natural; To : Natural);
1141          --  Move procedure for Sort call
1142
1143          --------
1144          -- Lt --
1145          --------
1146
1147          function Lt (Op1, Op2 : Natural) return Boolean is
1148             T1 : Xref_Entry renames Xrefs.Table (Rnums (Nat (Op1)));
1149             T2 : Xref_Entry renames Xrefs.Table (Rnums (Nat (Op2)));
1150
1151          begin
1152             --  First test: if entity is in different unit, sort by unit
1153
1154             if T1.Eun /= T2.Eun then
1155                return Dependency_Num (T1.Eun) < Dependency_Num (T2.Eun);
1156
1157             --  Second test: within same unit, sort by entity Sloc
1158
1159             elsif T1.Def /= T2.Def then
1160                return T1.Def < T2.Def;
1161
1162             --  Third test: sort definitions ahead of references
1163
1164             elsif T1.Loc = No_Location then
1165                return True;
1166
1167             elsif T2.Loc = No_Location then
1168                return False;
1169
1170             --  Fourth test: for same entity, sort by reference location unit
1171
1172             elsif T1.Lun /= T2.Lun then
1173                return Dependency_Num (T1.Lun) < Dependency_Num (T2.Lun);
1174
1175             --  Fifth test: order of location within referencing unit
1176
1177             elsif T1.Loc /= T2.Loc then
1178                return T1.Loc < T2.Loc;
1179
1180             --  Finally, for two locations at the same address, we prefer
1181             --  the one that does NOT have the type 'r' so that a modification
1182             --  or extension takes preference, when there are more than one
1183             --  reference at the same location.
1184
1185             else
1186                return T2.Typ = 'r';
1187             end if;
1188          end Lt;
1189
1190          ----------
1191          -- Move --
1192          ----------
1193
1194          procedure Move (From : Natural; To : Natural) is
1195          begin
1196             Rnums (Nat (To)) := Rnums (Nat (From));
1197          end Move;
1198
1199          -----------------
1200          -- Name_Change --
1201          -----------------
1202
1203          --  Why a string comparison here??? Why not compare Name_Id values???
1204
1205          function Name_Change (X : Entity_Id) return Boolean is
1206          begin
1207             Get_Unqualified_Name_String (Chars (X));
1208
1209             if Name_Len /= Curlen then
1210                return True;
1211
1212             else
1213                return Name_Buffer (1 .. Curlen) /= Curnam (1 .. Curlen);
1214             end if;
1215          end Name_Change;
1216
1217       --  Start of processing for Output_Refs
1218
1219       begin
1220          --  Capture the definition Sloc values. We delay doing this till now,
1221          --  since at the time the reference or definition is made, private
1222          --  types may be swapped, and the Sloc value may be incorrect. We
1223          --  also set up the pointer vector for the sort.
1224
1225          for J in 1 .. Nrefs loop
1226             Rnums (J) := J;
1227             Xrefs.Table (J).Def :=
1228               Original_Location (Sloc (Xrefs.Table (J).Ent));
1229          end loop;
1230
1231          --  Sort the references
1232
1233          GNAT.Heap_Sort_A.Sort
1234            (Integer (Nrefs),
1235             Move'Unrestricted_Access,
1236             Lt'Unrestricted_Access);
1237
1238          --  Eliminate duplicate entries
1239
1240          declare
1241             NR : constant Nat := Nrefs;
1242
1243          begin
1244             --  We need this test for NR because if we force ALI file
1245             --  generation in case of errors detected, it may be the case
1246             --  that Nrefs is 0, so we should not reset it here
1247
1248             if NR >= 2 then
1249                Nrefs := 1;
1250
1251                for J in 2 .. NR loop
1252                   if Xrefs.Table (Rnums (J)) /=
1253                      Xrefs.Table (Rnums (Nrefs))
1254                   then
1255                      Nrefs := Nrefs + 1;
1256                      Rnums (Nrefs) := Rnums (J);
1257                   end if;
1258                end loop;
1259             end if;
1260          end;
1261
1262          --  Initialize loop through references
1263
1264          Curxu  := No_Unit;
1265          Curent := Empty;
1266          Curdef := No_Location;
1267          Curru  := No_Unit;
1268          Crloc  := No_Location;
1269
1270          --  Loop to output references
1271
1272          for Refno in 1 .. Nrefs loop
1273             Output_One_Ref : declare
1274                P2  : Source_Ptr;
1275                WC  : Char_Code;
1276                Err : Boolean;
1277                Ent : Entity_Id;
1278
1279                XE : Xref_Entry renames Xrefs.Table (Rnums (Refno));
1280                --  The current entry to be accessed
1281
1282                P : Source_Ptr;
1283                --  Used to index into source buffer to get entity name
1284
1285                Left  : Character;
1286                Right : Character;
1287                --  Used for {} or <> or () for type reference
1288
1289                procedure Check_Type_Reference
1290                  (Ent : Entity_Id;
1291                   List_Interface : Boolean);
1292                --  Find whether there is a meaningful type reference for
1293                --  Ent, and display it accordingly. If List_Interface is
1294                --  true, then Ent is a progenitor interface of the current
1295                --  type entity being listed. In that case list it as is,
1296                --  without looking for a type reference for it.
1297
1298                procedure Output_Instantiation_Refs (Loc : Source_Ptr);
1299                --  Recursive procedure to output instantiation references for
1300                --  the given source ptr in [file|line[...]] form. No output
1301                --  if the given location is not a generic template reference.
1302
1303                procedure Output_Overridden_Op (Old_E : Entity_Id);
1304                --  For a subprogram that is overriding, display information
1305                --  about the inherited operation that it overrides.
1306
1307                --------------------------
1308                -- Check_Type_Reference --
1309                --------------------------
1310
1311                procedure Check_Type_Reference
1312                  (Ent : Entity_Id;
1313                   List_Interface : Boolean)
1314                is
1315                begin
1316                   if List_Interface then
1317
1318                      --  This is a progenitor interface of the type for which
1319                      --  xref information is being generated.
1320
1321                      Tref  := Ent;
1322                      Left  := '<';
1323                      Right := '>';
1324
1325                   else
1326                      Get_Type_Reference (Ent, Tref, Left, Right);
1327                   end if;
1328
1329                   if Present (Tref) then
1330
1331                      --  Case of standard entity, output name
1332
1333                      if Sloc (Tref) = Standard_Location then
1334                         Write_Info_Char (Left);
1335                         Write_Info_Name (Chars (Tref));
1336                         Write_Info_Char (Right);
1337
1338                      --  Case of source entity, output location
1339
1340                      else
1341                         Write_Info_Char (Left);
1342                         Trunit := Get_Source_Unit (Sloc (Tref));
1343
1344                         if Trunit /= Curxu then
1345                            Write_Info_Nat (Dependency_Num (Trunit));
1346                            Write_Info_Char ('|');
1347                         end if;
1348
1349                         Write_Info_Nat
1350                           (Int (Get_Logical_Line_Number (Sloc (Tref))));
1351
1352                         declare
1353                            Ent  : Entity_Id := Tref;
1354                            Kind : constant Entity_Kind := Ekind (Ent);
1355                            Ctyp : Character := Xref_Entity_Letters (Kind);
1356
1357                         begin
1358                            if Ctyp = '+'
1359                              and then Present (Full_View (Ent))
1360                            then
1361                               Ent := Underlying_Type (Ent);
1362
1363                               if Present (Ent) then
1364                                  Ctyp := Xref_Entity_Letters (Ekind (Ent));
1365                               end if;
1366                            end if;
1367
1368                            Write_Info_Char (Ctyp);
1369                         end;
1370
1371                         Write_Info_Nat
1372                           (Int (Get_Column_Number (Sloc (Tref))));
1373
1374                         --  If the type comes from an instantiation, add the
1375                         --  corresponding info.
1376
1377                         Output_Instantiation_Refs (Sloc (Tref));
1378                         Write_Info_Char (Right);
1379                      end if;
1380                   end if;
1381                end Check_Type_Reference;
1382
1383                -------------------------------
1384                -- Output_Instantiation_Refs --
1385                -------------------------------
1386
1387                procedure Output_Instantiation_Refs (Loc : Source_Ptr) is
1388                   Iloc : constant Source_Ptr := Instantiation_Location (Loc);
1389                   Lun  : Unit_Number_Type;
1390                   Cu   : constant Unit_Number_Type := Curru;
1391
1392                begin
1393                   --  Nothing to do if this is not an instantiation
1394
1395                   if Iloc = No_Location then
1396                      return;
1397                   end if;
1398
1399                   --  Output instantiation reference
1400
1401                   Write_Info_Char ('[');
1402                   Lun := Get_Source_Unit (Iloc);
1403
1404                   if Lun /= Curru then
1405                      Curru := Lun;
1406                      Write_Info_Nat (Dependency_Num (Curru));
1407                      Write_Info_Char ('|');
1408                   end if;
1409
1410                   Write_Info_Nat (Int (Get_Logical_Line_Number (Iloc)));
1411
1412                   --  Recursive call to get nested instantiations
1413
1414                   Output_Instantiation_Refs (Iloc);
1415
1416                   --  Output final ] after call to get proper nesting
1417
1418                   Write_Info_Char (']');
1419                   Curru := Cu;
1420                   return;
1421                end Output_Instantiation_Refs;
1422
1423                --------------------------
1424                -- Output_Overridden_Op --
1425                --------------------------
1426
1427                procedure Output_Overridden_Op (Old_E : Entity_Id) is
1428                begin
1429                   if Present (Old_E)
1430                     and then Sloc (Old_E) /= Standard_Location
1431                   then
1432                      declare
1433                         Loc      : constant Source_Ptr := Sloc (Old_E);
1434                         Par_Unit : constant Unit_Number_Type :=
1435                                      Get_Source_Unit (Loc);
1436                      begin
1437                         Write_Info_Char ('<');
1438
1439                         if Par_Unit /= Curxu then
1440                            Write_Info_Nat (Dependency_Num (Par_Unit));
1441                            Write_Info_Char ('|');
1442                         end if;
1443
1444                         Write_Info_Nat (Int (Get_Logical_Line_Number (Loc)));
1445                         Write_Info_Char ('p');
1446                         Write_Info_Nat (Int (Get_Column_Number (Loc)));
1447                         Write_Info_Char ('>');
1448                      end;
1449                   end if;
1450                end Output_Overridden_Op;
1451
1452             --  Start of processing for Output_One_Ref
1453
1454             begin
1455                Ent := XE.Ent;
1456                Ctyp := Xref_Entity_Letters (Ekind (Ent));
1457
1458                --  Skip reference if it is the only reference to an entity,
1459                --  and it is an END line reference, and the entity is not in
1460                --  the current extended source. This prevents junk entries
1461                --  consisting only of packages with END lines, where no
1462                --  entity from the package is actually referenced.
1463
1464                if XE.Typ = 'e'
1465                  and then Ent /= Curent
1466                  and then (Refno = Nrefs or else
1467                              Ent /= Xrefs.Table (Rnums (Refno + 1)).Ent)
1468                  and then
1469                    not In_Extended_Main_Source_Unit (Ent)
1470                then
1471                   goto Continue;
1472                end if;
1473
1474                --  For private type, get full view type
1475
1476                if Ctyp = '+'
1477                  and then Present (Full_View (XE.Ent))
1478                then
1479                   Ent := Underlying_Type (Ent);
1480
1481                   if Present (Ent) then
1482                      Ctyp := Xref_Entity_Letters (Ekind (Ent));
1483                   end if;
1484                end if;
1485
1486                --  Special exception for Boolean
1487
1488                if Ctyp = 'E' and then Is_Boolean_Type (Ent) then
1489                   Ctyp := 'B';
1490                end if;
1491
1492                --  For variable reference, get corresponding type
1493
1494                if Ctyp = '*' then
1495                   Ent := Etype (XE.Ent);
1496                   Ctyp := Fold_Lower (Xref_Entity_Letters (Ekind (Ent)));
1497
1498                   --  If variable is private type, get full view type
1499
1500                   if Ctyp = '+'
1501                     and then Present (Full_View (Etype (XE.Ent)))
1502                   then
1503                      Ent := Underlying_Type (Etype (XE.Ent));
1504
1505                      if Present (Ent) then
1506                         Ctyp := Fold_Lower (Xref_Entity_Letters (Ekind (Ent)));
1507                      end if;
1508
1509                   elsif Is_Generic_Type (Ent) then
1510
1511                      --  If the type of the entity is a generic private type,
1512                      --  there is no usable full view, so retain the indication
1513                      --  that this is an object.
1514
1515                      Ctyp := '*';
1516                   end if;
1517
1518                   --  Special handling for access parameter
1519
1520                   declare
1521                      K : constant Entity_Kind := Ekind (Etype (XE.Ent));
1522
1523                   begin
1524                      if (K = E_Anonymous_Access_Type
1525                            or else
1526                          K = E_Anonymous_Access_Subprogram_Type
1527                             or else K =
1528                          E_Anonymous_Access_Protected_Subprogram_Type)
1529                        and then Is_Formal (XE.Ent)
1530                      then
1531                         Ctyp := 'p';
1532
1533                         --  Special handling for Boolean
1534
1535                      elsif Ctyp = 'e' and then Is_Boolean_Type (Ent) then
1536                         Ctyp := 'b';
1537                      end if;
1538                   end;
1539                end if;
1540
1541                --  Special handling for abstract types and operations
1542
1543                if Is_Overloadable (XE.Ent)
1544                  and then Is_Abstract_Subprogram (XE.Ent)
1545                then
1546                   if Ctyp = 'U' then
1547                      Ctyp := 'x';            --  Abstract procedure
1548
1549                   elsif Ctyp = 'V' then
1550                      Ctyp := 'y';            --  Abstract function
1551                   end if;
1552
1553                elsif Is_Type (XE.Ent)
1554                  and then Is_Abstract_Type (XE.Ent)
1555                then
1556                   if Is_Interface (XE.Ent) then
1557                      Ctyp := 'h';
1558
1559                   elsif Ctyp = 'R' then
1560                      Ctyp := 'H';            --  Abstract type
1561                   end if;
1562                end if;
1563
1564                --  Only output reference if interesting type of entity, and
1565                --  suppress self references, except for bodies that act as
1566                --  specs. Also suppress definitions of body formals (we only
1567                --  treat these as references, and the references were
1568                --  separately recorded).
1569
1570                if Ctyp = ' '
1571                  or else (XE.Loc = XE.Def
1572                             and then
1573                               (XE.Typ /= 'b'
1574                                 or else not Is_Subprogram (XE.Ent)))
1575                  or else (Is_Formal (XE.Ent)
1576                             and then Present (Spec_Entity (XE.Ent)))
1577                then
1578                   null;
1579
1580                else
1581                   --  Start new Xref section if new xref unit
1582
1583                   if XE.Eun /= Curxu then
1584                      if Write_Info_Col > 1 then
1585                         Write_Info_EOL;
1586                      end if;
1587
1588                      Curxu := XE.Eun;
1589                      Cursrc := Source_Text (Source_Index (Curxu));
1590
1591                      Write_Info_Initiate ('X');
1592                      Write_Info_Char (' ');
1593                      Write_Info_Nat (Dependency_Num (XE.Eun));
1594                      Write_Info_Char (' ');
1595                      Write_Info_Name (Reference_Name (Source_Index (XE.Eun)));
1596                   end if;
1597
1598                   --  Start new Entity line if new entity. Note that we
1599                   --  consider two entities the same if they have the same
1600                   --  name and source location. This causes entities in
1601                   --  instantiations to be treated as though they referred
1602                   --  to the template.
1603
1604                   if No (Curent)
1605                     or else
1606                       (XE.Ent /= Curent
1607                          and then
1608                            (Name_Change (XE.Ent) or else XE.Def /= Curdef))
1609                   then
1610                      Curent := XE.Ent;
1611                      Curdef := XE.Def;
1612
1613                      Get_Unqualified_Name_String (Chars (XE.Ent));
1614                      Curlen := Name_Len;
1615                      Curnam (1 .. Curlen) := Name_Buffer (1 .. Curlen);
1616
1617                      if Write_Info_Col > 1 then
1618                         Write_Info_EOL;
1619                      end if;
1620
1621                      --  Write column number information
1622
1623                      Write_Info_Nat (Int (Get_Logical_Line_Number (XE.Def)));
1624                      Write_Info_Char (Ctyp);
1625                      Write_Info_Nat (Int (Get_Column_Number (XE.Def)));
1626
1627                      --  Write level information
1628
1629                      Write_Level_Info : declare
1630                         function Is_Visible_Generic_Entity
1631                           (E : Entity_Id) return Boolean;
1632                         --  Check whether E is declared in the visible part
1633                         --  of a generic package. For source navigation
1634                         --  purposes, treat this as a visible entity.
1635
1636                         function Is_Private_Record_Component
1637                           (E : Entity_Id) return Boolean;
1638                         --  Check whether E is a non-inherited component of a
1639                         --  private extension. Even if the enclosing record is
1640                         --  public, we want to treat the component as private
1641                         --  for navigation purposes.
1642
1643                         ---------------------------------
1644                         -- Is_Private_Record_Component --
1645                         ---------------------------------
1646
1647                         function Is_Private_Record_Component
1648                           (E : Entity_Id) return Boolean
1649                         is
1650                            S : constant Entity_Id := Scope (E);
1651                         begin
1652                            return
1653                              Ekind (E) = E_Component
1654                                and then Nkind (Declaration_Node (S)) =
1655                                  N_Private_Extension_Declaration
1656                                and then Original_Record_Component (E) = E;
1657                         end Is_Private_Record_Component;
1658
1659                         -------------------------------
1660                         -- Is_Visible_Generic_Entity --
1661                         -------------------------------
1662
1663                         function Is_Visible_Generic_Entity
1664                           (E : Entity_Id) return Boolean
1665                         is
1666                            Par : Node_Id;
1667
1668                         begin
1669                            if Ekind (Scope (E)) /= E_Generic_Package then
1670                               return False;
1671                            end if;
1672
1673                            Par := Parent (E);
1674                            while Present (Par) loop
1675                               if
1676                                 Nkind (Par) = N_Generic_Package_Declaration
1677                               then
1678                                  --  Entity is a generic formal
1679
1680                                  return False;
1681
1682                               elsif
1683                                 Nkind (Parent (Par)) = N_Package_Specification
1684                               then
1685                                  return
1686                                    Is_List_Member (Par)
1687                                      and then List_Containing (Par) =
1688                                        Visible_Declarations (Parent (Par));
1689                               else
1690                                  Par := Parent (Par);
1691                               end if;
1692                            end loop;
1693
1694                            return False;
1695                         end Is_Visible_Generic_Entity;
1696
1697                      --  Start of processing for Write_Level_Info
1698
1699                      begin
1700                         if Is_Hidden (Curent)
1701                           or else Is_Private_Record_Component (Curent)
1702                         then
1703                            Write_Info_Char (' ');
1704
1705                         elsif
1706                            Is_Public (Curent)
1707                              or else Is_Visible_Generic_Entity (Curent)
1708                         then
1709                            Write_Info_Char ('*');
1710
1711                         else
1712                            Write_Info_Char (' ');
1713                         end if;
1714                      end Write_Level_Info;
1715
1716                      --  Output entity name. We use the occurrence from the
1717                      --  actual source program at the definition point.
1718
1719                      P := Original_Location (Sloc (XE.Ent));
1720
1721                      --  Entity is character literal
1722
1723                      if Cursrc (P) = ''' then
1724                         Write_Info_Char (Cursrc (P));
1725                         Write_Info_Char (Cursrc (P + 1));
1726                         Write_Info_Char (Cursrc (P + 2));
1727
1728                      --  Entity is operator symbol
1729
1730                      elsif Cursrc (P) = '"' or else Cursrc (P) = '%' then
1731                         Write_Info_Char (Cursrc (P));
1732
1733                         P2 := P;
1734                         loop
1735                            P2 := P2 + 1;
1736                            Write_Info_Char (Cursrc (P2));
1737                            exit when Cursrc (P2) = Cursrc (P);
1738                         end loop;
1739
1740                      --  Entity is identifier
1741
1742                      else
1743                         loop
1744                            if Is_Start_Of_Wide_Char (Cursrc, P) then
1745                               Scan_Wide (Cursrc, P, WC, Err);
1746                            elsif not Identifier_Char (Cursrc (P)) then
1747                               exit;
1748                            else
1749                               P := P + 1;
1750                            end if;
1751                         end loop;
1752
1753                         --  Write out the identifier by copying the exact
1754                         --  source characters used in its declaration. Note
1755                         --  that this means wide characters will be in their
1756                         --  original encoded form.
1757
1758                         for J in
1759                           Original_Location (Sloc (XE.Ent)) .. P - 1
1760                         loop
1761                            Write_Info_Char (Cursrc (J));
1762                         end loop;
1763                      end if;
1764
1765                      --  See if we have a renaming reference
1766
1767                      if Is_Object (XE.Ent)
1768                        and then Present (Renamed_Object (XE.Ent))
1769                      then
1770                         Rref := Renamed_Object (XE.Ent);
1771
1772                      elsif Is_Overloadable (XE.Ent)
1773                        and then Nkind (Parent (Declaration_Node (XE.Ent))) =
1774                                             N_Subprogram_Renaming_Declaration
1775                      then
1776                         Rref := Name (Parent (Declaration_Node (XE.Ent)));
1777
1778                      elsif Ekind (XE.Ent) = E_Package
1779                        and then Nkind (Declaration_Node (XE.Ent)) =
1780                                          N_Package_Renaming_Declaration
1781                      then
1782                         Rref := Name (Declaration_Node (XE.Ent));
1783
1784                      else
1785                         Rref := Empty;
1786                      end if;
1787
1788                      if Present (Rref) then
1789                         if Nkind (Rref) = N_Expanded_Name then
1790                            Rref := Selector_Name (Rref);
1791                         end if;
1792
1793                         if Nkind (Rref) = N_Identifier
1794                           or else Nkind (Rref) = N_Operator_Symbol
1795                         then
1796                            null;
1797
1798                         --  For renamed array components, use the array name
1799                         --  for the renamed entity, which reflect the fact that
1800                         --  in general the whole array is aliased.
1801
1802                         elsif Nkind (Rref) = N_Indexed_Component then
1803                            if Nkind (Prefix (Rref)) = N_Identifier then
1804                               Rref := Prefix (Rref);
1805                            elsif Nkind (Prefix (Rref)) = N_Expanded_Name then
1806                               Rref := Selector_Name (Prefix (Rref));
1807                            else
1808                               Rref := Empty;
1809                            end if;
1810
1811                         else
1812                            Rref := Empty;
1813                         end if;
1814                      end if;
1815
1816                      --  Write out renaming reference if we have one
1817
1818                      if Present (Rref) then
1819                         Write_Info_Char ('=');
1820                         Write_Info_Nat
1821                           (Int (Get_Logical_Line_Number (Sloc (Rref))));
1822                         Write_Info_Char (':');
1823                         Write_Info_Nat
1824                           (Int (Get_Column_Number (Sloc (Rref))));
1825                      end if;
1826
1827                      --  Indicate that the entity is in the unit of the current
1828                      --  xref section.
1829
1830                      Curru := Curxu;
1831
1832                      --  Write out information about generic parent, if entity
1833                      --  is an instance.
1834
1835                      if  Is_Generic_Instance (XE.Ent) then
1836                         declare
1837                            Gen_Par : constant Entity_Id :=
1838                                        Generic_Parent
1839                                          (Specification
1840                                             (Unit_Declaration_Node (XE.Ent)));
1841                            Loc     : constant Source_Ptr := Sloc (Gen_Par);
1842                            Gen_U   : constant Unit_Number_Type :=
1843                                        Get_Source_Unit (Loc);
1844
1845                         begin
1846                            Write_Info_Char ('[');
1847                            if Curru /= Gen_U then
1848                               Write_Info_Nat (Dependency_Num (Gen_U));
1849                               Write_Info_Char ('|');
1850                            end if;
1851
1852                            Write_Info_Nat
1853                              (Int (Get_Logical_Line_Number (Loc)));
1854                            Write_Info_Char (']');
1855                         end;
1856                      end if;
1857
1858                      --  See if we have a type reference and if so output
1859
1860                      Check_Type_Reference (XE.Ent, False);
1861
1862                      --  Additional information for types with progenitors
1863
1864                      if Is_Record_Type (XE.Ent)
1865                        and then Present (Abstract_Interfaces (XE.Ent))
1866                      then
1867                         declare
1868                            Elmt : Elmt_Id;
1869
1870                         begin
1871                            Elmt := First_Elmt (Abstract_Interfaces (XE.Ent));
1872                            while Present (Elmt) loop
1873                               Check_Type_Reference (Node (Elmt), True);
1874                               Next_Elmt (Elmt);
1875                            end loop;
1876                         end;
1877
1878                      --  For array types, list index types as well.
1879                      --  (This is not C, indices have distinct types).
1880
1881                      elsif Is_Array_Type (XE.Ent) then
1882                         declare
1883                            Indx : Node_Id;
1884                         begin
1885                            Indx := First_Index (XE.Ent);
1886                            while Present (Indx) loop
1887                               Check_Type_Reference
1888                                 (First_Subtype (Etype (Indx)), True);
1889                               Next_Index (Indx);
1890                            end loop;
1891                         end;
1892                      end if;
1893
1894                      --  If the entity is an overriding operation, write info
1895                      --  on operation that was overridden.
1896
1897                      if Is_Subprogram (XE.Ent)
1898                        and then Is_Overriding_Operation (XE.Ent)
1899                      then
1900                         Output_Overridden_Op (Overridden_Operation (XE.Ent));
1901                      end if;
1902
1903                      --  End of processing for entity output
1904
1905                      Crloc := No_Location;
1906                   end if;
1907
1908                   --  Output the reference
1909
1910                   if XE.Loc /= No_Location
1911                      and then XE.Loc /= Crloc
1912                   then
1913                      Crloc := XE.Loc;
1914
1915                      --  Start continuation if line full, else blank
1916
1917                      if Write_Info_Col > 72 then
1918                         Write_Info_EOL;
1919                         Write_Info_Initiate ('.');
1920                      end if;
1921
1922                      Write_Info_Char (' ');
1923
1924                      --  Output file number if changed
1925
1926                      if XE.Lun /= Curru then
1927                         Curru := XE.Lun;
1928                         Write_Info_Nat (Dependency_Num (Curru));
1929                         Write_Info_Char ('|');
1930                      end if;
1931
1932                      Write_Info_Nat  (Int (Get_Logical_Line_Number (XE.Loc)));
1933                      Write_Info_Char (XE.Typ);
1934
1935                      if Is_Overloadable (XE.Ent)
1936                        and then Is_Imported (XE.Ent)
1937                        and then XE.Typ = 'b'
1938                      then
1939                         Output_Import_Export_Info (XE.Ent);
1940                      end if;
1941
1942                      Write_Info_Nat  (Int (Get_Column_Number (XE.Loc)));
1943
1944                      Output_Instantiation_Refs (Sloc (XE.Ent));
1945                   end if;
1946                end if;
1947             end Output_One_Ref;
1948
1949          <<Continue>>
1950             null;
1951          end loop;
1952
1953          Write_Info_EOL;
1954       end Output_Refs;
1955    end Output_References;
1956
1957 end Lib.Xref;