-------------------------------------------------------------------------------
-- (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 E_Strings;

separate (Sem)
procedure Wf_Renaming_Declaration (Node  : in STree.SyntaxNode;
                                   Scope : in Dictionary.Scopes) is
   Spec_Node : STree.SyntaxNode;

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

   procedure Check_Position
     (Node        : in     STree.SyntaxNode;
      Pack_String : in     LexTokenManager.Lex_String;
      Scope       : in     Dictionary.Scopes;
      Pos_OK      :    out Boolean)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_String,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Pos_OK                     from LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_String,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.renaming_declaration;
   is
      Last_Node : STree.SyntaxNode;
      Ident     : LexTokenManager.Lex_String;
   begin
      if Dictionary.Get_Visibility (Scope => Scope) = Dictionary.Visible then
         -- If this renaming is part of the visible part of a package, then
         -- it must be in legal position because syntax ensures it is.
         Pos_OK := True;
      else
         Last_Node := Parent_Node (Current_Node => Node);
         -- ASSUME Last_Node = initial_declarative_item_rep OR renaming_declaration_rep
         if Syntax_Node_Type (Node => Last_Node) = SP_Symbols.initial_declarative_item_rep then
            -- ASSUME Last_Node = initial_declarative_item_rep
            -- If a renaming is part of an initial_declartive_item_rep, then
            -- it should follow be following an embedded package declaration
            Ident := Find_Previous_Package (Node => Last_Node);
            if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Ident,
                                                                    Lex_Str2 => LexTokenManager.Null_String) =
              LexTokenManager.Str_Eq then
               -- There is no preceding package
               ErrorHandler.Semantic_Error
                 (Err_Num   => 300,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Node),
                  Id_Str    => LexTokenManager.Null_String);
               Pos_OK := False;
            elsif LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Ident,
                                                                       Lex_Str2 => Pack_String) /=
              LexTokenManager.Str_Eq then
               -- There is a preceding package, but it's the wrong one!
               ErrorHandler.Semantic_Error
                 (Err_Num   => 301,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Node),
                  Id_Str    => Ident);
               Pos_OK := False;
            else
               -- There is a preceding package and it _is_ the one
               -- mentioned in the renaming
               Pos_OK := True;
            end if;
         elsif Syntax_Node_Type (Node => Last_Node) = SP_Symbols.renaming_declaration_rep then
            -- ASSUME Last_Node = renaming_declaration_rep

            -- Find the enclosing declarative_part node
            loop
               Last_Node := Parent_Node (Current_Node => Last_Node);
               exit when Syntax_Node_Type (Node => Last_Node) = SP_Symbols.declarative_part;
            end loop;
            -- ASSUME Last_Node = declarative_part

            Last_Node := Parent_Node (Current_Node => Last_Node);
            -- ASSUME Last_Node = subprogram_implementation OR package_implementation
            if Syntax_Node_Type (Node => Last_Node) = SP_Symbols.subprogram_implementation then
               -- ASSUME Last_Node = subprogram_implementation
               Last_Node := Parent_Node (Current_Node => Last_Node);
               -- ASSUME Last_Node = subprogram_body OR not_overriding_subprogram_body OR task_body OR entry_body
               if Syntax_Node_Type (Node => Last_Node) = SP_Symbols.not_overriding_subprogram_body then
                  -- ASSUME Last_Node = not_overriding_subprogram_body
                  Last_Node := Parent_Node (Current_Node => Last_Node);
                  -- ASSUME Last_Node = protected_operation_item OR generic_subprogram_body OR main_program_declaration
                  if Syntax_Node_Type (Node => Last_Node) = SP_Symbols.protected_operation_item
                    or else Syntax_Node_Type (Node => Last_Node) = SP_Symbols.generic_subprogram_body then
                     -- ASSUME Last_Node = protected_operation_item OR generic_subprogram_body
                     -- If a renaming is in a subprogram implementation, but that subprogram
                     -- isn't the main program, then error
                     ErrorHandler.Semantic_Error
                       (Err_Num   => 300,
                        Reference => ErrorHandler.No_Reference,
                        Position  => Node_Position (Node => Node),
                        Id_Str    => LexTokenManager.Null_String);
                     Pos_OK := False;
                  elsif Syntax_Node_Type (Node => Last_Node) = SP_Symbols.main_program_declaration then
                     -- ASSUME Last_Node = main_program_declaration
                     Pos_OK := True;
                  else
                     Pos_OK := False;
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                        Msg     => "Expect Last_Node = protected_operation_item OR generic_subprogram_body OR " &
                          "main_program_declaration in Check_Position");
                  end if;
               elsif Syntax_Node_Type (Node => Last_Node) = SP_Symbols.subprogram_body
                 or else Syntax_Node_Type (Node => Last_Node) = SP_Symbols.task_body
                 or else Syntax_Node_Type (Node => Last_Node) = SP_Symbols.entry_body then
                  -- ASSUME Last_Node = subprogram_body OR task_body OR entry_body
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 300,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Node),
                     Id_Str    => LexTokenManager.Null_String);
                  Pos_OK := False;
               else
                  Pos_OK := False;
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Last_Node = subprogram_body OR not_overriding_subprogram_body OR " &
                       "task_body OR entry_body in Check_Position");
               end if;
            elsif Syntax_Node_Type (Node => Last_Node) = SP_Symbols.package_implementation then
               -- ASSUME Last_Node = package_implementation
               Pos_OK := True;
            else
               Pos_OK := False;
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Last_Node = subprogram_implementation in Check_Position");
            end if;
         else
            Pos_OK := False;
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Last_Node = initial_declarative_item_rep OR renaming_declaration_rep in Check_Position");
         end if;
      end if;
   end Check_Position;

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

   procedure Check_Operator_Renaming (Node  : in STree.SyntaxNode;
                                      Scope : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     LexTokenManager.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out STree.Table;
   --# derives Dictionary.Dict,
   --#         STree.Table                from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.renaming_declaration;
   --# post STree.Table = STree.Table~;
   is
      type Expected_Argument_Type is (None, One, One_Or_Two, Two);
      type Param_Count_Type is (One_Parameter, Two_Parameters, Too_Many_Parameters);

      Pack_Node                                               : STree.SyntaxNode;
      Type_Node                                               : STree.SyntaxNode;
      Formal_Node                                             : STree.SyntaxNode;
      Op2_Node                                                : STree.SyntaxNode;
      Op_Node                                                 : STree.SyntaxNode;
      First_Param_Node                                        : STree.SyntaxNode;
      Second_Param_Node                                       : STree.SyntaxNode;
      Second_Type_Node                                        : STree.SyntaxNode;
      First_Type_Node                                         : STree.SyntaxNode;
      First_Type, Second_Type, Return_Type, Return_Type_Given : Dictionary.Symbol;
      Op1, Op2                                                : SP_Symbols.SP_Symbol;
      Expected1, Expected2_Unused                             : Expected_Argument_Type;
      OK, Defined, Already_Visible                            : Boolean;
      Number_Found                                            : Param_Count_Type;
      Op_Name1_Unused, Op_Name2                               : LexTokenManager.Lex_String;

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

      procedure Wf_Operator_Symbol
        (Node    : in     STree.SyntaxNode;
         Op      :    out SP_Symbols.SP_Symbol;
         Op_Name :    out LexTokenManager.Lex_String;
         Params  :    out Expected_Argument_Type)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table &
      --#         Op,
      --#         Op_Name,
      --#         Params                     from LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.operator_symbol;
      is
         Op_String : E_Strings.T;
      begin
         Op_Name   := Node_Lex_String (Node => Child_Node (Current_Node => Node));
         Op_String := LexTokenManager.Lex_String_To_String (Lex_Str => Op_Name);
         if E_Strings.Get_Element (E_Str => Op_String,
                                   Pos   => 2) = '='
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.equals;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '/'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = '='
           and then E_Strings.Get_Length (E_Str => Op_String) = 4 then
            Op     := SP_Symbols.not_equal;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '<'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.less_than;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '<'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = '='
           and then E_Strings.Get_Length (E_Str => Op_String) = 4 then
            Op     := SP_Symbols.less_or_equal;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '>'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.greater_than;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '>'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = '='
           and then E_Strings.Get_Length (E_Str => Op_String) = 4 then
            Op     := SP_Symbols.greater_or_equal;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '+'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.plus;
            Params := One_Or_Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '-'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.minus;
            Params := One_Or_Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '/'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.divide;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '*'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.multiply;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '&'
           and then E_Strings.Get_Length (E_Str => Op_String) = 3 then
            Op     := SP_Symbols.ampersand;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = '*'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = '*'
           and then E_Strings.Get_Length (E_Str => Op_String) = 4 then
            Op     := SP_Symbols.double_star;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'r'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'e'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 4) = 'm'
           and then E_Strings.Get_Length (E_Str => Op_String) = 5 then
            Op     := SP_Symbols.RWrem;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'm'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'o'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 4) = 'd'
           and then E_Strings.Get_Length (E_Str => Op_String) = 5 then
            Op     := SP_Symbols.RWmod;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'a'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'b'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 4) = 's'
           and then E_Strings.Get_Length (E_Str => Op_String) = 5 then
            Op     := SP_Symbols.RWabs;
            Params := One;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'a'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'n'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 4) = 'd'
           and then E_Strings.Get_Length (E_Str => Op_String) = 5 then
            Op     := SP_Symbols.RWand;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'o'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'r'
           and then E_Strings.Get_Length (E_Str => Op_String) = 4 then
            Op     := SP_Symbols.RWor;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'x'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'o'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 4) = 'r'
           and then E_Strings.Get_Length (E_Str => Op_String) = 5 then
            Op     := SP_Symbols.RWxor;
            Params := Two;
         elsif E_Strings.Get_Element (E_Str => Op_String,
                                      Pos   => 2) = 'n'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 3) = 'o'
           and then E_Strings.Get_Element (E_Str => Op_String,
                                           Pos   => 4) = 't'
           and then E_Strings.Get_Length (E_Str => Op_String) = 5 then
            Op     := SP_Symbols.RWnot;
            Params := One;
         else
            Op      := SP_Symbols.SPEND;
            Op_Name := LexTokenManager.Null_String;
            Params  := None;
            ErrorHandler.Semantic_Error
              (Err_Num   => 20,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => LexTokenManager.Null_String);
         end if;
      end Wf_Operator_Symbol;

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

      procedure Get_Parameters
        (Node             : in     STree.SyntaxNode;
         Scope            : in     Dictionary.Scopes;
         Number_Found     :    out Param_Count_Type;
         First_Type       :    out Dictionary.Symbol;
         Second_Type      :    out Dictionary.Symbol;
         First_Node       :    out STree.SyntaxNode;
         Second_Node      :    out STree.SyntaxNode;
         First_Type_Node  :    out STree.SyntaxNode;
         Second_Type_Node :    out STree.SyntaxNode)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table &
      --#         First_Node,
      --#         First_Type_Node            from Node,
      --#                                         STree.Table &
      --#         First_Type,
      --#         Number_Found,
      --#         Second_Node,
      --#         Second_Type,
      --#         Second_Type_Node,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         Scope,
      --#                                         STree.Table;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.formal_part;
      --# post STree.Table = STree.Table~ and
      --#   Syntax_Node_Type (First_Node, STree.Table) = SP_Symbols.identifier and
      --#   (Syntax_Node_Type (Second_Node, STree.Table) = SP_Symbols.identifier or
      --#      Second_Node = STree.NullNode) and
      --#   (Syntax_Node_Type (First_Type_Node, STree.Table) = SP_Symbols.type_mark or
      --#      First_Type_Node = STree.NullNode) and
      --#   (Syntax_Node_Type (Second_Type_Node, STree.Table) = SP_Symbols.type_mark or
      --#      Second_Type_Node = STree.NullNode) and
      --#   ((First_Type_Node = STree.NullNode) -> (Number_Found = Too_Many_Parameters)) and
      --#   ((Second_Type_Node = STree.NullNode) -> (Number_Found = Too_Many_Parameters));
      is
         Next_Node : STree.SyntaxNode;
         Type_Sym  : Dictionary.Symbol;

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

         procedure Check_Mode (Mode_Node : in STree.SyntaxNode)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         Mode_Node,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table;
         --# pre Syntax_Node_Type (Mode_Node, STree.Table) = SP_Symbols.mode;
         is
            Next_Node : STree.SyntaxNode;
         begin
            Next_Node := Child_Node (Current_Node => Mode_Node);
            -- ASSUME Next_Node = in_mode OR inout_mode OR out_mode OR NULL
            if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.inout_mode
              or else Syntax_Node_Type (Node => Next_Node) = SP_Symbols.out_mode then
               -- ASSUME Next_Node = inout_mode OR out_mode
               ErrorHandler.Semantic_Error
                 (Err_Num   => 64,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Parent_Node (Current_Node => Mode_Node)),
                  Id_Str    => LexTokenManager.Null_String);
            elsif Next_Node /= STree.NullNode and then Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.in_mode then
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Next_Node = in_mode OR inout_mode OR out_mode OR NULL in Check_Mode");
            end if;
         end Check_Mode;

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

         procedure Check_Extra_Branches (Node  : in     STree.SyntaxNode;
                                         Count : in out Param_Count_Type)
         --# global in STree.Table;
         --# derives Count from *,
         --#                    Node,
         --#                    STree.Table;
         --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.type_mark;
         is
            Next_Node : STree.SyntaxNode;
         begin
            Next_Node := Parent_Node (Current_Node => Node);
            if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.parameter_specification then
               -- ASSUME Next_Node = parameter_specification
               Next_Node := Parent_Node (Current_Node => Next_Node);
               if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.formal_part_rep then
                  -- ASSUME Next_Node = formal_part_rep
                  Next_Node := Parent_Node (Current_Node => Next_Node);
                  -- ASSUME Next_Node = formal_part OR formal_part_rep
                  if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.formal_part_rep then
                     -- ASSUME Next_Node = formal_part_rep
                     Count := Too_Many_Parameters;
                  elsif Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.formal_part then
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                        Msg     => "Expect Next_Node = formal_part_rep OR formal_part in Check_Extra_Branches");
                  end if;
               else
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Next_Node = formal_part_rep in Check_Extra_Branches");
               end if;
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Next_Node = parameter_specification in Check_Extra_Branches");
            end if;
         end Check_Extra_Branches;

      begin -- Get_Parameters
         First_Node := Last_Child_Of (Start_Node => Node);
         -- ASSUME First_Node = identifier
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => First_Node) = SP_Symbols.identifier,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect First_Node = identifier in Get_Parameters");
         Next_Node := Next_Sibling (Current_Node => Parent_Node (Current_Node => First_Node));
         -- ASSUME Next_Node = identifier OR mode
         if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.identifier then
            -- ASSUME Next_Node = identifier
            -- "(LEFT, RIGHT : TYPE)" construction
            Number_Found := Two_Parameters;
            Second_Node  := Next_Node;
            Next_Node    := Next_Sibling (Current_Node => Parent_Node (Current_Node => Next_Node));
            -- ASSUME Next_Node = identifier OR mode
            if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.identifier then
               -- ASSUME Next_Node = identifier
               -- "(LEFT, RIGHT, OTHER : TYPE)" construction => Too_Many_Parameters
               First_Type_Node  := STree.NullNode;
               Second_Type_Node := STree.NullNode;
               First_Type       := Dictionary.GetUnknownTypeMark;
               Second_Type      := Dictionary.GetUnknownTypeMark;
               Number_Found     := Too_Many_Parameters;
            elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.mode then
               -- ASSUME Next_Node = mode
               -- "(LEFT, RIGHT : TYPE)" construction
               Check_Mode (Mode_Node => Next_Node);
               Next_Node := Next_Sibling (Current_Node => Next_Node);
               -- ASSUME Next_Node = type_mark
               SystemErrors.RT_Assert
                 (C       => Next_Node /= STree.NullNode and then Syntax_Node_Type (Node => Next_Node) = SP_Symbols.type_mark,
                  Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Next_Node = type_mark in Get_Parameters");
               First_Type_Node  := Next_Node;
               Second_Type_Node := Next_Node;
               Wf_Type_Mark
                 (Node          => Next_Node,
                  Current_Scope => Scope,
                  Context       => Dictionary.ProgramContext,
                  Type_Sym      => Type_Sym);
               First_Type  := Type_Sym;
               Second_Type := Type_Sym;
               -- Check "(LEFT, RIGHT : TYPE; OTHER : TYPE)" construction => Too_Many_Parameters
               Check_Extra_Branches (Node  => Next_Node,
                                     Count => Number_Found);
            else
               First_Type_Node  := STree.NullNode;
               Second_Type_Node := STree.NullNode;
               First_Type       := Dictionary.GetUnknownTypeMark;
               Second_Type      := Dictionary.GetUnknownTypeMark;
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Next_Node = identifier OR mode in Get_Parameters");
            end if;
         elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.mode then
            -- ASSUME Next_Node = mode
            -- "(LEFT : TYPE; RIGHT : TYPE)" or "(RIGHT : TYPE)" construction
            Check_Mode (Mode_Node => Next_Node);
            Next_Node := Next_Sibling (Current_Node => Next_Node);
            -- ASSUME Next_Node = type_mark
            SystemErrors.RT_Assert
              (C       => Next_Node /= STree.NullNode and then Syntax_Node_Type (Node => Next_Node) = SP_Symbols.type_mark,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Next_Node = type_mark in Get_Parameters");
            First_Type_Node  := Next_Node;
            Second_Type_Node := Next_Node;
            Wf_Type_Mark (Node          => Next_Node,
                          Current_Scope => Scope,
                          Context       => Dictionary.ProgramContext,
                          Type_Sym      => First_Type);
            Next_Node := Next_Sibling (Current_Node => Parent_Node (Current_Node => Parent_Node (Current_Node => Next_Node)));
            -- ASSUME Next_Node = parameter_specification OR NULL
            if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.parameter_specification then
               -- ASSUME Next_Node = parameter_specification
               -- "(LEFT : TYPE; RIGHT : TYPE)" construction
               Number_Found := Two_Parameters;
               Next_Node    := Last_Child_Of (Start_Node => Next_Node);
               -- ASSUME Next_Node = identifier
               SystemErrors.RT_Assert
                 (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.identifier,
                  Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Next_Node = identifier in Get_Parameters");
               Second_Node := Next_Node;
               Next_Node   := Next_Sibling (Current_Node => Parent_Node (Current_Node => Next_Node));
               -- ASSUME Next_Node = identifier OR mode
               if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.identifier then
                  -- ASSUME Next_Node = identifier
                  -- "(LEFT : TYPE; RIGHT, OTHER : TYPE)" construction => Too_Many_Parameters
                  Second_Type  := Dictionary.GetUnknownTypeMark;
                  Number_Found := Too_Many_Parameters;
               elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.mode then
                  -- ASSUME Next_Node = mode
                  -- "(LEFT : TYPE; RIGHT : TYPE)" construction
                  Check_Mode (Mode_Node => Next_Node);
                  Next_Node := Next_Sibling (Current_Node => Next_Node);
                  -- ASSUME Next_Node = type_mark
                  SystemErrors.RT_Assert
                    (C       => Next_Node /= STree.NullNode and then Syntax_Node_Type (Node => Next_Node) = SP_Symbols.type_mark,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Next_Node = type_mark in Get_Parameters");
                  Second_Type_Node := Next_Node;
                  Wf_Type_Mark
                    (Node          => Next_Node,
                     Current_Scope => Scope,
                     Context       => Dictionary.ProgramContext,
                     Type_Sym      => Second_Type);
                  -- Check "(LEFT : TYPE; RIGHT : TYPE; OTHER : TYPE)" construction => Too_Many_Parameters
                  Check_Extra_Branches (Node  => Next_Node,
                                        Count => Number_Found);
               else
                  Second_Type := Dictionary.GetUnknownTypeMark;
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Next_Node = identifier OR mode in Get_Parameters");
               end if;
            elsif Next_Node = STree.NullNode then
               -- "(RIGHT : TYPE)" construction
               Second_Node  := STree.NullNode;
               Second_Type  := Dictionary.GetUnknownTypeMark;
               Number_Found := One_Parameter;
            else
               Second_Node  := STree.NullNode;
               Second_Type  := Dictionary.GetUnknownTypeMark;
               Number_Found := Too_Many_Parameters;
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Next_Node = parameter_specification OR NULL in Get_Parameters");
            end if;
         else
            Second_Node      := STree.NullNode;
            First_Type_Node  := STree.NullNode;
            Second_Type_Node := STree.NullNode;
            First_Type       := Dictionary.GetUnknownTypeMark;
            Second_Type      := Dictionary.GetUnknownTypeMark;
            Number_Found     := Too_Many_Parameters;
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Next_Node = identifier OR mode in Get_Parameters");
         end if;
      end Get_Parameters;

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

      function Number_Correct (Expected : Expected_Argument_Type;
                               Found    : Param_Count_Type) return Boolean
      --# return B => ((Found = Too_Many_Parameters) -> (not B));
      is
      begin
         return Found /= Too_Many_Parameters
           and then (Found /= Two_Parameters or else Expected /= One)
           and then (Found /= One_Parameter or else Expected /= Two);
      end Number_Correct;

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

      procedure Check_Names_Right
        (Number_Found : in Param_Count_Type;
         First_Node   : in STree.SyntaxNode;
         Second_Node  : in STree.SyntaxNode)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         First_Node,
      --#                                         LexTokenManager.State,
      --#                                         Number_Found,
      --#                                         Second_Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table;
      --# pre Syntax_Node_Type (First_Node, STree.Table) = SP_Symbols.identifier and
      --#   (Syntax_Node_Type (Second_Node, STree.Table) = SP_Symbols.identifier or
      --#      Second_Node = STree.NullNode);
      is
      begin
         if Number_Found = One_Parameter then
            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => Node_Lex_String (Node => First_Node),
               Lex_Str2 => LexTokenManager.Right_Token) /=
              LexTokenManager.Str_Eq then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 65,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => First_Node),
                  Id_Str    => LexTokenManager.Null_String);
            end if;
         elsif Number_Found = Two_Parameters then
            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => Node_Lex_String (Node => First_Node),
               Lex_Str2 => LexTokenManager.Left_Token) /=
              LexTokenManager.Str_Eq then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 65,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => First_Node),
                  Id_Str    => LexTokenManager.Null_String);
            end if;
            -- ASSUME Second_Node = identifier
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Second_Node) = SP_Symbols.identifier,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Second_Node = identifier in Check_Names_Right");
            if LexTokenManager.Lex_String_Case_Insensitive_Compare
              (Lex_Str1 => Node_Lex_String (Node => Second_Node),
               Lex_Str2 => LexTokenManager.Right_Token) /=
              LexTokenManager.Str_Eq then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 65,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Second_Node),
                  Id_Str    => LexTokenManager.Null_String);
            end if;
         end if;
      end Check_Names_Right;

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

      procedure Check_Types
        (Number_Found            : in     Param_Count_Type;
         Op                      : in     SP_Symbols.SP_Symbol;
         Scope                   : in     Dictionary.Scopes;
         First_Type, Second_Type : in     Dictionary.Symbol;
         Op_Node                 : in     STree.SyntaxNode;
         OK                      :    out Boolean)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         First_Type,
      --#                                         LexTokenManager.State,
      --#                                         Number_Found,
      --#                                         Op,
      --#                                         Op_Node,
      --#                                         Scope,
      --#                                         Second_Type,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table &
      --#         OK                         from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         First_Type,
      --#                                         Number_Found,
      --#                                         Op,
      --#                                         Scope,
      --#                                         Second_Type;
      --# pre Syntax_Node_Type (Op_Node, STree.Table) = SP_Symbols.operator_symbol;
      is
      begin
         OK := True;
         if Number_Found = One_Parameter then
            if not (Dictionary.IsType (First_Type) or else Dictionary.IsUnknownTypeMark (First_Type)) then
               OK := False;
               ErrorHandler.Semantic_Error
                 (Err_Num   => 68,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Op_Node),
                  Id_Str    => LexTokenManager.Null_String);
            elsif Dictionary.TypeIsLimited (First_Type, Scope)
              -- For private type Time_Span, unary "-" and "abs" can be renamed.
              -- No other unary operators are renamable for any private type.
              -- Note that we do not need to do a test to see if the operator is
              -- defined here, since that is covered by Check_Operator.
              or else (Dictionary.IsPrivateType (First_Type, Scope)
                         and then (not CommandLineData.Ravenscar_Selected
                                     or else not Dictionary.IsPredefinedTimeSpanType (First_Type))) then
               OK := False;
               ErrorHandler.Semantic_Error_Sym
                 (Err_Num   => 119,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Next_Sibling (Current_Node => Op_Node)),
                  Sym       => First_Type,
                  Scope     => Scope);
            elsif (Dictionary.TypeIsModular (First_Type)
                     and then (Op = SP_Symbols.RWabs or else Op = SP_Symbols.plus or else Op = SP_Symbols.minus)) then
               -- Unary arithmetic operators are not allowed for modular types,
               -- so their renamings must also be illegal.  Note we _do_ allow
               -- logical unary "not" on modular types.
               OK := False;
               ErrorHandler.Semantic_Error
                 (Err_Num   => 803,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Op_Node),
                  Id_Str    => LexTokenManager.Null_String);
            end if;
         elsif Number_Found = Two_Parameters then
            if not ((Dictionary.IsType (First_Type) or else Dictionary.IsUnknownTypeMark (First_Type))
                    and then (Dictionary.IsType (Second_Type) or else Dictionary.IsUnknownTypeMark (Second_Type))) then
               OK := False;
               ErrorHandler.Semantic_Error
                 (Err_Num   => 68,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Op_Node),
                  Id_Str    => LexTokenManager.Null_String);
            elsif Dictionary.TypeIsLimited (First_Type, Scope)
              or else Dictionary.TypeIsLimited (Second_Type, Scope)
              -- For private types Time and Time_Span, all defined binary operators
              -- can be renamed. For other private types, only "=" can be renamed.
              or else (Dictionary.IsPrivateType (First_Type, Scope)
                         and then Op /= SP_Symbols.equals
                         and then (not CommandLineData.Ravenscar_Selected or else not Dictionary.IsPredefinedTimeType (First_Type)))
              or else (Dictionary.IsPrivateType (Second_Type, Scope)
                         and then Op /= SP_Symbols.equals
                         and then (not CommandLineData.Ravenscar_Selected or else not Dictionary.IsPredefinedTimeType (Second_Type)))
            then
               OK := False;
               ErrorHandler.Semantic_Error_Sym2
                 (Err_Num   => 35,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Next_Sibling (Current_Node => Op_Node)),
                  Sym       => First_Type,
                  Sym2      => Second_Type,
                  Scope     => Scope);
            end if;
         else
            OK := False;
         end if;
      end Check_Types;

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

      procedure Check_Operator
        (Number_Found             : in     Param_Count_Type;
         Op                       : in     SP_Symbols.SP_Symbol;
         Scope                    : in     Dictionary.Scopes;
         First_Type, Second_Type  : in     Dictionary.Symbol;
         Defined, Already_Visible :    out Boolean;
         Return_Type              :    out Dictionary.Symbol)
      --# global in CommandLineData.Content;
      --#        in Dictionary.Dict;
      --# derives Already_Visible from CommandLineData.Content,
      --#                              Dictionary.Dict,
      --#                              First_Type,
      --#                              Number_Found,
      --#                              Op,
      --#                              Scope,
      --#                              Second_Type &
      --#         Defined,
      --#         Return_Type     from CommandLineData.Content,
      --#                              Dictionary.Dict,
      --#                              First_Type,
      --#                              Number_Found,
      --#                              Op,
      --#                              Second_Type;
      is
      begin
         if Number_Found = One_Parameter then
            Defined := Dictionary.UnaryOperatorIsDefined (Op, First_Type);
            if Defined then
               Already_Visible := Dictionary.UnaryOperatorIsVisible (Op, First_Type, Scope);
               Return_Type     := First_Type;
            else
               Already_Visible := False;
               Return_Type     := Dictionary.GetUnknownTypeMark;
            end if;
         elsif Number_Found = Two_Parameters then
            Return_Type := Dictionary.Get_Binary_Operator_Type (Name  => Op,
                                                                Left  => First_Type,
                                                                Right => Second_Type);
            if Dictionary.Is_Null_Symbol (Return_Type) then
               Already_Visible := False;
               Return_Type     := Dictionary.GetUnknownTypeMark;
               Defined         := False;
            else
               Already_Visible := Dictionary.BinaryOperatorIsVisible (Op, First_Type, Second_Type, Scope);
               Defined         := True;
            end if;
         else
            Already_Visible := False;
            Return_Type     := Dictionary.GetUnknownTypeMark;
            Defined         := False;
         end if;
      end Check_Operator;

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

      function Renamed_From_Right_Place (Pack_Node, First_Type_Node, Second_Type_Node : STree.SyntaxNode) return Boolean
      --# global in LexTokenManager.State;
      --#        in STree.Table;
      --# pre (Syntax_Node_Type (Pack_Node, STree.Table) = SP_Symbols.dotted_simple_name or
      --#        Syntax_Node_Type (Pack_Node, STree.Table) = SP_Symbols.identifier) and
      --#   Syntax_Node_Type (First_Type_Node, STree.Table) = SP_Symbols.type_mark and
      --#   Syntax_Node_Type (Second_Type_Node, STree.Table) = SP_Symbols.type_mark;
      is
         OK : Boolean;

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

         function Names_Match (Pack_Node, Type_Node : STree.SyntaxNode) return Boolean
         --# global in LexTokenManager.State;
         --#        in STree.Table;
         --# pre (Syntax_Node_Type (Pack_Node, STree.Table) = SP_Symbols.dotted_simple_name or
         --#        Syntax_Node_Type (Pack_Node, STree.Table) = SP_Symbols.identifier) and
         --#   Syntax_Node_Type (Type_Node, STree.Table) = SP_Symbols.type_mark;
         is
            Curr_Pack_Node, Curr_Type_Node : STree.SyntaxNode;
            Match                          : Boolean;
            Pack_Done, Type_Done           : Boolean;
         begin
            Curr_Type_Node := Child_Node (Current_Node => Child_Node (Current_Node => Type_Node));
            -- ASSUME Curr_Type_Node = identifier OR dotted_simple_name
            if Syntax_Node_Type (Node => Curr_Type_Node) = SP_Symbols.identifier then
               -- ASSUME Curr_Type_Node = identifier
               -- no prefix on type mark
               Match := False;
            elsif Syntax_Node_Type (Node => Curr_Type_Node) = SP_Symbols.dotted_simple_name then
               -- ASSUME Curr_Type_Node = dotted_simple_name
               Curr_Pack_Node := Last_Child_Of (Start_Node => Pack_Node);
               -- ASSUME Curr_Pack_Node = identifier
               Curr_Type_Node := Last_Child_Of (Start_Node => Curr_Type_Node);
               -- ASSUME Curr_Type_Node = identifier
               loop
                  SystemErrors.RT_Assert
                    (C       => Syntax_Node_Type (Node => Curr_Pack_Node) = SP_Symbols.identifier,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Curr_Pack_Node = identifier in Names_Match");
                  SystemErrors.RT_Assert
                    (C       => Syntax_Node_Type (Node => Curr_Type_Node) = SP_Symbols.identifier,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Curr_Type_Node = identifier in Names_Match");
                  Match :=
                    LexTokenManager.Lex_String_Case_Insensitive_Compare
                    (Lex_Str1 => Node_Lex_String (Node => Curr_Pack_Node),
                     Lex_Str2 => Node_Lex_String (Node => Curr_Type_Node)) =
                    LexTokenManager.Str_Eq;

                  exit when not Match;

                  Curr_Pack_Node := Parent_Node (Current_Node => Curr_Pack_Node);
                  -- ASSUME Curr_Pack_Node = dotted_simple_name
                  SystemErrors.RT_Assert
                    (C       => Syntax_Node_Type (Node => Curr_Pack_Node) = SP_Symbols.dotted_simple_name,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Curr_Pack_Node = dotted_simple_name in Names_Match");
                  Pack_Done := Curr_Pack_Node = Parent_Node (Current_Node => Pack_Node);

                  Curr_Type_Node := Parent_Node (Current_Node => Curr_Type_Node);
                  -- ASSUME Curr_Type_Node = dotted_simple_name
                  SystemErrors.RT_Assert
                    (C       => Syntax_Node_Type (Node => Curr_Type_Node) = SP_Symbols.dotted_simple_name,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Curr_Type_Node = dotted_simple_name in Names_Match");
                  Type_Done := Curr_Type_Node = Child_Node (Current_Node => Child_Node (Current_Node => Type_Node));

                  if Pack_Done or else Type_Done then
                     Match := Pack_Done and then Type_Done;
                     exit;
                  end if;

                  -- move on to next identifiers in names:
                  Curr_Pack_Node := Next_Sibling (Current_Node => Curr_Pack_Node);
                  -- ASSUME Curr_Pack_Node = identifier
                  Curr_Type_Node := Next_Sibling (Current_Node => Curr_Type_Node);
                  -- ASSUME Curr_Type_Node = identifier
               end loop;
            else
               Match := False;
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Curr_Type_Node = identifier OR dotted_simple_name in Names_Match");
            end if;
            return Match;
         end Names_Match;

      begin -- Renamed_From_Right_Place
         OK := Names_Match (Pack_Node => Pack_Node,
                            Type_Node => First_Type_Node);
         if not OK then
            OK := Names_Match (Pack_Node => Pack_Node,
                               Type_Node => Second_Type_Node);
         end if;
         return OK;
      end Renamed_From_Right_Place;

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

      procedure Do_Rename
        (Number_Found            : in Param_Count_Type;
         Op                      : in SP_Symbols.SP_Symbol;
         First_Type, Second_Type : in Dictionary.Symbol;
         Scope                   : in Dictionary.Scopes;
         Declaration             : in Dictionary.Location;
         Op_Node                 : in STree.SyntaxNode)
      --# global in     ContextManager.Ops.Unit_Stack;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives Dictionary.Dict   from *,
      --#                                ContextManager.Ops.Unit_Stack,
      --#                                Declaration,
      --#                                First_Type,
      --#                                Number_Found,
      --#                                Op,
      --#                                Scope,
      --#                                Second_Type &
      --#         SPARK_IO.File_Sys from *,
      --#                                ContextManager.Ops.Unit_Stack,
      --#                                Declaration,
      --#                                Dictionary.Dict,
      --#                                First_Type,
      --#                                LexTokenManager.State,
      --#                                Number_Found,
      --#                                Op,
      --#                                Scope,
      --#                                Second_Type &
      --#         STree.Table       from *,
      --#                                ContextManager.Ops.Unit_Stack,
      --#                                Declaration,
      --#                                Dictionary.Dict,
      --#                                First_Type,
      --#                                Number_Found,
      --#                                Op,
      --#                                Op_Node,
      --#                                Scope,
      --#                                Second_Type;
      --# pre Syntax_Node_Type (Op_Node, STree.Table) = SP_Symbols.operator_symbol;
      --# post STree.Table = STree.Table~;
      is
         Op_Sym : Dictionary.Symbol;
      begin
         case Number_Found is
            when One_Parameter =>
               Dictionary.RenameUnaryOperator
                 (Name        => Op,
                  Comp_Unit   => ContextManager.Ops.Current_Unit,
                  Declaration => Declaration,
                  Operand     => First_Type,
                  Scope       => Scope,
                  Op_Sym      => Op_Sym);
            when Two_Parameters =>
               Dictionary.RenameBinaryOperator
                 (Name        => Op,
                  Comp_Unit   => ContextManager.Ops.Current_Unit,
                  Declaration => Declaration,
                  Left        => First_Type,
                  Right       => Second_Type,
                  Scope       => Scope,
                  Op_Sym      => Op_Sym);
            when Too_Many_Parameters =>
               Op_Sym := Dictionary.NullSymbol;
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "in Check_Operator_Renaming.Do_Rename");
         end case;
         STree.Add_Node_Symbol (Node => Op_Node,
                                Sym  => Op_Sym);
      end Do_Rename;

   begin -- Check_Operator_Renaming
      Op_Node := Child_Node (Current_Node => Node);
      -- ASSUME Op_Node = operator_symbol
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Op_Node) = SP_Symbols.operator_symbol,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Op_Node = operator_symbol in Check_Operator_Renaming");
      Formal_Node := Next_Sibling (Current_Node => Op_Node);
      -- ASSUME Formal_Node = formal_part
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.formal_part,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Formal_Node = formal_part in Check_Operator_Renaming");
      Type_Node := Next_Sibling (Current_Node => Formal_Node);
      -- ASSUME Type_Node = type_mark
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Type_Node) = SP_Symbols.type_mark,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Type_Node = type_mark in Check_Operator_Renaming");
      Pack_Node := Child_Node (Current_Node => Next_Sibling (Current_Node => Type_Node));
      -- ASSUME Pack_Node = dotted_simple_name OR identifier
      Op2_Node := Next_Sibling (Current_Node => Next_Sibling (Current_Node => Type_Node));
      -- ASSUME Op2_Node = operator_symbol
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Op2_Node) = SP_Symbols.operator_symbol,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Op2_Node = operator_symbol in Check_Operator_Renaming");
      if Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.dotted_simple_name then
         -- ASSUME Pack_Node = dotted_simple_name
         case CommandLineData.Content.Language_Profile is
            when CommandLineData.SPARK83 =>
               -- report error at second identifier in name
               Pack_Node := Next_Sibling (Current_Node => Parent_Node (Current_Node => Last_Child_Of (Start_Node => Pack_Node)));
               -- ASSUME Pack_Node = identifier
               SystemErrors.RT_Assert
                 (C       => Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.identifier,
                  Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Pack_Node = identifier in Check_Operator_Renaming");
               ErrorHandler.Semantic_Error
                 (Err_Num   => 610,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Pack_Node),
                  Id_Str    => LexTokenManager.Null_String);
               OK := False;
            when CommandLineData.SPARK95_Onwards =>
               Check_Position (Node        => Node,
                               Pack_String => LexTokenManager.Null_String,
                               Scope       => Scope,
                               Pos_OK      => OK);
         end case;
      elsif Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.identifier then
         -- ASSUME Pack_Node = identifier
         Check_Position (Node        => Node,
                         Pack_String => Node_Lex_String (Node => Pack_Node),
                         Scope       => Scope,
                         Pos_OK      => OK);
      else
         OK := False;
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Pack_Node = dotted_simple_name OR identifier in Check_Operator_Renaming");
      end if;
      if OK then
         --# accept Flow, 10, Op_Name1_Unused, "Expected ineffective assignment";
         Wf_Operator_Symbol (Node    => Op_Node,
                             Op      => Op1,
                             Op_Name => Op_Name1_Unused,
                             Params  => Expected1);
         --# end accept;
         --# accept Flow, 10, Expected2_Unused, "Expected ineffective assignment";
         Wf_Operator_Symbol (Node    => Op2_Node,
                             Op      => Op2,
                             Op_Name => Op_Name2,
                             Params  => Expected2_Unused);
         --# end accept;
         if Op1 /= Op2 then
            ErrorHandler.Semantic_Error
              (Err_Num   => 303,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Op2_Node),
               Id_Str    => LexTokenManager.Null_String);
            -- check that /= is not being renamed
         elsif Op1 = SP_Symbols.not_equal then
            ErrorHandler.Semantic_Error
              (Err_Num   => 304,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Op_Node),
               Id_Str    => Node_Lex_String (Node => Child_Node (Current_Node => Op_Node)));
         else -- operator strings are the same (and neither is /=)
            Get_Parameters
              (Node             => Formal_Node,
               Scope            => Scope,
               Number_Found     => Number_Found,
               First_Type       => First_Type,
               Second_Type      => Second_Type,
               First_Node       => First_Param_Node,
               Second_Node      => Second_Param_Node,
               First_Type_Node  => First_Type_Node,
               Second_Type_Node => Second_Type_Node);
            if Number_Correct (Expected => Expected1,
                               Found    => Number_Found) then
               Check_Names_Right (Number_Found => Number_Found,
                                  First_Node   => First_Param_Node,
                                  Second_Node  => Second_Param_Node);
               Check_Types
                 (Number_Found => Number_Found,
                  Op           => Op1,
                  Scope        => Scope,
                  First_Type   => First_Type,
                  Second_Type  => Second_Type,
                  Op_Node      => Op_Node,
                  OK           => OK);
               if OK then
                  Check_Operator
                    (Number_Found    => Number_Found,
                     Op              => Op1,
                     Scope           => Scope,
                     First_Type      => First_Type,
                     Second_Type     => Second_Type,
                     Defined         => Defined,
                     Already_Visible => Already_Visible,
                     Return_Type     => Return_Type);
                  if not Defined then
                     if Number_Found = One_Parameter then
                        ErrorHandler.Semantic_Error_Sym
                          (Err_Num   => 119,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Formal_Node),
                           Sym       => First_Type,
                           Scope     => Scope);
                     elsif Number_Found = Two_Parameters then
                        ErrorHandler.Semantic_Error_Sym2
                          (Err_Num   => 35,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Formal_Node),
                           Sym       => First_Type,
                           Sym2      => Second_Type,
                           Scope     => Scope);
                     end if;
                  elsif Already_Visible then
                     ErrorHandler.Semantic_Error
                       (Err_Num   => 306,
                        Reference => ErrorHandler.No_Reference,
                        Position  => Node_Position (Node => Op2_Node),
                        Id_Str    => Op_Name2);
                  else
                     Wf_Type_Mark
                       (Node          => Type_Node,
                        Current_Scope => Scope,
                        Context       => Dictionary.ProgramContext,
                        Type_Sym      => Return_Type_Given);
                     if not Dictionary.Types_Are_Equal
                       (Left_Symbol        => Return_Type,
                        Right_Symbol       => Return_Type_Given,
                        Full_Range_Subtype => False) then
                        ErrorHandler.Semantic_Error
                          (Err_Num   => 305,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Type_Node),
                           Id_Str    => Op_Name2);
                     elsif Renamed_From_Right_Place
                       (Pack_Node        => Pack_Node,
                        First_Type_Node  => First_Type_Node,
                        Second_Type_Node => Second_Type_Node) then
                        Do_Rename
                          (Number_Found => Number_Found,
                           Op           => Op1,
                           First_Type   => First_Type,
                           Second_Type  => Second_Type,
                           Scope        => Scope,
                           Declaration  => Dictionary.Location'(Start_Position => Node_Position (Node => Op2_Node),
                                                                End_Position   => Node_Position (Node => Op2_Node)),
                           Op_Node      => Op_Node);
                     else
                        if Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.dotted_simple_name then
                           -- use last identifier in package name to report error
                           Pack_Node := Next_Sibling (Current_Node => Pack_Node);
                        end if;
                        ErrorHandler.Semantic_Error
                          (Err_Num   => 307,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Op2_Node),
                           Id_Str    => Node_Lex_String (Node => Pack_Node));
                     end if;
                  end if;
               end if;
            else -- number of parameters wrong
               ErrorHandler.Semantic_Error
                 (Err_Num   => 305,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Formal_Node),
                  Id_Str    => Op_Name2);
            end if;
         end if;
      end if;
      --# accept Flow, 33, Expected2_Unused, "Expected to be neither referenced nor exported" &
      --#        Flow, 33, Op_Name1_Unused, "Expected to be neither referenced nor exported";
   end Check_Operator_Renaming;

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

   procedure Check_Subprogram_Renaming (Node  : in STree.SyntaxNode;
                                        Scope : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     LexTokenManager.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out STree.Table;
   --# derives Dictionary.Dict            from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         STree.Table                from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.renaming_declaration;
   --# post STree.Table = STree.Table~;
   is
      type Subprog_Sorts is (Func, Proc, Unknown);

      Pack_Sym, Subprog_Sym                           : Dictionary.Symbol;
      Spec_Node, Formal_Node, Pack_Node, Subprog_Node : STree.SyntaxNode;
      OK                                              : Boolean;
      Subprog_Sort                                    : Subprog_Sorts;

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

      procedure Check_Names_Same (Node, Subprog_Node : in     STree.SyntaxNode;
                                  OK                 :    out Boolean)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         Subprog_Node &
      --#         OK                         from LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table,
      --#                                         Subprog_Node;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.renaming_declaration and
      --#   Syntax_Node_Type (Subprog_Node, STree.Table) = SP_Symbols.identifier;
      is
      begin
         if LexTokenManager.Lex_String_Case_Insensitive_Compare
           (Lex_Str1 => Node_Lex_String (Node => Subprog_Node),
            Lex_Str2 => Node_Lex_String (Node => Last_Child_Of (Start_Node => Node))) /=
           LexTokenManager.Str_Eq then
            OK := False;
            ErrorHandler.Semantic_Error
              (Err_Num   => 312,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => LexTokenManager.Null_String);
         else
            OK := True;
         end if;
      end Check_Names_Same;

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

      procedure Find_Package (Scope     : in     Dictionary.Scopes;
                              Pack_Node : in     STree.SyntaxNode;
                              Pack_Sym  :    out Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Pack_Node,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table &
      --#         Pack_Sym,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Pack_Node,
      --#                                         Scope,
      --#                                         STree.Table;
      --# pre Syntax_Node_Type (Pack_Node, STree.Table) = SP_Symbols.dotted_simple_name or
      --#   Syntax_Node_Type (Pack_Node, STree.Table) = SP_Symbols.identifier;
      --# post STree.Table = STree.Table~;
      is
         Curr_Node : STree.SyntaxNode;
         Prefix_OK : Boolean;
      begin
         Curr_Node := Last_Child_Of (Start_Node => Pack_Node);
         -- ASSUME Curr_Node = identifier
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Curr_Node) = SP_Symbols.identifier,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Curr_Node = identifier in Find_Package");
         Pack_Sym :=
           Dictionary.LookupItem
           (Name              => Node_Lex_String (Node => Curr_Node),
            Scope             => Scope,
            Context           => Dictionary.ProgramContext,
            Full_Package_Name => False);

         loop -- loop to handle multiple prefixes

            --# assert STree.Table = STree.Table~;
            if Dictionary.Is_Null_Symbol (Pack_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 1,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Curr_Node),
                  Id_Str    => Node_Lex_String (Node => Curr_Node));
               exit;
            end if;
            if not Dictionary.IsPackage (Pack_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 18,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Curr_Node),
                  Id_Str    => Node_Lex_String (Node => Curr_Node));
               Pack_Sym := Dictionary.NullSymbol;
               exit;
            end if;
            Check_Package_Prefix
              (Node_Pos => Node_Position (Node => Curr_Node),
               Pack_Sym => Pack_Sym,
               Scope    => Scope,
               OK       => Prefix_OK);
            if not Prefix_OK then
               Pack_Sym := Dictionary.NullSymbol;
               exit;
            end if;
            STree.Set_Node_Lex_String (Sym  => Pack_Sym,
                                       Node => Curr_Node);
            -- finished if processed all identifiers under Pack_Node
            Curr_Node := Parent_Node (Current_Node => Curr_Node);
            -- ASSUME Curr_Node = dotted_simple_name
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Curr_Node) = SP_Symbols.dotted_simple_name,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Curr_Node = dotted_simple_name in Find_Package");
            exit when Curr_Node = Parent_Node (Current_Node => Pack_Node);
            Curr_Node := Next_Sibling (Current_Node => Curr_Node);
            -- ASSUME Curr_Node = identifier
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Curr_Node) = SP_Symbols.identifier,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Curr_Node = identifier in Find_Package");
            Pack_Sym :=
              Dictionary.LookupSelectedItem
              (Prefix   => Pack_Sym,
               Selector => Node_Lex_String (Node => Curr_Node),
               Scope    => Scope,
               Context  => Dictionary.ProgramContext);
         end loop;
      end Find_Package;

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

      procedure Find_Subprogram
        (Node_Pos     : in     LexTokenManager.Token_Position;
         Scope        : in     Dictionary.Scopes;
         Pack_Sym     : in     Dictionary.Symbol;
         Subprog_Node : in     STree.SyntaxNode;
         Sort         : in     Subprog_Sorts;
         Subprog_Sym  :    out Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node_Pos,
      --#                                         Pack_Sym,
      --#                                         Scope,
      --#                                         Sort,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         Subprog_Node &
      --#         STree.Table,
      --#         Subprog_Sym                from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Pack_Sym,
      --#                                         Scope,
      --#                                         STree.Table,
      --#                                         Subprog_Node;
      --# pre Syntax_Node_Type (Subprog_Node, STree.Table) = SP_Symbols.identifier;
      --# post STree.Table = STree.Table~;
      is

         function Select_Error (S : Subprog_Sorts) return Natural is
            Res : Natural;
         begin
            case S is
               when Func =>
                  Res := 334;
               when Proc =>
                  Res := 19;
               when Unknown =>
                  Res := 0;
            end case;
            return Res;
         end Select_Error;

      begin -- Find_Subprogram
         if Dictionary.IsDefined
           (Name              => Node_Lex_String (Node => Subprog_Node),
            Scope             => Scope,
            Context           => Dictionary.ProofContext,
            Full_Package_Name => False) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 10,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Pos,
               Id_Str    => Node_Lex_String (Node => Subprog_Node));
            Subprog_Sym := Dictionary.NullSymbol;
         else
            Subprog_Sym :=
              Dictionary.LookupSelectedItem (Pack_Sym, Node_Lex_String (Node => Subprog_Node), Scope, Dictionary.ProgramContext);
            if Dictionary.Is_Null_Symbol (Subprog_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 1,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Subprog_Node),
                  Id_Str    => Node_Lex_String (Node => Subprog_Node));
            elsif not Dictionary.Is_Subprogram (Subprog_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => Select_Error (S => Sort),
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Subprog_Node),
                  Id_Str    => Node_Lex_String (Node => Subprog_Node));
               Subprog_Sym := Dictionary.NullSymbol;
               -- check to prevent 2nd renames
            elsif Dictionary.Is_Renamed
              (Subprogram => Subprog_Sym,
               Scope      => Dictionary.Set_Visibility (The_Visibility => Dictionary.Local,
                                                        The_Unit       => Pack_Sym))
              or else Dictionary.Is_Renamed
              (Subprogram => Subprog_Sym,
               Scope      => Dictionary.Set_Visibility (The_Visibility => Dictionary.Visible,
                                                        The_Unit       => Pack_Sym))
            then
               ErrorHandler.Semantic_Error2
                 (Err_Num   => 339,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Subprog_Node),
                  Id_Str1   => Node_Lex_String (Node => Subprog_Node),
                  Id_Str2   => Dictionary.GetSimpleName (Pack_Sym));
               Subprog_Sym := Dictionary.NullSymbol;
            else
               STree.Set_Node_Lex_String (Sym  => Subprog_Sym,
                                          Node => Subprog_Node);
            end if;
         end if;
      end Find_Subprogram;

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

      procedure Check_Consistency
        (Scope                                : in     Dictionary.Scopes;
         Subprog_Sym                          : in     Dictionary.Symbol;
         Spec_Node, Formal_Node, Subprog_Node : in     STree.SyntaxNode;
         OK                                   :    out Boolean)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         Formal_Node,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys,
      --#                                         Spec_Node,
      --#                                         STree.Table,
      --#                                         Subprog_Node,
      --#                                         Subprog_Sym &
      --#         OK,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         Formal_Node,
      --#                                         LexTokenManager.State,
      --#                                         Scope,
      --#                                         Spec_Node,
      --#                                         STree.Table,
      --#                                         Subprog_Sym;
      --# pre Syntax_Node_Type (Spec_Node, STree.Table) = SP_Symbols.subprogram_specification and
      --#   (Syntax_Node_Type (Formal_Node, STree.Table) = SP_Symbols.formal_part or
      --#      Syntax_Node_Type (Formal_Node, STree.Table) = SP_Symbols.type_mark or
      --#      Formal_Node = STree.NullNode) and
      --#   Syntax_Node_Type (Subprog_Node, STree.Table) = SP_Symbols.identifier;
      --# post STree.Table = STree.Table~;
      is
         It                                                : Dictionary.Iterator;
         Param_Count                                       : Natural;
         Current_Formal_Mode, Current_Mode                 : Dictionary.Modes;
         Current_Formal, Current_Formal_Type, Current_Type : Dictionary.Symbol;
         List_Node, Param_Node, Ident_Node                 : STree.SyntaxNode;
         Specs_It                                          : STree.Iterator;
         Ident_It                                          : STree.Iterator;
         Current_Formal_Ident                              : LexTokenManager.Lex_String;

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

         function Check_Right_Sort_Of_Subprogram (Sym  : Dictionary.Symbol;
                                                  Node : STree.SyntaxNode) return Boolean
         --# global in Dictionary.Dict;
         --#        in STree.Table;
         --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.subprogram_specification;
         is
            Right_Sort : Boolean;
         begin
            if Dictionary.IsFunction (Sym) then
               Right_Sort := Syntax_Node_Type (Node => Child_Node (Current_Node => Node)) = SP_Symbols.function_specification;
            else
               Right_Sort := Syntax_Node_Type (Node => Child_Node (Current_Node => Node)) = SP_Symbols.procedure_specification;
            end if;
            return Right_Sort;
         end Check_Right_Sort_Of_Subprogram;

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

         function Get_Mode (Node : STree.SyntaxNode) return Dictionary.Modes
         --# global in STree.Table;
         --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.parameter_specification;
         is
            Mode_Node : STree.SyntaxNode;
            Result    : Dictionary.Modes;
         begin
            Mode_Node := Child_Node (Current_Node => Next_Sibling (Current_Node => Child_Node (Current_Node => Node)));
            -- ASSUME Mode_Node = in_mode OR inout_mode OR out_mode OR NULL
            if Mode_Node = STree.NullNode then
               -- ASSUME Mode_Node = NULL
               Result := Dictionary.InMode;
            else
               case Syntax_Node_Type (Node => Mode_Node) is
                  when SP_Symbols.in_mode =>
                     -- ASSUME Mode_Node = in_mode
                     Result := Dictionary.InMode;
                  when SP_Symbols.inout_mode =>
                     -- ASSUME Mode_Node = inout_mode
                     Result := Dictionary.InOutMode;
                  when SP_Symbols.out_mode =>
                     -- ASSUME Mode_Node = out_mode
                     Result := Dictionary.OutMode;
                  when others =>
                     Result := Dictionary.InvalidMode;
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                        Msg     => "Expect Mode_Node = in_mode OR inout_mode OR out_mode OR NULL in Get_Mode");
               end case;
            end if;
            return Result;
         end Get_Mode;

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

         procedure Get_Type (Node     : in     STree.SyntaxNode;
                             Scope    : in     Dictionary.Scopes;
                             Type_Sym :    out Dictionary.Symbol)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --#        in out STree.Table;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         Node,
         --#                                         Scope,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table &
         --#         STree.Table,
         --#         Type_Sym                   from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Node,
         --#                                         Scope,
         --#                                         STree.Table;
         --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.parameter_specification;
         --# post STree.Table = STree.Table~;
         is
            Type_Node : STree.SyntaxNode;
         begin
            Type_Node := Next_Sibling (Current_Node => Next_Sibling (Current_Node => Child_Node (Current_Node => Node)));
            -- ASSUME Type_Node = type_mark
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Type_Node) = SP_Symbols.type_mark,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Type_Node = type_mark in Get_Type");
            Wf_Type_Mark (Node          => Type_Node,
                          Current_Scope => Scope,
                          Context       => Dictionary.ProgramContext,
                          Type_Sym      => Type_Sym);
         end Get_Type;

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

         function Modes_Equivalent (Formal_Mode, Renamed_Mode : Dictionary.Modes) return Boolean is
            Equivalent : Boolean;
         begin
            if Formal_Mode = Dictionary.DefaultMode then
               Equivalent := Renamed_Mode = Dictionary.InMode;
            else
               Equivalent := Formal_Mode = Renamed_Mode;
            end if;
            return Equivalent;
         end Modes_Equivalent;

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

         procedure Check_Return_Type
           (Subprog_Sym : in     Dictionary.Symbol;
            Formal_Node : in     STree.SyntaxNode;
            Scope       : in     Dictionary.Scopes;
            Consistent  : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --#        in out STree.Table;
         --# derives Consistent                 from *,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         Formal_Node,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         STree.Table,
         --#                                         Subprog_Sym &
         --#         ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         Formal_Node,
         --#                                         LexTokenManager.State,
         --#                                         Scope,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table &
         --#         STree.Table                from *,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         Formal_Node,
         --#                                         LexTokenManager.State,
         --#                                         Scope;
         --# pre Syntax_Node_Type (Formal_Node, STree.Table) = SP_Symbols.formal_part or
         --#   Syntax_Node_Type (Formal_Node, STree.Table) = SP_Symbols.type_mark or
         --#   Formal_Node = STree.NullNode;
         --# post STree.Table = STree.Table~;
         is
            Type_Node : STree.SyntaxNode;
            Type_Sym  : Dictionary.Symbol;
         begin
            -- ASSUME Formal_Node = formal_part OR type_mark OR NULL
            if Formal_Node = STree.NullNode or else Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.type_mark then
               -- ASSUME Formal_Node = type_mark OR NULL
               Type_Node := Formal_Node;
            elsif Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.formal_part then
               -- ASSUME Formal_Node = formal_part
               Type_Node := Next_Sibling (Current_Node => Formal_Node);
            else
               Type_Node := STree.NullNode;
            end if;
            -- ASSUME Type_Node = type_mark OR NULL
            if Syntax_Node_Type (Node => Type_Node) = SP_Symbols.type_mark then
               -- ASSUME Type_Node = type_mark
               Wf_Type_Mark
                 (Node          => Type_Node,
                  Current_Scope => Scope,
                  Context       => Dictionary.ProgramContext,
                  Type_Sym      => Type_Sym);
               Consistent := Consistent
                 and then Dictionary.Types_Are_Equal
                 (Left_Symbol        => Type_Sym,
                  Right_Symbol       => Dictionary.GetType (Subprog_Sym),
                  Full_Range_Subtype => False);
            elsif Type_Node /= STree.NullNode then
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Type_Node = type_mark OR NULL in Check_Return_Type");
            end if;
         end Check_Return_Type;

      begin -- Check_Consistency
         OK := Check_Right_Sort_Of_Subprogram (Sym  => Subprog_Sym,
                                               Node => Spec_Node);
         if OK then
            if Formal_Node = STree.NullNode or else Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.type_mark then
               -- ASSUME Formal_Node = type_mark OR NULL
               OK := Dictionary.GetNumberOfSubprogramParameters (Subprog_Sym) = 0;
            elsif Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.formal_part then
               -- ASSUME Formal_Node = formal_part
               Param_Count := 0;
               It          := Dictionary.FirstSubprogramParameter (Subprog_Sym);
               Specs_It    :=
                 Find_First_Node
                 (Node_Kind    => SP_Symbols.parameter_specification,
                  From_Root    => Formal_Node,
                  In_Direction => STree.Down);

               while not STree.IsNull (Specs_It) loop
                  Param_Node := Get_Node (It => Specs_It);
                  --# assert Syntax_Node_Type (Param_Node, STree.Table) = SP_Symbols.parameter_specification and
                  --#   Param_Node = Get_Node (Specs_It) and
                  --#   STree.Table = STree.Table~;
                  Current_Mode := Get_Mode (Node => Param_Node);
                  Get_Type (Node     => Param_Node,
                            Scope    => Scope,
                            Type_Sym => Current_Type);
                  List_Node := Child_Node (Current_Node => Param_Node);
                  -- ASSUME List_Node = identifier_list
                  SystemErrors.RT_Assert
                    (C       => Syntax_Node_Type (Node => List_Node) = SP_Symbols.identifier_list,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect List_Node = identifier_list in Check_Consistency");
                  Ident_It :=
                    Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                     From_Root    => List_Node,
                                     In_Direction => STree.Down);
                  while not STree.IsNull (Ident_It) loop
                     Ident_Node := Get_Node (It => Ident_It);
                     --# assert Syntax_Node_Type (Param_Node, STree.Table) = SP_Symbols.parameter_specification and
                     --#   Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.identifier and
                     --#   Param_Node = Get_Node (Specs_It) and
                     --#   Ident_Node = Get_Node (Ident_It) and
                     --#   STree.Table = STree.Table~;
                     if Param_Count < Natural'Last then
                        Param_Count := Param_Count + 1;
                     else
                        OK := False;
                     end if;
                     if Dictionary.IsNullIterator (It) then
                        OK := False;
                     else
                        Current_Formal       := Dictionary.CurrentSymbol (It);
                        Current_Formal_Type  := Dictionary.GetType (Current_Formal);
                        Current_Formal_Mode  := Dictionary.GetSubprogramParameterMode (Current_Formal);
                        Current_Formal_Ident := Dictionary.GetSimpleName (Current_Formal);
                        OK                   :=
                          OK
                          and then Dictionary.Types_Are_Equal
                          (Left_Symbol        => Current_Type,
                           Right_Symbol       => Current_Formal_Type,
                           Full_Range_Subtype => False)
                          and then Modes_Equivalent (Formal_Mode  => Current_Formal_Mode,
                                                     Renamed_Mode => Current_Mode)
                          and then LexTokenManager.Lex_String_Case_Insensitive_Compare
                          (Lex_Str1 => Current_Formal_Ident,
                           Lex_Str2 => Node_Lex_String (Node => Ident_Node)) =
                          LexTokenManager.Str_Eq;
                        It                   := Dictionary.NextSymbol (It);
                     end if;
                     Ident_It := STree.NextNode (Ident_It);
                  end loop; -- Idents
                  Specs_It := STree.NextNode (Specs_It);
               end loop; -- Specs
               OK := OK and then (Param_Count = Dictionary.GetNumberOfSubprogramParameters (Subprog_Sym));
            end if;

            if Dictionary.IsFunction (Subprog_Sym) then
               Check_Return_Type (Subprog_Sym => Subprog_Sym,
                                  Formal_Node => Formal_Node,
                                  Scope       => Scope,
                                  Consistent  => OK);
            end if;
         end if;

         if not OK then
            ErrorHandler.Semantic_Error
              (Err_Num   => 302,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Subprog_Node),
               Id_Str    => Node_Lex_String (Node => Subprog_Node));
         end if;
      end Check_Consistency;

   begin -- Check_Subprogram_Renaming

      -- check that we are not in package spec
      if Dictionary.Get_Visibility (Scope => Scope) = Dictionary.Visible then
         ErrorHandler.Semantic_Error
           (Err_Num   => 340,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Node),
            Id_Str    => LexTokenManager.Null_String);
      else
         Spec_Node := Child_Node (Current_Node => Node);
         -- ASSUME Spec_Node = subprogram_specification
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Spec_Node) = SP_Symbols.subprogram_specification,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Spec_Node = subprogram_specification in Check_Subprogram_Renaming");
         Pack_Node := Child_Node (Current_Node => Next_Sibling (Current_Node => Spec_Node));
         -- ASSUME Pack_Node = dotted_simple_name OR identifier
         if Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.dotted_simple_name then
            -- ASSUME Pack_Node = dotted_simple_name
            case CommandLineData.Content.Language_Profile is
               when CommandLineData.SPARK83 =>
                  -- report error at second identifier in name
                  Pack_Node :=
                    Next_Sibling (Current_Node => Parent_Node (Current_Node => Last_Child_Of (Start_Node => Pack_Node)));
                  -- ASSUME Pack_Node = identifier
                  SystemErrors.RT_Assert
                    (C       => Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.identifier,
                     Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                     Msg     => "Expect Pack_Node = identifier in Check_Subprogram_Renaming");
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 610,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Pack_Node),
                     Id_Str    => LexTokenManager.Null_String);
                  OK := False;
               when CommandLineData.SPARK95_Onwards =>
                  Check_Position (Node        => Node,
                                  Pack_String => LexTokenManager.Null_String,
                                  Scope       => Scope,
                                  Pos_OK      => OK);
            end case;
         elsif Syntax_Node_Type (Node => Pack_Node) = SP_Symbols.identifier then
            -- ASSUME Pack_Node = identifier
            Check_Position (Node        => Node,
                            Pack_String => Node_Lex_String (Node => Pack_Node),
                            Scope       => Scope,
                            Pos_OK      => OK);
         else
            OK := False;
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Pack_Node = dotted_simple_name OR identifier in Check_Subprogram_Renaming");
         end if;
         if OK then
            Subprog_Node := Child_Node (Current_Node => Next_Sibling (Current_Node => Next_Sibling (Current_Node => Spec_Node)));
            -- ASSUME Subprog_Node = identifier
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Subprog_Node) = SP_Symbols.identifier,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Subprog_Node = identifier in Check_Subprogram_Renaming");
            Check_Names_Same (Node         => Node,
                              Subprog_Node => Subprog_Node,
                              OK           => OK);
            if OK then
               Find_Package (Scope     => Scope,
                             Pack_Node => Pack_Node,
                             Pack_Sym  => Pack_Sym);
               if not Dictionary.Is_Null_Symbol (Pack_Sym) then
                  -- detect sort of subprogram so that Find_Subprogram can report
                  -- correct error
                  if Syntax_Node_Type (Node => Child_Node (Current_Node => Spec_Node)) =
                    SP_Symbols.procedure_specification then
                     -- ASSUME Child_Node (Current_Node => Spec_Node) = procedure_specification
                     Subprog_Sort := Proc;
                  elsif Syntax_Node_Type (Node => Child_Node (Current_Node => Spec_Node)) =
                    SP_Symbols.function_specification then
                     -- ASSUME Child_Node (Current_Node => Spec_Node) = function_specification
                     Subprog_Sort := Func;
                  else
                     Subprog_Sort := Unknown;
                     SystemErrors.Fatal_Error
                       (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                        Msg     => "Expect Spec_Node = procedure_specification OR " &
                          "function_specification in Check_Subprogram_Renaming");
                  end if;

                  Find_Subprogram
                    (Node_Pos     => Node_Position (Node => Node),
                     Scope        => Scope,
                     Pack_Sym     => Pack_Sym,
                     Subprog_Node => Subprog_Node,
                     Sort         => Subprog_Sort,
                     Subprog_Sym  => Subprog_Sym);
                  if not Dictionary.Is_Null_Symbol (Subprog_Sym) then
                     Formal_Node :=
                       Next_Sibling (Current_Node => Child_Node (Current_Node => Child_Node (Current_Node => Spec_Node)));
                     -- ASSUME Formal_Node = formal_part OR type_mark OR NULL
                     SystemErrors.RT_Assert
                       (C       => Formal_Node = STree.NullNode
                          or else Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.formal_part
                          or else Syntax_Node_Type (Node => Formal_Node) = SP_Symbols.type_mark,
                        Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                        Msg     => "Expect Formal_Node = formal_part OR type_mark OR NULL in Check_Subprogram_Renaming");
                     Check_Consistency
                       (Scope        => Scope,
                        Subprog_Sym  => Subprog_Sym,
                        Spec_Node    => Spec_Node,
                        Formal_Node  => Formal_Node,
                        Subprog_Node => Subprog_Node,
                        OK           => OK);
                     if OK then
                        Dictionary.RenameSubprogram
                          (Subprogram          => Subprog_Sym,
                           SubprogramReference => Dictionary.Location'(Start_Position => Node_Position (Node => Subprog_Node),
                                                                       End_Position   => Node_Position (Node => Subprog_Node)),
                           Comp_Unit           => ContextManager.Ops.Current_Unit,
                           Declaration         => Dictionary.Location'(Start_Position => Node_Position (Node => Node),
                                                                       End_Position   => Node_Position (Node => Node)),
                           Scope               => Scope);
                     end if;  -- consistency check
                  end if;  -- names not same
               end if;  -- no such subprogram
            end if;  -- not a package
         end if;  -- wrong place
      end if;  -- in package spec
   end Check_Subprogram_Renaming;

begin -- Wf_Renaming_Declaration
   Spec_Node := Child_Node (Current_Node => Node);
   -- ASSUME Spec_Node = operator_symbol OR subprogram_specification OR package_renaming_declaration
   case Syntax_Node_Type (Node => Spec_Node) is
      when SP_Symbols.subprogram_specification =>
         -- ASSUME Spec_Node = subprogram_specification
         Check_Subprogram_Renaming (Node  => Node,
                                    Scope => Scope);
      when SP_Symbols.operator_symbol =>
         -- ASSUME Spec_Node = operator_symbol
         Check_Operator_Renaming (Node  => Node,
                                  Scope => Scope);
      when SP_Symbols.package_renaming_declaration =>
         -- ASSUME Spec_Node = package_renaming_declaration
         ErrorHandler.Semantic_Error
           (Err_Num   => 111,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Node),
            Id_Str    => LexTokenManager.Null_String);
      when others =>
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Spec_Node = operator_symbol OR subprogram_specification OR " &
              "package_renaming_declaration in Wf_Renaming_Declaration");
   end case;
end Wf_Renaming_Declaration;
