-------------------------------------------------------------------------------
-- (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.
--
--=============================================================================

separate (Dictionary)
procedure Add_Renaming_Declaration
  (The_Subprogram : in RawDict.Subprogram_Info_Ref;
   The_Operator   : in RawDict.Operator_Info_Ref;
   Comp_Unit      : in ContextManager.UnitDescriptors;
   Declaration    : in Location;
   Scope          : in Scopes) is

   Region          : Symbol;
   The_Declaration : RawDict.Declaration_Info_Ref;

   --------------------------------------------------------------------------------

   procedure Add_Renaming_Declaration_To_Subprogram
     (The_Declaration : in RawDict.Declaration_Info_Ref;
      The_Subprogram  : in RawDict.Subprogram_Info_Ref)
   --# global in out Dict;
   --# derives Dict from *,
   --#                   The_Declaration,
   --#                   The_Subprogram;
   is
   begin
      RawDict.Set_Next_Declaration
        (The_Declaration => The_Declaration,
         Next            => RawDict.Get_Subprogram_Renaming_Declarations (The_Subprogram => The_Subprogram));
      RawDict.Set_Subprogram_Renaming_Declarations (The_Subprogram  => The_Subprogram,
                                                    The_Declaration => The_Declaration);
   end Add_Renaming_Declaration_To_Subprogram;

   --------------------------------------------------------------------------------

   procedure Add_Renaming_Declaration_To_Package (The_Declaration : in RawDict.Declaration_Info_Ref;
                                                  Scope           : in Scopes)
   --# global in out Dict;
   --# derives Dict from *,
   --#                   Scope,
   --#                   The_Declaration;
   is
      The_Package : RawDict.Package_Info_Ref;

      --------------------------------------------------------------------------------

      procedure Add_Renaming_Declaration_To_Package_Specification
        (The_Declaration : in RawDict.Declaration_Info_Ref;
         The_Package     : in RawDict.Package_Info_Ref)
      --# global in out Dict;
      --# derives Dict from *,
      --#                   The_Declaration,
      --#                   The_Package;
      is
      begin
         RawDict.Set_Next_Declaration
           (The_Declaration => The_Declaration,
            Next            => RawDict.Get_Package_Visible_Renaming_Declarations (The_Package => The_Package));
         RawDict.Set_Package_Visible_Renaming_Declarations (The_Package     => The_Package,
                                                            The_Declaration => The_Declaration);
      end Add_Renaming_Declaration_To_Package_Specification;

      --------------------------------------------------------------------------------

      procedure Add_Renaming_Declaration_To_Package_Body
        (The_Declaration : in RawDict.Declaration_Info_Ref;
         The_Package     : in RawDict.Package_Info_Ref)
      --# global in out Dict;
      --# derives Dict from *,
      --#                   The_Declaration,
      --#                   The_Package;
      is
      begin
         RawDict.Set_Next_Declaration
           (The_Declaration => The_Declaration,
            Next            => RawDict.Get_Package_Local_Renaming_Declarations (The_Package => The_Package));
         RawDict.Set_Package_Local_Renaming_Declarations (The_Package     => The_Package,
                                                          The_Declaration => The_Declaration);
      end Add_Renaming_Declaration_To_Package_Body;

   begin -- Add_Renaming_Declaration_To_Package
      The_Package := RawDict.Get_Package_Info_Ref (GetRegion (Scope));
      case Get_Visibility (Scope => Scope) is
         when Visible =>
            Add_Renaming_Declaration_To_Package_Specification (The_Declaration => The_Declaration,
                                                               The_Package     => The_Package);
         when Local =>
            Add_Renaming_Declaration_To_Package_Body (The_Declaration => The_Declaration,
                                                      The_Package     => The_Package);
         when Privat =>
            null;
      end case;
   end Add_Renaming_Declaration_To_Package;

begin -- Add_Renaming_Declaration
   RawDict.Create_Declaration
     (Context         => ProgramContext,
      Scope           => Scope,
      Comp_Unit       => Comp_Unit,
      Loc             => Declaration.Start_Position,
      The_Declaration => The_Declaration);
   if The_Subprogram /= RawDict.Null_Subprogram_Info_Ref and then The_Operator = RawDict.Null_Operator_Info_Ref then
      RawDict.Set_Declaration_Item (The_Declaration => The_Declaration,
                                    Item            => RawDict.Get_Subprogram_Symbol (The_Subprogram));
   elsif The_Subprogram = RawDict.Null_Subprogram_Info_Ref and then The_Operator /= RawDict.Null_Operator_Info_Ref then
      RawDict.Set_Declaration_Item (The_Declaration => The_Declaration,
                                    Item            => RawDict.Get_Operator_Symbol (The_Operator));
   else
      SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                                Msg     => "in Dictionary.Add_Renaming_Declaration");
   end if;
   Region := GetRegion (Scope);
   case RawDict.GetSymbolDiscriminant (Region) is
      when Package_Symbol =>
         Add_Renaming_Declaration_To_Package (The_Declaration => The_Declaration,
                                              Scope           => Scope);
      when Subprogram_Symbol =>
         Add_Renaming_Declaration_To_Subprogram
           (The_Declaration => The_Declaration,
            The_Subprogram  => RawDict.Get_Subprogram_Info_Ref (Item => Region));
      when others => -- non-exec code
         SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Invalid_Symbol_Table,
                                   Msg     => "in Dictionary.Add_Renaming_Declaration");
   end case;
end Add_Renaming_Declaration;
