add more comments
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 1aa4a1e326bee3558bb3e4aa3ef554fcd6a20269..56fa8c20a834884300580ce9d53f8311c9aceb6f 100644 (file)
@@ -7,6 +7,9 @@ import IR.*;
 import java.util.*;
 import java.io.*;
 import Util.Relation;
+import Analysis.TaskStateAnalysis.FlagState;
+import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
+import Analysis.TaskStateAnalysis.Predicate;
 
 public class BuildCode {
     State state;
@@ -24,9 +27,10 @@ public class BuildCode {
     Virtual virtualcalls;
     TypeUtil typeutil;
     private int maxtaskparams=0;
+    private int maxcount=0;
     ClassDescriptor[] cdarray;
     TypeDescriptor[] arraytable;
-
+   
     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
        state=st;
        this.temptovar=temptovar;
@@ -52,27 +56,25 @@ public class BuildCode {
        PrintWriter outvirtual=null;
        PrintWriter outtask=null;
        PrintWriter outtaskdefs=null;
+       PrintWriter outoptionalarrays=null;
+       PrintWriter optionalheaders=null;
 
        try {
-           OutputStream str=new FileOutputStream(PREFIX+"structdefs.h");
-           outstructs=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"methodheaders.h");
-           outmethodheader=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"classdefs.h");
-           outclassdefs=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"methods.c");
-           outmethod=new java.io.PrintWriter(str, true);
-           str=new FileOutputStream(PREFIX+"virtualtable.h");
-           outvirtual=new java.io.PrintWriter(str, true);
+           outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
+           outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
+           outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
+           outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
+           outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
            if (state.TASK) {
-               str=new FileOutputStream(PREFIX+"task.h");
-               outtask=new java.io.PrintWriter(str, true);
-               str=new FileOutputStream(PREFIX+"taskdefs.c");
-               outtaskdefs=new java.io.PrintWriter(str, true);
+               outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
+               outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
+               if (state.OPTIONAL){
+                   outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
+                   optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
+               } 
            }
            if (state.structfile!=null) {
-               str=new FileOutputStream(PREFIX+state.structfile+".struct");
-               outrepairstructs=new java.io.PrintWriter(str, true);
+               outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -82,110 +84,33 @@ public class BuildCode {
        /* Build the virtual dispatch tables */
        buildVirtualTables(outvirtual);
 
-
        /* Output includes */
-
        outmethodheader.println("#ifndef METHODHEADERS_H");
        outmethodheader.println("#define METHODHEADERS_H");
        outmethodheader.println("#include \"structdefs.h\"");
 
-       outstructs.println("#ifndef STRUCTDEFS_H");
-       outstructs.println("#define STRUCTDEFS_H");
-       outstructs.println("#include \"classdefs.h\"");
-
-
+       /* Output Structures */
+       outputStructs(outstructs);
 
-       /* Output types for short array and string */
-       outstructs.println("#define STRINGARRAYTYPE "+
-                          (state.getArrayNumber(
-                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
-
-       outstructs.println("#define OBJECTARRAYTYPE "+
-                          (state.getArrayNumber(
-                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
-
-
-       outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
-       outstructs.println("#define CHARARRAYTYPE "+
-                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
-
-       outstructs.println("#define BYTEARRAYTYPE "+
-                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
-
-       outstructs.println("#define BYTEARRAYARRAYTYPE "+
-                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
-       
-       outstructs.println("#define NUMCLASSES "+state.numClasses());
-       if (state.TASK) {
-           outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
-           outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
-           outstructs.println("#define TAGARRAYTYPE "+
-                              (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
-       }
-       
        // Output the C class declarations
        // These could mutually reference each other
-       if (state.THREAD)
-           outclassdefs.println("#include <pthread.h>");
-
-       outclassdefs.println("struct "+arraytype+";");
+       outputClassDeclarations(outclassdefs);
 
-       Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
-       while(it.hasNext()) {
-           ClassDescriptor cn=(ClassDescriptor)it.next();
-           outclassdefs.println("struct "+cn.getSafeSymbol()+";");
-       }
-       outclassdefs.println("");
-       {
-           //Print out definition for array type
-           outclassdefs.println("struct "+arraytype+" {");
-           outclassdefs.println("  int type;");
-           if (state.THREAD) {
-               outclassdefs.println("  pthread_t tid;");
-               outclassdefs.println("  void * lockentry;");
-               outclassdefs.println("  int lockcount;");
-           }
-               
-           if (state.TASK) {
-               outclassdefs.println("  int flag;");
-               outclassdefs.println("  void * flagptr;");
-           }
-           printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
-           outclassdefs.println("  int ___length___;");
-           outclassdefs.println("};\n");
-
-           if (state.TASK) {
-           //Print out definitions for task types
-               outtask.println("struct parameterdescriptor {");
-               outtask.println("int type;");
-               outtask.println("int numberterms;");
-               outtask.println("int *intarray;");
-               outtask.println("void * queue;");
-               outtask.println("int numbertags;");
-               outtask.println("int *tagarray;");
-               outtask.println("};");
-
-               outtask.println("struct taskdescriptor {");
-               outtask.println("void * taskptr;");
-               outtask.println("int numParameters;");
-               outtask.println("int numTotal;");
-               outtask.println("struct parameterdescriptor **descriptorarray;");
-               outtask.println("char * name;");
-               outtask.println("};");
-               outtask.println("extern struct taskdescriptor * taskarray[];");
-               outtask.println("extern numtasks;");
-           }
-       }
+       /* Outputs task structures if this is a task program */
+       if (state.TASK)
+           outputTaskTypes(outtask);
 
        // Output function prototypes and structures for parameters
-       it=state.getClassSymbolTable().getDescriptorsIterator();
+       Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
        while(it.hasNext()) {
            ClassDescriptor cn=(ClassDescriptor)it.next();
            generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
        }
+       outclassdefs.close();
 
        if (state.TASK) {
            /* Map flags to integers */
+           /* The runtime keeps track of flags using these integers */
            it=state.getClassSymbolTable().getDescriptorsIterator();
            while(it.hasNext()) {
                ClassDescriptor cn=(ClassDescriptor)it.next();
@@ -195,11 +120,112 @@ public class BuildCode {
            generateTaskStructs(outstructs, outmethodheader);
        }
 
-       outmethodheader.println("#endif");
+       /* Build the actual methods */
+       outputMethods(outmethod);
 
+       if (state.TASK) {
+           outputTaskCode(outtaskdefs, outmethod);
+           outtaskdefs.close();
+       } else if (state.main!=null) {
+           /* Generate main method */
+           outputMainMethod(outmethod);
+       }
+       outmethodheader.println("#endif");
        outmethodheader.close();
+       outmethod.close();
+       
+       if (state.TASK)
+           outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
+       outstructs.println("#endif");
+       outstructs.close();
+       
+       /* Generate information for task with optional parameters */
+       if (state.TASK&&state.OPTIONAL){
+           generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
+           outoptionalarrays.close();
+       } 
 
-       /* Build the actual methods */
+       /* Output structure definitions for repair tool */
+       if (state.structfile!=null) {
+           buildRepairStructs(outrepairstructs);
+           outrepairstructs.close();
+       }
+    }
+
+    private void outputMainMethod(PrintWriter outmethod) {
+       outmethod.println("int main(int argc, const char *argv[]) {");
+       outmethod.println("  int i;");
+       if (GENERATEPRECISEGC) {
+           outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
+       } else {
+           outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
+       }
+       if (state.THREAD) {
+           outmethod.println("initializethreads();");
+       }
+       outmethod.println("  for(i=1;i<argc;i++) {");
+       outmethod.println("    int length=strlen(argv[i]);");
+       if (GENERATEPRECISEGC) {
+           outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
+       } else {
+           outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
+       }
+       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
+       outmethod.println("  }");
+       
+       
+       MethodDescriptor md=typeutil.getMain();
+       ClassDescriptor cd=typeutil.getMainClass();
+       
+       outmethod.println("   {");
+       if (GENERATEPRECISEGC) {
+           outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
+           outmethod.println("1, NULL,"+"stringarray};");
+           outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
+       } else
+           outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
+       outmethod.println("   }");
+       
+       if (state.THREAD) {
+           outmethod.println("pthread_mutex_lock(&gclistlock);");
+           outmethod.println("threadcount--;");
+           outmethod.println("pthread_cond_signal(&gccond);");
+           outmethod.println("pthread_mutex_unlock(&gclistlock);");
+           outmethod.println("pthread_exit(NULL);");
+       }
+       outmethod.println("}");
+    }
+
+    private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
+       /* Compile task based program */
+       outtaskdefs.println("#include \"task.h\"");
+       outtaskdefs.println("#include \"methodheaders.h\"");
+       Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+       while(taskit.hasNext()) {
+           TaskDescriptor td=(TaskDescriptor)taskit.next();
+           FlatMethod fm=state.getMethodFlat(td);
+           generateFlatMethod(fm, outmethod);
+           generateTaskDescriptor(outtaskdefs, fm, td);
+       }
+       
+       //Output task descriptors
+       taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+       outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
+       boolean first=true;
+       while(taskit.hasNext()) {
+           TaskDescriptor td=(TaskDescriptor)taskit.next();
+           if (first)
+               first=false;
+           else
+               outtaskdefs.println(",");
+           outtaskdefs.print("&task_"+td.getSafeSymbol());
+       }
+       outtaskdefs.println("};");
+
+       outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
+    }
+
+    private void outputMethods(PrintWriter outmethod) {
        outmethod.println("#include \"methodheaders.h\"");
        outmethod.println("#include \"virtualtable.h\"");
        outmethod.println("#include <runtime.h>");
@@ -208,15 +234,9 @@ public class BuildCode {
        if (state.main!=null) {
            outmethod.println("#include <string.h>");       
        }
-
        if (state.CONSCHECK) {
            outmethod.println("#include \"checkers.h\"");
        }
-       outclassdefs.println("extern int classsize[];");
-       outclassdefs.println("extern int hasflags[];");
-       outclassdefs.println("extern int * pointerarray[];");
-       outclassdefs.println("extern int supertypes[];");
-
        //Store the sizes of classes & array elements
        generateSizeArray(outmethod);
        
@@ -239,97 +259,102 @@ public class BuildCode {
                    generateFlatMethod(fm,outmethod);
            }
        }
+    }
 
-       if (state.TASK) {
-           /* Compile task based program */
-           outtaskdefs.println("#include \"task.h\"");
-           outtaskdefs.println("#include \"methodheaders.h\"");
-           Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
-           while(taskit.hasNext()) {
-               TaskDescriptor td=(TaskDescriptor)taskit.next();
-               FlatMethod fm=state.getMethodFlat(td);
-               generateFlatMethod(fm, outmethod);
-               generateTaskDescriptor(outtaskdefs, fm, td);
-           }
-
-           {
-               //Output task descriptors
-               taskit=state.getTaskSymbolTable().getDescriptorsIterator();
-               outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
-               boolean first=true;
-               while(taskit.hasNext()) {
-                   TaskDescriptor td=(TaskDescriptor)taskit.next();
-                   if (first)
-                       first=false;
-                   else
-                       outtaskdefs.println(",");
-                   outtaskdefs.print("&task_"+td.getSafeSymbol());
-               }
-               outtaskdefs.println("};");
-           }
+    private void outputStructs(PrintWriter outstructs) {
+       outstructs.println("#ifndef STRUCTDEFS_H");
+       outstructs.println("#define STRUCTDEFS_H");
+       outstructs.println("#include \"classdefs.h\"");
 
-           outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
+       /* Output #defines that the runtime uses to determine type
+        * numbers for various objects it needs */
 
-       } else if (state.main!=null) {
-           /* Generate main method */
-           outmethod.println("int main(int argc, const char *argv[]) {");
-           outmethod.println("  int i;");
-           if (GENERATEPRECISEGC) {
-               outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
-           } else {
-               outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
-           }
-           if (state.THREAD) {
-               outmethod.println("initializethreads();");
-           }
-           outmethod.println("  for(i=1;i<argc;i++) {");
-           outmethod.println("    int length=strlen(argv[i]);");
-           if (GENERATEPRECISEGC) {
-               outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
-           } else {
-               outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
-           }
-           outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
-           outmethod.println("  }");
+       outstructs.println("#define STRINGARRAYTYPE "+
+                          (state.getArrayNumber(
+                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
 
+       outstructs.println("#define OBJECTARRAYTYPE "+
+                          (state.getArrayNumber(
+                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
 
-           MethodDescriptor md=typeutil.getMain();
-           ClassDescriptor cd=typeutil.getMainClass();
 
-           outmethod.println("   {");
-           if (GENERATEPRECISEGC) {
-               outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
-               outmethod.println("1, NULL,"+"stringarray};");
-               outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
-           } else
-               outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
-           outmethod.println("   }");
-           
-           if (state.THREAD) {
-               outmethod.println("pthread_mutex_lock(&gclistlock);");
-               outmethod.println("threadcount--;");
-               outmethod.println("pthread_cond_signal(&gccond);");
-               outmethod.println("pthread_mutex_unlock(&gclistlock);");
-               outmethod.println("pthread_exit(NULL);");
-           }
-           outmethod.println("}");
-       }
-       if (state.TASK)
-           outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
+       outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
+       outstructs.println("#define CHARARRAYTYPE "+
+                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
 
+       outstructs.println("#define BYTEARRAYTYPE "+
+                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
 
-       /* Output structure definitions for repair tool */
-       if (state.structfile!=null) {
-           buildRepairStructs(outrepairstructs);
-           outrepairstructs.close();
+       outstructs.println("#define BYTEARRAYARRAYTYPE "+
+                          (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
+       
+       outstructs.println("#define NUMCLASSES "+state.numClasses());
+       if (state.TASK) {
+           outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
+           outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
+           outstructs.println("#define TAGARRAYTYPE "+
+                              (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
        }
-       outstructs.println("#endif");
+    }
 
-       outstructs.close();
-       outmethod.close();
+    private void outputClassDeclarations(PrintWriter outclassdefs) {
+       if (state.THREAD)
+           outclassdefs.println("#include <pthread.h>");
+       outclassdefs.println("struct "+arraytype+";");
+       /* Start by declaring all structs */
+       Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
+       while(it.hasNext()) {
+           ClassDescriptor cn=(ClassDescriptor)it.next();
+           outclassdefs.println("struct "+cn.getSafeSymbol()+";");
+       }
+       outclassdefs.println("");
+       //Print out definition for array type
+       outclassdefs.println("struct "+arraytype+" {");
+       outclassdefs.println("  int type;");
+       if (state.THREAD) {
+           outclassdefs.println("  pthread_t tid;");
+           outclassdefs.println("  void * lockentry;");
+           outclassdefs.println("  int lockcount;");
+       }
+       if (state.TASK) {
+           outclassdefs.println("  int flag;");
+           outclassdefs.println("  void * flagptr;");
+           if(state.OPTIONAL) outclassdefs.println("  int failedstatus;");
+       }
+       printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
+       
+       outclassdefs.println("  int ___length___;");
+       outclassdefs.println("};\n");
+       outclassdefs.println("extern int classsize[];");
+       outclassdefs.println("extern int hasflags[];");
+       outclassdefs.println("extern int * pointerarray[];");
+       outclassdefs.println("extern int supertypes[];");
     }
 
-    private int maxcount=0;
+    private void outputTaskTypes(PrintWriter outtask) {
+       //Print out definitions for task types
+       outtask.println("#ifndef _TASK_H");
+       outtask.println("#define _TASK_H");
+       outtask.println("struct parameterdescriptor {");
+       outtask.println("int type;");
+       outtask.println("int numberterms;");
+       outtask.println("int *intarray;");
+       outtask.println("void * queue;");
+       outtask.println("int numbertags;");
+       outtask.println("int *tagarray;");
+       outtask.println("};");
+       
+       outtask.println("struct taskdescriptor {");
+       outtask.println("void * taskptr;");
+       outtask.println("int numParameters;");
+       outtask.println("int numTotal;");
+       outtask.println("struct parameterdescriptor **descriptorarray;");
+       outtask.println("char * name;");
+       outtask.println("};");
+       outtask.println("extern struct taskdescriptor * taskarray[];");
+       outtask.println("extern numtasks;");
+       outtask.println("#endif");
+    }
 
     private void buildRepairStructs(PrintWriter outrepairstructs) {
        Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
@@ -629,7 +654,14 @@ public class BuildCode {
            }
        }
     }
-    
+
+    /** This method outputs the following information about classes
+     * and arrays:
+     * (1) For classes, what are the locations of pointers.
+     * (2) For arrays, does the array contain pointers or primitives.
+     * (3) For classes, does the class contain flags.
+     */
+
     private void generateLayoutStructs(PrintWriter output) {
        Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
        while(it.hasNext()) {
@@ -789,6 +821,7 @@ public class BuildCode {
        if (state.TASK) {
            classdefout.println("  int flag;");
            classdefout.println("  void * flagptr;");
+           if (state.OPTIONAL) classdefout.println("  int failedstatus;");
        }
        printClassStruct(cn, classdefout);
        classdefout.println("};\n");
@@ -928,7 +961,7 @@ public class BuildCode {
        }
     }
 
-    /** Generate code for flatmethod fm. */
+    /** Generate code for FlatMethod fm. */
 
     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
        MethodDescriptor md=fm.getMethod();
@@ -1075,6 +1108,12 @@ public class BuildCode {
 
     private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
        switch(fn.kind()) {
+       case FKind.FlatAtomicEnterNode:
+           generateFlatAtomicEnterNode(fm, (FlatAtomicEnterNode) fn, output);
+           return;
+       case FKind.FlatAtomicExitNode:
+           generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
+           return;
        case FKind.FlatTagDeclaration:
            generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
            return;
@@ -1127,9 +1166,14 @@ public class BuildCode {
        throw new Error();
 
     }
+    
+    public void generateFlatAtomicEnterNode(FlatMethod fm,  FlatAtomicEnterNode faen, PrintWriter output) {
+    }
 
-    private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
+    public void generateFlatAtomicExitNode(FlatMethod fm,  FlatAtomicExitNode faen, PrintWriter output) {
+    }
 
+    private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
        if (state.CONSCHECK) {
            String specname=fcn.getSpec();
            String varname="repairstate___";
@@ -1149,7 +1193,6 @@ public class BuildCode {
            output.println("free"+specname+"_state("+varname+");");
            output.println("abort_task();");
            output.println("}");
-
            output.println("}");
        }
     }
@@ -1393,7 +1436,6 @@ public class BuildCode {
     }
 
     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
-       
        if (frn.getReturnTemp()!=null)
            output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
        else
@@ -1404,6 +1446,9 @@ public class BuildCode {
        output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
     }
 
+    /** This method generates header information for the method or
+     * task referenced by the Descriptor des. */
+
     private void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) {
        /* Print header */
        ParamsObject objectparams=(ParamsObject)paramstable.get(des);
@@ -1581,4 +1626,341 @@ public class BuildCode {
            }
        }
     }
+
+     void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
+        
+        //GENERATE HEADERS
+        headers.println("#include \"task.h\"\n\n");
+        
+
+        
+        //STRUCT PREDICATEMEMBER
+        headers.println("struct predicatemember{");
+        headers.println("int type;");
+        headers.println("int numdnfterms;");
+        headers.println("int * flags;");
+        headers.println("int numtags;");
+        headers.println("int * tags;\n};\n\n");
+
+        //STRUCT EXITFLAGSTATE
+        headers.println("struct exitflagstate{");
+        headers.println("int numflags;");
+        headers.println("int * flags;");
+        /*
+          headers.println("int numtags;");
+          headers.println("int * tags;");
+        */
+        headers.println("\n};\n\n");
+        
+        //STRUCT EXITSTATES
+        headers.println("struct exitstates{");
+        headers.println("int numexitflagstates;");
+        headers.println("struct exitflagstate * exitflagstatearray;\n};\n\n");
+
+        //STRUCT OPTIONALTASKDESCRIPTOR
+        headers.println("struct optionaltaskdescriptor{");
+        headers.println("struct taskdescriptor * task;");
+        headers.println("int numpredicatemembers;");
+        headers.println("struct predicatemember * predicatememberarray;");
+        headers.println("int numexitstates;");
+        headers.println("struct existates * exitstatesarray;\n};\n\n");
+                
+        //STRUCT FSANALYSISWRAPPER
+        headers.println("struct fsanalysiswrapper{");
+        headers.println("int numflags;");
+        headers.println("int * flags;");
+        headers.println("int numtags;");
+        headers.println("int * tags;");
+        headers.println("int numoptionaltaskdescriptors;");
+        headers.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray;\n};\n\n");
+
+        //STRUCT CLASSANALYSISWRAPPER
+        headers.println("struct classanalyiswrapper{");
+        headers.println("int type;");
+        headers.println("int numfsanalysiswrappers;");
+        headers.println("struct fsanalysiswrapper * fsanalysiswrapperarray;\n};\n\n");
+
+        Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+        while(taskit.hasNext()) {
+            TaskDescriptor td=(TaskDescriptor)taskit.next();
+            headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
+        }
+        
+                                                  
+        
+        //GENERATE STRUCTS
+        output.println("#include \"optionalstruct.h\"\n\n");    
+        HashSet processedcd = new HashSet();
+       
+
+        Enumeration e = safeexecution.keys();
+        while (e.hasMoreElements()) {
+            
+            //get the class
+            ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
+            Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
+            
+            //Generate the struct of optionals
+            if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
+            Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
+            if( !c_otd.isEmpty() ){
+                for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
+                    OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
+                    
+                    //generate the int arrays for the predicate
+                    Predicate predicate = otd.predicate;
+                    int predicateindex = 0;
+                    //iterate through the classes concerned by the predicate
+                    Collection c_vard = predicate.vardescriptors.values();
+                    for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
+                        VarDescriptor vard = (VarDescriptor)vard_it.next();
+                        TypeDescriptor typed = vard.getType();
+                        
+                        //generate for flags
+                        HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
+                        output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                        int numberterms=0;
+                        if (fen_hashset!=null){
+                            for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
+                                FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
+                                if (fen==null) {
+                                    //output.println("0x0, 0x0 };");
+                                    //numberterms+=1;
+                                }
+                                else {
+                                    
+                                    DNFFlag dflag=fen.getDNF();
+                                    numberterms+=dflag.size();
+                                    
+                                    Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
+                                    
+                                    for(int j=0;j<dflag.size();j++) {
+                                        if (j!=0)
+                                            output.println(",");
+                                        Vector term=dflag.get(j);
+                                        int andmask=0;
+                                        int checkmask=0;
+                                        for(int k=0;k<term.size();k++) {
+                                            DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
+                                            FlagDescriptor fd=dfa.getFlag();
+                                            boolean negated=dfa.getNegated();
+                                            int flagid=1<<((Integer)flags.get(fd)).intValue();
+                                            andmask|=flagid;
+                                            if (!negated)
+                                                checkmask|=flagid;
+                                        }
+                                        output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
+                                    }
+                                }
+                            }
+                        }
+                        output.println("};\n");
+                        
+                        //generate for tags
+                        TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
+                        output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                        //BUG...added next line to fix, test with any task program
+                        int numtags = 0;
+                        if (tagel!=null){
+                            for(int j=0;j<tagel.numTags();j++) {
+                                if (j!=0)
+                                    output.println(",");
+                                /* for each tag we need */
+                                /* which slot it is */
+                                /* what type it is */
+                                //TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(tagel.getName(j));
+                                TempDescriptor tmp=tagel.getTemp(j);
+                                //got rid of slot
+                                output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
+                            }
+                            numtags = tagel.numTags();
+                        }
+                        output.println("};");
+                        
+                        //store the result into a predicatemember struct
+                        output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                        output.println("/*type*/"+typed.getClassDesc().getId()+",");
+                        output.println("/* number of dnf terms */"+numberterms+",");
+                        output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        output.println("/* number of tag */"+numtags+",");
+                        output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        output.println("};\n");
+                        predicateindex++;
+                    }
+                    
+
+                    //generate an array that stores the entire predicate
+                    output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                    for( int j = 0; j<predicateindex; j++){
+                        if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                    }
+
+                    //generate the struct for possible exitfses
+                    HashSet<HashSet> exitfses = otd.exitfses;
+                    int exitindex = 0;
+                    int nbexit = exitfses.size();
+                    int fsnumber;
+                    
+                    //iterate through possible exits
+                    for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
+                        HashSet temp_hashset = (HashSet)exitfseshash.next();
+                        fsnumber = 0 ;
+                        
+                        //iterate through possible FSes corresponding to the exit
+                        for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
+                           FlagState fs = (FlagState)exfses.next();
+                           fsnumber++;
+                           output.println("int flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                           int counterflag = 0;
+                           for(Iterator flags = fs.getFlags(); flags.hasNext();){
+                               FlagDescriptor flagd = (FlagDescriptor)flags.next();
+                               int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
+                               if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
+                               else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
+                               counterflag++;
+                           } 
+                           output.println("};\n");
+                           //do the same for tags;
+                           //maybe not needed because no tag changes tolerated.
+
+                           //store the information into a struct
+                           output.println("struct exitflagstate exitflagstate"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                           output.println("/*number of flags*/"+counterflag+",");
+                           output.println("flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                           output.println("};\n");
+                        }
+                        
+                        //store fses corresponding to this exit into an array
+                        output.println("struct exitflagstate * exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+" [] = {");
+                        for( int j = 0; j<fsnumber; j++){
+                            if( j != fsnumber-1)output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"'");
+                            else output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                        }
+                        
+                        //store that information in a struct
+                        output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                        output.println("/*number of exitflagstate*/"+fsnumber+",");
+                        output.println("exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                        output.println("};\n");
+
+                        exitindex++;
+                    }
+                    
+                    //store the information concerning all exits into an array
+                    output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                    for( int j = 0; j<nbexit; j++){
+                        if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                        else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                    }
+                                    
+                                    
+                    //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
+                    output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+                    output.println("task_"+otd.td.getSafeSymbol()+",");
+                    output.println("/*number of members */"+predicateindex+",");
+                    output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                    output.println("/*number of exit fses */"+nbexit+",");
+                    output.println("exitstatearray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+                    output.println("};\n");
+                }      
+            }
+            else continue; // if there is no optionals, there is no need to build the rest of the struct 
+            
+            //get all the possible falgstates reachable by an object
+            Hashtable hashtbtemp = safeexecution.get(cdtemp);
+            Enumeration fses = hashtbtemp.keys();
+            int fscounter = 0;
+            while(fses.hasMoreElements()){
+                FlagState fs = (FlagState)fses.nextElement();
+                fscounter++;
+                
+                //get the set of OptionalTaskDescriptors corresponding
+                HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
+                //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
+                
+                output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
+                for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
+                    OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
+                    if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
+                    
+                    else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+                }
+
+                //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
+                
+                output.println("int flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
+                for(Iterator flags = fs.getFlags(); flags.hasNext();){
+                    FlagDescriptor flagd = (FlagDescriptor)flags.next();
+                    int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
+                    if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
+                    else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
+                    
+                }
+                //process tag information
+                
+                int tagcounter = 0;
+                //TagExpressionList tagel = fs.getTags(); 
+                //output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+                //BUG...added next line to fix, test with any task program
+                
+                //if (tagel!=null){
+                //    for(int j=0;j<tagel.numTags();j++) {
+                //      if (j!=0)
+                //          output.println(",");
+                //      TempDescriptor tmp=tagel.getTemp(j);
+                //      output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
+                //   }
+                //  numtags = tagel.numTags();
+                //}
+                //output.println("};");
+                
+                
+                //Store the result in fsanalysiswrapper
+                output.println("};\n");
+                output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
+                output.println("/* number of flags*/"+fs.numFlags()+",");
+                output.println("flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+                output.println("/* number of tags*/"+tagcounter+",");
+                output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+                output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
+                output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
+                output.println("};\n");
+                
+            }
+
+            //Build the array of fsanalysiswrappers
+            output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
+            for(int i = 0; i<fscounter; i++){
+                if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
+                        
+                    else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
+            }
+
+            //Build the classanalysiswrapper referring to the previous array
+            output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
+            output.println("/*type*/"+cdtemp.getId()+",");
+            output.println("/* number of fsanalysiswrappers */"+fscounter+",");
+            output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
+            fscounter = 0;
+            processedcd.add(cdtemp);
+        }
+
+        //build an array containing every classes for which code has been build
+        output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
+        for(Iterator classit = processedcd.iterator(); classit.hasNext();){
+            ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
+            if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
+            else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
+        }
+        output.println("int numclasses = "+processedcd.size()+";");
+        
+     }
+    
 }
+        
+
+
+
+
+