changes
[IRC.git] / Robust / src / IR / Flat / BuildFlat.java
index 5c70bf8b1bcaa603f47dd3cac1cb487e9a7aac1f..148f089a0b678b9fe10b54b34717e6b0c4be07ed 100644 (file)
@@ -1,6 +1,7 @@
 package IR.Flat;
 import IR.*;
 import IR.Tree.*;
+
 import java.util.*;
 
 public class BuildFlat {
@@ -12,6 +13,9 @@ public class BuildFlat {
   HashSet breakset;
   HashSet continueset;
   FlatExit fe;
+  
+  // for synchronized blocks
+  Stack<TempDescriptor> lockStack;
 
   public BuildFlat(State st, TypeUtil typeutil) {
     state=st;
@@ -19,6 +23,7 @@ public class BuildFlat {
     this.typeutil=typeutil;
     this.breakset=new HashSet();
     this.continueset=new HashSet();
+    this.lockStack = new Stack<TempDescriptor>();
   }
 
   public Hashtable getMap() {
@@ -53,6 +58,7 @@ public class BuildFlat {
     }
 
     FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.PRE);
+    ffan.setNumLine(bn.getNumLine());
     ffan.addNext(fn);
 
     FlatMethod fm=new FlatMethod(td, fe);
@@ -156,53 +162,83 @@ public class BuildFlat {
     while(methodit.hasNext()) {     
       currmd=(MethodDescriptor)methodit.next();
       
-      // if MLP is on, splice a special SESE in to
-      // enclose the main method, and a special SESE
-      // in around every other method that statically
-      // represents the SESE instance that will call
-      // that method at runtime
+      // 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( state.MLP || state.OOOJAVA ) {
-       if( currmd.equals( typeutil.getMain() ) ) {
-         SESENode mainTree = new SESENode( "main" );
-         spliceSESE = new FlatSESEEnterNode( mainTree );
-         spliceExit = new FlatSESEExitNode ( mainTree );
-         spliceSESE.setFlatExit ( spliceExit );
-         spliceExit.setFlatEnter( spliceSESE );
-       } else {
-         SESENode callerSESETree = new SESENode( "caller SESE placeholder" );
-         spliceSESE = new FlatSESEEnterNode( callerSESETree );
-         spliceSESE.setCallerSESEplaceholder();
-         spliceExit = new FlatSESEExitNode ( callerSESETree );
-         spliceSESE.setFlatExit ( spliceExit );
-         spliceExit.setFlatEnter( spliceSESE );
-       }
-      }
+
+      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()) {
-       curran=new FlatAtomicEnterNode();
+        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);
+      }
       NodePair np=flattenBlockNode(bn);
       FlatNode fn=np.getBegin();
-      if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
+      if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) {
        MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
-       TempDescriptor thistd=getTempforVar(currmd.getThis());
-       FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
-       fc.addNext(fn);
-       fn=fc;
+    FlatNode first = null;
+    FlatNode end = null;
+    for(int j = 0; j < this.lockStack.size(); j++) {
+      TempDescriptor thistd = this.lockStack.elementAt(j);
+      FlatCall fc = new FlatCall(memd, null, thistd, new TempDescriptor[0]);
+      fc.setNumLine(bn.getNumLine());
+      if(first == null)  {
+        first = end = fc;
+      } else {
+        end.addNext(fc);
+        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");
-         FlatCall fcunlock=new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
-         np.getEnd().addNext(fcunlock);
-         FlatNode rnflat=spliceReturn(fcunlock);
+         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;
@@ -215,8 +251,7 @@ public class BuildFlat {
 
       } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) {
        FlatNode rnflat=null;
-       // splice implicit SESE exit after method body
-       if( state.MLP || state.OOOJAVA ) {
+       if( spliceInImplicitMain ) {
          np.getEnd().addNext(spliceExit);
          rnflat=spliceReturn(spliceExit);
        } else {
@@ -224,21 +259,20 @@ public class BuildFlat {
        }
        rnflat.addNext(fe);
       } else if (np.getEnd()!=null) {
-       // splice implicit SESE exit after method body
-       if( state.MLP || state.OOOJAVA ) {
+       if( spliceInImplicitMain ) {
          FlatReturnNode rnflat=(FlatReturnNode)np.getEnd();
          np.getEnd().addNext(spliceExit);
          spliceExit.addNext(fe);
        }
       }
 
-      // splice an implicit SESE enter before method body
-      if( state.MLP || state.OOOJAVA ) {
+      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()));
@@ -286,17 +320,20 @@ public class BuildFlat {
     TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
     NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
     FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
+    fcn.setNumLine(cn.getNumLine());
     np.getEnd().addNext(fcn);
     return new NodePair(np.getBegin(),fcn);
   }
 
   private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
     FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
+    fln.setNumLine(ln.getNumLine());
     return new NodePair(fln,fln);
   }
 
   private NodePair flattenOffsetNode(OffsetNode ofn, TempDescriptor out_temp) {
     FlatOffsetNode fln = new FlatOffsetNode(ofn.getClassType(), ofn.getField(), out_temp);
+    fln.setNumLine(ofn.getNumLine());
     return new NodePair(fln, fln);
   }
 
@@ -312,7 +349,9 @@ public class BuildFlat {
        if (fd.getType().iswrapper()) {
          TempDescriptor wrap_tmp=TempDescriptor.tempFactory("wrapper_obj",fd.getType());
          FlatNode fnwrapper=new FlatNew(fd.getType(), wrap_tmp, con.isGlobal());
+         fnwrapper.setNumLine(con.getNumLine());
          FlatSetFieldNode fsfn=new FlatSetFieldNode(out_temp, fd, wrap_tmp);
+         fsfn.setNumLine(con.getNumLine());
          last.addNext(fnwrapper);
          fnwrapper.addNext(fsfn);
          last=fsfn;
@@ -333,11 +372,13 @@ public class BuildFlat {
       MethodDescriptor md=con.getConstructor();
       //Call to constructor
       FlatCall fc=new FlatCall(md, null, out_temp, temps);
+      fc.setNumLine(con.getNumLine());
       last.addNext(fc);
       last=fc;
       if (td.getClassDesc().hasFlags()) {
        //          if (con.getFlagEffects()!=null) {
        FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
+       ffan.setNumLine(con.getNumLine());
        FlagEffects fes=con.getFlagEffects();
        TempDescriptor flagtemp=out_temp;
        if (fes!=null) {
@@ -359,6 +400,7 @@ public class BuildFlat {
       }
       return new NodePair(fn,last);
     } else {
+      if(con.getArrayInitializer() == null) {
       FlatNode first=null;
       FlatNode last=null;
       TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
@@ -389,6 +431,11 @@ public class BuildFlat {
        return new NodePair(first,np.getEnd());
       } else
        return new NodePair(first, fn);
+      } else if(state.MGC) {
+      // array creation with initializers
+        return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp);
+      }
+      return null;
     }
   }
 
@@ -444,7 +491,11 @@ public class BuildFlat {
     TempDescriptor thisarg=null;
 
     if (min.getExpression()!=null) {
-      thisarg=TempDescriptor.tempFactory("thisarg",min.getExpression().getType());
+      TypeDescriptor mtd = min.getExpression().getType();
+      if(state.MGC && mtd.isClass() && mtd.getClassDesc().isEnum()) {
+        mtd = new TypeDescriptor(TypeDescriptor.INT);
+      }
+      thisarg=TempDescriptor.tempFactory("thisarg", mtd);
       NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
       first=np.getBegin();
       last=np.getEnd();
@@ -453,7 +504,11 @@ public class BuildFlat {
     //Build arguments
     for(int i=0; i<min.numArgs(); i++) {
       ExpressionNode en=min.getArg(i);
-      TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
+      TypeDescriptor etd = en.getType();
+      if(state.MGC && etd.isClass() && etd.getClassDesc().isEnum()) {
+        etd = new TypeDescriptor(TypeDescriptor.INT);
+      }
+      TempDescriptor td=TempDescriptor.tempFactory("arg", etd);
       temps[i]=td;
       NodePair np=flattenExpressionNode(en, td);
       if (first==null)
@@ -469,9 +524,12 @@ public class BuildFlat {
 
     FlatCall fc;
     if(md.getReturnType()==null||md.getReturnType().isVoid())
-      fc=new FlatCall(md, null, thisarg, temps);
+      fc=new FlatCall(md, null, thisarg, temps);      
     else
       fc=new FlatCall(md, out_temp, thisarg, temps);
+    
+    fc.setNumLine(min.getNumLine());
+    
     if (first==null) {
       first=fc;
     } else
@@ -480,11 +538,21 @@ public class BuildFlat {
   }
 
   private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
-    TempDescriptor tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
-    NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
-    FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
-    npe.getEnd().addNext(fn);
-    return new NodePair(npe.getBegin(),fn);
+    TempDescriptor tmp=null;
+    if(fan.getExpression().getType().isClassNameRef()) {
+      // static field dereference with class name
+      tmp = new TempDescriptor(fan.getExpression().getType().getClassDesc().getSymbol(), fan.getExpression().getType());
+      FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
+      fn.setNumLine(fan.getNumLine());
+      return new NodePair(fn,fn);
+    } else {
+      tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
+      NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
+      FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
+      fn.setNumLine(fan.getNumLine());
+      npe.getEnd().addNext(fn);
+      return new NodePair(npe.getBegin(),fn);
+    }
   }
 
   private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
@@ -498,10 +566,12 @@ public class BuildFlat {
       arraytmp=TempDescriptor.tempFactory("temp", aan.getExpression().getType().dereference());
     }
     FlatNode fn=new FlatElementNode(tmp,tmpindex,arraytmp);
+    fn.setNumLine(aan.getNumLine());
     npe.getEnd().addNext(npi.getBegin());
     npi.getEnd().addNext(fn);
     if (aan.iswrapper()) {
       FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)aan.getExpression().getType().dereference().getClassDesc().getFieldTable().get("value") ,arraytmp,out_temp);
+      ffn.setNumLine(aan.getNumLine());
       fn.addNext(ffn);
       fn=ffn;
     }
@@ -527,11 +597,18 @@ public class BuildFlat {
 
     //Get src value
     if (an.getSrc()!=null) {
-      NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
-      first=np_src.getBegin();
-      last=np_src.getEnd();
+      if(an.getSrc().getEval() != null) {
+        FlatLiteralNode fln=new FlatLiteralNode(an.getSrc().getType(), an.getSrc().getEval().longValue(), src_tmp);
+        fln.setNumLine(an.getSrc().getNumLine());
+        first = last =fln;
+      } else {
+        NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
+        first=np_src.getBegin();
+        last=np_src.getEnd();
+      }
     } else if (!pre) {
       FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),new Integer(1),src_tmp);
+      fln.setNumLine(an.getNumLine());
       first=fln;
       last=fln;
     }
@@ -541,8 +618,17 @@ public class BuildFlat {
 
       FieldAccessNode fan=(FieldAccessNode)an.getDest();
       ExpressionNode en=fan.getExpression();
-      TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
-      NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
+      TempDescriptor dst_tmp=null;
+      NodePair np_baseexp=null;
+      if(en.getType().isClassNameRef()) {
+        // static field dereference with class name
+        dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
+        FlatNop nop=new FlatNop();
+        np_baseexp = new NodePair(nop,nop);
+      } else {
+        dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
+        np_baseexp=flattenExpressionNode(en, dst_tmp);
+      }
       if (first==null)
        first=np_baseexp.getBegin();
       else
@@ -555,6 +641,7 @@ public class BuildFlat {
        TempDescriptor src_tmp2=pre ? TempDescriptor.tempFactory("src",an.getDest().getType()) : out_temp;
        TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
        FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
+       ffn.setNumLine(an.getNumLine());
        last.addNext(ffn);
        last=ffn;
 
@@ -562,11 +649,13 @@ public class BuildFlat {
          ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
          MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat2", new TypeDescriptor[] {new TypeDescriptor(stringcd), new TypeDescriptor(stringcd)});
          FlatCall fc=new FlatCall(concatmd, tmp, null, new TempDescriptor[] {src_tmp2, src_tmp});
+         fc.setNumLine(an.getNumLine());
          src_tmp=tmp;
          last.addNext(fc);
          last=fc;
        } else {
          FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
+         fon.setNumLine(an.getNumLine());
          src_tmp=tmp;
          last.addNext(fon);
          last=fon;
@@ -574,10 +663,12 @@ public class BuildFlat {
       }
 
       FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
+      fsfn.setNumLine(en.getNumLine());
       last.addNext(fsfn);
       last=fsfn;
       if (pre) {
        FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
+       fon2.setNumLine(an.getNumLine());
        fsfn.addNext(fon2);
        last=fon2;
       }
@@ -609,12 +700,15 @@ public class BuildFlat {
          TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
          TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
          FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
+         fen.setNumLine(aan.getNumLine());
          FlatFieldNode ffn=new FlatFieldNode((FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp3,src_tmp2);
+         ffn.setNumLine(aan.getNumLine());
          last.addNext(fen);
          fen.addNext(ffn);
          last=ffn;
        } else {
          FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2);
+         fen.setNumLine(aan.getNumLine());
          last.addNext(fen);
          last=fen;
        }
@@ -622,11 +716,13 @@ public class BuildFlat {
          ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
          MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat2", new TypeDescriptor[] {new TypeDescriptor(stringcd), new TypeDescriptor(stringcd)});
          FlatCall fc=new FlatCall(concatmd, tmp, null, new TempDescriptor[] {src_tmp2, src_tmp});
+         fc.setNumLine(an.getNumLine());
          src_tmp=tmp;
          last.addNext(fc);
          last=fc;
        } else {
          FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
+         fon.setNumLine(an.getNumLine());
          src_tmp=tmp;
          last.addNext(fon);
          last=fon;
@@ -637,17 +733,21 @@ public class BuildFlat {
        TypeDescriptor arrayeltype=aan.getExpression().getType().dereference();
        TempDescriptor src_tmp3=TempDescriptor.tempFactory("src3",arrayeltype);
        FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp3);
+       fen.setNumLine(aan.getNumLine());
        FlatSetFieldNode fsfn=new FlatSetFieldNode(src_tmp3,(FieldDescriptor)arrayeltype.getClassDesc().getFieldTable().get("value"),src_tmp);
+       fsfn.setNumLine(aan.getExpression().getNumLine());
        last.addNext(fen);
        fen.addNext(fsfn);
        last=fsfn;
       } else { 
        FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
+       fsen.setNumLine(aan.getNumLine());
        last.addNext(fsen);
        last=fsen;
       }
       if (pre) {
        FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
+       fon2.setNumLine(an.getNumLine());
        last.addNext(fon2);
        last=fon2;
       }
@@ -661,8 +761,17 @@ public class BuildFlat {
        //It is a field
        FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
        ExpressionNode en=fan.getExpression();
-       TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
-       NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
+    TempDescriptor dst_tmp=null;
+    NodePair np_baseexp=null;
+    if(en.getType().isClassNameRef()) {
+      // static field dereference with class name
+      dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType());
+      FlatNop nop=new FlatNop();
+      np_baseexp = new NodePair(nop,nop);
+    } else {
+      dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
+      np_baseexp=flattenExpressionNode(en, dst_tmp);
+    }
        if (first==null)
          first=np_baseexp.getBegin();
        else
@@ -676,6 +785,7 @@ public class BuildFlat {
          TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
 
          FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2);
+         ffn.setNumLine(an.getNumLine());
          last.addNext(ffn);
          last=ffn;
 
@@ -684,11 +794,13 @@ public class BuildFlat {
            ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
            MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat2", new TypeDescriptor[] {new TypeDescriptor(stringcd), new TypeDescriptor(stringcd)});
            FlatCall fc=new FlatCall(concatmd, tmp, null, new TempDescriptor[] {src_tmp2, src_tmp});
+           fc.setNumLine(an.getNumLine());
            src_tmp=tmp;
            last.addNext(fc);
            last=fc;
          } else {
            FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
+           fon.setNumLine(an.getNumLine());
            src_tmp=tmp;
            last.addNext(fon);
            last=fon;
@@ -697,10 +809,12 @@ public class BuildFlat {
 
 
        FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
+       fsfn.setNumLine(en.getNumLine());
        last.addNext(fsfn);
        last=fsfn;
        if (pre) {
          FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
+         fon2.setNumLine(an.getNumLine());
          fsfn.addNext(fon2);
          last=fon2;
        }
@@ -715,8 +829,18 @@ public class BuildFlat {
            //If it is a preinc we need to store the initial value
            TempDescriptor src_tmp2=pre ? TempDescriptor.tempFactory("src",an.getDest().getType()) : out_temp;
            TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
+        
+        TempDescriptor ftmp= null;
+        if(state.MGC && (nn.getClassDesc() != null)) {
+          // this is a static field
+          ftmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
+
+        } else {
+          ftmp=getTempforVar(nn.getVar());
+        }
+        FlatFieldNode ffn=new FlatFieldNode(nn.getField(), ftmp, src_tmp2);
+        ffn.setNumLine(an.getNumLine());
 
-           FlatFieldNode ffn=new FlatFieldNode(nn.getField(), getTempforVar(nn.getVar()), src_tmp2);
            if (first==null)
              first=ffn;
            else {
@@ -729,18 +853,28 @@ public class BuildFlat {
              ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
              MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat2", new TypeDescriptor[] {new TypeDescriptor(stringcd), new TypeDescriptor(stringcd)});
              FlatCall fc=new FlatCall(concatmd, tmp, null, new TempDescriptor[] {src_tmp2, src_tmp});
+             fc.setNumLine(an.getNumLine());
              src_tmp=tmp;
              last.addNext(fc);
              last=fc;
            } else {
              FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
+             fon.setNumLine(an.getNumLine());
              src_tmp=tmp;
              last.addNext(fon);
              last=fon;
            }
          }
 
-         FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
+      FlatSetFieldNode fsfn=null;
+      if(nn.getClassDesc()!=null) {
+        // this is a static field access inside of a static block
+        fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp);
+        fsfn.setNumLine(nn.getNumLine());
+      } else {
+        fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
+        fsfn.setNumLine(nn.getNumLine());
+      }
          if (first==null) {
            first=fsfn;
          } else {
@@ -749,6 +883,7 @@ public class BuildFlat {
          last=fsfn;
          if (pre) {
            FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
+           fon2.setNumLine(an.getNumLine());
            fsfn.addNext(fon2);
            last=fon2;
          }
@@ -763,6 +898,7 @@ public class BuildFlat {
            TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3_",an.getDest().getType());
            if (!pre) {
              FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN));
+             fon.setNumLine(an.getNumLine());
              if (first==null)
                first=fon;
              else
@@ -775,6 +911,7 @@ public class BuildFlat {
              ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
              MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat2", new TypeDescriptor[] {new TypeDescriptor(stringcd), new TypeDescriptor(stringcd)});
              FlatCall fc=new FlatCall(concatmd, tmp, null, new TempDescriptor[] {src_tmp2, src_tmp});
+             fc.setNumLine(an.getNumLine());
              if (first==null)
                first=fc;
              else
@@ -783,6 +920,7 @@ public class BuildFlat {
              last=fc;
            } else {
              FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base);
+             fon.setNumLine(an.getNumLine());
              if (first==null)
                first=fon;
              else
@@ -793,11 +931,13 @@ public class BuildFlat {
          }
 
          FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
+         fon.setNumLine(an.getNumLine());
 
          last.addNext(fon);
          last=fon;
          if (pre) {
            FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN));
+           fon2.setNumLine(an.getNumLine());
            fon.addNext(fon2);
            last=fon2;
          }
@@ -814,8 +954,16 @@ public class BuildFlat {
       /* Hack - use subtree instead */
       return flattenExpressionNode(nn.getExpression(),out_temp);
     } else if (nn.getField()!=null) {
-      TempDescriptor tmp=getTempforVar(nn.getVar());
+      TempDescriptor tmp= null;
+      if(state.MGC && (nn.getClassDesc() != null)) {
+        // this is a static field
+        tmp = new TempDescriptor(nn.getClassDesc().getSymbol(), nn.getClassType());
+        
+      } else {
+      tmp=getTempforVar(nn.getVar());
+      }
       FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
+      ffn.setNumLine(nn.getNumLine());
       return new NodePair(ffn,ffn);
     } else {
       TempDescriptor tmp=getTempforVar(nn.isTag() ? nn.getTagVar() : nn.getVar());
@@ -824,6 +972,7 @@ public class BuildFlat {
        out_temp.setTag(tmp.getTag());
       }
       FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
+      fon.setNumLine(nn.getNumLine());
       return new NodePair(fon,fon);
     }
   }
@@ -847,8 +996,11 @@ public class BuildFlat {
     if (op.getOp()==Operation.LOGIC_OR) {
       /* Need to do shortcircuiting */
       FlatCondBranch fcb=new FlatCondBranch(temp_left);
+      fcb.setNumLine(on.getNumLine());
       FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
+      fon1.setNumLine(on.getNumLine());
       FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
+      fon2.setNumLine(on.getNumLine());
       FlatNop fnop=new FlatNop();
       left.getEnd().addNext(fcb);
       fcb.addFalseNext(right.getBegin());
@@ -860,8 +1012,11 @@ public class BuildFlat {
     } else if (op.getOp()==Operation.LOGIC_AND) {
       /* Need to do shortcircuiting */
       FlatCondBranch fcb=new FlatCondBranch(temp_left);
+      fcb.setNumLine(on.getNumLine());
       FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
+      fon1.setNumLine(on.getNumLine());
       FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
+      fon2.setNumLine(on.getNumLine());
       FlatNop fnop=new FlatNop();
       left.getEnd().addNext(fcb);
       fcb.addTrueNext(right.getBegin());
@@ -875,12 +1030,14 @@ public class BuildFlat {
       ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
       MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
       FlatCall fc=new FlatCall(concatmd, out_temp, temp_left, new TempDescriptor[] {temp_right});
+      fc.setNumLine(on.getNumLine());
       left.getEnd().addNext(right.getBegin());
       right.getEnd().addNext(fc);
       return new NodePair(left.getBegin(), fc);
     }
 
     FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
+    fon.setNumLine(on.getNumLine());
     left.getEnd().addNext(right.getBegin());
     right.getEnd().addNext(fon);
     return new NodePair(left.getBegin(),fon);
@@ -946,6 +1103,7 @@ public class BuildFlat {
     TagDescriptor tag=tvd.getTag();
     TempDescriptor tmp=getTempforVar(tvd);
     FlatTagDeclaration ftd=new FlatTagDeclaration(tag, tmp);
+    ftd.setNumLine(dn.getNumLine());
     return new NodePair(ftd,ftd);
   }
 
@@ -995,6 +1153,7 @@ public class BuildFlat {
     TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
     NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
     FlatCondBranch fcb=new FlatCondBranch(cond_temp);
+    fcb.setNumLine(isn.getNumLine());
     NodePair true_np=flattenBlockNode(isn.getTrueBlock());
     NodePair false_np;
     FlatNop nopend=new FlatNop();
@@ -1018,7 +1177,97 @@ public class BuildFlat {
 
     return new NodePair(cond.getBegin(), nopend);
   }
+  
+  private NodePair flattenSwitchStatementNode(SwitchStatementNode ssn) {
+    TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.INT));
+    NodePair cond=flattenExpressionNode(ssn.getCondition(),cond_temp);
+    FlatNop nopend=new FlatNop();
+    NodePair sbody = flattenSwitchBodyNode(ssn.getSwitchBody(), cond_temp, nopend);
+    
+    cond.getEnd().addNext(sbody.getBegin());
 
+    return new NodePair(cond.getBegin(), sbody.getEnd());
+  }
+  
+  private NodePair flattenSwitchBodyNode(BlockNode bn, TempDescriptor cond_temp, FlatNode endnode) {
+    FlatNode begin=null;
+    FlatNode end=endnode;
+    NodePair prev_true_branch = null;
+    NodePair prev_false_branch = null;
+    for(int i=0; i<bn.size(); i++) {
+      SwitchBlockNode sbn = (SwitchBlockNode)bn.get(i);
+      HashSet oldbs=breakset;
+      breakset=new HashSet();
+      
+      NodePair body=flattenBlockNode(sbn.getSwitchBlockStatement());
+      Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
+      FlatNode cond_begin = null;
+      NodePair prev_fnp = null;
+      for(int j = 0; j < slnv.size(); j++) {
+        SwitchLabelNode sln = slnv.elementAt(j);
+        NodePair left = null;
+        NodePair false_np = null;
+        if(sln.isDefault()) {
+          left = body;
+        } else {
+          TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
+          TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType());
+          Operation op=new Operation(Operation.EQUAL);
+          left=flattenExpressionNode(sln.getCondition(), temp_left);
+          FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op);
+          fon.setNumLine(sln.getNumLine());
+          left.getEnd().addNext(fon);
+
+          FlatCondBranch fcb=new FlatCondBranch(cond_tmp);
+          fcb.setNumLine(bn.getNumLine());
+          fcb.setTrueProb(State.TRUEPROB);
+
+          FlatNop nop=new FlatNop();
+          false_np=new NodePair(nop,nop);
+
+          fon.addNext(fcb);
+          fcb.addTrueNext(body.getBegin());
+          fcb.addFalseNext(false_np.getBegin());
+        }
+        if((prev_fnp != null) && (prev_fnp.getEnd() != null)) {
+          prev_fnp.getEnd().addNext(left.getBegin());
+        }
+        prev_fnp = false_np;
+        
+        if (begin==null) {
+          begin = left.getBegin();
+        }
+        if(cond_begin == null) {
+          cond_begin = left.getBegin();
+        }
+      }
+      if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
+        prev_false_branch.getEnd().addNext(cond_begin);
+      }
+      prev_false_branch = prev_fnp;
+      if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
+        prev_true_branch.getEnd().addNext(body.getBegin());
+      }
+      prev_true_branch = body;
+      for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
+        FlatNode fn=(FlatNode)breakit.next();
+        breakit.remove();
+        fn.addNext(endnode);
+      }
+      breakset=oldbs;
+    }
+    if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) {
+      prev_true_branch.getEnd().addNext(endnode);
+    }
+    if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) {
+      prev_false_branch.getEnd().addNext(endnode);
+    }
+    if(begin == null) {
+      end=begin=new FlatNop();
+    }
+    return new NodePair(begin,end);
+  }
+  
   private NodePair flattenLoopNode(LoopNode ln) {
     HashSet oldbs=breakset;
     HashSet oldcs=continueset;
@@ -1033,6 +1282,7 @@ public class BuildFlat {
       NodePair body=flattenBlockNode(ln.getBody());
       FlatNode begin=initializer.getBegin();
       FlatCondBranch fcb=new FlatCondBranch(cond_temp);
+      fcb.setNumLine(ln.getNumLine());
       fcb.setTrueProb(State.TRUEPROB);
       fcb.setLoop();
       FlatNop nopend=new FlatNop();
@@ -1067,6 +1317,7 @@ public class BuildFlat {
       NodePair body=flattenBlockNode(ln.getBody());
       FlatNode begin=condition.getBegin();
       FlatCondBranch fcb=new FlatCondBranch(cond_temp);
+      fcb.setNumLine(ln.getNumLine());
       fcb.setTrueProb(State.TRUEPROB);
       fcb.setLoop();
       FlatNop nopend=new FlatNop();
@@ -1099,6 +1350,7 @@ public class BuildFlat {
       NodePair body=flattenBlockNode(ln.getBody());
       FlatNode begin=body.getBegin();
       FlatCondBranch fcb=new FlatCondBranch(cond_temp);
+      fcb.setNumLine(ln.getNumLine());
       fcb.setTrueProb(State.TRUEPROB);
       fcb.setLoop();
       FlatNop nopend=new FlatNop();
@@ -1136,14 +1388,23 @@ public class BuildFlat {
     }
 
     FlatReturnNode rnflat=new FlatReturnNode(retval);
+    rnflat.setNumLine(rntree.getNumLine());
     rnflat.addNext(fe);
     FlatNode ln=rnflat;
-    if (state.THREAD&&currmd.getModifiers().isSynchronized()) {
-      MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
-      TempDescriptor thistd=getTempforVar(currmd.getThis());
-      FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]);
-      fc.addNext(ln);
-      ln=fc;
+    if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) {
+      FlatNode end = null;
+      MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
+      for(int j = this.lockStack.size(); j > 0; j--) {
+        TempDescriptor thistd = this.lockStack.elementAt(j-1);
+        FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]);
+        fcunlock.setNumLine(rntree.getNumLine());
+        if(end != null) {
+          end.addNext(fcunlock);
+        }
+        end = fcunlock;
+      }
+      end.addNext(ln);
+      ln=end;
     }
     if (state.DSM&&currmd.getModifiers().isAtomic()) {
       FlatAtomicExitNode faen=new FlatAtomicExitNode(curran);
@@ -1165,6 +1426,7 @@ public class BuildFlat {
     NodePair fcn=flattenConstraintCheck(ten.getChecks());
     ffan.addNext(fcn.getBegin());
     FlatReturnNode rnflat=new FlatReturnNode(null);
+    rnflat.setNumLine(ten.getNumLine());
     rnflat.addNext(fe);
     fcn.getEnd().addNext(rnflat);
     return new NodePair(ffan, null);
@@ -1202,25 +1464,51 @@ public class BuildFlat {
   }
 
   private NodePair flattenSynchronizedNode(SynchronizedNode sbn) {
-    TempDescriptor montmp=TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
-    NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
+    TempDescriptor montmp=null;
+    FlatNode first = null;
+    FlatNode end = null;
+    if(sbn.getExpr() instanceof ClassTypeNode) {
+      montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc());
+    } else {
+      montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType());
+      NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp);
+      first = npexp.getBegin();
+      end = npexp.getEnd();
+    }
+    this.lockStack.push(montmp);
     NodePair npblock=flattenBlockNode(sbn.getBlockNode());
 
     MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter");
     FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]);
+    fcen.setNumLine(sbn.getNumLine());
 
     MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit");
     FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]);
+    fcex.setNumLine(sbn.getNumLine());
+    
+    this.lockStack.pop();
 
-    npexp.getEnd().addNext(fcen);
+    if(first != null) {
+      end.addNext(fcen);
+    } else {
+      first = fcen;
+    }
     fcen.addNext(npblock.getBegin());
-    npblock.getEnd().addNext(fcex);
-    return new NodePair(npexp.getBegin(), fcex);
+    
+    if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) {
+      npblock.getEnd().addNext(fcex);
+    }
+    
+    /*if(npblock.getEnd() != null) {
+      npblock.getEnd().addNext(fcex);
+    }*/
+    return new NodePair(first, fcex);
   }
 
   private NodePair flattenAtomicNode(AtomicNode sbn) {
     NodePair np=flattenBlockNode(sbn.getBlockNode());
     FlatAtomicEnterNode faen=new FlatAtomicEnterNode();
+    faen.setNumLine(sbn.getNumLine());
     FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen);
     faen.addNext(np.getBegin());
     np.getEnd().addNext(faexn);
@@ -1235,6 +1523,7 @@ public class BuildFlat {
   private NodePair flattenSESENode(SESENode sn) {
     if( sn.isStart() ) {
       FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn);
+      fsen.setNumLine(sn.getNumLine());
       sn.setFlatEnter(fsen);
       return new NodePair(fsen, fsen);
     }
@@ -1261,48 +1550,53 @@ public class BuildFlat {
     TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType());
     NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp);
     FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp);
