-------------------------------------------------------------------------------
-- (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 Error_Types;
with VCG;

separate (Sem)
procedure CompUnit (Top_Node : in STree.SyntaxNode;
                    Do_VCG   : in Boolean) is

   type Hidden_Class is (Not_Hidden, Handler_Hidden, All_Hidden);

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

   --# inherit ExaminerConstants,
   --#         SPARK_IO,
   --#         SystemErrors;
   package Stack
   --# own State;
   is

      procedure Init;
      --# global out State;
      --# derives State from ;

      procedure Push (X : in Boolean);
      --# global in out State;
      --# derives State from *,
      --#                    X;

      procedure Pop;
      --# global in out State;
      --# derives State from *;

      -- Note: this is not a proper function as it has a hidden
      --       side effect if a system error is raised
      function Top return Boolean;
      --# global in State;

   end Stack;

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

   --------------- Procedure variables -----------------------------

   Semantic_Error_In_Subprogram_Body   : Boolean;
   Data_Flow_Error_In_Subprogram_Body  : Boolean;
   Unused_Data_Flow_Error_Flag         : Boolean;
   Stmt_Node, Last_Node, Next_Node     : STree.SyntaxNode;
   NodeType                            : SP_Symbols.SP_Symbol;
   ErrStatus                           : ErrorHandler.Error_Level;
   Err_Num_On_Success                  : Error_Types.ErrNumRange;
   Current_Scope                       : Dictionary.Scopes;
   TheHeap                             : Heap.HeapRecord;
   NodeTable                           : RefList.HashTable;
   GlobalComponentData                 : ComponentManager.ComponentData;
   Unused                              : Dictionary.Symbol;
   Package_Body_Withs_Own_Public_Child : Boolean;

   -------------- Package bodies ------------------------------

   package body Stack is separate;

   ------------------------------------------------------------
   ---------------- Embedded subprograms ----------------------
   ------------------------------------------------------------

   -- Returns whether a subprogram_implementation node has a fully hidden body,
   -- a hidden handler part, or no hiding at all.  This code depends on the grammar
   -- in SPARK.LLA section 6.3
   function Body_Hidden_Class (Node : STree.SyntaxNode) return Hidden_Class
   --# global in STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.subprogram_implementation;
   is
      Result          : Hidden_Class;
      Pragma_Rep_Node : STree.SyntaxNode;
      End_Node        : STree.SyntaxNode;
   begin
      Pragma_Rep_Node := Child_Node (Current_Node => Node);
      -- ASSUME Pragma_Rep_Node = pragma_rep
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Pragma_Rep_Node) = SP_Symbols.pragma_rep,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Pragma_Rep_Node = pragma_rep in Body_Hidden_Class");
      -- if the Pragma_Rep is immediately followed by hidden part, then the whole
      -- body must be hidden.  If the PragmaRep is followed by something else, then
      -- we _might_ have a hidden handler part at End_Node.
      End_Node := Next_Sibling (Current_Node => Pragma_Rep_Node);
      -- ASSUME End_Node = declarative_part OR sequence_of_statements OR code_insertion OR hidden_part
      if Syntax_Node_Type (Node => End_Node) = SP_Symbols.hidden_part then
         -- ASSUME End_Node = hidden_part
         Result := All_Hidden;
      elsif Syntax_Node_Type (Node => End_Node) = SP_Symbols.declarative_part
        or else Syntax_Node_Type (Node => End_Node) = SP_Symbols.sequence_of_statements
        or else Syntax_Node_Type (Node => End_Node) = SP_Symbols.code_insertion then
         -- ASSUME End_Node = declarative_part OR sequence_of_statements OR code_insertion
         End_Node := Last_Sibling_Of (Start_Node => End_Node);
         -- ASSUME End_Node = designator OR hidden_part
         if Syntax_Node_Type (Node => End_Node) = SP_Symbols.hidden_part then
            -- ASSUME End_Node = hidden_part
            Result := Handler_Hidden;
         elsif Syntax_Node_Type (Node => End_Node) = SP_Symbols.designator then
            -- ASSUME End_Node = designator
            Result := Not_Hidden;
         else
            Result := Not_Hidden;
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect End_Node = designator OR hidden_part in Body_Hidden_Class");
         end if;
      else
         Result := Not_Hidden;
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect End_Node =  declarative_part OR sequence_of_statements OR code_insertion OR " &
              "hidden_part in Body_Hidden_Class");
      end if;
      return Result;
   end Body_Hidden_Class;

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

   procedure Wf_Use_Type_Clause (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,
   --#                                         Node,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.use_type_clause;
      is separate;

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

   procedure Wf_Proof_Renaming_Declaration (Node  : in STree.SyntaxNode;
                                            Scope : in Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.proof_renaming_declaration;
      is separate;

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

   procedure WalkStatements
     (Seq_Node       : in     STree.SyntaxNode;
      Scope          : in     Dictionary.Scopes;
      Table          : in out RefList.HashTable;
      Component_Data :    out ComponentManager.ComponentData)
   --# 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;
   --#        in out TheHeap;
   --# derives Aggregate_Stack.State,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         Table,
   --#         TheHeap                    from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         Seq_Node,
   --#                                         STree.Table,
   --#                                         Table,
   --#                                         TheHeap &
   --#         Component_Data             from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         Seq_Node,
   --#                                         STree.Table,
   --#                                         Table,
   --#                                         TheHeap &
   --#         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,
   --#                                         Scope,
   --#                                         Seq_Node,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         Table,
   --#                                         TheHeap;
   --# pre Syntax_Node_Type (Seq_Node, STree.Table) = SP_Symbols.sequence_of_statements;
   --# post STree.Table = STree.Table~;
      is separate;

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

   -- function used by wf_subprogram_body and wf_body_stub

   function Has_Parameter_Global_Or_Return_Of_Local_Private_Type (Subprog_Sym : Dictionary.Symbol) return Boolean
   --# global in Dictionary.Dict;
   -- returns true if the subprogram has a parameter or global which is of a private type
   -- but which is not private when viewd from the subprogram
   is
      Result   : Boolean := False;
      It       : Dictionary.Iterator;
      Type_Sym : Dictionary.Symbol;

      function Is_Private_But_Not_Private_Here (Type_Sym    : Dictionary.Symbol;
                                                Subprog_Sym : Dictionary.Symbol) return Boolean
      --# global in Dictionary.Dict;
      is
      begin
         return Dictionary.TypeIsPrivate (TheType => Type_Sym)
           and then not Dictionary.IsPrivateType
           (Type_Sym,
            Dictionary.Set_Visibility (The_Visibility => Dictionary.Local,
                                       The_Unit       => Subprog_Sym));
      end Is_Private_But_Not_Private_Here;

   begin -- Has_Parameter_Global_Or_Return_Of_Local_Private_Type

      -- iterate through parameters
      It := Dictionary.FirstSubprogramParameter (Subprog_Sym);
      while It /= Dictionary.NullIterator loop
         Type_Sym := Dictionary.GetType (Dictionary.CurrentSymbol (It));
         Result   := Is_Private_But_Not_Private_Here (Type_Sym    => Type_Sym,
                                                      Subprog_Sym => Subprog_Sym);
         exit when Result;

         It := Dictionary.NextSymbol (It);
      end loop;

      if not Result then -- no parameters were private, so check globals
         It := Dictionary.FirstGlobalVariable (Dictionary.IsAbstract, Subprog_Sym);
         while It /= Dictionary.NullIterator loop
            Type_Sym := Dictionary.GetType (Dictionary.CurrentSymbol (It));
            Result   := Is_Private_But_Not_Private_Here (Type_Sym    => Type_Sym,
                                                         Subprog_Sym => Subprog_Sym);
            exit when Result;

            It := Dictionary.NextSymbol (It);
         end loop;
      end if;

      -- no parameters or globals were private, so check for function return type.
      if not Result then
         if Dictionary.IsFunction (Subprog_Sym) then
            Type_Sym := Dictionary.GetType (Subprog_Sym);
            Result   := Is_Private_But_Not_Private_Here (Type_Sym    => Type_Sym,
                                                         Subprog_Sym => Subprog_Sym);
         end if;
      end if;

      return Result;
   end Has_Parameter_Global_Or_Return_Of_Local_Private_Type;

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

   procedure Wf_Subprogram_Body
     (Node           : in     STree.SyntaxNode;
      Scope          : in out Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData;
      Next_Node      :    out STree.SyntaxNode)
   --# 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;
   --#        in out TheHeap;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         TheHeap                    from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         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,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         Next_Node,
   --#         Scope                      from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.subprogram_body or
   --#   Syntax_Node_Type (Node, STree.Table) = SP_Symbols.not_overriding_subprogram_body;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Wf_Entry_Body
     (Node           : in     STree.SyntaxNode;
      Scope          : in out Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData;
      Next_Node      :    out STree.SyntaxNode)
   --# 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;
   --#        in out TheHeap;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         TheHeap                    from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         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,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         Next_Node,
   --#         Scope                      from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.entry_body;
   --# post (Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.subprogram_implementation or
   --#         Next_Node = STree.NullNode) and
   --#   STree.Table = STree.Table~;
      is separate;

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

   procedure Wf_Proof_Function_Declaration
     (Node           : in     STree.SyntaxNode;
      Current_Scope  : in     Dictionary.Scopes;
      The_Heap       : in out Heap.HeapRecord;
      Proof_Func_Sym :    out Dictionary.Symbol)
   --# 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,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         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,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         Proof_Func_Sym             from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.proof_function_declaration;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Wf_Body_Stub
     (Node           : in     STree.SyntaxNode;
      Scope          : in     Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData)
   --# 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;
   --#        in out TheHeap;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         TheHeap                    from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         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,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         TheHeap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.body_stub;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Wf_Subunit (Node  : in     STree.SyntaxNode;
                         Scope : in out Dictionary.Scopes)
   --# 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,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Scope,
   --#         STree.Table                from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.subunit;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure CheckEmbedBodies (Comp_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,
   --#                                         Comp_Sym,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node_Pos,
   --#                                         SPARK_IO.File_Sys;
      is separate;

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

   procedure CheckSuspendsListAccountedFor
     (Proc_Or_Task : 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,
   --#                                         Proc_Or_Task,
   --#                                         SPARK_IO.File_Sys;
      is separate;

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

   procedure Up_Wf_Subprogram_Body (Node  : in     STree.SyntaxNode;
                                    Scope : in out Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Scope                      from *,
   --#                                         Dictionary.Dict;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.subprogram_body or
   --#   Syntax_Node_Type (Node, STree.Table) = SP_Symbols.not_overriding_subprogram_body;
      is separate;

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

   -- PNA temporary reduced annotation for phase 1 generics cfr 1340

   procedure Wf_Generic_Package_Instantiation (Node  : in STree.SyntaxNode;
                                               Scope : in Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.generic_package_instantiation;
      is separate;

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

   procedure Wf_Generic_Declaration (Node          : in STree.SyntaxNode;
                                     Current_Scope : in Dictionary.Scopes)
   --# 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 GlobalComponentData;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --#        in out TheHeap;
   --# derives Aggregate_Stack.State,
   --#         Dictionary.Dict,
   --#         GlobalComponentData,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         TheHeap                    from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         GlobalComponentData,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         GlobalComponentData,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         TheHeap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.generic_declaration;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure CheckPackageNeedsBody (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 separate;

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

   procedure Wf_Package_Body
     (Node              : in     STree.SyntaxNode;
      Scope             : in out Dictionary.Scopes;
      With_Public_Child :    out Boolean)
   --# 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,
   --#         Scope,
   --#         STree.Table,
   --#         With_Public_Child          from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.package_body;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Up_Wf_Package_Body
     (Node                   : in     STree.SyntaxNode;
      Scope                  : in out Dictionary.Scopes;
      Withs_Own_Public_Child : in     Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --# derives ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         Withs_Own_Public_Child &
   --#         Scope                      from *,
   --#                                         Dictionary.Dict &
   --#         SLI.State                  from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         Withs_Own_Public_Child &
   --#         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,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         STree.Table,
   --#                                         Withs_Own_Public_Child;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.package_body;
      is separate;

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

   procedure Wf_Package_Initialization (Node  : in STree.SyntaxNode;
                                        Scope : in Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.package_initialization;
      is separate;

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

   procedure Wf_Protected_Body
     (Node      : in     STree.SyntaxNode;
      Scope     : in out Dictionary.Scopes;
      Next_Node :    out STree.SyntaxNode)
   --# 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,
   --#         Next_Node,
   --#         Scope,
   --#         STree.Table                from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.protected_body;
   --# post STree.Table = STree.Table~ and
   --#   (Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.protected_operation_item or
   --#      Next_Node = STree.NullNode);
      is separate;

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

   procedure Up_Wf_Protected_Body (Node  : in     STree.SyntaxNode;
                                   Scope : in out Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Scope                      from *,
   --#                                         Dictionary.Dict;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.protected_body;
      is separate;

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

   procedure Wf_Task_Body
     (Node      : in     STree.SyntaxNode;
      Scope     : in out Dictionary.Scopes;
      Next_Node :    out STree.SyntaxNode)
   --# 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;
   --#        in out TheHeap;
   --# derives Aggregate_Stack.State,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         TheHeap                    from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         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,
   --#                                         Scope,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         TheHeap &
   --#         Next_Node,
   --#         Scope                      from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.task_body;
   --# post STree.Table = STree.Table~ and
   --#   (Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.subprogram_implementation or Next_Node = STree.NullNode);
      is separate;

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

   procedure Up_Wf_Task_Body (Node  : in     STree.SyntaxNode;
                              Scope : in out Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         Scope                      from *,
   --#                                         Dictionary.Dict;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.task_body;
      is separate;

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

   procedure Wf_Machine_Code_Insertion (Node  : in STree.SyntaxNode;
                                        Scope : in Dictionary.Scopes)
   --# 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,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.code_insertion;
      is separate;

begin -- CompUnit
   Package_Body_Withs_Own_Public_Child := False;
   Next_Node                           := Top_Node;
   Stack.Init;
   Heap.Initialize (TheHeap);
   RefList.Init (NodeTable);
   Aggregate_Stack.Init;
   ComponentManager.Initialise (GlobalComponentData);

   Current_Scope := Dictionary.GlobalScope;

   while Next_Node /= STree.NullNode
   --# assert STree.Table = STree.Table~;
   loop
      Last_Node := Next_Node;
      NodeType  := Syntax_Node_Type (Node => Last_Node);
      case NodeType is
         when SP_Symbols.package_declaration | SP_Symbols.private_package_declaration =>
            -- ASSUME Last_Node = package_declaration OR private_package_declaration
            ErrorHandler.Start_Unit;
            Wf_Package_Declaration
              (Node           => Last_Node,
               Current_Scope  => Current_Scope,
               Component_Data => GlobalComponentData,
               The_Heap       => TheHeap);
            ErrorHandler.End_Unit;
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.generic_declaration =>
            -- ASSUME Last_Node = generic_declaration
            ErrorHandler.Start_Unit;
            Wf_Generic_Declaration (Node          => Last_Node,
                                    Current_Scope => Current_Scope);
            ErrorHandler.End_Unit;
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.generic_package_instantiation =>
            -- ASSUME Last_Node = generic_package_instantiation
            Wf_Generic_Package_Instantiation (Node  => Last_Node,
                                              Scope => Current_Scope);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.generic_subprogram_instantiation =>
            -- ASSUME Last_Node = generic_subprogram_instantiation
            Wf_Generic_Subprogram_Instantiation
              (Node           => Last_Node,
               Scope          => Current_Scope,
               Component_Data => GlobalComponentData,
               The_Heap       => TheHeap);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.package_body =>
            -- ASSUME Last_Node = package_body
            ErrorHandler.Start_Unit;
            Wf_Package_Body (Node              => Last_Node,
                             Scope             => Current_Scope,
                             With_Public_Child => Package_Body_Withs_Own_Public_Child);
            Next_Node := Child_Node (Current_Node => Last_Node);
         when SP_Symbols.subprogram_body | SP_Symbols.not_overriding_subprogram_body =>
            -- ASSUME Last_Node = subprogram_body OR not_overriding_subprogram_body
            ErrorHandler.Error_Reset;
            ErrorHandler.Start_Unit;
            Wf_Subprogram_Body
              (Node           => Last_Node,
               Scope          => Current_Scope,
               Component_Data => GlobalComponentData,
               Next_Node      => Next_Node);
            ErrorHandler.Get_Error_Severity (Severity => ErrStatus);
            if ErrStatus = ErrorHandler.No_Error then
               Stack.Push (False);
            else
               Stack.Push (True);
            end if;
         when SP_Symbols.entry_body =>
            -- ASSUME Last_Node = entry_body
            ErrorHandler.Error_Reset;
            ErrorHandler.Start_Unit;
            Wf_Entry_Body (Node           => Last_Node,
                           Scope          => Current_Scope,
                           Component_Data => GlobalComponentData,
                           Next_Node      => Next_Node);
            ErrorHandler.Get_Error_Severity (Severity => ErrStatus);
            if ErrStatus = ErrorHandler.No_Error then
               Stack.Push (False);
            else
               Stack.Push (True);
            end if;
         when SP_Symbols.task_body =>
            -- ASSUME Last_Node = task_body
            --# accept Flow, 41, "Expected stable expression";
            if CommandLineData.Ravenscar_Selected then
               --# end accept;
               ErrorHandler.Error_Reset;
               ErrorHandler.Start_Unit;
               Wf_Task_Body (Node      => Last_Node,
                             Scope     => Current_Scope,
                             Next_Node => Next_Node);
               ErrorHandler.Get_Error_Severity (Severity => ErrStatus);
               if ErrStatus = ErrorHandler.No_Error then
                  Stack.Push (False);
               else
                  Stack.Push (True);
               end if;
            else -- can't use task except in Ravenscar
               ErrorHandler.Semantic_Error
                 (Err_Num   => 850,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Last_Node),
                  Id_Str    => LexTokenManager.Null_String);
               -- prune tree walk, we don't want to enter this production when it's illegal
               Next_Node := STree.NullNode;
            end if;
         when SP_Symbols.protected_body =>
            -- ASSUME Last_Node = protected_body
            --# accept Flow, 41, "Expected stable expression";
            if CommandLineData.Ravenscar_Selected then
               --# end accept;
               ErrorHandler.Start_Unit;
               Wf_Protected_Body (Node      => Last_Node,
                                  Scope     => Current_Scope,
                                  Next_Node => Next_Node);
            else -- can't use protected type except in Ravenscar
               ErrorHandler.Semantic_Error
                 (Err_Num   => 850,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Last_Node),
                  Id_Str    => LexTokenManager.Null_String);
               -- prune tree walk, we don't want to enter this production when it's illegal
               Next_Node := STree.NullNode;
            end if;
         when SP_Symbols.body_stub =>
            -- ASSUME Last_Node = body_stub
            Wf_Body_Stub (Node           => Last_Node,
                          Scope          => Current_Scope,
                          Component_Data => GlobalComponentData);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.subunit =>
            -- ASSUME Last_Node = subunit
            Wf_Subunit (Node  => Last_Node,
                        Scope => Current_Scope);
            Next_Node := Child_Node (Current_Node => Last_Node);
            -- ASSUME Next_Node = parent_unit_name
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.parent_unit_name,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Next_Node = parent_unit_name in CompUnit");
         when SP_Symbols.proof_function_declaration =>
            -- ASSUME Last_Node = proof_function_declaration
            --# accept Flow, 10, Unused, "Expected ineffective assignment to Unused";
            Wf_Proof_Function_Declaration
              (Node           => Last_Node,
               Current_Scope  => Current_Scope,
               The_Heap       => TheHeap,
               Proof_Func_Sym => Unused);
            --# end accept;
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.basic_declarative_item =>
            -- ASSUME Last_Node = basic_declarative_item
            Wf_Basic_Declarative_Item
              (Node           => Last_Node,
               Current_Scope  => Current_Scope,
               Component_Data => GlobalComponentData,
               The_Heap       => TheHeap);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.renaming_declaration =>
            -- ASSUME Last_Node = renaming_declaration
            Wf_Renaming_Declaration (Node  => Last_Node,
                                     Scope => Current_Scope);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.proof_renaming_declaration =>
            -- ASSUME Last_Node = proof_renaming_declaration
            Wf_Proof_Renaming_Declaration (Node  => Last_Node,
                                           Scope => Current_Scope);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.use_type_clause =>
            -- ASSUME Last_Node = use_type_clause
            Wf_Use_Type_Clause (Node => Last_Node);
            Next_Node := STree.NullNode; -- nothing below here used
         when SP_Symbols.sequence_of_statements =>
            -- ASSUME Last_Node = sequence_of_statements
            Heap.ReportUsage (TheHeap);
            Heap.Reset (TheHeap);
            RefList.Init (NodeTable);
            WalkStatements (Seq_Node       => Last_Node,
                            Scope          => Current_Scope,
                            Table          => NodeTable,
                            Component_Data => GlobalComponentData);
            ComponentManager.ReportUsage (GlobalComponentData);
            Next_Node := STree.NullNode;
         when SP_Symbols.package_initialization =>
            -- ASSUME Last_Node = package_initialization
            Wf_Package_Initialization (Node  => Last_Node,
                                       Scope => Current_Scope);
            ErrorHandler.Error_Reset;
            Next_Node := Child_Node (Last_Node);
            -- ASSUME Next_Node = sequence_of_statements OR hidden_part
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.sequence_of_statements
                 or else Syntax_Node_Type (Node => Next_Node) = SP_Symbols.hidden_part,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Next_Node = sequence_of_statements OR hidden_part in CompUnit");
         when SP_Symbols.apragma =>
            -- ASSUME Last_Node = apragma
            Wf_Pragma (Node  => Last_Node,
                       Scope => Current_Scope);
            Next_Node := STree.NullNode;
         when SP_Symbols.code_insertion =>
            -- ASSUME Last_Node = code_insertion
            Wf_Machine_Code_Insertion (Node  => Last_Node,
                                       Scope => Current_Scope);
            Next_Node := STree.NullNode;
            -- following series of cases are places where we prune tree walk
            -- because there is nothing below node of use to us
         when SP_Symbols.with_clause           |
           SP_Symbols.code_statement        | -- probably can't reach this one any more
           SP_Symbols.context_clause_rep    |
           SP_Symbols.refinement_definition =>
            -- ASSUME Last_Node = with_clause OR code_statement OR context_clause_rep OR refinement_definition
            Next_Node := STree.NullNode;
            -- this tests for whether down loop end has been reached at a terminal
         when others =>
            if NodeType in SP_Symbols.SP_Non_Terminal then
               Next_Node := Child_Node (Current_Node => Last_Node);
            else
               Next_Node := STree.NullNode;
            end if;
      end case;

      if Next_Node = STree.NullNode then ------up loop----------
         loop
            --# assert STree.Table = STree.Table~;
            Next_Node := Next_Sibling (Current_Node => Last_Node);
            exit when Next_Node /= STree.NullNode;

            Next_Node := Parent_Node (Current_Node => Last_Node);
            exit when Next_Node = STree.NullNode;

            Last_Node := Next_Node;
            case Syntax_Node_Type (Node => Last_Node) is
               when SP_Symbols.package_body =>
                  -- ASSUME Last_Node = package_body
                  Up_Wf_Package_Body
                    (Node                   => Last_Node,
                     Scope                  => Current_Scope,
                     Withs_Own_Public_Child => Package_Body_Withs_Own_Public_Child);
                  ErrorHandler.End_Unit;
               when SP_Symbols.protected_body =>
                  -- ASSUME Last_Node = protected_body
                  Up_Wf_Protected_Body (Node  => Last_Node,
                                        Scope => Current_Scope);
                  ErrorHandler.End_Unit;
               when SP_Symbols.task_body =>
                  -- ASSUME Last_Node = task_body
                  Up_Wf_Task_Body (Node  => Last_Node,
                                   Scope => Current_Scope);
                  Stack.Pop;
                  ErrorHandler.Error_Reset;
                  ErrorHandler.End_Unit;
               when SP_Symbols.entry_body =>
                  -- ASSUME Last_Node = entry_body
                  Current_Scope := Dictionary.GetEnclosingScope (Current_Scope);
                  Stack.Pop;
                  ErrorHandler.Error_Reset;
                  ErrorHandler.End_Unit;
               when SP_Symbols.package_initialization =>
                  -- ASSUME Last_Node = package_initialization
                  Stmt_Node := Child_Node (Current_Node => Last_Node);
                  ErrorHandler.Get_Error_Severity (Severity => ErrStatus);
                  if Syntax_Node_Type (Node => Stmt_Node) /= SP_Symbols.hidden_part
                    and then ErrStatus = ErrorHandler.No_Error then
                     --# accept Flow, 10, Unused_Data_Flow_Error_Flag,
                     --#        "Expected ineffective assignment to Unused_Data_Flow_Error_Flag";
                     FlowAnalyser.FlowAnalyse
                       (Dictionary.GetRegion (Current_Scope),
                        Stmt_Node,
                        Node_Position (Node => Next_Sibling (Current_Node => Stmt_Node)),
                        GlobalComponentData,
                        TheHeap,
                        NodeTable,
                        Unused_Data_Flow_Error_Flag);
                     --# end accept;
                     ErrorHandler.Get_Error_Severity (Severity => ErrStatus);

                     if ErrStatus = ErrorHandler.No_Error then
                        ErrorHandler.Report_Success
                          (Position    => Node_Position (Node => Next_Sibling (Current_Node => Stmt_Node)),
                           Subprog_Str => LexTokenManager.Null_String,
                           Err_Num     => ErrorHandler.No_Error_Default);
                     end if;
                  end if;

               when SP_Symbols.subprogram_implementation =>
                  -- ASSUME Last_Node = subprogram_implementation
                  Stmt_Node := Child_Node (Current_Node => Last_Node);
                  while Stmt_Node /= STree.NullNode
                    and then Syntax_Node_Type (Node => Stmt_Node) /= SP_Symbols.sequence_of_statements
                  --# assert STree.Table = STree.Table~;
                  loop
                     Stmt_Node := Next_Sibling (Current_Node => Stmt_Node);
                  end loop;
                  if Stmt_Node /= STree.NullNode then
                     ErrorHandler.Get_Error_Severity (Severity => ErrStatus);
                     Semantic_Error_In_Subprogram_Body  := not (ErrStatus = ErrorHandler.No_Error and then Stack.Top = False);
                     Data_Flow_Error_In_Subprogram_Body := False; -- default in case flow analyser not called below
                     if not Semantic_Error_In_Subprogram_Body then
                        -- don't do flow analysis in presence of semantic errors
                        FlowAnalyser.FlowAnalyse
                          (Dictionary.GetRegion (Current_Scope),
                           Stmt_Node,
                           Node_Position (Node => Next_Sibling (Current_Node => Stmt_Node)),
                           GlobalComponentData,
                           TheHeap,
                           NodeTable,
                           -- to get
                           Data_Flow_Error_In_Subprogram_Body);

                        -- If flow=auto then issue a note informing the user which flow analysis mode was used.
                        -- If it's a function or a procedure with a derives, then info flow is used, otherwise
                        -- data flow is used. Don't need to worry about 83/95/2005 because flow=auto is not
                        -- allowed in 83 mode.
                        Err_Num_On_Success := ErrorHandler.No_Error_Default;
                        --# accept F, 41, "Stable expression OK here";
                        if CommandLineData.Content.Flow_Option = CommandLineData.Auto_Flow then
                           if Dictionary.GetHasDerivesAnnotation (Dictionary.GetRegion (Current_Scope)) then
                              -- information flow
                              Err_Num_On_Success := ErrorHandler.No_Error_Info_Flow;
                           else
                              -- data flow
                              Err_Num_On_Success := ErrorHandler.No_Error_Data_Flow;
                           end if;
                        end if;
                        --# end accept;

                        ErrorHandler.Get_Error_Severity (Severity => ErrStatus);

                        if ErrStatus = ErrorHandler.No_Error then
                           ErrorHandler.Report_Success
                             (Position    => Node_Position (Node => Next_Sibling (Current_Node => Stmt_Node)),
                              Subprog_Str => Dictionary.GetSimpleName (Dictionary.GetRegion (Current_Scope)),
                              Err_Num     => Err_Num_On_Success);
                        end if;
                        ErrorHandler.Flush_Echo_Messages;
                     end if;
                     -- Call VCG regardless of error status (used to be inside above IF statement).  Instead, we pass
                     -- the error status to the VCG which generates a false VC for subprograms
                     -- containing static semantic errors
                     --# accept F, 41, "Language_Profile expected to be invariant";
                     if CommandLineData.Content.Language_Profile in CommandLineData.Auto_Code_Generators
                       and then not CommandLineData.Content.VCG then
                        ErrorHandler.Semantic_Warning
                          (Err_Num  => 425,
                           Position => Node_Position (Node => Next_Sibling (Current_Node => Stmt_Node)),
                           Id_Str   => LexTokenManager.Null_String);
                     end if;
                     --# end accept;
                     VCG.Generate_VCs
                       (Start_Node                    => Stmt_Node,
                        Scope                         => Current_Scope,
                        Do_VCG                        => Do_VCG,
                        End_Position                  => Node_Position (Node => Next_Sibling (Current_Node => Stmt_Node)),
                        Flow_Heap                     => TheHeap,
                        Semantic_Error_In_Subprogram  => Semantic_Error_In_Subprogram_Body,
                        Data_Flow_Error_In_Subprogram => Data_Flow_Error_In_Subprogram_Body,
                        Type_Check_Exports            => ErrorHandler.Possibly_Invalid_Values);
                  end if;

               when SP_Symbols.subprogram_body | SP_Symbols.not_overriding_subprogram_body =>
                  -- ASSUME Last_Node = subprogram_body OR not_overriding_subprogram_body
                  Up_Wf_Subprogram_Body (Node  => Last_Node,
                                         Scope => Current_Scope);
                  Stack.Pop;
                  ErrorHandler.Error_Reset;
                  ErrorHandler.End_Unit;
               when SP_Symbols.main_program_declaration =>
                  -- ASSUME Last_Node = main_program_declaration
                  if not Dictionary.Is_Null_Symbol (Dictionary.GetThePartition)
                    and then Dictionary.SubprogramSignatureIsWellformed (Dictionary.IsAbstract, Dictionary.GetThePartition) then
                     FlowAnalyser.FlowAnalysePartition (Node    => Last_Node,
                                                        TheHeap => TheHeap);
                  end if;
               when others =>
                  null;
            end case;
         end loop;
      end if;
   end loop;

   Heap.ReportUsage (TheHeap);

   --# accept Flow, 33, Unused, "Expected Unused to be neither referenced nor exported" &
   --#        Flow, 33, Unused_Data_Flow_Error_Flag, "Expected Unused_Data_Flow_Error_Flag to be neither referenced nor exported";
end CompUnit;
