-------------------------------------------------------------------------------
-- (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 Cells;
with Dictionary;
with LexTokenManager;
with Pairs;
with SPARK_IO;

use type Cells.Cell;
use type Cells.Cell_Kind;
use type Cells.Cell_Rank;
use type Dictionary.Abstractions;
use type Dictionary.Symbol;
use type LexTokenManager.Str_Comp_Result;

--# inherit AdjustFDL_RWs,
--#         Cells,
--#         Cell_Storage,
--#         Clists,
--#         CommandLineData,
--#         CStacks,
--#         DAG_IO,
--#         Debug,
--#         Dictionary,
--#         ErrorHandler,
--#         ExaminerConstants,
--#         E_Strings,
--#         LexTokenManager,
--#         Lists,
--#         Maths,
--#         Pairs,
--#         Pile,
--#         SPARK_IO,
--#         SP_Symbols,
--#         Statistics,
--#         Symbol_Set,
--#         SystemErrors;

package Declarations
--# own State;
--# initializes State;
is

   type UsedSymbolIterator is private;
   NullIterator : constant UsedSymbolIterator;

   procedure Initialize (It : out UsedSymbolIterator);
   --# global in State;
   --# derives It from State;

   function CurrentNode (It : in UsedSymbolIterator) return Cells.Cell;

   function NextNode (Heap : in Cells.Heap_Record;
                      It   : in UsedSymbolIterator) return UsedSymbolIterator;

   function IsNullIterator (It : in UsedSymbolIterator) return Boolean;

   procedure StartProcessing (Heap : in out Cells.Heap_Record);
   --# global in out Statistics.TableUsage;
   --#           out State;
   --# derives Heap,
   --#         Statistics.TableUsage from *,
   --#                                    Heap &
   --#         State                 from Heap;

   procedure Add (Heap   : in out Cells.Heap_Record;
                  Symbol : in     Dictionary.Symbol);
   --# global in     Dictionary.Dict;
   --#        in out State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         State,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    Heap,
   --#                                    State,
   --#                                    Symbol;

   procedure AddAttribute (Heap     : in out Cells.Heap_Record;
                           TickCell : in     Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    Heap,
   --#                                    LexTokenManager.State,
   --#                                    State,
   --#                                    TickCell;

   procedure AddBitwiseOp (Heap   : in out Cells.Heap_Record;
                           OpCell : in     Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         State,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    Heap,
   --#                                    OpCell,
   --#                                    State;

   procedure AddProcedureExport (Heap       : in out Cells.Heap_Record;
                                 ExportCell : in     Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         State,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    ExportCell,
   --#                                    Heap,
   --#                                    LexTokenManager.State,
   --#                                    State;

   procedure AddReturnVar (Heap          : in out Cells.Heap_Record;
                           ReturnVarCell : in     Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         State,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    Heap,
   --#                                    ReturnVarCell,
   --#                                    State;

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

   -- Traverses the DAG denoted by Root and adds all declarations
   -- needed by it.
   procedure Find_DAG_Declarations (Heap : in out Cells.Heap_Record;
                                    Root : in     Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         State,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    Heap,
   --#                                    LexTokenManager.State,
   --#                                    Root,
   --#                                    State;

   -- Traverses the VC DAGs denoted by PredicatePair and adds all declarations
   -- needed by them. If IgnoreTriviallyTrueVCs is True, then VCs with all
   -- conclusions "True" are ignored, regardless of the hypotheses.
   procedure FindVCFormulaDeclarations
     (Heap                   : in out Cells.Heap_Record;
      PredicatePair          : in     Pairs.Pair;
      IgnoreTriviallyTrueVCs : in     Boolean);
   --# global in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out State;
   --#        in out Statistics.TableUsage;
   --# derives Heap,
   --#         State,
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    Heap,
   --#                                    IgnoreTriviallyTrueVCs,
   --#                                    LexTokenManager.State,
   --#                                    PredicatePair,
   --#                                    State;

   procedure PrintDeclarationTail (File : in SPARK_IO.File_Type);
   --# global in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                File;

   procedure OutputDeclarations
     (Heap        : in out Cells.Heap_Record;
      File        : in     SPARK_IO.File_Type;
      Rule_File   : in     SPARK_IO.File_Type;
      Scope       : in     Dictionary.Scopes;
      Write_Rules : in     Boolean;
      EndPosition : in     LexTokenManager.Token_Position);
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     State;
   --#        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,
   --#                                         EndPosition,
   --#                                         ErrorHandler.Error_Context,
   --#                                         File,
   --#                                         Heap,
   --#                                         LexTokenManager.State,
   --#                                         Rule_File,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         State,
   --#                                         Write_Rules &
   --#         Heap,
   --#         Statistics.TableUsage      from *,
   --#                                         Dictionary.Dict,
   --#                                         Heap,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         State,
   --#                                         Write_Rules;

private
   type UsedSymbolIterator is record
      It : Cells.Cell;
   end record;

   NullIterator : constant UsedSymbolIterator := UsedSymbolIterator'(It => Cells.Null_Cell);

end Declarations;
