changes to make sure that i don't step on stephen's work on imports...
authorbdemsky <bdemsky>
Wed, 20 Apr 2011 22:39:55 +0000 (22:39 +0000)
committerbdemsky <bdemsky>
Wed, 20 Apr 2011 22:39:55 +0000 (22:39 +0000)
Robust/src/Analysis/CallGraph/BaseCallGraph.java
Robust/src/IR/Flat/BuildFlat.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/JavaBuilder.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Main/Main.java

index 5859300af52fe8ddceb7d99557217a95107b05c4..aa5e9e496f276f6a20dc4aaa78e311690a34cfe9 100644 (file)
@@ -93,7 +93,6 @@ public class BaseCallGraph implements CallGraph {
            possInterfaces.add((ClassDescriptor)supit.next());
          }
          Set possiblematches=IFdesc.getMethodTable().getSet(md.getSymbol());
-         boolean foundmatch=false;
          for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
            MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
            if (md.matches(matchmd)) {
@@ -109,7 +108,6 @@ public class BaseCallGraph implements CallGraph {
        ClassDescriptor superdesc=cn.getSuperDesc();
        if (superdesc!=null) {
          Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
-         boolean foundmatch=false;
          for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
            MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
            if (md.matches(matchmd)) {
index ffc9e382c00e6ec38789887b3f19b724b3aad6e5..a1d53b80acdf5e65877948dc7ea99b2565ac8a22 100644 (file)
@@ -161,127 +161,122 @@ public class BuildFlat {
     Iterator methodit=cn.getMethods();
     while(methodit.hasNext()) {     
       currmd=(MethodDescriptor)methodit.next();
-      
-      // if OOOJava is on, splice a special SESE in to
-      // enclose the main method
-      boolean spliceInImplicitMain = 
-        state.OOOJAVA &&
-        currmd.equals( typeutil.getMain() );
-
-      FlatSESEEnterNode spliceSESE = null;
-      FlatSESEExitNode  spliceExit = null;
-
-      if( spliceInImplicitMain ) {
-        SESENode mainTree = new SESENode( "main" );
-        spliceSESE = new FlatSESEEnterNode( mainTree );
-        spliceExit = new FlatSESEExitNode ( mainTree );
-        spliceSESE.setFlatExit ( spliceExit );
-        spliceExit.setFlatEnter( spliceSESE );
-        spliceSESE.setIsMainSESE();
-      } 
-
-
-      fe=new FlatExit();
-
-      BlockNode bn=state.getMethodBody(currmd);
+      flattenMethod(cn, currmd);
+    }
+  }
+  
+  public void flattenMethod(ClassDescriptor cn, MethodDescriptor currmd) {
+    // if OOOJava is on, splice a special SESE in to
+    // enclose the main method
+    boolean spliceInImplicitMain = state.OOOJAVA && currmd.equals( typeutil.getMain() );
+    
+    FlatSESEEnterNode spliceSESE = null;
+    FlatSESEExitNode  spliceExit = null;
+    
+    if( spliceInImplicitMain ) {
+      SESENode mainTree = new SESENode( "main" );
+      spliceSESE = new FlatSESEEnterNode( mainTree );
+      spliceExit = new FlatSESEExitNode ( mainTree );
+      spliceSESE.setFlatExit ( spliceExit );
+      spliceExit.setFlatEnter( spliceSESE );
+      spliceSESE.setIsMainSESE();
+    } 
+    
+    fe=new FlatExit();
+    BlockNode bn=state.getMethodBody(currmd);
 
-      if (state.DSM&&currmd.getModifiers().isAtomic()) {
-        FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
-        faen.setNumLine(bn.getNumLine());
-       curran = faen;
-      } else
-       curran=null;
-      if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
-        TempDescriptor thistd = null;
-        if(currmd.getModifiers().isStatic()) {
-          // need to lock the Class object
-          thistd=new TempDescriptor("classobj", cn);
-        } else {
-          // lock this object
-          thistd=getTempforVar(currmd.getThis());
-        }
-        if(!this.lockStack.isEmpty()) {
-          throw new Error("The lock stack for synchronized blocks/methods is not empty!");
-        }
-        this.lockStack.push(thistd);
+    if (state.DSM&&currmd.getModifiers().isAtomic()) {
+      FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
+      faen.setNumLine(bn.getNumLine());
+      curran = faen;
+    } else
+      curran=null;
+    if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
+      TempDescriptor thistd = null;
+      if(currmd.getModifiers().isStatic()) {
+       // need to lock the Class object
+       thistd=new TempDescriptor("classobj", cn);
+      } else {
+       // lock this object
+       thistd=getTempforVar(currmd.getThis());
       }
-      NodePair np=flattenBlockNode(bn);
-      FlatNode fn=np.getBegin();
-      if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
-       MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
-       FlatNode first = null;
-       FlatNode end = null;
-
-       {
-         if (lockStack.size()!=1) {
-           throw new Error("TOO MANY THINGS ON LOCKSTACK");
-         }
-         TempDescriptor thistd = this.lockStack.elementAt(0);
+      if(!this.lockStack.isEmpty()) {
+       throw new Error("The lock stack for synchronized blocks/methods is not empty!");
+      }
+      this.lockStack.push(thistd);
+    }
+    NodePair np=flattenBlockNode(bn);
+    FlatNode fn=np.getBegin();
+    if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
+      MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
+      FlatNode first = null;
+      FlatNode end = null;
+      
+      {
+       if (lockStack.size()!=1) {
+         throw new Error("TOO MANY THINGS ON LOCKSTACK");
+       }
+       TempDescriptor thistd = this.lockStack.elementAt(0);
          FlatCall fc = new FlatCall(memd, null, thistd, new TempDescriptor[0]);
          fc.setNumLine(bn.getNumLine());
          first = end = fc;
+      }
+      
+      end.addNext(fn);
+      fn=first;
+      end = np.getEnd();
+      if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
+       MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+       while(!this.lockStack.isEmpty()) {
+         TempDescriptor thistd = this.lockStack.pop();
+         FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
+         fcunlock.setNumLine(bn.getNumLine());
+         end.addNext(fcunlock);
+         end = fcunlock;
        }
-
-       end.addNext(fn);
-       fn=first;
-       end = np.getEnd();
-       if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
-         MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
-         while(!this.lockStack.isEmpty()) {
-           TempDescriptor thistd = this.lockStack.pop();
-           FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
-           fcunlock.setNumLine(bn.getNumLine());
-           end.addNext(fcunlock);
-           end = fcunlock;
-         }
-         FlatNode rnflat=spliceReturn(end);
-         rnflat.addNext(fe);
-       } else {
-         this.lockStack.clear();   
-       }
-      } else if (state.DSM&&currmd.getModifiers().isAtomic()) {
-       curran.addNext(fn);
-       fn=curran;
-       if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
-         FlatAtomicExitNode aen=new FlatAtomicExitNode(curran);
-         np.getEnd().addNext(aen);
-         FlatNode rnflat=spliceReturn(aen);
-         rnflat.addNext(fe);
-       }       
-
-      } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
-       FlatNode rnflat=null;
-       if( spliceInImplicitMain ) {
-         np.getEnd().addNext(spliceExit);
-         rnflat=spliceReturn(spliceExit);
-       } else {
-         rnflat=spliceReturn(np.getEnd());
-       }
+       FlatNode rnflat=spliceReturn(end);
        rnflat.addNext(fe);
-      } else if (np.getEnd()!=null) {
-       if( spliceInImplicitMain ) {
-         FlatReturnNode rnflat=(FlatReturnNode)np.getEnd();
-         np.getEnd().addNext(spliceExit);
-         spliceExit.addNext(fe);
-       }
+      } else {
+       this.lockStack.clear();   
       }
-
+    } else if (state.DSM&&currmd.getModifiers().isAtomic()) {
+      curran.addNext(fn);
+      fn=curran;
+      if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
+       FlatAtomicExitNode aen=new FlatAtomicExitNode(curran);
+       np.getEnd().addNext(aen);
+       FlatNode rnflat=spliceReturn(aen);
+       rnflat.addNext(fe);
+      }        
+    } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
+      FlatNode rnflat=null;
       if( spliceInImplicitMain ) {
-       spliceSESE.addNext(fn);
-       fn=spliceSESE;   
+       np.getEnd().addNext(spliceExit);
+       rnflat=spliceReturn(spliceExit);
+      } else {
+       rnflat=spliceReturn(np.getEnd());
       }
