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

-- Overview:
-- Checks a Package Specification for Sem on down pass through
-- TreeProcessor.  Starts at node package_specification.  May directly raise
-- errors for: mismatch between initial and terminal identifier.
-- Other errors may be raised indirectly by wf_package_annotation which
-- are called from here.
--------------------------------------------------------------------------------

with SLI;

separate (Sem.Wf_Package_Declaration)
procedure Wf_Package_Specification
  (Node           : in     STree.SyntaxNode;
   Ident_Str      : in     LexTokenManager.Lex_String;
   Pack_Sym       : in     Dictionary.Symbol;
   Current_Scope  : in     Dictionary.Scopes;
   Component_Data : in out ComponentManager.ComponentData;
   The_Heap       : in out Heap.HeapRecord)
is
   Enclosing_Scope_Type                                                              : Enclosing_Scope_Types;
   End_Pos_Node, Anno_Node, Vis_Part_Node, Priv_Part_Node, Ident_Node, End_Name_Node : STree.SyntaxNode;
   Pack_Vis_Scope                                                                    : Dictionary.Scopes;

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

   procedure Get_Package_Specification_Key_Nodes
     (Node           : in     STree.SyntaxNode;
      Anno_Node      :    out STree.SyntaxNode;
      Ident_Node     :    out STree.SyntaxNode;
      Vis_Part_Node  :    out STree.SyntaxNode;
      Priv_Part_Node :    out STree.SyntaxNode)
   --# global in STree.Table;
   --# derives Anno_Node,
   --#         Ident_Node,
   --#         Priv_Part_Node,
   --#         Vis_Part_Node  from Node,
   --#                             STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.package_specification;
   --# post Syntax_Node_Type (Anno_Node, STree.Table) = SP_Symbols.package_annotation and
   --#   Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.identifier and
   --#   Syntax_Node_Type (Vis_Part_Node, STree.Table) = SP_Symbols.visible_part_rep and
   --#   (Syntax_Node_Type (Priv_Part_Node, STree.Table) = SP_Symbols.basic_declarative_item_rep or
   --#      Syntax_Node_Type (Priv_Part_Node, STree.Table) = SP_Symbols.hidden_part or
   --#      Priv_Part_Node = STree.NullNode);
   is
   begin
      Anno_Node := Next_Sibling (Current_Node => Child_Node (Current_Node => Node));
      -- ASSUME Anno_Node = package_annotation
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Anno_Node) = SP_Symbols.package_annotation,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Anno_Node = package_annotation in Get_Package_Specification_Key_Nodes");

      Ident_Node := Child_Node (Current_Node => Child_Node (Current_Node => Node));
      -- ASSUME Ident_Node = dotted_simple_name OR identifier
      if Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.dotted_simple_name then
         -- ASSUME Ident_Node = dotted_simple_name
         -- declaring a child package
         Ident_Node := Last_Child_Of (Start_Node => Ident_Node);
      elsif Syntax_Node_Type (Node => Ident_Node) /= SP_Symbols.identifier then
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Ident_Node = dotted_simple_name OR identifier in Get_Package_Specification_Key_Nodes");
      end if;
      -- 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 Get_Package_Specification_Key_Nodes");

      Vis_Part_Node := Child_Node (Current_Node => Next_Sibling (Current_Node => Anno_Node));
      -- ASSUME Vis_Part_Node = visible_part_rep
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Vis_Part_Node) = SP_Symbols.visible_part_rep,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Vis_Part_Node = visible_part_rep in Get_Package_Specification_Key_Nodes");

      Priv_Part_Node := Next_Sibling (Current_Node => Next_Sibling (Current_Node => Anno_Node));
      -- ASSUME Priv_Part_Node = private_part OR dotted_simple_name
      if Syntax_Node_Type (Node => Priv_Part_Node) = SP_Symbols.private_part then
         -- ASSUME Private_Part = private_part
         Priv_Part_Node := Child_Node (Current_Node => Priv_Part_Node);
      elsif Syntax_Node_Type (Node => Priv_Part_Node) = SP_Symbols.dotted_simple_name then
         -- ASSUME Priv_Part_Node = dotted_simple_name
         Priv_Part_Node := STree.NullNode;
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Priv_Part_Node = private_part OR dotted_simple_name in Get_Package_Specification_Key_Nodes");
      end if;
      -- ASSUME Priv_Part_Node = basic_declarative_item_rep OR hidden_part OR NULL
      SystemErrors.RT_Assert
        (C       => Priv_Part_Node = STree.NullNode
           or else Syntax_Node_Type (Node => Priv_Part_Node) = SP_Symbols.basic_declarative_item_rep
           or else Syntax_Node_Type (Node => Priv_Part_Node) = SP_Symbols.hidden_part,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Private_Part = basic_declarative_item_rep OR hidden_part OR NULL " &
           "in Get_Package_Specification_Key_Nodes");
   end Get_Package_Specification_Key_Nodes;

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

   procedure Wf_Anno
     (Node       : in     STree.SyntaxNode;
      Pack_Sym   : in     Dictionary.Symbol;
      Scope_Type : in     Enclosing_Scope_Types;
      Scope      : in     Dictionary.Scopes;
      The_Heap   : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         Scope,
   --#                                         Scope_Type,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         Scope,
   --#                                         Scope_Type,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.package_annotation;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Wf_Visible
     (Node           : in     STree.SyntaxNode;
      Pack_Sym       : in     Dictionary.Symbol;
      Current_Scope  : in     Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData;
      The_Heap       : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.visible_part_rep;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Check_Deferred_Items (Error_Pos : in LexTokenManager.Token_Position;
                                   Pack_Sym  : in Dictionary.Symbol)
   --# 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,
   --#                                         Error_Pos,
   --#                                         LexTokenManager.State,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
   is
      It  : Dictionary.Iterator;
      Sym : Dictionary.Symbol;
   begin
      It := Dictionary.First_Deferred_Constant (The_Package => Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Sym := Dictionary.CurrentSymbol (It);
         if not Dictionary.Is_Declared (Item => Sym) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 26,
               Reference => ErrorHandler.No_Reference,
               Position  => Error_Pos,
               Id_Str    => Dictionary.GetSimpleName (Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;

      It := Dictionary.First_Private_Type (The_Package => Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         Sym := Dictionary.CurrentSymbol (It);
         if not Dictionary.Is_Declared (Item => Sym) then
            ErrorHandler.Semantic_Error
              (Err_Num   => 27,
               Reference => ErrorHandler.No_Reference,
               Position  => Error_Pos,
               Id_Str    => Dictionary.GetSimpleName (Sym));
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Deferred_Items;

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

   procedure Check_Types_Can_Be_Used
     (Pack_Sym     : in Dictionary.Symbol;
      Err_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,
   --#                                         Err_Node_Pos,
   --#                                         LexTokenManager.State,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys;
      is separate;

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

   procedure Check_Modes
     (Node     : in     STree.SyntaxNode;
      Pack_Sym : in     Dictionary.Symbol;
      The_Heap : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         Statistics.TableUsage,
   --#         The_Heap                   from *,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.visible_part_rep;
      is separate;

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

   procedure Wf_Private
     (Node           : in     STree.SyntaxNode;
      Current_Scope  : in     Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData;
      The_Heap       : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.basic_declarative_item_rep;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Check_Body_Required_By_Spark (Node_Pos : in LexTokenManager.Token_Position;
                                           Pack_Sym : in Dictionary.Symbol)
   --# 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;
   begin
      It := Dictionary.FirstInitializedOwnVariable (Pack_Sym);
      while not Dictionary.IsNullIterator (It) loop
         if Dictionary.Is_Declared (Item => Dictionary.CurrentSymbol (It))
           and then not Dictionary.VariableIsInitialized (Dictionary.CurrentSymbol (It)) then
            case CommandLineData.Content.Language_Profile is
               when CommandLineData.SPARK83 =>
                  ErrorHandler.Semantic_Warning (Err_Num  => 407,
                                                 Position => Node_Pos,
                                                 Id_Str   => LexTokenManager.Null_String);
               when CommandLineData.SPARK95_Onwards =>
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 607,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Pos,
                     Id_Str    => LexTokenManager.Null_String);
            end case;
            exit;
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end Check_Body_Required_By_Spark;

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

   procedure Check_State_Can_Be_Initialized (Pack_Sym  : in Dictionary.Symbol;
                                             Anno_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 Anno_Node,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Anno_Node, STree.Table) = SP_Symbols.package_annotation;
      is separate;

begin -- Wf_Package_Specification
   Get_Package_Specification_Key_Nodes
     (Node           => Node,
      Anno_Node      => Anno_Node,
      Ident_Node     => Ident_Node,
      Vis_Part_Node  => Vis_Part_Node,
      Priv_Part_Node => Priv_Part_Node);
   -- tells us where package is being declared
   Find_Enclosing_Scope_Type (Scope                => Current_Scope,
                              Enclosing_Scope_Type => Enclosing_Scope_Type);

   Pack_Vis_Scope := Dictionary.Set_Visibility (The_Visibility => Dictionary.Visible,
                                                The_Unit       => Pack_Sym);

   --# assert STree.Table = STree.Table~ and
   --#   Syntax_Node_Type (Anno_Node, STree.Table) = SP_Symbols.package_annotation and
   --#   Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.identifier and
   --#   Syntax_Node_Type (Vis_Part_Node, STree.Table) = SP_Symbols.visible_part_rep;
   Wf_Anno
     (Node       => Anno_Node,
      Pack_Sym   => Pack_Sym,
      Scope_Type => Enclosing_Scope_Type,
      Scope      => Pack_Vis_Scope,
      The_Heap   => The_Heap);

   Wf_Visible
     (Node           => Vis_Part_Node,
      Pack_Sym       => Pack_Sym,
      Current_Scope  => Pack_Vis_Scope,
      Component_Data => Component_Data,
      The_Heap       => The_Heap);

   --# assert STree.Table = STree.Table~ and
   --#   Syntax_Node_Type (Anno_Node, STree.Table) = SP_Symbols.package_annotation and
   --#   Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.identifier and
   --#   Syntax_Node_Type (Vis_Part_Node, STree.Table) = SP_Symbols.visible_part_rep;

   -- ASSUME Priv_Part_Node = basic_declarative_item_rep OR hidden_part OR NULL
   if Priv_Part_Node = STree.NullNode then
      -- ASSUME Priv_Part_Node = NULL
      -- no private part
      End_Name_Node := Last_Sibling_Of (Start_Node => Anno_Node);
      -- ASSUME End_Name_Node = dotted_simple_name
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => End_Name_Node) = SP_Symbols.dotted_simple_name,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect End_Name_Node = dotted_simple_name in Wf_Package_Specification");
      Check_Closing_Identifier (End_Name_Node => End_Name_Node,
                                Ident_Node    => Ident_Node);
      Check_Deferred_Items
        (Error_Pos => Node_Position (Node => Child_Node (Current_Node => End_Name_Node)),
         Pack_Sym  => Pack_Sym);
      Check_Types_Can_Be_Used (Pack_Sym     => Pack_Sym,
                               Err_Node_Pos => Node_Position (Node => End_Name_Node));
   elsif Syntax_Node_Type (Node => Priv_Part_Node) = SP_Symbols.hidden_part then
      -- ASSUME Priv_Part_Node = hidden_part
      Dictionary.AddPrivatePart
        (Pack_Sym,
         Dictionary.Location'(Start_Position => Node_Position (Node => Priv_Part_Node),
                              End_Position   => Node_Position (Node => Priv_Part_Node)),
         True);
      ErrorHandler.Hidden_Text
        (Position => Node_Position (Node => Priv_Part_Node),
         Unit_Str => Ident_Str,
         Unit_Typ => SP_Symbols.private_part);
      Check_Types_Can_Be_Used (Pack_Sym     => Pack_Sym,
                               Err_Node_Pos => Node_Position (Node => Priv_Part_Node));
   elsif Syntax_Node_Type (Node => Priv_Part_Node) = SP_Symbols.basic_declarative_item_rep then
      -- ASSUME Priv_Part_Node = basic_declarative_item_rep
      Dictionary.AddPrivatePart
        (Pack_Sym,
         Dictionary.Location'(Start_Position => Node_Position (Node => Priv_Part_Node),
                              End_Position   => Node_Position (Node => Priv_Part_Node)),
         False);
      Wf_Private
        (Node           => Priv_Part_Node,
         Current_Scope  => Dictionary.Set_Visibility (The_Visibility => Dictionary.Privat,
                                                      The_Unit       => Pack_Sym),
         Component_Data => Component_Data,
         The_Heap       => The_Heap);

      -- check that private types resolved into scalars have not
      -- invalidated parameter declarations of exported procedures
      if CommandLineData.Content.Language_Profile = CommandLineData.SPARK83 then
         -- guarded because '83 rules different from '95 onwards
         Check_Modes (Node     => Vis_Part_Node,
                      Pack_Sym => Pack_Sym,
                      The_Heap => The_Heap);
      end if;
      End_Name_Node := Next_Sibling (Current_Node => Priv_Part_Node);
      -- ASSUME End_Name_Node = dotted_simple_name
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => End_Name_Node) = SP_Symbols.dotted_simple_name,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect End_Name_Node = dotted_simple_name in Wf_Package_Specification");
      Check_Closing_Identifier (End_Name_Node => End_Name_Node,
                                Ident_Node    => Ident_Node);
      Check_Deferred_Items
        (Error_Pos => Node_Position (Node => Child_Node (Current_Node => End_Name_Node)),
         Pack_Sym  => Pack_Sym);
      Check_Types_Can_Be_Used (Pack_Sym     => Pack_Sym,
                               Err_Node_Pos => Node_Position (Node => End_Name_Node));
   else
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Private_Part = basic_declarative_item_rep OR hidden_part OR NULL in Wf_Package_Specification");
   end if;

   -- check for cases where package requires a body
   --# assert STree.Table = STree.Table~ and
   --#   Syntax_Node_Type (Anno_Node, STree.Table) = SP_Symbols.package_annotation;
   if Enclosing_Scope_Type = In_Library and then not Dictionary.PackageRequiresBody (Pack_Sym) then
      End_Pos_Node := Last_Sibling_Of (Start_Node => Anno_Node);
      -- ASSUME End_Pos_Node = private_part OR dotted_simple_name
      if Syntax_Node_Type (Node => End_Pos_Node) = SP_Symbols.private_part then
         -- ASSUME End_Pos_Node = private_part
         -- declaring a library package for which Ada rules do not demand a body so
         -- checks must be made to see if Spark rules require a body
         End_Pos_Node := Child_Node (Current_Node => End_Pos_Node);
         -- ASSUME End_Pos_Node = basic_declarative_item_rep OR hidden_part
         if Syntax_Node_Type (Node => End_Pos_Node) = SP_Symbols.basic_declarative_item_rep then
            End_Pos_Node := Next_Sibling (Current_Node => End_Pos_Node);
         elsif Syntax_Node_Type (Node => End_Pos_Node) /= SP_Symbols.hidden_part then
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect End_Pos_Node = basic_declarative_item_rep OR hidden_part in Wf_Package_Specification");
         end if;
      elsif Syntax_Node_Type (Node => End_Pos_Node) /= SP_Symbols.dotted_simple_name then
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect End_Pos_Node = private_part OR dotted_simple_name in Wf_Package_Specification");
      end if;
      Check_Body_Required_By_Spark (Node_Pos => Node_Position (Node => End_Pos_Node),
                                    Pack_Sym => Pack_Sym);
   end if;

   Check_State_Can_Be_Initialized (Pack_Sym  => Pack_Sym,
                                   Anno_Node => Anno_Node);
   Check_Announced_Types_Declared
     (Pack_Sym => Pack_Sym,
      Scope    => Dictionary.Set_Visibility (The_Visibility => Dictionary.Visible,
                                             The_Unit       => Pack_Sym),
      Node_Pos => Node_Position (Node => Last_Sibling_Of (Start_Node => Anno_Node)));

   -- The cross-references for the own variables are generated
   -- after the full semantic analysis of the package
   -- specification because we need to know if an own variable is
   -- actually an abstract own variable or a visble concrete own
   -- variable. If it is an abstract own variable, the own
   -- variable is considered as a declaration, if it is a visible
   -- concrete own variable, the own variable is a usage of the
   -- visible concrete variable that will be declared later in the
   -- same package specification. If the declaration of the
   -- concrete variable only appears in the package body, the own
   -- variable is considered as an abstract declaration.
   if ErrorHandler.Generate_SLI and then Child_Node (Current_Node => Anno_Node) /= STree.NullNode then
      SLI.Generate_Xref_Own
        (Comp_Unit  => ContextManager.Ops.Current_Unit,
         Parse_Tree => Child_Node (Current_Node => Anno_Node),
         Scope      => Pack_Vis_Scope);
   end if;
end Wf_Package_Specification;
