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     }