-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with CommandLineData;
with ContextManager.Ops;
with E_Strings;
with FileSystem;
with IndexManager;
with LexTokenLists;
with SLI.IO;
with SLI.Xref;
with SPARK_IO;
with SP_Symbols;
with SystemErrors;
with Version;

use type CommandLineData.Concurrency_Profiles;
use type CommandLineData.Language_Profiles;
use type SP_Symbols.SP_Symbol;

package body SLI
--# own State is SLI.Xref.State,
--#              out SLI.IO.Stream_Buffer;
is

   function "=" (Left, Right : IO.File_Status) return Boolean renames IO."=";

   procedure Create_File (File_Descriptor : in ContextManager.FileDescriptors)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     LexTokenManager.State;
   --#        in out SPARK_IO.File_Sys;
   --#           out IO.Stream_Buffer;
   --# derives IO.Stream_Buffer  from CommandLineData.Content,
   --#                                ContextManager.Ops.File_Heap,
   --#                                File_Descriptor,
   --#                                LexTokenManager.State &
   --#         SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                ContextManager.Ops.File_Heap,
   --#                                File_Descriptor,
   --#                                LexTokenManager.State;
   is
      SLI_File_Status : IO.File_Status;
      SLI_File_Name   : E_Strings.T;
   begin
      --  Build the SLI filename.
      SLI_File_Name :=
        FileSystem.Just_File
        (Fn  => LexTokenManager.Lex_String_To_String
           (Lex_Str => ContextManager.Ops.GetSourceFileName (Descriptor => File_Descriptor)),
         Ext => False);
      E_Strings.Append_String (E_Str => SLI_File_Name,
                               Str   => ".sli");
      CommandLineData.Normalize_File_Name_To_Output_Directory (F => SLI_File_Name);
      --  Create the SLI file.
      IO.Create_File (Name_Of_File => SLI_File_Name,
                      Status       => SLI_File_Status);
      if SLI_File_Status /= IO.Ok then
         SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                              Item => "Unable to open SLI file: ",
                              Stop => 0);
         E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                               E_Str => SLI_File_Name);
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "");
      end if;
   end Create_File;

   procedure Close_File
   --# global out IO.Stream_Buffer;
   --# derives IO.Stream_Buffer from ;
   is
   begin
      --  Close the SLI file.
      IO.Close;
   end Close_File;

   procedure Header (File_Descriptor : in ContextManager.FileDescriptors)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     Dictionary.Dict;
   --#        in     STree.Table;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out IndexManager.State;
   --#        in out LexTokenManager.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out XMLReport.State;
   --#           out IO.Stream_Buffer;
   --# derives ContextManager.Ops.Unit_Heap from * &
   --#         ErrorHandler.Error_Context,
   --#         IndexManager.State,
   --#         LexTokenManager.State,
   --#         SPARK_IO.File_Sys            from CommandLineData.Content,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           File_Descriptor,
   --#                                           IndexManager.State,
   --#                                           LexTokenManager.State,
   --#                                           SPARK_IO.File_Sys,
   --#                                           STree.Table &
   --#         IO.Stream_Buffer             from CommandLineData.Content,
   --#                                           ContextManager.Ops.File_Heap,
   --#                                           ContextManager.Ops.Unit_Heap,
   --#                                           Dictionary.Dict,
   --#                                           ErrorHandler.Error_Context,
   --#                                           File_Descriptor,
   --#                                           IndexManager.State,
   --#                                           LexTokenManager.State,
   --#                                           SPARK_IO.File_Sys,
   --#                                           STree.Table,
   --#                                           XMLReport.State &
   --#         XMLReport.State              from *,
   --#                                           CommandLineData.Content;
   is

      It                          : ContextManager.UnitDescriptors;
      Unit_Pointer_Spec           : ContextManager.UnitDescriptors;
      Unit_Pointer_Body           : ContextManager.UnitDescriptors;
      Unit_Name                   : LexTokenLists.Lists;
      Unit_Type                   : ContextManager.UnitTypes;
      Str                         : E_Strings.T;
      Lex_String_Source_File_Name : LexTokenManager.Lex_String;
      Source_File_Name            : E_Strings.T;
      Actual_Unit_Type            : ContextManager.UnitTypes;
      Found                       : Boolean;
      Line_Number                 : Positive;

      --  Write the A section (see A section of the ALI format)
      --  containing all the arguments given to the Examiner in
      --  the SLI file.
      procedure Print_Args
      --# global in     CommandLineData.Content;
      --#        in     SPARK_IO.File_Sys;
      --#        in out XMLReport.State;
      --#           out IO.Stream_Buffer;
      --# derives IO.Stream_Buffer from CommandLineData.Content,
      --#                               SPARK_IO.File_Sys,
      --#                               XMLReport.State &
      --#         XMLReport.State  from *,
      --#                               CommandLineData.Content;
      is
         Option_Str : E_Strings.T;
      begin
         CommandLineData.Output_Command_Line (Prefix     => "A -",
                                              XML        => False,
                                              Option_Str => Option_Str);
         IO.E_Strings_Put_String (E_Str => Option_Str);
      end Print_Args;

      --  Write a dotted name identifier (List) in the SLI file.
      procedure Print_List (List : in LexTokenLists.Lists)
      --# global in     LexTokenManager.State;
      --#           out IO.Stream_Buffer;
      --# derives IO.Stream_Buffer from LexTokenManager.State,
      --#                               List;
      is
      begin
         for I in LexTokenLists.Positions range 1 .. LexTokenLists.Get_Length (List => List) loop
            IO.E_Strings_Put_String
              (E_Str => LexTokenManager.Lex_String_To_String (Lex_Str => LexTokenLists.Get_Element (List => List,
                                                                                                    Pos  => I)));
            if I < LexTokenLists.Get_Length (List => List) then
               IO.Put_Char (Item => '.');
            end if;
         end loop;
      end Print_List;

   begin -- Header

      --  Write the V, A, P, R sections.
      if CommandLineData.Content.Plain_Output then
         IO.Put_Line (Item => "V ""SPARK 0.0.0""");
      else
         IO.Put_Line (Item => "V ""SPARK " & Version.Toolset_Version & """");
      end if;
      Print_Args;
      IO.Put_Line (Item => "P");
      IO.Put_Line (Item => "R");
      IO.New_Line;

      --  Find the Unit_Pointer_Body of the File_Descriptor.
      ContextManager.Ops.Get_Unit (Descriptor      => File_Descriptor,
                                   Unit_Descriptor => Unit_Pointer_Body);

      --  Write the U section.
      ContextManager.Ops.GetUnitName (Descriptor => Unit_Pointer_Body,
                                      UnitName   => Unit_Name,
                                      UnitType   => Unit_Type);
      IO.Put_String (Item => "U ");
      Print_List (List => Unit_Name);
      Str :=
        LexTokenManager.Lex_String_To_String (Lex_Str => ContextManager.Ops.GetSourceFileName (Descriptor => File_Descriptor));

      if Unit_Type = ContextManager.PackageSpecification then
         --  It is an Ada package specification.
         Unit_Pointer_Spec := Unit_Pointer_Body;
         IO.Put_String (Item => "%s ");
         IO.E_Strings_Put_Line (E_Str => FileSystem.Just_File (Fn  => Str,
                                                               Ext => True));
      elsif Unit_Type = ContextManager.PackageBody then
         --  It is an Ada package body.
         IO.Put_String (Item => "%b ");
         IO.E_Strings_Put_Line (E_Str => FileSystem.Just_File (Fn  => Str,
                                                               Ext => True));

         --  Find the specification of the Unit_Pointer_Body.
         ContextManager.Ops.GetUnitByName
           (UnitName    => Unit_Name,
            UnitTypeSet => ContextManager.PackageSpecificationSet,
            Descriptor  => Unit_Pointer_Spec);

         IO.Put_String (Item => "U ");
         Print_List (List => Unit_Name);
         IO.Put_String (Item => "%s ");
         IO.E_Strings_Put_Line
           (E_Str => FileSystem.Just_File
              (Fn  => LexTokenManager.Lex_String_To_String
                 (Lex_Str => ContextManager.Ops.GetSourceFileName
                    (Descriptor => ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Unit_Pointer_Spec))),
               Ext => True));
      elsif Unit_Type = ContextManager.SubUnit
        or else Unit_Type = ContextManager.MainProgram
        or else Unit_Type = ContextManager.GenericSubprogramBody then
         --  It is an Ada separate unit or an Ada main program.
         Unit_Pointer_Spec := ContextManager.NullUnit;
         IO.Put_String (Item => "%b ");
         IO.E_Strings_Put_Line (E_Str => FileSystem.Just_File (Fn  => Str,
                                                               Ext => True));
      else
         Unit_Pointer_Spec := ContextManager.NullUnit;
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "SLI.HEADER PROGRAM ERROR");
      end if;

      --  Write the W section.
      It := ContextManager.Ops.FirstUnitDescriptor;
      while It /= ContextManager.NullUnit loop
         ContextManager.Ops.GetUnitName (Descriptor => It,
                                         UnitName   => Unit_Name,
                                         UnitType   => Unit_Type);
         if Unit_Type = ContextManager.PackageSpecification
           and then ContextManager.Ops.In_Closure (Descriptor => It)
           and then It /= Unit_Pointer_Spec then
            --  It is an Ada package specification in the closure.
            IO.Put_String (Item => "W ");
            Print_List (List => Unit_Name);
            IO.Put_String (Item => "%s ");
            --# accept Flow, 10, Actual_Unit_Type, "Expected ineffective assignment to Actual_Unit_Type";
            IndexManager.Look_Up
              (Required_Unit       => Unit_Name,
               Possible_Unit_Types => ContextManager.SubUnitSet,
               Source_Filename     => Lex_String_Source_File_Name,
               Actual_Unit_Type    => Actual_Unit_Type,
               Found               => Found);
            --# end accept;
            if not Found then
               --  The SLI file is not associated with an Ada package
               --  body or an Ada separate unit.
               Lex_String_Source_File_Name :=
                 ContextManager.Ops.GetSourceFileName
                 (Descriptor => ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => It));
            end if;
            Source_File_Name := LexTokenManager.Lex_String_To_String (Lex_Str => Lex_String_Source_File_Name);
            IO.E_Strings_Put_String (E_Str => FileSystem.Just_File (Fn  => Source_File_Name,
                                                                    Ext => True));
            IO.Put_Char (Item => ' ');
            IO.E_Strings_Put_String (E_Str => FileSystem.Just_File (Fn  => Source_File_Name,
                                                                    Ext => False));
            IO.Put_Line (Item => ".sli");
         end if;
         It := ContextManager.Ops.NextUnitDescriptor (Descriptor => It);
      end loop;

      IO.New_Line;

      --  Write the D section.
      Line_Number := 1;
      It          := ContextManager.Ops.FirstUnitDescriptor;
      while It /= ContextManager.NullUnit loop
         if ContextManager.Ops.In_Closure (Descriptor => It) then
            --  It is an Ada package in the closure.
            IO.Put_String (Item => "D ");
            IO.E_Strings_Put_String
              (E_Str => FileSystem.Just_File
                 (Fn  => LexTokenManager.Lex_String_To_String
                    (Lex_Str => ContextManager.Ops.GetSourceFileName
                       (Descriptor => ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => It))),
                  Ext => True));
            IO.Put_Line (Item => " 00000000000000 00000000");
            --  Keep the line number in the SLI file.
            ContextManager.Ops.Set_Line_Number (Descriptor  => It,
                                                Line_Number => Line_Number);
            Line_Number := Line_Number + 1;
         end if;
         It := ContextManager.Ops.NextUnitDescriptor (Descriptor => It);
      end loop;
      --# accept Flow, 33, Actual_Unit_Type, "Expected Actual_Unit_Type to be neither referenced nor exported";
   end Header;

   procedure Dump_Xref (File_Descriptor : in ContextManager.FileDescriptors)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --#           out IO.Stream_Buffer;
   --# derives ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         Dictionary.Dict,
   --#                                         File_Descriptor,
   --#                                         LexTokenManager.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         IO.Stream_Buffer           from ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         Dictionary.Dict,
   --#                                         File_Descriptor,
   --#                                         LexTokenManager.State,
   --#                                         Xref.State &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         File_Descriptor,
   --#                                         LexTokenManager.State,
   --#                                         STree.Table,
   --#                                         Xref.State &
   --#         Xref.State                 from *,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         Dictionary.Dict,
   --#                                         File_Descriptor,
   --#                                         LexTokenManager.State;
   is
      Unit_Descriptor : ContextManager.UnitDescriptors;
   begin
      ContextManager.Ops.Get_Unit (Descriptor      => File_Descriptor,
                                   Unit_Descriptor => Unit_Descriptor);
      Xref.Dump (Comp_Unit => Unit_Descriptor);
   end Dump_Xref;

   procedure Look_Up
     (Prefix            : in out Dictionary.Symbol;
      Scope             : in     Dictionary.Scopes;
      Subprog_Sym       : in     Dictionary.Symbol;
      Lex_Str           : in     LexTokenManager.Lex_String;
      Pos               : in     LexTokenManager.Token_Position;
      Full_Package_Name : in     Boolean)
   is
      Prefix_Str : E_Strings.T;
      Sym        : Dictionary.Symbol;
   begin
      if Dictionary.Is_Null_Symbol (Prefix) then
         --  Try to find the symbol definition in the dictionary.
         Sym :=
           Dictionary.LookupItem
           (Name              => Lex_Str,
            Scope             => Scope,
            Context           => Dictionary.ProofContext,
            Full_Package_Name => Full_Package_Name);
         if Dictionary.Is_Null_Symbol (Sym) and then not Dictionary.Is_Null_Symbol (Subprog_Sym) then
            --  Try to find the symbol definition with the
            --  procedure/function name as prefix in the dictionary.
            Sym :=
              Dictionary.LookupSelectedItem
              (Prefix   => Subprog_Sym,
               Selector => Lex_Str,
               Scope    => Scope,
               Context  => Dictionary.ProofContext);
         end if;
         Prefix_Str := E_Strings.Empty_String;
      else
         --  Try to find the symbol definition with a prefix in the
         --  dictionary.
         Sym        :=
           Dictionary.LookupSelectedItem
           (Prefix   => Prefix,
            Selector => Lex_Str,
            Scope    => Scope,
            Context  => Dictionary.ProofContext);
         Prefix_Str := Dictionary.GenerateSimpleName (Item      => Prefix,
                                                      Separator => ".");
         E_Strings.Append_String (E_Str => Prefix_Str,
                                  Str   => ".");
      end if;

      if Dictionary.Is_Null_Symbol (Sym) and then CommandLineData.Content.Debug.SLI then
         --  Symbol not found -> show the error.
         SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                            Item => ' ');
         E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                               E_Str => Prefix_Str);
         E_Strings.Put_String
           (File  => SPARK_IO.Standard_Output,
            E_Str => LexTokenManager.Lex_String_To_String (Lex_Str => Lex_Str));
         SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                              Item => " (",
                              Stop => 0);
         SPARK_IO.Put_Integer (File  => SPARK_IO.Standard_Output,
                               Item  => Integer (Pos.Start_Line_No),
                               Width => 0,
                               Base  => 10);
         SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                            Item => ':');
         SPARK_IO.Put_Integer (File  => SPARK_IO.Standard_Output,
                               Item  => Pos.Start_Pos,
                               Width => 0,
                               Base  => 10);
         SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                            Item => ") SYMBOL NOT FOUND",
                            Stop => 0);
      end if;

      Prefix := Sym;
   end Look_Up;

   --  Add a cross-reference for the symbol (Sym) located at the node
   --  (Current_Node). The symbol is used in the compilation unit
   --  (Comp_Unit). The type of reference is Ref_Type.
   procedure Add_Usage
     (Comp_Unit    : in ContextManager.UnitDescriptors;
      Sym          : in Dictionary.Symbol;
      Current_Node : in STree.SyntaxNode;
      Ref_Type     : in Character)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Current_Node,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Ref_Type,
   --#                                STree.Table,
   --#                                Sym,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Current_Node,
   --#                                Dictionary.Dict,
   --#                                Ref_Type,
   --#                                STree.Table,
   --#                                Sym;
   is
      Node_Pos      : LexTokenManager.Token_Position;
      Decl_Pos      : LexTokenManager.Token_Position;
      Str           : E_Strings.T;
      Unit_Des      : ContextManager.UnitDescriptors;
      Node_File_Des : ContextManager.FileDescriptors;
      Decl_File_Des : ContextManager.FileDescriptors;
   begin
      Node_Pos := STree.Node_Position (Node => Current_Node);
      Decl_Pos := Dictionary.Get_Symbol_Location (Item => Sym);
      Unit_Des := Dictionary.Get_Symbol_Compilation_Unit (Item => Sym);
      if Unit_Des /= ContextManager.NullUnit then
         Decl_File_Des := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Unit_Des);
      else
         Decl_File_Des := ContextManager.NullFile;
      end if;
      if Comp_Unit /= ContextManager.NullUnit then
         Node_File_Des := ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Comp_Unit);
      else
         Node_File_Des := ContextManager.NullFile;
      end if;
      if Node_Pos /= Decl_Pos or Decl_File_Des /= Node_File_Des then
         Xref.Add_Usage
           (Decl_Comp_Unit  => Unit_Des,
            Sym             => Sym,
            Usage_Comp_Unit => Comp_Unit,
            Pos             => Node_Pos,
            Ref_Type        => Ref_Type);
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                               Item => ' ');
            E_Strings.Put_String
              (File  => SPARK_IO.Standard_Output,
               E_Str => Dictionary.GenerateSimpleName (Item      => Sym,
                                                       Separator => "."));
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => " (",
                                 Stop => 0);
            E_Strings.Put_String
              (File  => SPARK_IO.Standard_Output,
               E_Str => FileSystem.Just_File
                 (Fn  => LexTokenManager.Lex_String_To_String
                    (Lex_Str => ContextManager.Ops.GetSourceFileName
                       (Descriptor => ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Comp_Unit))),
                  Ext => True));
            SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                               Item => ':');
            SPARK_IO.Put_Integer
              (File  => SPARK_IO.Standard_Output,
               Item  => Integer (Node_Pos.Start_Line_No),
               Width => 0,
               Base  => 10);
            SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                               Item => Ref_Type);
            SPARK_IO.Put_Integer (File  => SPARK_IO.Standard_Output,
                                  Item  => Node_Pos.Start_Pos,
                                  Width => 0,
                                  Base  => 10);
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => ") FOUND AT ",
                                 Stop => 0);
            if Unit_Des /= ContextManager.NullUnit then
               Str :=
                 LexTokenManager.Lex_String_To_String
                 (Lex_Str => ContextManager.Ops.GetSourceFileName
                    (Descriptor => ContextManager.Ops.Get_File_Descriptor (Unit_Descriptor => Unit_Des)));
            else
               Str := E_Strings.Copy_String (Str => "no_file.ada");
            end if;
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => FileSystem.Just_File (Fn  => Str,
                                                                 Ext => True));
            SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                               Item => ':');
            SPARK_IO.Put_Integer
              (File  => SPARK_IO.Standard_Output,
               Item  => Integer (Decl_Pos.Start_Line_No),
               Width => 0,
               Base  => 10);
            SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                               Item => ',');
            SPARK_IO.Put_Integer (File  => SPARK_IO.Standard_Output,
                                  Item  => Decl_Pos.Start_Pos,
                                  Width => 0,
                                  Base  => 10);
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => "!!!",
                                 Stop => 0);
         end if;
      end if;
   end Add_Usage;

   --  Add cross-references for the dotted name identifier (Node)
   --  giving a procedure/function name (Subprog_Sym) and a scope
   --  (Scope). The dotted name identifier is used in the compilation
   --  unit (Comp_Unit). The type of reference is Ref_Type.
   procedure Generate_Xref_List
     (Comp_Unit         : in ContextManager.UnitDescriptors;
      Node              : in STree.SyntaxNode;
      Ref_Type          : in Character;
      Scope             : in Dictionary.Scopes;
      Subprog_Sym       : in Dictionary.Symbol;
      Full_Package_Name : in Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                Full_Package_Name,
   --#                                LexTokenManager.State,
   --#                                Node,
   --#                                Ref_Type,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                Full_Package_Name,
   --#                                LexTokenManager.State,
   --#                                Node,
   --#                                Ref_Type,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym;
   is
      Prefix_Sym   : Dictionary.Symbol;
      It           : STree.Iterator;
      Current_Node : STree.SyntaxNode;
   begin
      It := STree.Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                   From_Root    => Node,
                                   In_Direction => STree.Down);
      if It /= STree.NullIterator then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => "!!! XREF",
                                 Stop => 0);
         end if;
         Prefix_Sym := Dictionary.NullSymbol;
         while It /= STree.NullIterator loop
            Current_Node := STree.Get_Node (It => It);
            Look_Up
              (Prefix            => Prefix_Sym,
               Scope             => Scope,
               Subprog_Sym       => Subprog_Sym,
               Lex_Str           => STree.Node_Lex_String (Node => Current_Node),
               Pos               => STree.Node_Position (Node => Current_Node),
               Full_Package_Name => Full_Package_Name);
            if not Dictionary.Is_Null_Symbol (Prefix_Sym) then
               Add_Usage (Comp_Unit    => Comp_Unit,
                          Sym          => Prefix_Sym,
                          Current_Node => Current_Node,
                          Ref_Type     => Ref_Type);
               It := STree.NextNode (It => It);
            else
               It := STree.NullIterator;
            end if;
         end loop;
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                               Spacing => 1);
         end if;
      else
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "SLI.GENERATE_XREF_LIST PROGRAM ERROR");
      end if;
   end Generate_Xref_List;

   --  Add cross-reference for the identifier (Node) giving a
   --  procedure/function name (Subprog_Sym) and a scope (Scope). The
   --  identifier is used in the compilation unit (Comp_Unit).
   procedure Generate_Xref_Identifier
     (Comp_Unit         : in ContextManager.UnitDescriptors;
      Node              : in STree.SyntaxNode;
      Scope             : in Dictionary.Scopes;
      Subprog_Sym       : in Dictionary.Symbol;
      Full_Package_Name : in Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                Full_Package_Name,
   --#                                LexTokenManager.State,
   --#                                Node,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                Full_Package_Name,
   --#                                LexTokenManager.State,
   --#                                Node,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym;
   is
      Current_Node : STree.SyntaxNode;
      Sym          : Dictionary.Symbol;
   begin
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                      From_Root    => Node,
                                      In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         Sym := Dictionary.NullSymbol;
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => "!!! XREF",
                                 Stop => 0);
         end if;
         Look_Up
           (Prefix            => Sym,
            Scope             => Scope,
            Subprog_Sym       => Subprog_Sym,
            Lex_Str           => STree.Node_Lex_String (Node => Current_Node),
            Pos               => STree.Node_Position (Node => Current_Node),
            Full_Package_Name => Full_Package_Name);
         if not Dictionary.Is_Null_Symbol (Sym) then
            Add_Usage (Comp_Unit    => Comp_Unit,
                       Sym          => Sym,
                       Current_Node => Current_Node,
                       Ref_Type     => 'r');
         end if;
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                               Spacing => 1);
         end if;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_IDENTIFIER PROGRAM ERROR");
      end if;
   end Generate_Xref_Identifier;

   procedure Generate_Xref_Inherit
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
   begin
      --  XRef for the inherit clause.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node (Node_Kind    => SP_Symbols.inherit_clause,
                                      From_Root    => Parse_Tree,
                                      In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF INHERIT CLAUSE !!!",
                               Stop => 0);
         end if;
         It :=
           STree.Find_First_Node
           (Node_Kind    => SP_Symbols.dotted_simple_name,
            From_Root    => Current_Node,
            In_Direction => STree.Down);
         if It /= STree.NullIterator then
            while It /= STree.NullIterator loop
               --  inherit P ! w ! package P
               Generate_Xref_List
                 (Comp_Unit         => Comp_Unit,
                  Node              => STree.Get_Node (It => It),
                  Ref_Type          => 'w',
                  Scope             => Scope,
                  Subprog_Sym       => Dictionary.NullSymbol,
                  Full_Package_Name => False);
               It := STree.NextNode (It => It);
            end loop;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_INHERIT PROGRAM ERROR");
         end if;
      else
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "SLI.GENERATE_XREF_INHERIT PROGRAM ERROR");
      end if;
   end Generate_Xref_Inherit;

   procedure Generate_Xref_Suspends_Protects
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      It : STree.Iterator;
   begin
      --  XRef for suspends or protects property.
      It :=
        STree.Find_First_Node (Node_Kind    => SP_Symbols.annotation_primary,
                               From_Root    => Parse_Tree,
                               In_Direction => STree.Down);
      if It /= STree.NullIterator then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line
              (File => SPARK_IO.Standard_Output,
               Item => "!!! XREF PROPERTY LIST : SUSPENDS PROTECTS !!!",
               Stop => 0);
         end if;
         while It /= STree.NullIterator loop
            --  declare ... => P...                    ! r ! package P
            --  declare ... => V                       ! r ! [own] V : [in|out] T
            --  own [protected|task] ... (... => P...) ! r ! package P
            --  own [protected|task] ... (... => V)    ! r ! [own] V : [in|out] T
            --  own [protected|task] ... (... => Proc) ! r ! procedure/entry Proc
            --  own [protected|task] ... (... => F)    ! r ! function F
            Generate_Xref_List
              (Comp_Unit         => Comp_Unit,
               Node              => STree.Get_Node (It => It),
               Ref_Type          => 'r',
               Scope             => Scope,
               Subprog_Sym       => Dictionary.NullSymbol,
               Full_Package_Name => False);
            It := STree.NextNode (It => It);
         end loop;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_SUSPENDS_PROTECTS PROGRAM ERROR");
      end if;
   end Generate_Xref_Suspends_Protects;

   procedure Generate_Xref_Interrupt
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      It : STree.Iterator;
   begin
      --  XRef for interrupt property.
      It :=
        STree.Find_First_Node
        (Node_Kind    => SP_Symbols.annotation_aggregate_choice_rep,
         From_Root    => Parse_Tree,
         In_Direction => STree.Down);
      if CommandLineData.Content.Debug.SLI then
         --  Debug
         SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                            Item => "!!! XREF PROPERTY LIST : INTERRUPT !!!",
                            Stop => 0);
      end if;
      while It /= STree.NullIterator loop
         --  declare interrupt => (Proc => ...)                    ! r ! procedure/entry Proc
         --  declare interrupt => (F    => ...)                    ! r ! function F
         --  own [protected|task] ... (interrupt => (Proc => ...)) ! r ! procedure/entry Proc
         --  own [protected|task] ... (interrupt => (F    => ...)) ! r ! function F
         Generate_Xref_Identifier
           (Comp_Unit         => Comp_Unit,
            Node              => STree.Get_Node (It => It),
            Scope             => Scope,
            Subprog_Sym       => Dictionary.NullSymbol,
            Full_Package_Name => False);
         It := STree.NextNode (It => It);
      end loop;
   end Generate_Xref_Interrupt;

   procedure Generate_Xref_Own
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      Current_Node : STree.SyntaxNode;
      Prev_Node    : STree.SyntaxNode;
      Value_Node   : STree.SyntaxNode;
      It           : STree.Iterator;
      It_Id        : STree.Iterator;
      It_Prop      : STree.Iterator;
      Sym          : Dictionary.Symbol;
      PO_Scope     : Dictionary.Scopes;
      Name_Node    : STree.SyntaxNode;
      Name_Str     : E_Strings.T;

   begin
      --  XRef for the own variable clause.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.own_variable_clause,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         Prev_Node := Current_Node;
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF OWN VARIABLE CLAUSE !!!",
                               Stop => 0);
         end if;
         --  XRef for the own variable.
         It :=
           STree.Find_First_Node (Node_Kind    => SP_Symbols.own_variable_list,
                                  From_Root    => Prev_Node,
                                  In_Direction => STree.Down);
         if It /= STree.NullIterator then
            while It /= STree.NullIterator loop
               --# accept F, 41, "Stable expression expected here";
               if CommandLineData.Content.Debug.SLI then
                  --  Debug
                  SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                                     Item => "!!! XREF OWN VARIABLE LIST !!!",
                                     Stop => 0);
               end if;
               --# end accept;
               It_Id :=
                 STree.Find_First_Node
                 (Node_Kind    => SP_Symbols.identifier,
                  From_Root    => STree.Get_Node (It => It),
                  In_Direction => STree.Down);
               if It_Id /= STree.NullIterator then
                  while It_Id /= STree.NullIterator loop
                     --  own [in|out|protected|task] V : T ! o ! V : T
                     --# accept F, 41, "Stable expression expected here";
                     if CommandLineData.Content.Debug.SLI then
                        --  Debug
                        SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                             Item => "!!! XREF",
                                             Stop => 0);
                     end if;
                     --# end accept;
                     Current_Node := STree.Get_Node (It => It_Id);
                     Sym          := Dictionary.NullSymbol;
                     Look_Up
                       (Prefix            => Sym,
                        Scope             => Scope,
                        Subprog_Sym       => Dictionary.NullSymbol,
                        Lex_Str           => STree.Node_Lex_String (Node => Current_Node),
                        Pos               => STree.Node_Position (Node => Current_Node),
                        Full_Package_Name => False);
                     if not Dictionary.Is_Null_Symbol (Sym) then
                        Add_Usage (Comp_Unit    => Comp_Unit,
                                   Sym          => Sym,
                                   Current_Node => Current_Node,
                                   Ref_Type     => 'o');
                     end if;
                     It_Id := STree.NextNode (It => It_Id);
                     --# accept F, 41, "Stable expression expected here";
                     if CommandLineData.Content.Debug.SLI then
                        --  Debug
                        SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                                           Spacing => 1);
                     end if;
                     --# end accept;
                  end loop;
               else
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Other_Internal_Error,
                     Msg     => "SLI.GENERATE_XREF_OWN PROGRAM ERROR");
               end if;

               It := STree.NextNode (It => It);
            end loop;
         else
            SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                      Msg     => "SLI.GENERATE_XREF_OWN PROGRAM ERROR");
         end if;

         --  XRef for the type.
         It := STree.Find_First_Node (Node_Kind    => SP_Symbols.type_mark,
                                      From_Root    => Prev_Node,
                                      In_Direction => STree.Down);
         while It /= STree.NullIterator loop
            --# accept F, 41, "Stable expression expected here";
            if CommandLineData.Content.Debug.SLI then
               --  Debug
               SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                                  Item => "!!! XREF TYPE MARK !!!",
                                  Stop => 0);
            end if;
            --# end accept;
            Current_Node :=
              STree.Get_Node
              (It => STree.Find_First_Node
                 (Node_Kind    => SP_Symbols.dotted_simple_name,
                  From_Root    => STree.Get_Node (It => It),
                  In_Direction => STree.Down));
            if Current_Node /= STree.NullNode then
               --  own ... : P... ! r ! package P
               --  own ... : T    ! r ! [protected|task] type T is ... / type T is abstract
               Generate_Xref_List
                 (Comp_Unit         => Comp_Unit,
                  Node              => Current_Node,
                  Ref_Type          => 'r',
                  Scope             => Scope,
                  Subprog_Sym       => Dictionary.NullSymbol,
                  Full_Package_Name => False);
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Other_Internal_Error,
                  Msg     => "SLI.GENERATE_XREF_OWN PROGRAM ERROR");
            end if;
            It := STree.NextNode (It => It);
         end loop;

         --  XRef for property list.
         It :=
           STree.Find_First_Node
           (Node_Kind    => SP_Symbols.own_variable_specification,
            From_Root    => Prev_Node,
            In_Direction => STree.Down);
         while It /= STree.NullIterator loop
            It_Prop :=
              STree.Find_First_Node
              (Node_Kind    => SP_Symbols.property,
               From_Root    => STree.Get_Node (It => It),
               In_Direction => STree.Down);
            while It_Prop /= STree.NullIterator loop
               Name_Node  :=
                 STree.Child_Node (Current_Node => STree.Child_Node (Current_Node => STree.Get_Node (It => It_Prop)));
               Value_Node := STree.Next_Sibling (Current_Node => Name_Node);
               Name_Str   := LexTokenManager.Lex_String_To_String (Lex_Str => STree.Node_Lex_String (Name_Node));
               if E_Strings.Eq1_String (E_Str => Name_Str,
                                        Str   => "protects") then
                  Current_Node :=
                    STree.Get_Node
                    (It => STree.Find_First_Node
                       (Node_Kind    => SP_Symbols.annotation_primary,
                        From_Root    => Value_Node,
                        In_Direction => STree.Down));
                  if Current_Node /= STree.NullNode then
                     --  Update the scope.
                     Current_Node :=
                       STree.Get_Node
                       (It => STree.Find_First_Node
                          (Node_Kind    => SP_Symbols.type_mark,
                           From_Root    => STree.Get_Node (It => It),
                           In_Direction => STree.Down));
                     --# accept F, 41, "Stable expression expected here";
                     if Current_Node /= STree.NullNode then
                        PO_Scope := Scope;
                        It_Id    :=
                          STree.Find_First_Node
                          (Node_Kind    => SP_Symbols.identifier,
                           From_Root    => Current_Node,
                           In_Direction => STree.Down);
                        while It_Id /= STree.NullIterator loop
                           Sym :=
                             Dictionary.LookupImmediateScope
                             (Name    => STree.Node_Lex_String (Node => STree.Get_Node (It => It_Id)),
                              Scope   => PO_Scope,
                              Context => Dictionary.ProofContext);
                           if not Dictionary.Is_Null_Symbol (Sym) then
                              PO_Scope := Dictionary.Set_Visibility (The_Visibility => Dictionary.Privat,
                                                                     The_Unit       => Sym);
                           else
                              SystemErrors.Fatal_Error
                                (Sys_Err => SystemErrors.Other_Internal_Error,
                                 Msg     => "SLI.GENERATE_XREF_OWN PROGRAM ERROR");
                           end if;
                           It_Id := STree.NextNode (It => It_Id);
                        end loop;
                     else
                        PO_Scope := Scope;
                     end if;
                     --# end accept;
                     Generate_Xref_Suspends_Protects (Comp_Unit  => Comp_Unit,
                                                      Parse_Tree => Value_Node,
                                                      Scope      => PO_Scope);
                  end if;
               elsif E_Strings.Eq1_String (E_Str => Name_Str,
                                           Str   => "interrupt") then
                  Current_Node :=
                    STree.Get_Node
                    (It => STree.Find_First_Node
                       (Node_Kind    => SP_Symbols.annotation_aggregate_choice_rep,
                        From_Root    => Value_Node,
                        In_Direction => STree.Down));
                  if Current_Node /= STree.NullNode then
                     --  Update the scope.
                     Current_Node :=
                       STree.Get_Node
                       (It => STree.Find_First_Node
                          (Node_Kind    => SP_Symbols.type_mark,
                           From_Root    => STree.Get_Node (It => It),
                           In_Direction => STree.Down));
                     --# accept F, 41, "Stable expression expected here";
                     if Current_Node /= STree.NullNode then
                        PO_Scope := Scope;
                        It_Id    :=
                          STree.Find_First_Node
                          (Node_Kind    => SP_Symbols.identifier,
                           From_Root    => Current_Node,
                           In_Direction => STree.Down);
                        while It_Id /= STree.NullIterator loop
                           Sym :=
                             Dictionary.LookupImmediateScope
                             (Name    => STree.Node_Lex_String (Node => STree.Get_Node (It => It_Id)),
                              Scope   => PO_Scope,
                              Context => Dictionary.ProofContext);
                           if not Dictionary.Is_Null_Symbol (Sym) then
                              PO_Scope := Dictionary.Set_Visibility (The_Visibility => Dictionary.Privat,
                                                                     The_Unit       => Sym);
                           else
                              SystemErrors.Fatal_Error
                                (Sys_Err => SystemErrors.Other_Internal_Error,
                                 Msg     => "SLI.GENERATE_XREF_OWN PROGRAM ERROR");
                           end if;
                           It_Id := STree.NextNode (It => It_Id);
                        end loop;
                     else
                        PO_Scope := Scope;
                     end if;
                     --# end accept;
                     Generate_Xref_Interrupt (Comp_Unit  => Comp_Unit,
                                              Parse_Tree => Value_Node,
                                              Scope      => PO_Scope);
                  end if;
               end if;
               It_Prop := STree.NextNode (It => It_Prop);
            end loop;
            It := STree.NextNode (It => It);
         end loop;
      else
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "SLI.GENERATE_XREF_OWN PROGRAM ERROR");
      end if;
   end Generate_Xref_Own;

   procedure Generate_Xref_Refinement
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
      It_Id        : STree.Iterator;
      Sym          : Dictionary.Symbol;
   begin
      --  XRef for the own refinement.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.refinement_definition,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF OWN REFINEMENT DEFINITION !!!",
                               Stop => 0);
         end if;
         It :=
           STree.Find_First_Node
           (Node_Kind    => SP_Symbols.refinement_clause,
            From_Root    => Current_Node,
            In_Direction => STree.Down);
         if It /= STree.NullIterator then
            while It /= STree.NullIterator loop
               --# accept F, 41, "Stable expression expected here";
               if CommandLineData.Content.Debug.SLI then
                  --  Debug
                  SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                                     Item => "!!! XREF OWN REFINEMENT CLAUSE !!!",
                                     Stop => 0);
               end if;
               --# end accept;
               Current_Node :=
                 STree.Get_Node
                 (It => STree.Find_First_Node
                    (Node_Kind    => SP_Symbols.identifier,
                     From_Root    => STree.Get_Node (It => It),
                     In_Direction => STree.Down));
               if Current_Node /= STree.NullNode then
                  --  own S is ... ! c ! own S
                  --# accept F, 41, "Stable expression expected here";
                  if CommandLineData.Content.Debug.SLI then
                     --  Debug
                     SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                          Item => "!!! XREF",
                                          Stop => 0);
                  end if;
                  --# end accept;
                  Sym := Dictionary.NullSymbol;
                  Look_Up
                    (Prefix            => Sym,
                     Scope             => Scope,
                     Subprog_Sym       => Dictionary.NullSymbol,
                     Lex_Str           => STree.Node_Lex_String (Node => Current_Node),
                     Pos               => STree.Node_Position (Node => Current_Node),
                     Full_Package_Name => False);
                  if not Dictionary.Is_Null_Symbol (Sym) then
                     Add_Usage (Comp_Unit    => Comp_Unit,
                                Sym          => Sym,
                                Current_Node => Current_Node,
                                Ref_Type     => 'c');
                  end if;
                  --# accept F, 41, "Stable expression expected here";
                  if CommandLineData.Content.Debug.SLI then
                     --  Debug
                     SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                                        Spacing => 1);
                  end if;
                  --# end accept;
               else
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Other_Internal_Error,
                     Msg     => "SLI.GENERATE_XREF_REFINEMENT PROGRAM ERROR");
               end if;
               It_Id :=
                 STree.Find_First_Node
                 (Node_Kind    => SP_Symbols.dotted_simple_name,
                  From_Root    => STree.Get_Node (It => It),
                  In_Direction => STree.Down);
               if It_Id /= STree.NullIterator then
                  while It_Id /= STree.NullIterator loop
                     --  own ... is [in|out] P... ! o ! package P
                     --  own ... is [in|out] V    ! o ! V : T
                     Generate_Xref_List
                       (Comp_Unit         => Comp_Unit,
                        Node              => STree.Get_Node (It => It_Id),
                        Ref_Type          => 'o',
                        Scope             => Scope,
                        Subprog_Sym       => Dictionary.NullSymbol,
                        Full_Package_Name => False);
                     It_Id := STree.NextNode (It => It_Id);
                  end loop;
               else
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Other_Internal_Error,
                     Msg     => "SLI.GENERATE_XREF_REFINEMENT PROGRAM ERROR");
               end if;
               It := STree.NextNode (It => It);
            end loop;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_REFINEMENT PROGRAM ERROR");
         end if;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_REFINEMENT PROGRAM ERROR");
      end if;
   end Generate_Xref_Refinement;

   procedure Generate_Xref_Initializes
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
      Sym          : Dictionary.Symbol;
   begin
      --  XRef for the initializes.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.initialization_specification,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF INITIALIZATION_SPECIFICATION !!!",
                               Stop => 0);
         end if;
         It := STree.Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                      From_Root    => Current_Node,
                                      In_Direction => STree.Down);
         if It /= STree.NullIterator then
            while It /= STree.NullIterator loop
               --  initializes S ! r ! own S
               --  initializes V ! r ! V : T
               --# accept F, 41, "Stable expression expected here";
               if CommandLineData.Content.Debug.SLI then
                  --  Debug
                  SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                       Item => "!!! XREF",
                                       Stop => 0);
               end if;
               --# end accept;
               Current_Node := STree.Get_Node (It => It);
               Sym          := Dictionary.NullSymbol;
               Look_Up
                 (Prefix            => Sym,
                  Scope             => Scope,
                  Subprog_Sym       => Dictionary.NullSymbol,
                  Lex_Str           => STree.Node_Lex_String (Node => Current_Node),
                  Pos               => STree.Node_Position (Node => Current_Node),
                  Full_Package_Name => False);
               if not Dictionary.Is_Null_Symbol (Sym) then
                  Add_Usage (Comp_Unit    => Comp_Unit,
                             Sym          => Sym,
                             Current_Node => Current_Node,
                             Ref_Type     => 'r');
               end if;
               It := STree.NextNode (It => It);
               --# accept F, 41, "Stable expression expected here";
               if CommandLineData.Content.Debug.SLI then
                  --  Debug
                  SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                                     Spacing => 1);
               end if;
               --# end accept;
            end loop;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_INITIALIZES PROGRAM ERROR");
         end if;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_INITIALIZES PROGRAM ERROR");
      end if;
   end Generate_Xref_Initializes;

   procedure Generate_Xref_Global
     (Comp_Unit   : in ContextManager.UnitDescriptors;
      Parse_Tree  : in STree.SyntaxNode;
      Scope       : in Dictionary.Scopes;
      Subprog_Sym : in Dictionary.Symbol)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
      It_Id        : STree.Iterator;
      Mode         : Dictionary.Modes;
   begin
      --  XRef for the globals.
      It :=
        STree.Find_First_Node
        (Node_Kind    => SP_Symbols.global_variable_clause,
         From_Root    => Parse_Tree,
         In_Direction => STree.Down);
      if It /= STree.NullIterator then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF GLOBAL VARIABLE CLAUSE !!!",
                               Stop => 0);
         end if;
         while It /= STree.NullIterator loop

            Current_Node :=
              STree.Child_Node
              (Current_Node => STree.Get_Node
                 (It => STree.Find_First_Node
                    (Node_Kind    => SP_Symbols.mode,
                     From_Root    => STree.Get_Node (It => It),
                     In_Direction => STree.Down)));
            --  Get the mode (in/out/in out) of the global.
            if Current_Node /= STree.NullNode then
               if STree.Syntax_Node_Type (Node => Current_Node) = SP_Symbols.in_mode then
                  Mode := Dictionary.InMode;
               elsif STree.Syntax_Node_Type (Node => Current_Node) = SP_Symbols.inout_mode then
                  Mode := Dictionary.InOutMode;
               elsif STree.Syntax_Node_Type (Node => Current_Node) = SP_Symbols.out_mode then
                  Mode := Dictionary.OutMode;
               else
                  Mode := Dictionary.InvalidMode;
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Other_Internal_Error,
                     Msg     => "SLI.GENERATE_XREF_GLOBAL PROGRAM ERROR");
               end if;
            else
               --  Limitation will assume IN as default mode. No
               --  consequence for cross-references.
               Mode := Dictionary.DefaultMode;
            end if;

            It_Id :=
              STree.Find_First_Node
              (Node_Kind    => SP_Symbols.dotted_simple_name,
               From_Root    => STree.Get_Node (It => It),
               In_Direction => STree.Down);
            if It_Id /= STree.NullIterator then
               while It_Id /= STree.NullIterator loop
                  --  global [in|out] P... ! r ! package P
                  --  global [in|out] S    ! r ! own S
                  --  global [in|out] V    ! r ! [own] V : [in|out] T / {protected|task} type V is ...
                  Generate_Xref_List
                    (Comp_Unit         => Comp_Unit,
                     Node              => STree.Get_Node (It => It_Id),
                     Ref_Type          => 'r',
                     Scope             => Scope,
                     Subprog_Sym       => Dictionary.NullSymbol,
                     Full_Package_Name => False);
                  --  global [in|out] S    ! >/=/< ! procedure/entry Proc
                  --  global [in|out] V    ! >/=/< ! procedure/entry Proc
                  --  global [in|out] S    ! >     ! function F
                  --  global [in|out] V    ! >     ! function F
                  --# accept F, 41, "Stable expression expected here";
                  if CommandLineData.Content.Debug.SLI then
                     --  Debug
                     SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                          Item => "!!! XREF",
                                          Stop => 0);
                  end if;
                  --# end accept;

                  --# accept Flow, 41, "Expected stable expression";
                  if Mode = Dictionary.InMode or Mode = Dictionary.DefaultMode then
                     Add_Usage
                       (Comp_Unit    => Comp_Unit,
                        Sym          => Subprog_Sym,
                        Current_Node => STree.Last_Sibling_Of (Start_Node => STree.Child_Node (Current_Node => STree.Get_Node (It => It_Id))),
                        Ref_Type     => '>');
                  elsif Mode = Dictionary.InOutMode then
                     Add_Usage
                       (Comp_Unit    => Comp_Unit,
                        Sym          => Subprog_Sym,
                        Current_Node => STree.Last_Sibling_Of (Start_Node => STree.Child_Node (Current_Node => STree.Get_Node (It => It_Id))),
                        Ref_Type     => '=');
                  elsif Mode = Dictionary.OutMode then
                     Add_Usage
                       (Comp_Unit    => Comp_Unit,
                        Sym          => Subprog_Sym,
                        Current_Node => STree.Last_Sibling_Of (Start_Node => STree.Child_Node (Current_Node => STree.Get_Node (It => It_Id))),
                        Ref_Type     => '<');
                  end if;
                  --# end accept;

                  --# accept F, 41, "Stable expression expected here";
                  if CommandLineData.Content.Debug.SLI then
                     --  Debug
                     SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                                        Spacing => 1);
                  end if;
                  --# end accept;

                  It_Id := STree.NextNode (It => It_Id);
               end loop;
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Other_Internal_Error,
                  Msg     => "SLI.GENERATE_XREF_GLOBAL PROGRAM ERROR");
            end if;

            It := STree.NextNode (It => It);
         end loop;
      else
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "SLI.GENERATE_XREF_GLOBAL PROGRAM ERROR");
      end if;
   end Generate_Xref_Global;

   procedure Generate_Xref_Derives
     (Comp_Unit   : in ContextManager.UnitDescriptors;
      Parse_Tree  : in STree.SyntaxNode;
      Scope       : in Dictionary.Scopes;
      Subprog_Sym : in Dictionary.Symbol)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
      It_Id        : STree.Iterator;
   begin
      --  XRef for the derives.
      if CommandLineData.Content.Debug.SLI then
         --  Debug
         SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                            Item => "!!! XREF GLOBAL DEPENDENCY CLAUSE !!!",
                            Stop => 0);
      end if;
      It := STree.Find_First_Node (Node_Kind    => SP_Symbols.dependency_clause,
                                   From_Root    => Parse_Tree,
                                   In_Direction => STree.Down);
      while It /= STree.NullIterator loop

         --  XRef for the derives before the 'from'.
         Current_Node := STree.Child_Node (Current_Node => STree.Get_Node (It => It));
         if Current_Node /= STree.NullNode then
            It_Id :=
              STree.Find_First_Node
              (Node_Kind    => SP_Symbols.dotted_simple_name,
               From_Root    => Current_Node,
               In_Direction => STree.Down);
            if It_Id /= STree.NullIterator then
               while It_Id /= STree.NullIterator loop
                  --  derives P... from ... ! m ! package P
                  --  derives S    from ... ! m ! own S
                  --  derives V    from ... ! m ! [own] V : [in|out] T/{protected|task} type V is ...
                  Generate_Xref_List
                    (Comp_Unit         => Comp_Unit,
                     Node              => STree.Get_Node (It => It_Id),
                     Ref_Type          => 'm',
                     Scope             => Scope,
                     Subprog_Sym       => Subprog_Sym,
                     Full_Package_Name => False);
                  It_Id := STree.NextNode (It => It_Id);
               end loop;
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Other_Internal_Error,
                  Msg     => "SLI.GENERATE_XREF_DERIVES PROGRAM ERROR");
            end if;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_DERIVES PROGRAM ERROR");
         end if;

         --  XRef for the derives after the 'from'.
         Current_Node :=
           STree.Get_Node
           (It => STree.Find_First_Node
              (Node_Kind    => SP_Symbols.dependency_clause_opt,
               From_Root    => STree.Get_Node (It => It),
               In_Direction => STree.Down));
         if Current_Node /= STree.NullNode then
            It_Id :=
              STree.Find_First_Node
              (Node_Kind    => SP_Symbols.dotted_simple_name,
               From_Root    => Current_Node,
               In_Direction => STree.Down);
            while It_Id /= STree.NullIterator loop
               --  derives ... from P... ! r ! package P
               --  derives ... from S    ! r ! own S
               --  derives ... from V    ! r ! [own] V : [in|out] T/{protected|task} type V is ...
               Generate_Xref_List
                 (Comp_Unit         => Comp_Unit,
                  Node              => STree.Get_Node (It => It_Id),
                  Ref_Type          => 'r',
                  Scope             => Scope,
                  Subprog_Sym       => Subprog_Sym,
                  Full_Package_Name => False);
               It_Id := STree.NextNode (It => It_Id);
            end loop;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_DERIVES PROGRAM ERROR");
         end if;

         It := STree.NextNode (It => It);
      end loop;

      --  XRef for null import list.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.null_import_list,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         --  XRef for the derives after the 'from'.
         Current_Node :=
           STree.Get_Node
           (It => STree.Find_First_Node
              (Node_Kind    => SP_Symbols.dependency_clause_optrep,
               From_Root    => Current_Node,
               In_Direction => STree.Down));
         if Current_Node /= STree.NullNode then
            It_Id :=
              STree.Find_First_Node
              (Node_Kind    => SP_Symbols.dotted_simple_name,
               From_Root    => Current_Node,
               In_Direction => STree.Down);
            while It_Id /= STree.NullIterator loop
               --  derives null from P... ! r ! package P
               --  derives null from S    ! r ! own S
               --  derives null from V    ! r ! [own] V : [in|out] T/{protected|task} type V is ...
               Generate_Xref_List
                 (Comp_Unit         => Comp_Unit,
                  Node              => STree.Get_Node (It => It_Id),
                  Ref_Type          => 'r',
                  Scope             => Scope,
                  Subprog_Sym       => Subprog_Sym,
                  Full_Package_Name => False);
               It_Id := STree.NextNode (It => It_Id);
            end loop;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_DERIVES PROGRAM ERROR");
         end if;
      end if;

   end Generate_Xref_Derives;

   procedure Generate_Xref_Justification
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
   begin
      --  XRef for the justification clause.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.justification_statement,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF JUSTIFICATION CLAUSE !!!",
                               Stop => 0);
         end if;
         It :=
           STree.Find_First_Node
           (Node_Kind    => SP_Symbols.dotted_simple_name,
            From_Root    => Current_Node,
            In_Direction => STree.Down);
         while It /= STree.NullIterator loop
            --  accept P ! r ! package P
            --  accept V ! r ! [own] V : [in|out] T
            --  accept T ! r ! [protected|task] type T is ...
            Generate_Xref_List
              (Comp_Unit         => Comp_Unit,
               Node              => STree.Get_Node (It => It),
               Ref_Type          => 'r',
               Scope             => Scope,
               Subprog_Sym       => Dictionary.NullSymbol,
               Full_Package_Name => False);
            It := STree.NextNode (It => It);
         end loop;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_JUSTIFICATION PROGRAM ERROR");
      end if;
   end Generate_Xref_Justification;

   procedure Generate_Xref_Proof_Function
     (Comp_Unit   : in ContextManager.UnitDescriptors;
      Parse_Tree  : in STree.SyntaxNode;
      Scope       : in Dictionary.Scopes;
      Subprog_Sym : in Dictionary.Symbol)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Subprog_Sym;
   is
      Top_Node     : STree.SyntaxNode;
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
      It_Id        : STree.Iterator;
   begin
      --  XRef for the proof function.
      Top_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.function_specification,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Top_Node /= STree.NullNode then
         Current_Node :=
           STree.Get_Node
           (It => STree.Find_First_Node (Node_Kind    => SP_Symbols.formal_part,
                                         From_Root    => Top_Node,
                                         In_Direction => STree.Down));
         if Current_Node /= STree.NullNode then

            --  XRef for the formal parameters of a proof function.
            if CommandLineData.Content.Debug.SLI then
               --  Debug
               SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                                  Item => "!!! XREF FORMAL PARAMETERS !!!",
                                  Stop => 0);
            end if;
            It :=
              STree.Find_First_Node
              (Node_Kind    => SP_Symbols.parameter_specification,
               From_Root    => Current_Node,
               In_Direction => STree.Down);
            if It /= STree.NullIterator then
               while It /= STree.NullIterator loop

                  --  XRef for the formal parameter name.
                  Current_Node := STree.Child_Node (Current_Node => STree.Get_Node (It => It));
                  if Current_Node /= STree.NullNode then

                     --# accept F, 41, "Stable expression expected here";
                     if CommandLineData.Content.Debug.SLI then
                        --  Debug
                        SPARK_IO.Put_Line
                          (File => SPARK_IO.Standard_Output,
                           Item => "!!! XREF FORMAL PARAMETER NAMES !!!",
                           Stop => 0);
                     end if;
                     --# end accept;

                     It_Id :=
                       STree.Find_First_Node
                       (Node_Kind    => SP_Symbols.identifier,
                        From_Root    => Current_Node,
                        In_Direction => STree.Down);
                     if It_Id /= STree.NullIterator then
                        while It_Id /= STree.NullIterator loop

                           --# accept F, 41, "Stable expression expected here";
                           if CommandLineData.Content.Debug.SLI then
                              --  Debug
                              SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                                   Item => "!!! XREF",
                                                   Stop => 0);
                           end if;
                           --# end accept;

                           --  function F (V : ...) return ... ! > ! function F
                           Add_Usage
                             (Comp_Unit    => Comp_Unit,
                              Sym          => Subprog_Sym,
                              Current_Node => STree.Get_Node (It => It_Id),
                              Ref_Type     => '>');

                           --# accept F, 41, "Stable expression expected here";
                           if CommandLineData.Content.Debug.SLI then
                              --  Debug
                              SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                                                 Spacing => 1);
                           end if;
                           --# end accept;

                           It_Id := STree.NextNode (It => It_Id);
                        end loop;
                     else
                        SystemErrors.Fatal_Error
                          (Sys_Err => SystemErrors.Other_Internal_Error,
                           Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
                     end if;
                  else
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Other_Internal_Error,
                        Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
                  end if;

                  --  XRef for the formal parameter type.
                  Current_Node :=
                    STree.Get_Node
                    (It => STree.Find_First_Node
                       (Node_Kind    => SP_Symbols.dotted_simple_name,
                        From_Root    => STree.Last_Sibling_Of (Start_Node => Current_Node),
                        In_Direction => STree.Down));
                  if Current_Node /= STree.NullNode then

                     --# accept F, 41, "Stable expression expected here";
                     if CommandLineData.Content.Debug.SLI then
                        --  Debug
                        SPARK_IO.Put_Line
                          (File => SPARK_IO.Standard_Output,
                           Item => "!!! XREF FORMAL PARAMETER TYPE !!!",
                           Stop => 0);
                     end if;
                     --# end accept;

                     --  function ... (... : P...) return ... ! r ! package P
                     --  function ... (... : T) return ...    ! r ! type T is ...
                     Generate_Xref_List
                       (Comp_Unit         => Comp_Unit,
                        Node              => Current_Node,
                        Ref_Type          => 'r',
                        Scope             => Scope,
                        Subprog_Sym       => Dictionary.NullSymbol,
                        Full_Package_Name => False);
                  else
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Other_Internal_Error,
                        Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
                  end if;

                  It := STree.NextNode (It => It);
               end loop;
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Other_Internal_Error,
                  Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
            end if;
         end if;

         Current_Node := STree.Last_Sibling_Of (Start_Node => STree.Child_Node (Current_Node => Top_Node));
         if Current_Node /= STree.NullNode then
            if CommandLineData.Content.Debug.SLI then
               --  Debug
               SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                                  Item => "!!! XREF RETURN TYPE !!!",
                                  Stop => 0);
            end if;
            Current_Node :=
              STree.Get_Node
              (It => STree.Find_First_Node
                 (Node_Kind    => SP_Symbols.dotted_simple_name,
                  From_Root    => Current_Node,
                  In_Direction => STree.Down));
            if Current_Node /= STree.NullNode then
               --  function ... (... : ...) return P... ! r ! package P
               --  function ... (... : ...) return T    ! r ! type T is ...
               Generate_Xref_List
                 (Comp_Unit         => Comp_Unit,
                  Node              => Current_Node,
                  Ref_Type          => 'r',
                  Scope             => Scope,
                  Subprog_Sym       => Dictionary.NullSymbol,
                  Full_Package_Name => False);
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Other_Internal_Error,
                  Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
            end if;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
         end if;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_PROOF_FUNCTION PROGRAM ERROR");
      end if;
   end Generate_Xref_Proof_Function;

   procedure Generate_Xref_Object_Assertion
     (Comp_Unit  : in ContextManager.UnitDescriptors;
      Parse_Tree : in STree.SyntaxNode;
      Scope      : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                Scope,
   --#                                STree.Table;
   is
      Current_Node : STree.SyntaxNode;
      It           : STree.Iterator;
   begin
      --  XRef for the object assertion.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node
           (Node_Kind    => SP_Symbols.object_assertion,
            From_Root    => Parse_Tree,
            In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         It :=
           STree.Find_First_Node
           (Node_Kind    => SP_Symbols.dotted_simple_name,
            From_Root    => STree.Child_Node (Current_Node => Current_Node),
            In_Direction => STree.Down);
         if It /= STree.NullIterator then
            while It /= STree.NullIterator loop
               --  for P... declare [rule|norule] ! r ! package P
               --  for V declare [rule|norule]    ! r ! V : const T := ...
               Generate_Xref_List
                 (Comp_Unit         => Comp_Unit,
                  Node              => STree.Get_Node (It => It),
                  Ref_Type          => 'r',
                  Scope             => Scope,
                  Subprog_Sym       => Dictionary.NullSymbol,
                  Full_Package_Name => False);
               It := STree.NextNode (It => It);
            end loop;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Other_Internal_Error,
               Msg     => "SLI.GENERATE_XREF_OBJECT_ASSERTION PROGRAM ERROR");
         end if;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.GENERATE_XREF_OBJECT_ASSERTION PROGRAM ERROR");
      end if;
   end Generate_Xref_Object_Assertion;

   procedure Generate_Xref_Symbol
     (Comp_Unit      : in ContextManager.UnitDescriptors;
      Parse_Tree     : in STree.SyntaxNode;
      Symbol         : in Dictionary.Symbol;
      Is_Declaration : in Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.File_Heap,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                Is_Declaration,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                STree.Table,
   --#                                Symbol,
   --#                                Xref.State &
   --#         Xref.State        from *,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                Dictionary.Dict,
   --#                                Is_Declaration,
   --#                                Parse_Tree,
   --#                                STree.Table,
   --#                                Symbol;
   is
      Current_Node : STree.SyntaxNode;
   begin
      -- XRef for the precondition
      -- XRef for the postcondition
      -- XRef for the return
      -- XRef for the assert
      -- XRef for the check

      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                      From_Root    => Parse_Tree,
                                      In_Direction => STree.Down));
      if Current_Node /= STree.NullNode then
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => "!!! XREF PREDICATE !!!",
                               Stop => 0);
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => "!!! XREF",
                                 Stop => 0);
         end if;

         -- pre ... P ...    ! r ! package P
         -- pre ... F ...    ! r ! function F
         -- pre ... S ...    ! r ! own S
         -- pre ... V ...    ! r ! [own] V : [in|out] T
         -- pre ... T ...    ! r ! [protected|task] type T is ...
         -- post ... P ...   ! r ! package P
         -- post ... F ...   ! r ! function F
         -- post ... S ...   ! r ! own S
         -- post ... V ...   ! r ! [own] V : [in|out] T
         -- post ... T ...   ! r ! [protected|task] type T is ...
         -- return ... P ... ! r ! package P
         -- return ... F ... ! r ! function F
         -- return ... S ... ! r ! own S
         -- return ... V ... ! r ! [own] V : [in|out] T
         -- return ... T ... ! r ! [protected|task] type T is ...
         -- assert ... P ... ! r ! package P
         -- assert ... F ... ! r ! function F
         -- assert ... S ... ! r ! own S
         -- assert ... V ... ! r ! [own] V : [in|out] T
         -- assert ... T ... ! r ! [protected|task] type T is ...
         -- check ... P ...  ! r ! package P
         -- check ... F ...  ! r ! function F
         -- check ... S ...  ! r ! own S
         -- check ... V ...  ! r ! [own] V : [in|out] T
         -- check ... T ...  ! r ! [protected|task] type T is ...
         -- V : ...          ! O ! own V : ...
         -- type T is ...    ! O ! own ... : T
         if Is_Declaration then
            Add_Usage (Comp_Unit    => Comp_Unit,
                       Sym          => Symbol,
                       Current_Node => Current_Node,
                       Ref_Type     => 'O');
         else
            Add_Usage (Comp_Unit    => Comp_Unit,
                       Sym          => Symbol,
                       Current_Node => Current_Node,
                       Ref_Type     => 'r');
         end if;
         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.New_Line (File    => SPARK_IO.Standard_Output,
                               Spacing => 1);
         end if;
      else
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                   Msg     => "SLI.GENERATE_XREF_SYMBOL PROGRAM ERROR");
      end if;
   end Generate_Xref_Symbol;

   procedure Cleanup
   --# global in out Xref.State;
   --# derives Xref.State from *;
   is
   begin
      Xref.Cleanup_Decl_Comp_Unit;
   end Cleanup;

   procedure Increment_Nb_Separates (Comp_Unit  : in ContextManager.UnitDescriptors;
                                     Parse_Tree : in STree.SyntaxNode)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Xref.State;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content,
   --#                                Comp_Unit,
   --#                                ContextManager.Ops.Unit_Heap,
   --#                                LexTokenManager.State,
   --#                                Parse_Tree,
   --#                                STree.Table &
   --#         Xref.State        from *,
   --#                                Comp_Unit,
   --#                                Parse_Tree,
   --#                                STree.Table;
   is
      Current_Node    : STree.SyntaxNode;
      Unit_Name       : LexTokenLists.Lists;
      Dummy_Unit_Type : ContextManager.UnitTypes;
      Lex_Str         : LexTokenManager.Lex_String;

   begin
      --  Count number of separates.
      Current_Node :=
        STree.Get_Node
        (It => STree.Find_First_Node (Node_Kind    => SP_Symbols.body_stub,
                                      From_Root    => Parse_Tree,
                                      In_Direction => STree.Down));
      --  Try to find if the SP_Symbols.body_stub is a separate. The
      --  keyword "separate" (SP_Symbols.RWseparate) is not kept into
      --  the tree. But, from the SPARK.LLA file, if the last child is
      --  a pragma (SP_Symbols.apragma) then it is never a separate.
      if Current_Node /= STree.NullNode
        and then STree.Syntax_Node_Type (Node => STree.Last_Child_Of (Start_Node => Current_Node)) /= SP_Symbols.apragma then

         if CommandLineData.Content.Debug.SLI then
            --  Debug
            SPARK_IO.Put_String (File => SPARK_IO.Standard_Output,
                                 Item => "!!! ADD SEPARATE IN ",
                                 Stop => 0);
            --# accept F, 10, Dummy_Unit_Type, "Ineffective assignment here OK";
            ContextManager.Ops.GetUnitName (Descriptor => Comp_Unit,
                                            UnitName   => Unit_Name,
                                            UnitType   => Dummy_Unit_Type);
            --# end accept;
            LexTokenLists.Print_List (File => SPARK_IO.Standard_Output,
                                      List => Unit_Name);
            SPARK_IO.Put_Char (File => SPARK_IO.Standard_Output,
                               Item => '.');
            Current_Node :=
              STree.Get_Node
              (It => STree.Find_First_Node
                 (Node_Kind    => SP_Symbols.identifier,
                  From_Root    => Parse_Tree,
                  In_Direction => STree.Down));
            if Current_Node /= STree.NullNode then
               Lex_Str := STree.Node_Lex_String (Node => Current_Node);
               E_Strings.Put_String
                 (File  => SPARK_IO.Standard_Output,
                  E_Str => LexTokenManager.Lex_String_To_String (Lex_Str => Lex_Str));
            end if;
            SPARK_IO.Put_Line (File => SPARK_IO.Standard_Output,
                               Item => " !!!",
                               Stop => 0);
         end if;
         Xref.Increment_Nb_Separates (Comp_Unit => Comp_Unit);
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Other_Internal_Error,
            Msg     => "SLI.INCREMENT_NB_SEPARATES PROGRAM ERROR");
      end if;
      --# accept F, 33,Dummy_Unit_Type, "Dummy_Unit_Type not referenced here";
   end Increment_Nb_Separates;

end SLI;
