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

separate (FlowAnalyser.FlowAnalyse.AnalyseRelations)
procedure CheckUnused is
   It  : Dictionary.Iterator;
   Sym : Dictionary.Symbol;

   -- returns true if Sym is the transitive parent of something in S
   function ComponentsPresent (S   : SeqAlgebra.Seq;
                               Sym : Dictionary.Symbol) return Boolean
   --# global in ComponentData;
   --#        in TheHeap;
   is
      ParentComponent : ComponentManager.Component;
      Found           : Boolean := False;
      CurrentMember   : SeqAlgebra.MemberOfSeq;
   begin
      ParentComponent := ComponentManager.GetComponentNode (ComponentData, Sym);
      CurrentMember   := SeqAlgebra.FirstMember (TheHeap, S);
      while not SeqAlgebra.IsNullMember (CurrentMember) loop
         if ComponentManager.IsTransitiveParent
           (ComponentData,
            ParentComponent,
            ComponentManager.GetComponentNode
              (ComponentData,
               Dictionary.ConvertSymbolRef
                 (ExaminerConstants.RefType (SeqAlgebra.Value_Of_Member (The_Heap => TheHeap,
                                                                         M        => CurrentMember))))) then
            Found := True;
            exit;
         end if;

         CurrentMember := SeqAlgebra.NextMember (TheHeap, CurrentMember);
      end loop;

      return Found;
   end ComponentsPresent;

begin -- CheckUnused
   if IsSubprogram (SubprogSym) then
      It := Dictionary.First_Local_Variable (Subprogram => SubprogSym);
      while not Dictionary.IsNullIterator (It) loop
         Sym := Dictionary.CurrentSymbol (It);
         if Dictionary.TypeIsRecord (Dictionary.GetType (Sym)) then
            if not ComponentsPresent (IFA_Stack.Top (S).AllVars, Sym) then
               ErrorHandler.Semantic_Warning (Err_Num  => 400,
                                              Position => EndPosition,
                                              Id_Str   => Dictionary.GetSimpleName (Sym));
            end if;
         else --not a record
            if not SeqAlgebra.IsMember (TheHeap, IFA_Stack.Top (S).AllVars, Natural (Dictionary.SymbolRef (Sym))) then
               ErrorHandler.Semantic_Warning (Err_Num  => 400,
                                              Position => EndPosition,
                                              Id_Str   => Dictionary.GetSimpleName (Sym));
            end if;
         end if;
         It := Dictionary.NextSymbol (It);
      end loop;
   end if;
end CheckUnused;