+    fion.setNumLine(tn.getNumLine());
     cond.getEnd().addNext(fion);
     return new NodePair(cond.getBegin(),fion);
   }
 
   private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) {
-    /*
-    TempDescriptor expr_temp=TempDescriptor.tempFactory("arry_init",ain.getType());
+    boolean isGlobal = false;
+    String disjointId = null;
+    // get the type the array to be initialized
+    TypeDescriptor td = ain.getType();
 
     // create a new array of size equal to the array initializer
-    //FlatNode first=null;
-    //FlatNode last=null;
-    TempDescriptor[] temps=new TempDescriptor[ain.numVarInitializers()];
-
-      for (int i=0; i<con.numArgs(); i++) {
-       ExpressionNode en=con.getArg(i);
-       TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
-       temps[i]=tmp;
-       NodePair np=flattenExpressionNode(en, tmp);
-       if (first==null)
-         first=np.getBegin();
-       else
-         last.addNext(np.getBegin());
-       last=np.getEnd();
-
-       TempDescriptor tmp2=(i==0) ?
-                            out_temp :
-                            TempDescriptor.tempFactory("arg",en.getType());
-      }
-      FlatNew fn=new FlatNew(td, out_temp, temps[0], con.isGlobal(), con.getDisjointId());
-      last.addNext(fn);
-
-
-    // assign each element of the new array to the flattened expression
-
-
-    FlatOpNode fonAssignArray=new FlatOpNode(out_temp, newarry_temp, null, new Operation(Operation.ASSIGN));
-    */
-    //return new NodePair( , fonAssignArray );
-    ain.printNode(0);
-    System.out.println( "Array initializers not implemented yet." );
-    System.exit( -1 );
-    return null;
+    FlatNode first=null;
+    FlatNode last=null;
+    TempDescriptor tmp=TempDescriptor.tempFactory("arg", new TypeDescriptor(TypeDescriptor.INT));
+    FlatLiteralNode fln_tmp=new FlatLiteralNode(tmp.getType(), new Integer(ain.numVarInitializers()), tmp);
+    fln_tmp.setNumLine(ain.getNumLine());
+    first = last=fln_tmp;
+    
+    // create the new array
+    FlatNew fn=new FlatNew(td, out_temp, tmp, isGlobal, disjointId);
+    last.addNext(fn);
+    last = fn;
+    
+    // initialize the new array
+    for(int i = 0; i < ain.numVarInitializers(); i++) {
+      ExpressionNode var_init_node = ain.getVarInitializer(i);
+      TempDescriptor tmp_toinit = out_temp;
+      TempDescriptor tmp_init=TempDescriptor.tempFactory("array_init", td.dereference());
+      // index=i
+      TempDescriptor index=TempDescriptor.tempFactory("index", new TypeDescriptor(TypeDescriptor.INT));
+      FlatLiteralNode fln=new FlatLiteralNode(index.getType(), new Integer(i), index);
+      fln.setNumLine(ain.getNumLine());
+      // calculate the initial value
+      NodePair np_init = flattenExpressionNode(var_init_node, tmp_init);
+      // TODO wrapper class process is missing now
+      /*if(td.isArray() && td.dereference().iswrapper()) {
+      }*/
+      FlatSetElementNode fsen=new FlatSetElementNode(tmp_toinit, index, tmp_init);
+      fsen.setNumLine(ain.getNumLine());
+      last.addNext(fln);
+      fln.addNext(np_init.getBegin());
+      np_init.getEnd().addNext(fsen);
+      last = fsen;
+    }
+    
+    return new NodePair(first, last);
   }
 
   private NodePair flattenTertiaryNode(TertiaryNode tn, TempDescriptor out_temp) {
@@ -1312,12 +1606,15 @@ public class BuildFlat {
 
     NodePair cond=flattenExpressionNode(tn.getCond(),cond_temp);
     FlatCondBranch fcb=new FlatCondBranch(cond_temp);
+    fcb.setNumLine(tn.getNumLine());
 
     NodePair trueExpr=flattenExpressionNode(tn.getTrueExpr(),true_temp);
     FlatOpNode fonT=new FlatOpNode(out_temp, true_temp, null, new Operation(Operation.ASSIGN));
+    fonT.setNumLine(tn.getNumLine());
 
     NodePair falseExpr=flattenExpressionNode(tn.getFalseExpr(),fals_temp);
     FlatOpNode fonF=new FlatOpNode(out_temp, fals_temp, null, new Operation(Operation.ASSIGN));
+    fonF.setNumLine(tn.getNumLine());
 
     FlatNop nopend=new FlatNop();
 
@@ -1348,6 +1645,9 @@ public class BuildFlat {
 
     case Kind.IfStatementNode:
       return flattenIfStatementNode((IfStatementNode)bsn);
+      
+    case Kind.SwitchStatementNode:
+      return flattenSwitchStatementNode((SwitchStatementNode)bsn);
 
     case Kind.LoopNode:
       return flattenLoopNode((LoopNode)bsn);