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

separate (FlowAnalyser.FlowAnalyse)
procedure AnalyseRelations is

   TheErrorHeap : ComponentErrors.HeapOfErrors;

   procedure CheckExpressions
   --# global in     CommandLineData.Content;
   --#        in     ComponentData;
   --#        in     Dictionary.Dict;
   --#        in     EndPosition;
   --#        in     ExpnLocations;
   --#        in     ExpSeqOfExports;
   --#        in     ExpSeqOfImports;
   --#        in     InnerExpns;
   --#        in     KindDictionary;
   --#        in     LexTokenManager.State;
   --#        in     OneStableExpnSeq;
   --#        in     OtherStableExpnSeq;
   --#        in     ParamDictionary;
   --#        in     S;
   --#        in     Scope;
   --#        in     SeqOfInitVars;
   --#        in     StmtLocations;
   --#        in     STree.Table;
   --#        in     SubprogSym;
   --#        in     ZeroStableExpnSeq;
   --#        in out DataFlowErrorFoundLocal;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out TheErrorHeap;
   --#        in out TheHeap;
   --# derives DataFlowErrorFoundLocal,
   --#         Statistics.TableUsage,
   --#         TheErrorHeap,
   --#         TheHeap                    from *,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ExpnLocations,
   --#                                         ExpSeqOfExports,
   --#                                         ExpSeqOfImports,
   --#                                         InnerExpns,
   --#                                         KindDictionary,
   --#                                         ParamDictionary,
   --#                                         S,
   --#                                         SeqOfInitVars,
   --#                                         StmtLocations,
   --#                                         STree.Table,
   --#                                         SubprogSym,
   --#                                         TheErrorHeap,
   --#                                         TheHeap &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ErrorHandler.Error_Context,
   --#                                         ExpnLocations,
   --#                                         ExpSeqOfExports,
   --#                                         ExpSeqOfImports,
   --#                                         InnerExpns,
   --#                                         KindDictionary,
   --#                                         LexTokenManager.State,
   --#                                         OneStableExpnSeq,
   --#                                         OtherStableExpnSeq,
   --#                                         ParamDictionary,
   --#                                         S,
   --#                                         Scope,
   --#                                         SeqOfInitVars,
   --#                                         SPARK_IO.File_Sys,
   --#                                         StmtLocations,
   --#                                         STree.Table,
   --#                                         SubprogSym,
   --#                                         TheErrorHeap,
   --#                                         TheHeap,
   --#                                         ZeroStableExpnSeq;
      is separate;

   procedure CheckUsages
   --# global in     CommandLineData.Content;
   --#        in     ComponentData;
   --#        in     Dictionary.Dict;
   --#        in     EndPosition;
   --#        in     ExpSeqOfExports;
   --#        in     ExpSeqOfImports;
   --#        in     InStreamsOfShareableProtectedVars;
   --#        in     LexTokenManager.State;
   --#        in     ReferencedVars;
   --#        in     S;
   --#        in     Scope;
   --#        in     SeqOfInitVars;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out TheErrorHeap;
   --#        in out TheHeap;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ErrorHandler.Error_Context,
   --#                                         ExpSeqOfExports,
   --#                                         ExpSeqOfImports,
   --#                                         InStreamsOfShareableProtectedVars,
   --#                                         LexTokenManager.State,
   --#                                         ReferencedVars,
   --#                                         S,
   --#                                         Scope,
   --#                                         SeqOfInitVars,
   --#                                         SPARK_IO.File_Sys,
   --#                                         TheErrorHeap,
   --#                                         TheHeap &
   --#         Statistics.TableUsage,
   --#         TheErrorHeap,
   --#         TheHeap                    from *,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ExpSeqOfExports,
   --#                                         ExpSeqOfImports,
   --#                                         InStreamsOfShareableProtectedVars,
   --#                                         ReferencedVars,
   --#                                         S,
   --#                                         SeqOfInitVars,
   --#                                         TheErrorHeap,
   --#                                         TheHeap;
      is separate;

   procedure CheckDependencies
   --# global in     CommandLineData.Content;
   --#        in     ComponentData;
   --#        in     DependencyRelation;
   --#        in     Dictionary.Dict;
   --#        in     EndPosition;
   --#        in     ExpSeqOfExports;
   --#        in     LexTokenManager.State;
   --#        in     S;
   --#        in     Scope;
   --#        in     SeqOfExports;
   --#        in     SeqOfImports;
   --#        in     SeqOfInitVars;
   --#        in     SubprogSym;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out TheErrorHeap;
   --#        in out TheHeap;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ComponentData,
   --#                                         DependencyRelation,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ErrorHandler.Error_Context,
   --#                                         ExpSeqOfExports,
   --#                                         LexTokenManager.State,
   --#                                         S,
   --#                                         Scope,
   --#                                         SeqOfExports,
   --#                                         SeqOfImports,
   --#                                         SeqOfInitVars,
   --#                                         SPARK_IO.File_Sys,
   --#                                         SubprogSym,
   --#                                         TheErrorHeap,
   --#                                         TheHeap &
   --#         Statistics.TableUsage,
   --#         TheErrorHeap,
   --#         TheHeap                    from *,
   --#                                         ComponentData,
   --#                                         DependencyRelation,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ExpSeqOfExports,
   --#                                         S,
   --#                                         SeqOfExports,
   --#                                         SeqOfImports,
   --#                                         SeqOfInitVars,
   --#                                         SubprogSym,
   --#                                         TheErrorHeap,
   --#                                         TheHeap;
      is separate;

   procedure CheckUnused
   --# global in     CommandLineData.Content;
   --#        in     ComponentData;
   --#        in     Dictionary.Dict;
   --#        in     EndPosition;
   --#        in     LexTokenManager.State;
   --#        in     S;
   --#        in     SubprogSym;
   --#        in     TheHeap;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         S,
   --#                                         SPARK_IO.File_Sys,
   --#                                         SubprogSym,
   --#                                         TheHeap;
      is separate;

   procedure ReportVarsUsedAsConsts
   --# global in     CommandLineData.Content;
   --#        in     ComponentData;
   --#        in     Dictionary.Dict;
   --#        in     EndPosition;
   --#        in     LexTokenManager.State;
   --#        in     VarsUsedAsConstants;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out TheErrorHeap;
   --#        in out TheHeap;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         TheErrorHeap,
   --#                                         TheHeap,
   --#                                         VarsUsedAsConstants &
   --#         Statistics.TableUsage,
   --#         TheErrorHeap,
   --#         TheHeap                    from *,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         EndPosition,
   --#                                         TheErrorHeap,
   --#                                         TheHeap,
   --#                                         VarsUsedAsConstants;
   is
      MemberOfConstVars : SeqAlgebra.MemberOfSeq;
      ConstVarRep       : Natural;
      ConstVar          : Dictionary.Symbol;
      NewError          : Natural;

   begin
      MemberOfConstVars := SeqAlgebra.FirstMember (TheHeap, VarsUsedAsConstants);
      while not SeqAlgebra.IsNullMember (MemberOfConstVars) loop
         ConstVarRep := SeqAlgebra.Value_Of_Member (The_Heap => TheHeap,
                                                    M        => MemberOfConstVars);
         ConstVar    := Dictionary.ConvertSymbolRef (ExaminerConstants.RefType (ConstVarRep));
         if Dictionary.IsSubcomponent (ConstVar) then
            ComponentErrors.CreateError
              (TheErrorHeap,
               TheHeap,
               ComponentErrors.SemanticWarning,
               403,
               EndPosition,
               Dictionary.NullSymbol,
               NewError);
            ComponentManager.AddError
              (TheHeap,
               TheErrorHeap,
               ComponentData,
               ComponentManager.GetComponentNode (ComponentData, ConstVar),
               NewError);
         else
            ErrorHandler.Semantic_Warning (Err_Num  => 403,
                                           Position => EndPosition,
                                           Id_Str   => Dictionary.GetSimpleName (ConstVar));
         end if;
         MemberOfConstVars := SeqAlgebra.NextMember (TheHeap, MemberOfConstVars);
      end loop;
   end ReportVarsUsedAsConsts;

   procedure MergeAndHandleErrors
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in     Scope;
   --#        in     TheErrorHeap;
   --#        in out ComponentData;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out TheHeap;
   --# derives ComponentData,
   --#         Statistics.TableUsage,
   --#         TheHeap                    from *,
   --#                                         ComponentData,
   --#                                         TheErrorHeap,
   --#                                         TheHeap &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ComponentData,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         TheErrorHeap,
   --#                                         TheHeap;
      is separate;

begin -- AnalyseRelations
   ComponentErrors.Initialise (TheErrorHeap);
   CheckExpressions;
   CheckUsages;
   CheckDependencies;
   CheckUnused;
   ReportVarsUsedAsConsts;
   ComponentErrors.ReportUsage (TheErrorHeap);
   MergeAndHandleErrors;
end AnalyseRelations;
