-- (C) Copyright International Business Machines Corporation 23 January 
-- 1990.  All Rights Reserved. 
--  
-- See the file USERAGREEMENT distributed with this software for full 
-- terms and conditions of use. 
-- File: exprusesroot.pp
-- Author: Andy Lowry
-- SCCS Info: @(#)exprusesroot.pp	1.8 3/13/90

-- This process checks whether a given rootname is mentioned in a
-- given expr structure.  An affirmative answer may be given when
-- there is actually no reference.  This pessimistic attitude is taken
-- for efficiency reasons, so we need not analyze embedded expression
-- blocks and selectors.

#include "typemark.h"
#include "codegen.h"

exprUsesRoot: using (exprTree)

process (Q: exprUsesRootQ)
  
declare
  args: exprUsesRoot;
begin
block begin
  receive args from Q;
  
  select exprType#(case of args.expr)
  where (exprType#'object')
    -- Simple object reference... compare with given object
    reveal args.expr.obj;
    if B(args.expr.obj.root = args.root) then
      args.used <- TRUE;
    else
      args.used <- FALSE;
    end if;
    
  where (exprType#'tree')
    -- expression tree.. check destination and all source args
    reveal args.expr.tree;
    block declare
      exprUsesRoot: exprUsesRootFn;
    begin
      if B(args.expr.tree.dst.root = args.root) then
	exit used;
      end if;
      -- Check all the source args in turn... bail out as soon as we
      -- get a hit
      exprUsesRoot <- exprUsesRootFn#(procedure of program#currentProgram);
      for arg in args.expr.tree.args[] inspect
	if B(exprUsesRoot(arg,args.root)) then
	  exit used;
	end if;
      end for;
      -- be pessimistic for now about embedded clauses
      if B(B(args.expr.tree.opcode = predefined!operator#'expression_block') or
	      B(predefined!qualifier_types#(case of args.expr.tree.qual) =
		predefined!qualifier_types#'selector')) then
	exit used;
      end if;
      -- object not used as destination or in any source args... we're
      -- clean
      args.used <- FALSE;
    on exit(used)
      -- here when a use is detected
      args.used <- TRUE;
    end block;
    
  otherwise
    exit cantHappen;
    
  end select;

  return args;
  
on exit(cantHappen)
  print S("Exit to cantHappen in exprUsesRoot");
end block;
end process
