1 cananian 1.1.2.1 // UseDefChecker.java, created Wed Nov 15 13:44:59 2000 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Analysis; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 7 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 8 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 9 cananian 1.1.2.3 import harpoon.IR.Properties.UseDefable; 10 cananian 1.1.2.1 import harpoon.Temp.Temp; 11 cananian 1.1.2.1 12 cananian 1.1.2.1 import java.util.Collection; 13 cananian 1.1.2.1 import java.util.Iterator; 14 cananian 1.1.2.1 import java.util.Set; 15 cananian 1.1.2.1 /** 16 cananian 1.1.2.1 * <code>UseDefChecker</code> verifies that all variables are defined 17 cananian 1.1.2.1 * before they are used. It aids in debugging code transformations. 18 cananian 1.1.2.1 * 19 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 20 cananian 1.3 * @version $Id: UseDefChecker.java,v 1.3 2004/02/08 03:19:12 cananian Exp $ 21 cananian 1.1.2.1 */ 22 cananian 1.1.2.1 public class UseDefChecker implements HCodeFactory { 23 cananian 1.1.2.1 HCodeFactory parent; 24 cananian 1.1.2.1 ReachingDefsFactory rdf; 25 cananian 1.1.2.1 /** Creates a <code>UseDefChecker</code> from a 26 cananian 1.1.2.1 * <code>ReachingDefsFactory</code>. */ 27 cananian 1.1.2.1 public UseDefChecker(HCodeFactory parent, ReachingDefsFactory rdf) { 28 cananian 1.1.2.1 this.parent = parent; this.rdf = rdf; 29 cananian 1.1.2.1 } 30 cananian 1.1.2.1 /** Creates a <code>UseDefChecker</code> using the named class 31 cananian 1.1.2.1 * as the <code>ReachingDefs</code> implementation. */ 32 cananian 1.1.2.1 public UseDefChecker(HCodeFactory parent, String reachingdefsClassName) { 33 cananian 1.1.2.1 this(parent, new GenericRDFactory(reachingdefsClassName)); 34 cananian 1.1.2.1 } 35 cananian 1.1.2.1 public String getCodeName() { return parent.getCodeName(); } 36 cananian 1.1.2.1 public void clear(HMethod m) { parent.clear(m); } 37 cananian 1.1.2.1 public HCode convert(HMethod m) { 38 cananian 1.1.2.1 HCode hc = parent.convert(m); 39 cananian 1.1.2.1 if (hc!=null) { 40 cananian 1.1.2.1 ReachingDefs rd = rdf.makeReachingDefs(hc); 41 cananian 1.1.2.1 for (Iterator it=hc.getElementsI(); it.hasNext(); ) { 42 cananian 1.1.2.3 UseDefable ud = (UseDefable) it.next(); 43 cananian 1.3 for (Object tO : ud.useC()) { 44 cananian 1.3 Temp t = (Temp) tO; 45 cananian 1.1.2.1 if (rd.reachingDefs(ud, t).size()==0) { 46 cananian 1.1.2.1 hc.print(new java.io.PrintWriter(System.err)); 47 cananian 1.1.2.1 throw new Error("Use of "+t+" in "+ud+" before def."); 48 cananian 1.1.2.1 } 49 cananian 1.1.2.1 } 50 cananian 1.1.2.1 } 51 cananian 1.1.2.1 } 52 cananian 1.1.2.1 return hc; 53 cananian 1.1.2.1 } 54 cananian 1.1.2.1 55 cananian 1.1.2.1 // inner classes. 56 cananian 1.1.2.2 /** The <code>UseDefChecker</code> constructor takes a 57 cananian 1.1.2.2 * <code>ReachingDefsFactory</code> argument to specify which 58 cananian 1.1.2.2 * <code>ReachingDefs</code> implementation it should use. */ 59 cananian 1.1.2.1 public static abstract class ReachingDefsFactory { 60 cananian 1.1.2.1 public abstract ReachingDefs makeReachingDefs(HCode hc); 61 cananian 1.1.2.1 } 62 cananian 1.1.2.1 private static final class GenericRDFactory extends ReachingDefsFactory { 63 cananian 1.1.2.1 final java.lang.reflect.Constructor constructor; 64 cananian 1.1.2.1 public GenericRDFactory(String classname) { 65 cananian 1.1.2.1 try { 66 cananian 1.1.2.1 this.constructor = Class.forName(classname) 67 cananian 1.1.2.1 .getDeclaredConstructor(new Class[] { HCode.class }); 68 cananian 1.1.2.1 } catch (Throwable t) { 69 cananian 1.1.2.1 throw new Error("GENERICRDFACTORY FAILED: "+t); 70 cananian 1.1.2.1 } 71 cananian 1.1.2.1 } 72 cananian 1.1.2.1 public ReachingDefs makeReachingDefs(HCode hc) { 73 cananian 1.1.2.1 try { 74 cananian 1.1.2.1 return (ReachingDefs) constructor.newInstance(new Object[] { hc }); 75 cananian 1.1.2.1 } catch (java.lang.reflect.InvocationTargetException e) { 76 cananian 1.1.2.1 e.printStackTrace(); 77 cananian 1.1.2.1 throw new Error(e.getTargetException().toString()); 78 cananian 1.1.2.1 } catch (Throwable t) { 79 cananian 1.1.2.1 throw new Error("REACHINGDEFS INSTANTIATION FAILED: "+t); 80 cananian 1.1.2.1 } 81 cananian 1.1.2.1 } 82 cananian 1.1.2.1 } 83 cananian 1.2 }