------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 1995 by International Computer Science Institute            --
-- This file is part of the GNU Sather package. It is free software; you may --
-- redistribute  and/or modify it under the terms of the  GNU General Public --
-- License (GPL)  as  published  by the  Free  Software  Foundation;  either --
-- version 2 of the license, or (at your option) any later version.          --
-- This  program  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 Doc/GPL for more details.        --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------

class CHECK_AM < $CHECK_AM is
   -- Check the code for routines which aren't called, but don't output
   -- any am code for them.

   include CS_COMPONENT;

   -- private attr sig_out:FSET{SIG};  -- Table of signatures which have been
                                    -- output.

   create(p:PROG):SAME is
      r::=new; 
      r.prog:=p; 
      return r; 
   end;   

   check_code is
      --      sig_out := prog.generate_am.sig_out;
      prog.is_check_am := true; -- enter the stage
      
      loop 
	 -- don't use prog.tp_done.elt! since pSather transformation
	 -- might add new helper objects to prog.tp_done.
	 -- The outer loop catches any entries in prog.tp_done that are
	 -- added on the fly. These are processed by working on tp_done
	 -- locally.
     	 if prog.tp_done.size = 0 then break! end;
         tp_done ::= prog.tp_done;
	 prog.tp_done := void;
	 loop tp:$TP:=tp_done.elt!;
	    typecase tp
	    when TP_CLASS then
	       if ~tp.is_abstract then 
		  ti::=tp.ifc;
		  if ~void(ti) and ~void(ti.sigs) then 
		     loop check_sig(ti.sigs.elt!) end;
		  end;
	       end;
	    else end;
	 end;
      end;
   end;
   
   check_sig(s:SIG) 
      -- Check `s' for errors, but only generate code for it if 
      -- `generate_checked_code' is true.
      pre ~void(s) is
      if s.am_created then return end; -- Already did it.
      s.am_created:=true; -- Mark it done.
      if prog.show_checked_sig then
         #OUT + "Check sig " + s.str + "\n" end;	 
      if s.tp.is_abstract then return end;
      elt:ELT:=s.tp.impl.elts.elt_with_sig(s);
      if elt.is_external and elt.is_abstract then return end;
      if void(elt) then return end;
      am:AM_ROUT_DEF:=TRANS::transform_elt(elt);
      if void(am) then return end;
      if prog.show_am_check then
  	 #OUT + "\nCheck AM for " + am.sig.str + "="; 
  	 AM_OUT::AM_out(am); #OUT + "\n" end;
      if prog.generate_checked_code then
	 prog.back_end.emit(am) end end;
	 
end; -- class CHECK_AM
