Added:
[repair.git] / Repair / RepairCompiler / MCC / IR / RelationInclusion.java
index f0fd0c436834126e3ffd2dcba7f639e058f56ddb..58e266478fec77a6d7bc0e79d33bbd3e6906267d 100755 (executable)
@@ -1,5 +1,5 @@
 package MCC.IR;
-
+import MCC.Compiler;
 import java.util.*;
 
 public class RelationInclusion extends Inclusion {
@@ -7,12 +7,41 @@ public class RelationInclusion extends Inclusion {
     Expr leftelementexpr, rightelementexpr;
     RelationDescriptor relation;
 
+    // #TBD#: this flag needs to be set by some static analysis
+    boolean typesafe = true;
+    public static boolean worklist = false;
+
     public RelationInclusion(Expr leftelementexpr, Expr rightelementexpr, RelationDescriptor relation) {
         this.leftelementexpr = leftelementexpr;
         this.rightelementexpr = rightelementexpr;
         this.relation = relation;
     }
 
+    public String toString() {
+       String str="<"+leftelementexpr.name()+","+rightelementexpr.name()+"> in "+relation.toString();
+       return str;
+    }
+
+    public boolean usesDescriptor(Descriptor d) {
+       if (d==relation)
+           return true;
+       else
+           return(leftelementexpr.usesDescriptor(d)
+                  ||rightelementexpr.usesDescriptor(d));
+    }
+
+    public Expr getLeftExpr() {
+        return leftelementexpr;
+    }
+    
+    public Expr getRightExpr() {
+        return rightelementexpr;
+    }
+
+    public RelationDescriptor getRelation() {
+        return relation;
+    }
+
     public Set getTargetDescriptors() {
         HashSet v = new HashSet();
         v.add(relation);
@@ -22,6 +51,12 @@ public class RelationInclusion extends Inclusion {
     public Set getRequiredDescriptors() {
         Set v = leftelementexpr.getRequiredDescriptors();
         v.addAll(rightelementexpr.getRequiredDescriptors());
+
+        if (!typesafe) { /* if not typesafe then domain and range are needed to make typesafety checks! */
+            v.add(relation.getDomain());
+            v.add(relation.getRange());
+        }
+
         return v;
     }
 
@@ -30,7 +65,54 @@ public class RelationInclusion extends Inclusion {
         leftelementexpr.generate(writer, ld);
         VarDescriptor rd = VarDescriptor.makeNew("rightele");
         rightelementexpr.generate(writer, rd);
-        writer.outputline(relation.getSafeSymbol() + "_hash->add((int)" + ld.getSafeSymbol() + ", (int)" + rd.getSafeSymbol() + ");");
+
+        /* typesafe checks! */
+        String typesafecheck = (VarDescriptor.makeNew("typesafecheck")).getSafeSymbol();
+
+        if (!typesafe) {
+            String check = "int " + typesafecheck + " = " ;
+
+            if (!(relation.getDomain() instanceof ReservedSetDescriptor)) {
+                check += relation.getDomain().getSafeSymbol() + "_hash->contains(" + ld.getSafeSymbol() + ") && ";
+            }
+
+            if (!(relation.getRange() instanceof ReservedSetDescriptor)) {
+                check += relation.getRange().getSafeSymbol() + "_hash->contains(" + rd.getSafeSymbol() + ") && ";
+            }
+
+            check += "1;"; // terminate boolean expression
+
+            writer.outputline(check);
+            writer.outputline("if (" + typesafecheck + ")");
+            writer.startblock();
+        }
+
+        String addeditem = (VarDescriptor.makeNew("addeditem")).getSafeSymbol();
+       if (!Compiler.REPAIR) {
+           writer.outputline("int " + addeditem + ";");
+           if (relation.testUsage(RelationDescriptor.IMAGE)) {
+               writer.outputline(addeditem + " = " + relation.getSafeSymbol() + "_hash->add((int)" + ld.getSafeSymbol() + ", (int)" + rd.getSafeSymbol() + ");");
+           }
+           
+           if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
+               writer.outputline(addeditem + " = " + relation.getSafeSymbol() + "_hashinv->add((int)" + rd.getSafeSymbol() + ", (int)" + ld.getSafeSymbol() + ");");
+           }
+       } else {
+           Repair.generate_dispatch(writer, relation, ld.getSafeSymbol(), rd.getSafeSymbol());
+       }
+       
+        if (RelationInclusion.worklist) {
+            writer.outputline("if (" + addeditem + ")");
+            writer.startblock(); {
+                WorkList.generate_dispatch(writer, relation, rd.getSafeSymbol(), ld.getSafeSymbol());
+            }
+            writer.endblock();
+        }
+
+        if (!typesafe) {
+            writer.endblock();
+        }
+
         //writer.outputline("printf(\"" + relation.getSafeSymbol() + " (add): <%d, %d>\\n\", " + ld.getSafeSymbol() + ", " + rd.getSafeSymbol() + ");");
     }
 
@@ -44,7 +126,11 @@ public class RelationInclusion extends Inclusion {
 
         boolean ok = true;
 
-        if (ld != relation.getDomain().getType()) {
+        /* #ATTN#: this check makes sure that the types match up, 
+           a runtime check needs to made that the set relationships 
+           are correct */
+
+        if (ld != relation.getDomain().getType()) { 
             sa.getErrorReporter().report(null, "Type of left element '" + ld.getSymbol() + "' must match domain type '" + relation.getDomain().getType().getSymbol() + "'");
             ok = false;
         }
@@ -55,7 +141,6 @@ public class RelationInclusion extends Inclusion {
             sa.getErrorReporter().report(null, "Type of right element '" + rd.getSymbol() + "' must match range type '" + relation.getRange().getType().getSymbol() + "'");
             ok = false;
         }
-
         return ok;
     }