-
-      FlatMethod fm=new FlatMethod(currmd, fe);
-      fm.setNumLine(bn.getNumLine());
-      fm.addNext(fn);
-      if (!currmd.isStatic())
-       fm.addParameterTemp(getTempforParam(currmd.getThis()));
-      for(int i=0; i<currmd.numParameters(); i++) {
-       fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
+      rnflat.addNext(fe);
+    } else if (np.getEnd()!=null) {
+      if( spliceInImplicitMain ) {
+       FlatReturnNode rnflat=(FlatReturnNode)np.getEnd();
+       np.getEnd().addNext(spliceExit);
+       spliceExit.addNext(fe);
       }
-      
-      state.addFlatCode(currmd,fm);
     }
+    if( spliceInImplicitMain ) {
+      spliceSESE.addNext(fn);
+      fn=spliceSESE;    
+    }
+    FlatMethod fm=new FlatMethod(currmd, fe);
+    fm.setNumLine(bn.getNumLine());
+    fm.addNext(fn);
+    if (!currmd.isStatic())
+      fm.addParameterTemp(getTempforParam(currmd.getThis()));
+    for(int i=0; i<currmd.numParameters(); i++) {
+      fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
+    }
+    state.addFlatCode(currmd,fm);
   }
 
   private NodePair flattenBlockNode(BlockNode bn) {
index 7a7006dd57855f656f3b7df96c5db9438ee7f868..4b7603a09d26bdbc908d3bd19b1e7d8f113d2ece 100644 (file)
@@ -512,7 +512,7 @@ public class BuildIR {
        } else if (isNode(decl,"block")) {
        } else if (isNode(decl,"location_order_declaration")) {
          parseLocationOrder(cn,decl.getChild("location_order_list"));
-  } else throw new Error();
+       } else throw new Error();
       }
     }
   }
