-------------------------------------------------------------------------------
-- (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)
function Is_Renamed_Local (The_Subprogram : RawDict.Subprogram_Info_Ref;
                           Scope          : Scopes) return Boolean is
   Current_Scope : Scopes;
   Region        : Symbol;
   Found         : Boolean;

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

   function Is_Renamed_In_This_Scope (The_Subprogram : RawDict.Subprogram_Info_Ref;
                                      Scope          : Scopes) return Boolean
   --# global in Dict;
   is
      Region : Symbol;
      Found  : Boolean;

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

      function Search_Renaming_Declarations
        (The_Subprogram : RawDict.Subprogram_Info_Ref;
         Declarations   : RawDict.Declaration_Info_Ref)
        return           Boolean
      --# global in Dict;
      is
         Current_Declaration : RawDict.Declaration_Info_Ref;
      begin
         Current_Declaration := Declarations;
         while Current_Declaration /= RawDict.Null_Declaration_Info_Ref
           and then (RawDict.GetSymbolDiscriminant (RawDict.Get_Declaration_Item (The_Declaration => Current_Declaration)) /=
                       Subprogram_Symbol
                       or else RawDict.Get_Subprogram_Info_Ref
                       (Item => RawDict.Get_Declaration_Item (The_Declaration => Current_Declaration)) /=
                       The_Subprogram) loop
            Current_Declaration := RawDict.Get_Next_Declaration (The_Declaration => Current_Declaration);
         end loop;
         return Current_Declaration /= RawDict.Null_Declaration_Info_Ref;
      end Search_Renaming_Declarations;

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

      function Is_Renamed_In_This_Package_Specification
        (The_Subprogram : RawDict.Subprogram_Info_Ref;
         The_Package    : RawDict.Package_Info_Ref)
        return           Boolean
      --# global in Dict;
      is
      begin
         return Search_Renaming_Declarations
           (The_Subprogram => The_Subprogram,
            Declarations   => RawDict.Get_Package_Visible_Renaming_Declarations (The_Package => The_Package));
      end Is_Renamed_In_This_Package_Specification;

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

      function Is_Renamed_In_This_Package_Body
        (The_Subprogram : RawDict.Subprogram_Info_Ref;
         The_Package    : RawDict.Package_Info_Ref)
        return           Boolean
      --# global in Dict;
      is
      begin
         return Search_Renaming_Declarations
           (The_Subprogram => The_Subprogram,
            Declarations   => RawDict.Get_Package_Local_Renaming_Declarations (The_Package => The_Package));
      end Is_Renamed_In_This_Package_Body;

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

      function Is_Renamed_In_This_Subprogram
        (Subprogram     : RawDict.Subprogram_Info_Ref;
         The_Subprogram : RawDict.Subprogram_Info_Ref)
        return           Boolean
      --# global in Dict;
      is
      begin
         return Search_Renaming_Declarations
           (The_Subprogram => Subprogram,
            Declarations   => RawDict.Get_Subprogram_Renaming_Declarations (The_Subprogram => The_Subprogram));
      end Is_Renamed_In_This_Subprogram;

   begin -- Is_Renamed_In_This_Scope
      Region := GetRegion (Scope);
      case RawDict.GetSymbolDiscriminant (Region) is
         when Package_Symbol =>
            case Get_Visibility (Scope => Scope) is
               when Visible | Privat =>
                  Found :=
                    Is_Renamed_In_This_Package_Specification
                    (The_Subprogram => The_Subprogram,
                     The_Package    => RawDict.Get_Package_Info_Ref (Item => Region));
               when Local =>
                  Found :=
                    Is_Renamed_In_This_Package_Body
                    (The_Subprogram => The_Subprogram,
                     The_Package    => RawDict.Get_Package_Info_Ref (Item => Region))
                    or else Is_Renamed_In_This_Package_Specification
                    (The_Subprogram => The_Subprogram,
                     The_Package    => RawDict.Get_Package_Info_Ref (Item => Region));
            end case;
         when Subprogram_Symbol =>
            Found :=
              Is_Renamed_In_This_Subprogram
              (Subprogram     => The_Subprogram,
               The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Region));
         when others =>
            Found := False;
      end case;
      return Found;
   end Is_Renamed_In_This_Scope;

begin -- Is_Renamed_Local
   Current_Scope := Scope;
   loop
      Found  := Is_Renamed_In_This_Scope (The_Subprogram => The_Subprogram,
                                          Scope          => Current_Scope);
      Region := GetRegion (Current_Scope);
      exit when Found
        or else RawDict.GetSymbolDiscriminant (Region) = Package_Symbol
        or else (RawDict.GetSymbolDiscriminant (Region) = Subprogram_Symbol
                   and then Is_Main_Program (The_Subprogram => RawDict.Get_Subprogram_Info_Ref (Item => Region)));
      Current_Scope := GetEnclosingScope (Current_Scope);
   end loop;
   return Found;
end Is_Renamed_Local;
