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

separate (Sem.CompUnit)
procedure Up_Wf_Package_Body (Node                   : in     STree.SyntaxNode;
                              Scope                  : in out Dictionary.Scopes;
                              Withs_Own_Public_Child : in     Boolean) is
   Ident_Node, End_Desig_Node, Node_To_Report_Errors, Next_Node, Ref_Node : STree.SyntaxNode;
   Pack_Sym                                                               : Dictionary.Symbol;

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

   procedure Check_Own_Variables_Declared
     (Pack_Sym : in Dictionary.Symbol;
      Node_Pos : in LexTokenManager.Token_Position;
      Scope    : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys;
   is
      Constituent_List, Own_Var_List : Dictionary.Iterator;
      Own_Var_Sym, Constituent       : Dictionary.Symbol;

      procedure Check_Stream_Has_Address (Sym      : in Dictionary.Symbol;
                                          Node_Pos : in LexTokenManager.Token_Position)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        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_Pos,
      --#                                         SPARK_IO.File_Sys,
      --#                                         Sym;
      is
      begin
         if Dictionary.GetOwnVariableOrConstituentMode (Sym) /= Dictionary.DefaultMode
           and then not Dictionary.IsProtectedTypeMark (Dictionary.GetType (Sym))
           and then not Dictionary.VariableHasAddressClause (Sym)
           and then not Dictionary.VariableHasPragmaImport (Sym) then
            ErrorHandler.Semantic_Warning (Err_Num  => 395,
                                           Position => Node_Pos,
                                           Id_Str   => Dictionary.GetSimpleName (Sym));
         end if;
      end Check_Stream_Has_Address;

      function Own_Var_Declared_Remotely (Constituent : Dictionary.Symbol) return Boolean
      --# global in Dictionary.Dict;
      is
      begin
         return Dictionary.IsOwnVariable (Constituent)
           and then Dictionary.GetContext (Dictionary.GetRegion (Dictionary.GetScope (Constituent))) =
           Dictionary.ProgramContext;
      end Own_Var_Declared_Remotely;

   begin -- Check_Own_Variables_Declared
      Own_Var_List := Dictionary.FirstOwnVariable (Pack_Sym);
      while not Dictionary.IsNullIterator (Own_Var_List) loop
         Own_Var_Sym := Dictionary.CurrentSymbol (Own_Var_List);
         if not Dictionary.GetOwnVariableIsInterruptStream (Own_Var_Sym) then
            if Dictionary.IsRefinedOwnVariable (Own_Var_Sym) then
               Constituent_List := Dictionary.FirstConstituent (Own_Var_Sym);
               while not Dictionary.IsNullIterator (Constituent_List) loop
                  Constituent := Dictionary.CurrentSymbol (Constituent_List);
                  if not (Own_Var_Declared_Remotely (Constituent => Constituent)
                            or else Dictionary.Is_Declared (Item => Constituent)) then
                     ErrorHandler.Semantic_Error_Sym
                       (Err_Num   => 84,
                        Reference => 20,
                        Position  => Node_Pos,
                        Sym       => Constituent,
                        Scope     => Scope);
                  elsif not Own_Var_Declared_Remotely (Constituent => Constituent) then
                     -- it is declared, so check streams have addresses, etc.
                     Check_Stream_Has_Address (Sym      => Constituent,
                                               Node_Pos => Node_Pos);
                     -- CheckProtectedReallyIs (Constituent);
                  end if;
                  Constituent_List := Dictionary.NextSymbol (Constituent_List);
               end loop;
            else
               if not Dictionary.Is_Declared (Item => Own_Var_Sym) then
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 28,
                     Reference => 20,
                     Position  => Node_Pos,
                     Id_Str    => Dictionary.GetSimpleName (Own_Var_Sym));
               else -- it is declared, so check streams have addresses, etc.
                  Check_Stream_Has_Address (Sym      => Own_Var_Sym,
                                            Node_Pos => Node_Pos);
               end if;
            end if;
         end if;
         Own_Var_List := Dictionary.NextSymbol (Own_Var_List);
      end loop;
   end Check_Own_Variables_Declared;

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

   -- Check that Integrity property of refinement constituents (if present)
   -- is OK with the Integrity of the abstract own variable(s), given
   -- the selected setting of CommandLineData.Content.InfoFlowPolicy
   procedure Check_Integrity_Of_Refinements
     (Pack_Sym : in Dictionary.Symbol;
      Node_Pos : in LexTokenManager.Token_Position;
      Scope    : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys;
   is
      Constituent_List, Own_Var_List            : Dictionary.Iterator;
      Own_Var_Sym, Constituent                  : Dictionary.Symbol;
      Abstract_Integrity, Constituent_Integrity : LexTokenManager.Lex_String;

      procedure Check_Integrities
        (Own_Var_Sym, Constituent                  : in Dictionary.Symbol;
         Abstract_Integrity, Constituent_Integrity : in LexTokenManager.Lex_String;
         Node_Pos                                  : in LexTokenManager.Token_Position;
         Scope                                     : in Dictionary.Scopes)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from Abstract_Integrity,
      --#                                         CommandLineData.Content,
      --#                                         Constituent,
      --#                                         Constituent_Integrity,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node_Pos,
      --#                                         Own_Var_Sym,
      --#                                         Scope,
      --#                                         SPARK_IO.File_Sys;
      is
      begin
         if Abstract_Integrity = LexTokenManager.Null_String then
            if Constituent_Integrity = LexTokenManager.Null_String then
               -- Both null. No action required.
               null;
            else
               -- Abstract integrity null, constituent not null - error!
               ErrorHandler.Semantic_Error_Sym2
                 (Err_Num   => 861,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Pos,
                  Sym       => Own_Var_Sym,
                  Sym2      => Constituent,
                  Scope     => Scope);
            end if;
         else
            if Constituent_Integrity = LexTokenManager.Null_String then
               -- Abstract var has an integrity, constituent doesn't.
               -- This is OK - the constituent inherits the Integrity of the abstract.
               null;
            else
               -- Both have specific Integrity properties, so need to check
               -- that they are the same, else error 862
               if Maths.ValueRep (Abstract_Integrity) /= Maths.ValueRep (Constituent_Integrity) then
                  ErrorHandler.Semantic_Error_Sym2
                    (Err_Num   => 862,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Pos,
                     Sym       => Own_Var_Sym,
                     Sym2      => Constituent,
                     Scope     => Scope);
               end if;
            end if;
         end if;
      end Check_Integrities;

   begin -- Check_Integrity_Of_Refinements
      case CommandLineData.Content.Info_Flow_Policy is
         when CommandLineData.None =>
            -- Nothing to do if -policy is not set at all...
            null;
         when CommandLineData.Safety | CommandLineData.Security =>
            Own_Var_List := Dictionary.FirstOwnVariable (Pack_Sym);
            while not Dictionary.IsNullIterator (Own_Var_List) loop
               Own_Var_Sym := Dictionary.CurrentSymbol (Own_Var_List);
               if not Dictionary.GetOwnVariableIsInterruptStream (Own_Var_Sym) then
                  if Dictionary.IsRefinedOwnVariable (Own_Var_Sym) then
                     Abstract_Integrity := Dictionary.GetIntegrityProperty (Own_Var_Sym);
                     Constituent_List   := Dictionary.FirstConstituent (Own_Var_Sym);
                     while not Dictionary.IsNullIterator (Constituent_List) loop
                        Constituent           := Dictionary.CurrentSymbol (Constituent_List);
                        Constituent_Integrity := Dictionary.GetIntegrityProperty (Constituent);
                        Check_Integrities
                          (Own_Var_Sym           => Own_Var_Sym,
                           Constituent           => Constituent,
                           Abstract_Integrity    => Abstract_Integrity,
                           Constituent_Integrity => Constituent_Integrity,
                           Node_Pos              => Node_Pos,
                           Scope                 => Scope);
                        Constituent_List := Dictionary.NextSymbol (Constituent_List);
                     end loop;
                  end if;
               end if;
               Own_Var_List := Dictionary.NextSymbol (Own_Var_List);
            end loop;
      end case;
   end Check_Integrity_Of_Refinements;

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

   procedure Check_Exported_Subprograms_Declared (Pack_Sym : in Dictionary.Symbol;
                                                  Node_Pos : in LexTokenManager.Token_Position)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is

      procedure Check_Subprograms (Subprogram_It : in Dictionary.Iterator;
                                   Node_Pos      : in LexTokenManager.Token_Position)
      --# global in     CommandLineData.Content;
      --#        in     Dictionary.Dict;
      --#        in     LexTokenManager.State;
      --#        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_Pos,
      --#                                         SPARK_IO.File_Sys,
      --#                                         Subprogram_It;
      is
         Subprog_Sym : Dictionary.Symbol;
         It          : Dictionary.Iterator;
      begin
         It := Subprogram_It;
         while not Dictionary.IsNullIterator (It) loop
            Subprog_Sym := Dictionary.CurrentSymbol (It);
            if not (Dictionary.IsProofFunction (Subprog_Sym)
                      or else Dictionary.HasBody (Subprog_Sym)
                      or else Dictionary.HasBodyStub (Subprog_Sym)) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 29,
                  Reference => 21,
                  Position  => Node_Pos,
                  Id_Str    => Dictionary.GetSimpleName (Subprog_Sym));
            end if;
            It := Dictionary.NextSymbol (It);
         end loop;
      end Check_Subprograms;

   begin -- Check_Exported_Subprograms_Declared
      Check_Subprograms
        (Subprogram_It => Dictionary.First_Visible_Subprogram (The_Package_Or_Type => Pack_Sym),
         Node_Pos      => Node_Pos);
      Check_Subprograms (Subprogram_It => Dictionary.First_Private_Subprogram (The_Package => Pack_Sym),
                         Node_Pos      => Node_Pos);
   end Check_Exported_Subprograms_Declared;

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

   procedure Check_Visible_Task_Types_Declared (Pack_Sym : in Dictionary.Symbol;
                                                Node_Pos : in LexTokenManager.Token_Position)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is
      It       : Dictionary.Iterator;
      Task_Sym : Dictionary.Symbol;
   begin
      It := Dictionary.First_Visible_Task_Type (The_Package => Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Task_Sym := Dictionary.CurrentSymbol (It);
         if not (Dictionary.HasBody (Task_Sym) or else Dictionary.HasBodyStub (Task_Sym)) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 896,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (Task_Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Visible_Task_Types_Declared;

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

   procedure Check_Private_Task_Types_Declared (Pack_Sym : in Dictionary.Symbol;
                                                Node_Pos : in LexTokenManager.Token_Position)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is
      It       : Dictionary.Iterator;
      Task_Sym : Dictionary.Symbol;
   begin
      It := Dictionary.First_Private_Task_Type (The_Package => Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Task_Sym := Dictionary.CurrentSymbol (It);
         if not (Dictionary.HasBody (Task_Sym) or else Dictionary.HasBodyStub (Task_Sym)) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 896,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (Task_Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Private_Task_Types_Declared;

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

   procedure Check_Visible_Protected_Types_Declared
     (Pack_Sym : in Dictionary.Symbol;
      Node_Pos : in LexTokenManager.Token_Position)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is
      It            : Dictionary.Iterator;
      Protected_Sym : Dictionary.Symbol;
   begin
      It := Dictionary.First_Visible_Protected_Type (The_Package => Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Protected_Sym := Dictionary.CurrentSymbol (It);
         if not (Dictionary.HasBody (Protected_Sym) or else Dictionary.HasBodyStub (Protected_Sym)) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 897,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (Protected_Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Visible_Protected_Types_Declared;

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

   procedure Check_Private_Protected_Types_Declared
     (Pack_Sym : in Dictionary.Symbol;
      Node_Pos : in LexTokenManager.Token_Position)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is
      It            : Dictionary.Iterator;
      Protected_Sym : Dictionary.Symbol;
   begin
      It := Dictionary.First_Private_Protected_Type (The_Package => Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Protected_Sym := Dictionary.CurrentSymbol (It);
         if not (Dictionary.HasBody (Protected_Sym) or else Dictionary.HasBodyStub (Protected_Sym)) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 897,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (Protected_Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Private_Protected_Types_Declared;

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

   procedure Check_Initialization
     (Pack_Sym : in Dictionary.Symbol;
      Node_Pos : in LexTokenManager.Token_Position;
      Scope    : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys;
   is
      Constituent_List, Init_Own_Var_List : Dictionary.Iterator;
      Init_Own_Var_Sym, Constituent_Sym   : Dictionary.Symbol;
   begin
      Init_Own_Var_List := Dictionary.FirstInitializedOwnVariable (Pack_Sym);
      -- Note.  Moded own variables will not get picked up by this iterator since
      -- other wffs ensure that moded own vars can never appear in Init clauses
      -- Note.  Protected moded own variables will get picked up by this iterator
      -- as protected own variables are implicitly initialized.
      while not Dictionary.IsNullIterator (Init_Own_Var_List) loop
         Init_Own_Var_Sym := Dictionary.CurrentSymbol (Init_Own_Var_List);
         if Dictionary.IsConcreteOwnVariable (Init_Own_Var_Sym) then
            if not Dictionary.VariableIsInitialized (Init_Own_Var_Sym) then
               ErrorHandler.Usage_Error
                 (Err_Type => ErrorHandler.Undefined_Var,
                  Position => Node_Pos,
                  Var_Sym  => Init_Own_Var_Sym,
                  Scope    => Scope);
               ErrorHandler.Usage_Error
                 (Err_Type => ErrorHandler.Undefined_Export,
                  Position => Node_Pos,
                  Var_Sym  => Init_Own_Var_Sym,
                  Scope    => Scope);
            end if;
         else -- abstract own var
            Constituent_List := Dictionary.FirstConstituent (Init_Own_Var_Sym);
            while not Dictionary.IsNullIterator (Constituent_List) loop
               Constituent_Sym := Dictionary.CurrentSymbol (Constituent_List);
               if (not Dictionary.IsOwnVariable (Constituent_Sym))
                 and then not Dictionary.VariableIsInitialized (Constituent_Sym)
                 and then Dictionary.GetConstituentMode (Constituent_Sym) = Dictionary.DefaultMode then
                  ErrorHandler.Usage_Error
                    (Err_Type => ErrorHandler.Undefined_Var,
                     Position => Node_Pos,
                     Var_Sym  => Constituent_Sym,
                     Scope    => Scope);
                  ErrorHandler.Usage_Error
                    (Err_Type => ErrorHandler.Undefined_Export,
                     Position => Node_Pos,
                     Var_Sym  => Constituent_Sym,
                     Scope    => Scope);
               end if;
               Constituent_List := Dictionary.NextSymbol (Constituent_List);
            end loop;
         end if;
         Init_Own_Var_List := Dictionary.NextSymbol (Init_Own_Var_List);
      end loop;
   end Check_Initialization;

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

   procedure Check_Own_Tasks_Declared (Pack_Sym : in Dictionary.Symbol;
                                       Node_Pos : in LexTokenManager.Token_Position)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        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_Pos,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is
      It           : Dictionary.Iterator;
      Own_Task_Sym : Dictionary.Symbol;
   begin
      It := Dictionary.FirstOwnTask (Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Own_Task_Sym := Dictionary.CurrentSymbol (It);
         if not Dictionary.Is_Declared (Item => Own_Task_Sym) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 931,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Pos,
               Id_Str    => Dictionary.GetSimpleName (Own_Task_Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Own_Tasks_Declared;

begin -- Up_Wf_Package_Body
   Pack_Sym := Dictionary.GetRegion (Scope);

   Next_Node := Child_Node (Current_Node => Last_Sibling_Of (Start_Node => Child_Node (Current_Node => Node)));
   -- ASSUME Next_Node = pragma_rep OR hidden_part
   if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.pragma_rep then
      -- ASSUME Next_Node = pragma_rep
      Next_Node := Next_Sibling (Current_Node => Next_Node);
      -- ASSUME Next_Node = declarative_part OR dotted_simple_name OR package_initialization
      if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.declarative_part then
         -- ASSUME Next_Node = declarative_part
         Next_Node := Next_Sibling (Current_Node => Next_Node);
      elsif Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.dotted_simple_name
        and then Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.package_initialization then
         Next_Node := STree.NullNode;
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Next_Node = declarative_part OR dotted_simple_name OR " &
              "package_initialization in Up_Wf_Package_Body");
      end if;
      -- ASSUME Next_Node = dotted_simple_name OR package_initialization
      if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.package_initialization then
         -- ASSUME Next_Node = package_initialization
         Next_Node := Child_Node (Current_Node => Next_Node);
         -- ASSUME Next_Node = sequence_of_statements OR hidden_part
         if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.hidden_part then
            -- ASSUME Next_Node = hidden_part
            End_Desig_Node        := STree.NullNode;
            Node_To_Report_Errors := Next_Node;
         elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.sequence_of_statements then
            -- ASSUME Next_Node = sequence_of_statements
            End_Desig_Node := Next_Sibling (Current_Node => Next_Node);
            -- ASSUME End_Desig_Node = dotted_simple_name
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => End_Desig_Node) = SP_Symbols.dotted_simple_name,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect End_Desig_Node = dotted_simple_name in Up_Wf_Package_Body");
            Node_To_Report_Errors := End_Desig_Node;
         else
            End_Desig_Node        := STree.NullNode;
            Node_To_Report_Errors := STree.NullNode;
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Next_Node = sequence_of_statements OR hidden_part in Up_Wf_Package_Body");
         end if;
      elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.dotted_simple_name then
         -- ASSUME Next_Node = dotted_simple_name
         -- no pack init part provided
         End_Desig_Node        := Next_Node;
         Node_To_Report_Errors := End_Desig_Node;
         Check_Initialization (Pack_Sym => Pack_Sym,
                               Node_Pos => Node_Position (Node => Node_To_Report_Errors),
                               Scope    => Scope);
      else
         End_Desig_Node        := STree.NullNode;
         Node_To_Report_Errors := STree.NullNode;
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Next_Node = dotted_simple_name OR package_initialization in Up_Wf_Package_Body");
      end if;
      --# check (Syntax_Node_Type (End_Desig_Node, STree.Table) = SP_Symbols.dotted_simple_name or
      --#          End_Desig_Node = STree.NullNode) and
      --#   (Syntax_Node_Type (Node_To_Report_Errors, STree.Table) = SP_Symbols.hidden_part or
      --#      Syntax_Node_Type (Node_To_Report_Errors, STree.Table) = SP_Symbols.dotted_simple_name);

      if Syntax_Node_Type (Node => End_Desig_Node) = SP_Symbols.dotted_simple_name then
         -- ASSUME End_Desig_Node = dotted_simple_name
         Ident_Node := Last_Child_Of (Start_Node => Node);
         -- ASSUME Ident_Node = identifier
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Ident_Node = identifier in Up_Wf_Package_Body");
         Check_Closing_Identifier (End_Name_Node => End_Desig_Node,
                                   Ident_Node    => Ident_Node);
      end if;

      Check_Announced_Types_Declared
        (Pack_Sym => Pack_Sym,
         Scope    => Scope,
         Node_Pos => Node_Position (Node => Node_To_Report_Errors));

      Check_Own_Variables_Declared
        (Pack_Sym => Pack_Sym,
         Node_Pos => Node_Position (Node => Node_To_Report_Errors),
         Scope    => Scope);

      Check_Integrity_Of_Refinements
        (Pack_Sym => Pack_Sym,
         Node_Pos => Node_Position (Node => Node_To_Report_Errors),
         Scope    => Scope);

      Check_Exported_Subprograms_Declared (Pack_Sym => Pack_Sym,
                                           Node_Pos => Node_Position (Node => Node_To_Report_Errors));
      Check_Visible_Task_Types_Declared (Pack_Sym => Pack_Sym,
                                         Node_Pos => Node_Position (Node => Node_To_Report_Errors));
      Check_Private_Task_Types_Declared (Pack_Sym => Pack_Sym,
                                         Node_Pos => Node_Position (Node => Node_To_Report_Errors));
      Check_Visible_Protected_Types_Declared (Pack_Sym => Pack_Sym,
                                              Node_Pos => Node_Position (Node => Node_To_Report_Errors));
      Check_Private_Protected_Types_Declared (Pack_Sym => Pack_Sym,
                                              Node_Pos => Node_Position (Node => Node_To_Report_Errors));
      CheckEmbedBodies (Comp_Sym => Pack_Sym,
                        Node_Pos => Node_Position (Node => Node_To_Report_Errors));

      Check_Own_Tasks_Declared (Pack_Sym => Pack_Sym,
                                Node_Pos => Node_Position (Node => Node_To_Report_Errors));

      if Withs_Own_Public_Child then
         ErrorHandler.Semantic_Warning
           (Err_Num  => 426,
            Position => Node_Position (Node => Node_To_Report_Errors),
            Id_Str   => LexTokenManager.Null_String);
      end if;

   elsif Syntax_Node_Type (Node => Next_Node) /= SP_Symbols.hidden_part then
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Next_Node = pragma_rep OR hidden_part in Up_Wf_Package_Body");
   end if;

   --  The cross-references for the refinement are generated after the
   --  full semantic analysis of the package body because we need to
   --  know if a refinement constituent is actually an abstract own
   --  variable or a body concrete own variable. If it is an abstract
   --  own variable, the refinement constituent is considered as a
   --  declaration, if it is a body concrete own variable, the
   --  refinement constituent is a usage of the body concrete variable
   --  that will be declared later in the package body.
   if ErrorHandler.Generate_SLI then
      Ref_Node := Next_Sibling (Current_Node => Child_Node (Current_Node => Node));
      -- ASSUME Ref_Node = refinement_definition OR package_implementation
      if Syntax_Node_Type (Node => Ref_Node) = SP_Symbols.refinement_definition then
         -- ASSUME Ref_Node = refinement_definition
         SLI.Generate_Xref_Refinement
           (Comp_Unit  => ContextManager.Ops.Current_Unit,
            Parse_Tree => Ref_Node,
            Scope      => Dictionary.Set_Visibility (The_Visibility => Dictionary.Local,
                                                     The_Unit       => Pack_Sym));
      elsif Syntax_Node_Type (Node => Ref_Node) /= SP_Symbols.package_implementation then
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Ref_Node = refinement_definition OR package_implementation in Up_Wf_Package_Body");
      end if;
   end if;

   Scope := Dictionary.GetEnclosingScope (Scope);

end Up_Wf_Package_Body;