@@ -527,7 +527,7 @@ public class BuildIR {
       if(isNode(loc,"location_property")){
         String spinLoc=loc.getChildren().elementAt(0).getLabel();
         spinLocSet.add(spinLoc);
-      }else{
+      } else {
         String lowerLoc=loc.getChildren().elementAt(0).getLabel();
         String higherLoc= loc.getChildren().elementAt(1).getLabel();
         locOrder.put(higherLoc, lowerLoc);
index e11a677ec07a195465aa27a9c1b9fdabd8869783..d9aabf11a1a4e58cf716b6efca69c5840979058d 100644 (file)
 package IR.Tree;
-
 import IR.*;
+import IR.Tree.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+import Util.Pair;
 
 public class JavaBuilder {
   State state;
+  HashSet<Descriptor> checkedDesc=new HashSet<Descriptor>();
+  HashMap<ClassDescriptor, Integer> classStatus=new HashMap<ClassDescriptor, Integer>();
+  public final int CDNONE=0;
+  public final int CDINIT=1;
+  public final int CDINSTANTIATED=2;
+  BuildIR bir;
+  TypeUtil tu;
+  SemanticCheck sc;
+  BuildFlat bf;
+  Stack<MethodDescriptor> toprocess=new Stack<MethodDescriptor>();
+  HashSet<MethodDescriptor> discovered=new HashSet<MethodDescriptor>();
+
+  /* Maps class/interfaces to all instantiated classes that extend or
+   * implement those classes or interfaces */
+
+  HashMap<ClassDescriptor, Set<ClassDescriptor>> implementationMap=new HashMap<ClassDescriptor, Set<ClassDescriptor>>();
+
+  /* Maps methods to the methods they call */
+  
+  HashMap<MethodDescriptor, Set<MethodDescriptor>> callMap=new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
+
+  /* Invocation map */
+  HashMap<ClassDescriptor, Set<Pair<MethodDescriptor, MethodDescriptor>>> invocationMap=new HashMap<ClassDescriptor, Set<Pair<MethodDescriptor, MethodDescriptor>>>();
+  
 
   public JavaBuilder(State state) {
     this.state=state;
+    bir=new BuildIR(state);
+    tu=new TypeUtil(state, bir);
+    sc=new SemanticCheck(state, tu, false);
+    bf=new BuildFlat(state,tu);
   }
 
+  public TypeUtil getTypeUtil() {
+    return tu;
+  }
 
-  public void build(Vector<String> sourcefiles) {
-    BuildIR bir=new BuildIR(state);
-    TypeUtil tu=new TypeUtil(state, bir);
+  public BuildFlat getBuildFlat() {
+    return bf;
+  }
 
-    for(int i=0;i<sourcefiles.size();i++)
-      loadClass(bir, sourcefiles.get(i));
+  public void build() {
+    ClassDescriptor mainClass=sc.getClass(null, state.main, SemanticCheck.INIT);
+    MethodDescriptor mainMethod=tu.getMain();
+    toprocess.push(mainMethod);
+    computeFixPoint();
+  }
 
-    
+  void checkMethod(MethodDescriptor md) {
+    try {
+      sc.checkMethodBody(md.getClassDesc(), md);
+    } catch( Error e ) {
+      System.out.println( "Error in "+md );
+      throw e;
+    }
+  }
+  
+  void initClassDesc(ClassDescriptor cd) {
+    if (classStatus.get(cd)==null) {
+      classStatus.put(cd, CDINIT);
+      //TODO...LOOK FOR STATIC INITIALIZERS
+    }
+  }
+  
+  void computeFixPoint() {
+    while(!toprocess.isEmpty()) {
+      MethodDescriptor md=toprocess.pop();
+      checkMethod(md);
+      initClassDesc(md.getClassDesc());
+      bf.flattenMethod(md.getClassDesc(), md);
+      processFlatMethod(md);
+    }
+  }
+  
+  void processCall(MethodDescriptor md, FlatCall fcall) {
+    MethodDescriptor callmd=fcall.getMethod();
+
+    //First handle easy cases...
+    if (callmd.isStatic()||callmd.isConstructor()) {
+      if (!discovered.contains(callmd)) {
+       discovered.add(callmd);
+       toprocess.push(callmd);
+      }
+      callMap.get(md).add(callmd);
+      return;
+    }
 
-    BuildFlat bf=new BuildFlat(state,tu);
-    bf.buildFlat();
+    //Otherwise, handle virtual dispatch...
+    ClassDescriptor cn=callmd.getClassDesc();
+    Set<ClassDescriptor> impSet=implementationMap.get(cn);
 
+    if (!invocationMap.containsKey(cn))
+      invocationMap.put(cn, new HashSet<Pair<MethodDescriptor,MethodDescriptor>>());
+    invocationMap.get(cn).add(new Pair<MethodDescriptor, MethodDescriptor>(md, callmd));
+
+    for(ClassDescriptor cdactual:impSet) {
+      searchimp:
+      while(cdactual!=null) {
+       Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol());
+
+       for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
+         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+         if (callmd.matches(matchmd)) {
+           //Found the method that will be called
+           if (!discovered.contains(matchmd)) {
+             discovered.add(matchmd);
+             toprocess.push(matchmd);
+           }
+           callMap.get(md).add(matchmd);
+           
+           break searchimp;
+         }
+       }
+
+       //Didn't find method...look in super class
+       cdactual=cdactual.getSuperDesc();
+      }
+    }
+  }
+
+  void processNew(FlatNew fnew) {
+    TypeDescriptor tdnew=fnew.getType();
+    if (!tdnew.isClass())
+      return;
+    ClassDescriptor cdnew=tdnew.getClassDesc();
+    Stack<ClassDescriptor> tovisit=new Stack<ClassDescriptor>();
+    tovisit.add(cdnew);
+    
+    while(!tovisit.isEmpty()) {
+      ClassDescriptor cdcurr=tovisit.pop();
+      if (!implementationMap.containsKey(cdcurr))
+       implementationMap.put(cdcurr, new HashSet<ClassDescriptor>());
+      if (implementationMap.get(cdcurr).add(cdnew)) {
+       //new implementation...see if it affects implementationmap
+       if (invocationMap.containsKey(cdcurr)) {
+         for(Pair<MethodDescriptor, MethodDescriptor> mdpair:invocationMap.get(cdcurr)) {
+           MethodDescriptor md=mdpair.getFirst();
+           MethodDescriptor callmd=mdpair.getSecond();
+           ClassDescriptor cdactual=cdnew;
+           
+           searchimp:
+           while(cdactual!=null) {
+             Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol());
+             for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
+               MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+               if (callmd.matches(matchmd)) {
+                 //Found the method that will be called
+                 if (!discovered.contains(matchmd)) {
+                   discovered.add(matchmd);
+                   toprocess.push(matchmd);
+                 }
+                 callMap.get(md).add(matchmd);
+                 break searchimp;
+               }
+             }
+             
+             //Didn't find method...look in super class
+             cdactual=cdactual.getSuperDesc();
+           }
+         }
+       }
+      }
+      if (cdcurr.getSuperDesc()!=null)
+       tovisit.push(cdcurr.getSuperDesc());
+      for(Iterator interit=cdcurr.getSuperInterfaces();interit.hasNext();) {
+       ClassDescriptor cdinter=(ClassDescriptor) interit.next();
+       tovisit.push(cdinter);
+      }
+    }
+  }
+
+  void processFlatMethod(MethodDescriptor md) {
+    if (!callMap.containsKey(md))
+      callMap.put(md, new HashSet<MethodDescriptor>());
+    
+    FlatMethod fm=state.getMethodFlat(md);
+    for(FlatNode fn:fm.getNodeSet()) {
+      switch(fn.kind()) {
+      case FKind.FlatCall: {
+       FlatCall fcall=(FlatCall)fn;
+       processCall(md, fcall);
+       break;
+      }
+      case FKind.FlatNew: {
+       FlatNew fnew=(FlatNew)fn;
+       processNew(fnew);
+       break;
+      }
+      }
+    }
   }
 
   public static ParseNode readSourceFile(State state, String sourcefile) {
@@ -51,7 +227,7 @@ public class JavaBuilder {
     }
   }
 
-  public static void loadClass(BuildIR bir, String sourcefile) {
+  public void loadClass(BuildIR bir, String sourcefile) {
     try {
       ParseNode pn=readSourceFile(state, sourcefile);
       bir.buildtree(pn, null,sourcefile);
index 4c3a00df7d563b3c2caf4877ba981f91dd91583b..1c93457977aee3cd6277077ca4b82128524ba6a3 100644 (file)
@@ -9,73 +9,86 @@ public class SemanticCheck {
   TypeUtil typeutil;
   Stack loopstack;
   HashSet toanalyze;
-  HashSet completed;
+  HashMap<ClassDescriptor, Integer> completed;
   
-  //This is the class mappings for a particular file based 
-  //on the import names. Maps class to canonical class name. 
-  Hashtable classnameMappings;
-
+  public static final int NOCHECK=0;
+  public static final int REFERENCE=1;
+  public static final int INIT=2;
+  
+  boolean checkAll;
 
   public SemanticCheck(State state, TypeUtil tu) {
+    this(state, tu, true);
+  }
+
+  public SemanticCheck(State state, TypeUtil tu, boolean checkAll) {
     this.state=state;
     this.typeutil=tu;
     this.loopstack=new Stack();
     this.toanalyze=new HashSet();
-    this.completed=new HashSet();
+    this.completed=new HashMap<ClassDescriptor, Integer>();
+    this.checkAll=checkAll;
   }
 
-  public ClassDescriptor getClass(String classname) {
+  public ClassDescriptor getClass(ClassDescriptor context, String classname) {
+    return getClass(context, classname, INIT);
+  }
+
+  public ClassDescriptor getClass(ClassDescriptor context, String classname, int fullcheck) {
+    if (context!=null) {
+      Hashtable remaptable=context.getSingleImportMappings();
+      classname=remaptable.containsKey(classname)?((String)remaptable.get(classname)):classname;
+    }
     ClassDescriptor cd=typeutil.getClass(classname, toanalyze);
-    checkClass(cd);
+    checkClass(cd, fullcheck);
     return cd;
   }
 
   private void checkClass(ClassDescriptor cd) {
-    if (!completed.contains(cd)) {
-      completed.add(cd);
+    checkClass(cd, INIT);
+  }
+
+  private void checkClass(ClassDescriptor cd, int fullcheck) {
+    if (!completed.containsKey(cd)||completed.get(cd)<fullcheck) {
+      int oldstatus=completed.containsKey(cd)?completed.get(cd):0;
+      completed.put(cd, fullcheck);
       
-      //Set superclass link up
-      if (cd.getSuper()!=null) {
-       cd.setSuper(getClass(cd.getSuper()));
-    if(cd.getSuperDesc().isInterface()) {
-      throw new Error("Error! Class " + cd.getSymbol() + " extends interface " + cd.getSuper());
-    }
-       // Link together Field, Method, and Flag tables so classes
-       // inherit these from their superclasses
-       cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
-       cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
-       cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
-      }
-      // Link together Field, Method tables do classes inherit these from 
-      // their ancestor interfaces
-      Vector<String> sifv = cd.getSuperInterface();
-      for(int i = 0; i < sifv.size(); i++) {
-       ClassDescriptor superif = getClass(sifv.elementAt(i));
-       if(!superif.isInterface()) {
-         throw new Error("Error! Class " + cd.getSymbol() + " implements non-interface " + superif.getSymbol());
+      if (fullcheck>=REFERENCE&&oldstatus<REFERENCE) {
+       //Set superclass link up
+       if (cd.getSuper()!=null) {
+         cd.setSuper(getClass(cd, cd.getSuper(), fullcheck));
+         if(cd.getSuperDesc().isInterface()) {
+           throw new Error("Error! Class " + cd.getSymbol() + " extends interface " + cd.getSuper());
+         }
+         // Link together Field, Method, and Flag tables so classes
+         // inherit these from their superclasses
+         cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
+         cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
+         cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
+       }
+       // Link together Field, Method tables do classes inherit these from 
+       // their ancestor interfaces
+       Vector<String> sifv = cd.getSuperInterface();
+       for(int i = 0; i < sifv.size(); i++) {
+         ClassDescriptor superif = getClass(cd, sifv.elementAt(i), fullcheck);
+         if(!superif.isInterface()) {
+           throw new Error("Error! Class " + cd.getSymbol() + " implements non-interface " + superif.getSymbol());
+         }
+         cd.addSuperInterfaces(superif);
+         cd.getFieldTable().addParentIF(superif.getFieldTable());
+         cd.getMethodTable().addParentIF(superif.getMethodTable());
        }
-       cd.addSuperInterfaces(superif);
-       cd.getFieldTable().addParentIF(superif.getFieldTable());
-       cd.getMethodTable().addParentIF(superif.getMethodTable());
-      }
-      
-      /* Check to see that fields are well typed */
-      for(Iterator field_it=cd.getFields(); field_it.hasNext();) {
-       FieldDescriptor fd=(FieldDescriptor)field_it.next();
-       checkField(cd,fd);
       }
-      
-      for(Iterator method_it=cd.getMethods(); method_it.hasNext();) {
-        MethodDescriptor md=(MethodDescriptor)method_it.next();
-        checkMethod(cd,md);
-        if(md.isDefaultConstructor() && (cd.getSuperDesc() != null)) {
-          // add the construction of it super class, can only be super()
-          NameDescriptor nd=new NameDescriptor("super");
-          MethodInvokeNode min=new MethodInvokeNode(nd);
-          BlockExpressionNode ben=new BlockExpressionNode(min);
-          BlockNode bn = state.getMethodBody(md);
-          bn.addFirstBlockStatement(ben);
-        }
+      if (oldstatus<INIT&&fullcheck>=INIT) {
+       /* Check to see that fields are well typed */
+       for(Iterator field_it=cd.getFields(); field_it.hasNext();) {
+         FieldDescriptor fd=(FieldDescriptor)field_it.next();
+         checkField(cd,fd);
+       }
+       for(Iterator method_it=cd.getMethods(); method_it.hasNext();) {
+         MethodDescriptor md=(MethodDescriptor)method_it.next();
+         checkMethod(cd,md);
+       }
       }
     }
   }
@@ -100,12 +113,10 @@ public class SemanticCheck {
       } else {
         ClassDescriptor cd = (ClassDescriptor) obj;
         toanalyze.remove(cd);
-        //set the class mappings based on imports. 
-        classnameMappings = cd.getSingleImportMappings();
         
         // need to initialize typeutil object here...only place we can
         // get class descriptors without first calling getclass
-        getClass(cd.getSymbol());
+        getClass(cd, cd.getSymbol());
         for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
           MethodDescriptor md = (MethodDescriptor) method_it.next();
           try {
@@ -119,7 +130,7 @@ public class SemanticCheck {
     }
   }
 
-  public void checkTypeDescriptor(TypeDescriptor td) {
+  private void checkTypeDescriptor(ClassDescriptor cd, TypeDescriptor td) {
     if (td.isPrimitive())
       return;       /* Done */
     else if (td.isClass()) {
@@ -128,7 +139,8 @@ public class SemanticCheck {
       if(index != -1) {
         name = name.substring(index+1);
       }
-      ClassDescriptor field_cd=getClass(getFullName(name));
+      ClassDescriptor field_cd=checkAll?getClass(cd, name):getClass(cd, name, REFERENCE);
+
       if (field_cd==null)
        throw new Error("Undefined class "+name);
       td.setClassDescriptor(field_cd);
@@ -140,7 +152,7 @@ public class SemanticCheck {
   }
 
   public void checkField(ClassDescriptor cd, FieldDescriptor fd) {
-    checkTypeDescriptor(fd.getType());
+    checkTypeDescriptor(cd, fd.getType());
   }
 
   public void checkConstraintCheck(TaskDescriptor td, SymbolTable nametable, Vector ccs) {
@@ -203,7 +215,7 @@ public class SemanticCheck {
     for(int i=0; i<td.numParameters(); i++) {
       /* Check that parameter is well typed */
       TypeDescriptor param_type=td.getParamType(i);
-      checkTypeDescriptor(param_type);
+      checkTypeDescriptor(null, param_type);
 
       /* Check the parameter's flag expression is well formed */
       FlagExpressionNode fen=td.getFlag(td.getParameter(i));
@@ -257,12 +269,12 @@ public class SemanticCheck {
 
     /* Check return type */
     if (!md.isConstructor() && !md.isStaticBlock())
-      if (!md.getReturnType().isVoid())
-       checkTypeDescriptor(md.getReturnType());
-
+      if (!md.getReturnType().isVoid()) {
+       checkTypeDescriptor(cd, md.getReturnType());
+      }
     for(int i=0; i<md.numParameters(); i++) {
       TypeDescriptor param_type=md.getParamType(i);
-      checkTypeDescriptor(param_type);
+      checkTypeDescriptor(cd, param_type);
     }
     /* Link the naming environments */
     if (!md.isStatic())     /* Fields aren't accessible directly in a static method, so don't link in this table */
@@ -272,6 +284,14 @@ public class SemanticCheck {
       VarDescriptor thisvd=new VarDescriptor(new TypeDescriptor(cd),"this");
       md.setThis(thisvd);
     }
+    if(md.isDefaultConstructor() && (cd.getSuperDesc() != null)) {
+      // add the construction of it super class, can only be super()
+      NameDescriptor nd=new NameDescriptor("super");
+      MethodInvokeNode min=new MethodInvokeNode(nd);
+      BlockExpressionNode ben=new BlockExpressionNode(min);
+      BlockNode bn = state.getMethodBody(md);
+      bn.addFirstBlockStatement(ben);
+    }
   }
 
   public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
@@ -365,7 +385,7 @@ public class SemanticCheck {
 
   void checkDeclarationNode(Descriptor md, SymbolTable nametable,  DeclarationNode dn) {
     VarDescriptor vd=dn.getVarDescriptor();
-    checkTypeDescriptor(vd.getType());
+    checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), vd.getType());
     Descriptor d=nametable.get(vd.getSymbol());
     if ((d==null)||
         (d instanceof FieldDescriptor)) {
@@ -557,21 +577,20 @@ public class SemanticCheck {
   }
 
   void checkClassTypeNode(Descriptor md, SymbolTable nametable, ClassTypeNode tn, TypeDescriptor td) {
-    checkTypeDescriptor(tn.getType());
+    checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), tn.getType());
   }
   
   void checkCastNode(Descriptor md, SymbolTable nametable, CastNode cn, TypeDescriptor td) {
     /* Get type descriptor */
     if (cn.getType()==null) {
       NameDescriptor typenamed=cn.getTypeName().getName();
-      String typename=getFullName(typenamed.toString());
-      TypeDescriptor ntd=new TypeDescriptor(getClass(typename));
+      TypeDescriptor ntd=new TypeDescriptor(getClass(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), typenamed.toString()));
       cn.setType(ntd);
     }
 
     /* Check the type descriptor */
     TypeDescriptor cast_type=cn.getType();
-    checkTypeDescriptor(cast_type);
+    checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null),cast_type);
 
     /* Type check */
     if (td!=null) {
@@ -689,7 +708,7 @@ public class SemanticCheck {
     } else if (o instanceof Character) {
       ln.setType(new TypeDescriptor(TypeDescriptor.CHAR));
     } else if (o instanceof String) {
-      ln.setType(new TypeDescriptor(getClass(TypeUtil.StringClass)));
+      ln.setType(new TypeDescriptor(getClass(null, TypeUtil.StringClass)));
     }
 
     if (td!=null)
@@ -742,7 +761,7 @@ public class SemanticCheck {
             if(varname.equals("this")) {
               throw new Error("Error: access this obj in a static block");
             }
-            cd=getClass(getFullName(varname));
+            cd=getClass(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), varname);
             if(cd != null) {
               // this is a class name
               nn.setClassDesc(cd);
@@ -772,7 +791,7 @@ public class SemanticCheck {
               throw new Error("Name "+varname+" should not be used in " + md);
             }
           }
-          cd=getClass(varname);
+          cd=getClass(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), varname);
           if(cd != null) {
             // this is a class name
             nn.setClassDesc(cd);
@@ -813,7 +832,7 @@ public class SemanticCheck {
 
   void checkOffsetNode(Descriptor md, SymbolTable nameTable, OffsetNode ofn, TypeDescriptor td) {
     TypeDescriptor ltd=ofn.td;
-    checkTypeDescriptor(ltd);
+    checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null),ltd);
     
     String fieldname = ofn.fieldname;
     FieldDescriptor fd=null;
@@ -849,7 +868,7 @@ public class SemanticCheck {
     if (td!=null&&!td.isBoolean())
       throw new Error("Expecting type "+td+"for instanceof expression");
     
-    checkTypeDescriptor(tn.getExprType());
+    checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), tn.getExprType());
     checkExpressionNode(md, nametable, tn.getExpr(), null);
   }
 
@@ -928,7 +947,7 @@ public class SemanticCheck {
 
     if (an.getDest().getType().isString()&&an.getOperation().getOp()==AssignOperation.PLUSEQ) {
       //String add
-      ClassDescriptor stringcl=getClass(TypeUtil.StringClass);
+      ClassDescriptor stringcl=getClass(null, TypeUtil.StringClass);
       TypeDescriptor stringtd=new TypeDescriptor(stringcl);
       NameDescriptor nd=new NameDescriptor("String");
       NameDescriptor valuend=new NameDescriptor(nd, "valueOf");
@@ -1013,7 +1032,7 @@ public class SemanticCheck {
     }
 
     TypeDescriptor typetolookin = con.getType();
-    checkTypeDescriptor(typetolookin);
+    checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), typetolookin);
 
     if (td != null && !typeutil.isSuperorType(td, typetolookin))
       throw new Error(typetolookin + " isn't a " + td);
@@ -1190,7 +1209,7 @@ public class SemanticCheck {
          //we have a type
          ClassDescriptor cd = null;
          //if (min.getBaseName().getSymbol().equals("System.out"))
-         cd=getClass("System");
+         cd=getClass(null, "System");
          /*else {
             cd=getClass(min.getBaseName().getSymbol());
            }*/
@@ -1418,7 +1437,7 @@ NextMethod:
 
     case Operation.ADD:
       if (ltd.isString()||rtd.isString()) {
-       ClassDescriptor stringcl=getClass(TypeUtil.StringClass);
+       ClassDescriptor stringcl=getClass(null, TypeUtil.StringClass);
        TypeDescriptor stringtd=new TypeDescriptor(stringcl);
        NameDescriptor nd=new NameDescriptor("String");
        NameDescriptor valuend=new NameDescriptor(nd, "valueOf");
@@ -1511,7 +1530,4 @@ NextMethod:
       }
   }
   
-  public String getFullName(String classIn) {
-    return (String) ((this.classnameMappings.containsKey(classIn))?classnameMappings.get(classIn):classIn);
-  }
 }
index 1374e1f44bc701fea12d6761f565ef9ca67a95d6..2b8f6968d8d33f35d7185604c68ab5cc87facebd 100644 (file)
@@ -13,6 +13,7 @@ import java.util.Vector;
 
 import IR.Tree.ParseNode;
 import IR.Tree.BuildIR;
+import IR.Tree.JavaBuilder;
 import IR.Tree.SemanticCheck;
 import IR.Flat.BuildCodeMultiCore;
 import IR.Flat.BuildCodeMGC;
@@ -412,30 +413,40 @@ public class Main {
     State.logEvent("Done Parsing Commands");
 
     SSJavaAnalysis ssjava=new SSJavaAnalysis(state);
-    BuildIR bir=new BuildIR(state);
-    TypeUtil tu=new TypeUtil(state, bir);
 
-    SemanticCheck sc=new SemanticCheck(state,tu);
+    TypeUtil tu;
+    BuildFlat bf;
 
-    for(int i=0;i<sourcefiles.size();i++)
-      loadClass(state, bir, sourcefiles.get(i));
-
-    //Stuff the runtime wants to see
-
-    if (state.TASK) {
-      sc.getClass("TagDescriptor");
+    if (true) {
+      BuildIR bir=new BuildIR(state);
+      tu=new TypeUtil(state, bir);
+      SemanticCheck sc=new SemanticCheck(state,tu);
+      
+      for(int i=0;i<sourcefiles.size();i++)
+       loadClass(state, bir, sourcefiles.get(i));
+      
+      //Stuff the runtime wants to see
+      
+      if (state.TASK) {
+       sc.getClass(null, "TagDescriptor");
+      }
+      
+      sc.semanticCheck();
+      State.logEvent("Done Semantic Checking");
+      
+      tu.createFullTable();
+      State.logEvent("Done Creating TypeUtil");
+      
+      bf=new BuildFlat(state,tu);
+      bf.buildFlat();
+      State.logEvent("Done Building Flat");
+    } else {
+      JavaBuilder jb=new JavaBuilder(state);
+      jb.build();
+      tu=jb.getTypeUtil();
+      bf=jb.getBuildFlat();
     }
-
-    sc.semanticCheck();
-    State.logEvent("Done Semantic Checking");
-
-    tu.createFullTable();
-    State.logEvent("Done Creating TypeUtil");
-
-    BuildFlat bf=new BuildFlat(state,tu);
-    bf.buildFlat();
-    State.logEvent("Done Building Flat");
-
+    
     SafetyAnalysis sa=null;
     PrefetchAnalysis pa=null;
     OoOJavaAnalysis  oooa=null;