From 20f4a8dc41dedff13ccdd90bcf420d0f1f78844c Mon Sep 17 00:00:00 2001 From: Peizhao Ou Date: Wed, 30 Oct 2013 19:05:38 -0700 Subject: [PATCH] add lots of stuff --- notes/generated_code_examples.txt | 9 +- .../codeGenerator/CodeAddition.java | 4 + .../codeGenerator/CodeGenerator.java | 88 ++--- .../codeGenerator/CodeVariables.java | 309 ++++++++++++++++-- .../codeGenerator/SemanticsChecker.java | 48 ++- .../specExtraction/FunctionHeader.java | 30 +- .../specExtraction/ParserUtils.java | 24 +- .../specExtraction/QualifiedName.java | 11 +- test.cc | 18 + 9 files changed, 456 insertions(+), 85 deletions(-) create mode 100644 test.cc diff --git a/notes/generated_code_examples.txt b/notes/generated_code_examples.txt index 1658001..0993e2f 100644 --- a/notes/generated_code_examples.txt +++ b/notes/generated_code_examples.txt @@ -77,7 +77,7 @@ bool Get_check_action(void *info, id_t __ID__) { /* Initialization of interface<->function_ptr table */ #define INTERFACE_SIZE 2 -void* func_ptr_table[INTERFACE_SIZE * 2]; +void** func_ptr_table; /* Beginning of other user-defined variables */ bool lock_acquired; @@ -88,6 +88,11 @@ int reader_lock_cnt; /* Define function for sequential code initialization */ void __sequential_init() { /* Init func_ptr_table */ + func_ptr_table = (void**) malloc(sizeof(void*) * 2); + func_ptr_table[0] = (void*) &Put_id; + func_ptr_table[1] = (void*) &Put_check_action; + func_ptr_table[2] = (void*) &Get_id; + func_ptr_table[3] = (void*) &Get_check_action; /* Init user-defined variables */ lock_acquired = false; @@ -150,7 +155,6 @@ TypeReturn interfaceName(ARGType1 arg1, ARGType2 arg2) // And more (if any) // Interface ends - spec_annotation annotation_interface_end; INTERFACE_LABEL_info info = (INTERFACE_LABEL_info*) malloc(sizeof(INTERFACE_LABEL_info)); info->__RET__ = __RET__; info->arg1 = arg1; @@ -158,6 +162,7 @@ TypeReturn interfaceName(ARGType1 arg1, ARGType2 arg2) anno_interface_end interface_end; interface_end.interface_num = 0; // Interface number interface_end.info = info; // Info + spec_annotation annotation_interface_end; annotation_interface_end.type = INTERFACE_END; annotation_interface_end.annotation = &interface_end; cdsannotate(SPEC_ANALYSIS, &annoation_interface_end); diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeAddition.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeAddition.java index 6359d82..f127772 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeAddition.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeAddition.java @@ -3,6 +3,10 @@ package edu.uci.eecs.specCompiler.codeGenerator; import java.util.ArrayList; public class CodeAddition { + public static class CodeAdditionComparator { + + } + public final int lineNum; public final ArrayList newCode; diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java index e685bc6..e78624c 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java @@ -11,8 +11,10 @@ import java.util.Iterator; import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct; import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface; import edu.uci.eecs.specCompiler.specExtraction.Construct; +import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct; import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct; import edu.uci.eecs.specCompiler.specExtraction.IDExtractor; import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct; @@ -41,18 +43,14 @@ public class CodeGenerator { private HashMap> codeAdditions; - private ArrayList globalContent; - public CodeGenerator(File[] srcFiles) { this.srcFiles = srcFiles; _extractor = new SpecExtractor(); _extractor.extract(srcFiles); - + this.srcFilesInfo = _extractor.srcFilesInfo; - - this.globalContent = null; - this.codeAdditions = new HashMap>(); + this.codeAdditions = new HashMap>(); _semantics = new SemanticsChecker(_extractor); try { @@ -72,32 +70,26 @@ public class CodeGenerator { private void globalConstruct2Code(GlobalConstruct construct) { ArrayList newCode = CodeVariables.generateGlobalVarDeclaration( _semantics, construct); - // Record the global content array to generate the new file - globalContent = newCode; + // Add it to the codeAdditions + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); + } + CodeAddition addition = new CodeAddition(construct.beginLineNum, + newCode); + codeAdditions.get(construct.file).add(addition); + newCode = CodeVariables.generateStaticVarDefine(_semantics, construct); + if (newCode.size() > 0) { + addition = new CodeAddition(_semantics.getClassEndConstruct().beginLineNum, newCode); + codeAdditions.get(construct.file).add(addition); + } } // Mainly rename and wrap the interface private void interface2Code(InterfaceConstruct construct) throws InterfaceWrongFormatException { - int lineNum = construct.beginLineNum; - String funcName = ""; - - // Rename the interface name - - // Rename the function declaration - - // Also rename the function definition if it's separated from the - // declaration - InterfaceDefineConstruct definition = (InterfaceDefineConstruct) _semantics.interfaceName2DefineConstruct - .get(construct.name); - if (definition != null) { - String funcDefintionName = renameInterface(definition); - assert (funcDefintionName.equals(funcName)); - } - - // Generate new wrapper ArrayList newCode = CodeVariables.generateInterfaceWrapper( _semantics, construct); + int lineNum = construct.beginLineNum; // Add it to the codeAdditions CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -106,37 +98,10 @@ public class CodeGenerator { codeAdditions.get(construct.file).add(addition); } - // Returns the function name that has been renamed and replace the old line - private String renameInterface(Construct construct) - throws InterfaceWrongFormatException { - String funcDecl = ""; - ArrayList content = srcFilesInfo.get(construct.file).content; - - // Depending on "(" to find the function name, so it doesn't matter if - // there's any template - int beginIdx = funcDecl.indexOf('('); - if (beginIdx == -1) { - throw new InterfaceWrongFormatException(funcDecl - + "\n has wrong format!"); - } - IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx); - String funcName = idExtractor.getPrevID(); - int idBeginIdx = idExtractor.getIDBeginIdx(), idEndIdx = idExtractor - .getIDEndIdx(), idLineBeginIdx = idExtractor.lineBeginIdxOfID(), idLineEndIdx = idExtractor - .lineEndIdxOfID(); - String newLine = funcDecl.substring(idLineBeginIdx, idBeginIdx) - + CodeVariables.SPEC_INTERFACE_WRAPPER + funcName - + funcDecl.substring(idEndIdx + 1, idLineEndIdx + 1); - - int lineNumOfID = idExtractor.lineNumOfID(); - // Be careful: lineNum - 1 -> index of content array - content.set(construct.beginLineNum - 1, newLine); - return funcName; - } - private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) { int lineNum = construct.beginLineNum; - ArrayList newCode = new ArrayList(); + ArrayList newCode = CodeVariables.generatePotentialCPDefine( + _semantics, construct); CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -147,7 +112,7 @@ public class CodeGenerator { private void CPDefine2Code(CPDefineConstruct construct) { int lineNum = construct.beginLineNum; - ArrayList newCode = new ArrayList(); + ArrayList newCode = CodeVariables.generateCPDefine(_semantics, construct); CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -157,8 +122,20 @@ public class CodeGenerator { } private void CPDefineCheck2Code(CPDefineCheckConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generateCPDefineCheck(_semantics, construct); + + CodeAddition addition = new CodeAddition(lineNum, newCode); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); + } + codeAdditions.get(construct.file).add(addition); + } + + private void EntryPoint2Code(EntryPointConstruct construct) { int lineNum = construct.beginLineNum; ArrayList newCode = new ArrayList(); + newCode.add(") CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -166,6 +143,7 @@ public class CodeGenerator { } codeAdditions.get(construct.file).add(addition); } + public void generateCode() { for (int i = 0; i < _semantics.constructs.size(); i++) { diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java index 2900601..dd815db 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java @@ -6,11 +6,15 @@ import java.io.File; import edu.uci.eecs.specCompiler.grammerParser.ParseException; import edu.uci.eecs.specCompiler.grammerParser.SpecParser; +import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; +import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface; +import edu.uci.eecs.specCompiler.specExtraction.Construct; import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader; import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct; import edu.uci.eecs.specCompiler.specExtraction.IDExtractor; import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct; +import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.ParserUtils; import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct; @@ -40,18 +44,19 @@ public class CodeVariables { public static final String SPEC_ANNO_TYPE_HB_CONDITION = "HB_CONDITION"; public static final String SPEC_ANNO_TYPE_INTERFACE_END = "INTERFACE_END"; public static final String SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE = "POTENTIAL_CP_DEFINE"; + public static final String SPEC_ANNO_TYPE_CP_DEFINE_CHECK = "CP_DEFINE_CHECK"; + public static final String SPEC_ANNO_TYPE_CP_DEFINE = "CP_DEFINE"; public static final String SPEC_ANNOTATION = "spec_annotation"; public static final String SPEC_ANNOTATION_FIELD_TYPE = "type"; public static final String SPEC_ANNOTATION_FIELD_ANNO = "annotation"; public static final String ANNO_HB_INIT = "anno_hb_init"; - public static final String ANNO_INTERFACE_BOUNDARY = "anno_interface_boundary"; - public static final String ANNO_ID = "anno_id"; + public static final String ANNO_INTERFACE_BEGIN = "anno_interface_begin"; + public static final String ANNO_INTERFACE_END = "anno_interface_end"; public static final String ANNO_POTENTIAL_CP_DEFINE = "anno_potentail_cp_define"; public static final String ANNO_CP_DEFINE = "anno_cp_define"; public static final String ANNO_CP_DEFINE_CHECK = "anno_cp_define_check"; public static final String ANNO_HB_CONDITION = "anno_hb_condition"; - public static final String ANNO_POST_CHECK = "anno_post_check"; // Specification variables public static final String SPEC_INTERFACE_WRAPPER = "__wrapper_"; @@ -96,6 +101,14 @@ public class CodeVariables { return "#undef " + macro; } + private static String GET_FIELD_BY_PTR(String ptr, String field) { + return ptr + "->" + field; + } + + private static String GET_FIELD(String var, String field) { + return var + "->" + field; + } + private static String BRACE(String val) { return "(" + val + ")"; } @@ -104,10 +117,19 @@ public class CodeVariables { return structName + "." + field + " = " + val + ";"; } + private static String ASSIGN(String varName, String val) { + return varName + " = " + val + ";"; + } + private static String ASSIGN_PTR(String structName, String field, String val) { return structName + "." + field + " = &" + val + ";"; } + private static String ASSIGN_TO_PTR(String structName, String field, + String val) { + return structName + "->" + field + " = " + val + ";"; + } + private static String DECLARE(String type, String name) { return type + " " + name + ";"; } @@ -151,6 +173,41 @@ public class CodeVariables { return code; } + private static ArrayList DEFINE_CHECK_ACTION_FUNC( + InterfaceConstruct construct, FunctionHeader header) { + String interfaceName = construct.name; + ArrayList code = new ArrayList(); + code.add("bool " + interfaceName + "_check_action(void *info, " + + IDType + " " + MACRO_ID + ") {"); + code.add(DECLARE("bool", "check_passed")); + String infoStructType = interfaceName + "_info", infoStructName = "theInfo"; + code.add(DECLARE_DEFINE(infoStructType + "*", infoStructName, + BRACE(infoStructType) + "info")); + code.add((DECLARE_DEFINE(header.returnType, MACRO_RETURN, + GET_FIELD_BY_PTR(infoStructName, MACRO_RETURN)))); + for (int i = 0; i < header.args.size(); i++) { + String type = header.args.get(i).type, var = header.args.get(i).name; + code.add((DECLARE_DEFINE(type, var, + GET_FIELD_BY_PTR(infoStructName, var)))); + } + code.add(""); + // __COND_SAT + code.add(DECLARE_DEFINE("bool", MACRO_COND, construct.condition)); + // Check + code.add(ASSIGN("check_passed", construct.check)); + code.add("if (!check_passed) return false;"); + // Action + code.addAll(construct.action); + // Post_check + code.add(ASSIGN("check_passed", construct.postCheck)); + code.add("if (!check_passed) return false;"); + // Post_action + code.addAll(construct.postAction); + code.add("}"); + + return code; + } + private static HashSet getAllHeaders(SemanticsChecker semantics) { HashSet headers = new HashSet(); for (String interfaceName : semantics.interfaceName2Construct.keySet()) { @@ -175,9 +232,12 @@ public class CodeVariables { } private static FunctionHeader getFunctionHeader(SemanticsChecker semantics, - InterfaceConstruct construct) { + Construct construct) { ArrayList content = semantics.srcFilesInfo.get(construct.file).content; String headerLine = content.get(construct.beginLineNum); + if (headerLine.startsWith("template")) { + headerLine = content.get(construct.beginLineNum + 1); + } try { return SpecParser.parseFuncHeader(headerLine); } catch (ParseException e) { @@ -227,17 +287,24 @@ public class CodeVariables { newCode.add(""); // Define ID function - newCode.add(COMMENT("ID functions of interface: " + interfaceName)); + newCode.add(COMMENT("ID function of interface: " + interfaceName)); newCode.addAll(DEFINE_ID_FUNC(interfaceName, iConstruct.idCode)); - newCode.add(""); newCode.add(COMMENT("End of ID function: + " + interfaceName)); newCode.add(""); - - // Define check_action function - + // Define check_action function + newCode.add(COMMENT("Check action function of interface: " + + interfaceName)); + newCode.addAll(DEFINE_CHECK_ACTION_FUNC(iConstruct, funcHeader)); + newCode.add(COMMENT("End of check action function: + " + + interfaceName)); + newCode.add(""); } - + // Interface function pointer table + String interfaceSize = Integer + .toString(semantics.interfaceName2Construct.size()); + newCode.add(DEFINE("INTERFACE_SIZE", interfaceSize)); + newCode.add(DECLARE("void**", "func_ptr_table")); // User-defined variables ArrayList varDecls = code.declareVar; for (int i = 0; i < varDecls.size(); i++) { @@ -245,10 +312,65 @@ public class CodeVariables { newCode.add(DECLARE(varDecl.type, varDecl.name)); } + newCode.add(""); + newCode.add(COMMENT("Define function for sequential code initialization")); + newCode.add("static void __sequential_init() {"); + // Init func_ptr_table + newCode.add(COMMENT("Init func_ptr_table")); + newCode.add(ASSIGN("func_ptr_table", + "(void**) malloc(sizeof(void*) * 2)")); + for (String interfaceName : semantics.interfaceName2Construct.keySet()) { + String interfaceNum = Integer.toString(semantics.interface2Num + .get(interfaceName)); + newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + "]", + "(void*) &" + interfaceName + "_id")); + newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + " + 1]", + "(void*) &" + interfaceName + "_check_action")); + } + newCode.add(""); + // Init user-defined variables + newCode.addAll(construct.code.initVar); + // Pass Happens-before relationship + generateHBInitAnnotation(semantics); + newCode.add("}"); + newCode.add(COMMENT("End of Global construct generation in class")); + // printCode(newCode); return newCode; } + public static ArrayList generateStaticVarDefine( + SemanticsChecker semantics, GlobalConstruct construct) { + ArrayList newCode = new ArrayList(); + String className = semantics.getClassName(); + if (className == null) + return newCode; // No need to define any static variables + String templateList = semantics.getTemplateStr(); + String varPrefix; + if (templateList == null) { + varPrefix = className + "::"; + } else { + varPrefix = className + templateList + "::"; + } + String templateDecl = semantics.getTemplateFullStr(); + if (templateList == null) { + newCode.add(DECLARE("void**", varPrefix + "func_ptr_table")); + for (int i = 0; i < construct.code.declareVar.size(); i++) { + VariableDeclaration varDecl = construct.code.declareVar.get(i); + newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name)); + } + } else { + newCode.add(templateDecl); + newCode.add(DECLARE("void**", varPrefix + "func_ptr_table")); + for (int i = 0; i < construct.code.declareVar.size(); i++) { + VariableDeclaration varDecl = construct.code.declareVar.get(i); + newCode.add(templateDecl); + newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name)); + } + } + return newCode; + } + private static ArrayList generateHBInitAnnotation( SemanticsChecker semantics) { ArrayList newCode = new ArrayList(); @@ -294,40 +416,183 @@ public class CodeVariables { public static ArrayList generateInterfaceWrapper( SemanticsChecker semantics, InterfaceConstruct construct) { ArrayList newCode = new ArrayList(); - + String interfaceName = construct.name; // Generate necessary header file (might be redundant but never mind) + newCode.add(INCLUDE(HEADER_THREADS)); + newCode.add(INCLUDE(HEADER_CDSANNOTATE)); + newCode.add(INCLUDE(HEADER_SPECANNOTATION)); + newCode.add(INCLUDE(HEADER_SPEC_LIB)); + FunctionHeader header = getFunctionHeader(semantics, construct); + String interfaceNum = Integer.toString(semantics.interface2Num + .get(construct.name)); + // Rename the interface + renameInterface(semantics, construct); + InterfaceDefineConstruct defineConstruct = semantics.interfaceName2DefineConstruct.get(interfaceName); + if (defineConstruct != null) { + renameInterface(semantics, defineConstruct); + } + // Generate wrapper header - + newCode.add(header.toString() + " {"); // Wrapper function body - + newCode.add(COMMENT("Interface begins")); // Interface begin - + String structName = "interface_begin"; + newCode.add(DECLARE(ANNO_INTERFACE_BEGIN, "interface_begin")); + newCode.add(ASSIGN(structName, "interface_num", interfaceNum)); + String anno = "annotation_interface_begin"; + newCode.add(DECLARE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN(structName, "type", SPEC_ANNO_TYPE_INTERFACE_BEGIN)); + newCode.add(ASSIGN_PTR(structName, "annotation", structName)); + newCode.add(ANNOTATE(anno)); // Call original renamed function - + newCode.add(DECLARE_DEFINE(header.returnType, MACRO_RETURN, + header.getRenamedCall(SPEC_INTERFACE_WRAPPER))); // HB conditions - + for (String label : construct.hbConditions.keySet()) { + String condition = construct.hbConditions.get(label); + String hbCondNum = Integer.toString(semantics.interface2Num + .get(label)); + newCode.add("if " + BRACE(condition) + " {"); + structName = "hb_condition"; + newCode.add(DECLARE(ANNO_HB_CONDITION, structName)); + newCode.add(ASSIGN(structName, "interface_num", interfaceNum)); + + newCode.add(ASSIGN(structName, "hb_condition_num", hbCondNum)); + anno = "annotation_hb_condition"; + newCode.add(DECLARE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION)); + newCode.add(ASSIGN_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + } // Interface end - + String infoStructType = interfaceName + "_info", infoName = "info"; + newCode.add(DECLARE_DEFINE(infoStructType, infoName, + BRACE(infoStructType + "*") + " malloc(sizeof(" + + infoStructType + "))")); + newCode.add(ASSIGN_TO_PTR(infoName, MACRO_RETURN, MACRO_RETURN)); + for (int i = 0; i < header.args.size(); i++) { + String argName = header.args.get(i).name; + newCode.add(ASSIGN_TO_PTR(infoName, argName, argName)); + } + structName = "interface_end"; + anno = "annoation_interface_end"; + newCode.add(DECLARE(ANNO_INTERFACE_END, structName)); + newCode.add(ASSIGN(structName, "interface_num", interfaceNum)); + newCode.add(ASSIGN(structName, "info", infoName)); + newCode.add(DECLARE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_INTERFACE_END)); + newCode.add(ASSIGN_PTR(anno, "annotation", structName)); + ANNOTATE(anno); // End of the wrapper function + newCode.add("}"); // printCode(newCode); return newCode; } + public static void renameInterface(SemanticsChecker semantics, + Construct construct) { + FunctionHeader header = getFunctionHeader(semantics, construct); + ArrayList content = semantics.srcFilesInfo.get(construct.file).content; + int lineNum = construct.beginLineNum; + String headerLine = content.get(construct.beginLineNum); + if (headerLine.startsWith("template")) { + headerLine = content.get(construct.beginLineNum + 1); + lineNum++; + } + String newLine = header.getRenamedHeader(SPEC_INTERFACE_WRAPPER) + .toString() + " {"; + content.set(lineNum, newLine); + } + + public static void addAtomicReturn(SemanticsChecker semantics, + Construct construct) { + int lineNum = construct.beginLineNum - 1; + ArrayList content = semantics.srcFilesInfo.get(construct.file).content; + String oldLine = content.get(lineNum); + String newLine = "uint64_t " + MACRO_ATOMIC_RETURN + " = " + oldLine; + content.set(lineNum, newLine); + } + public static ArrayList generatePotentialCPDefine( SemanticsChecker semantics, PotentialCPDefineConstruct construct) { ArrayList newCode = new ArrayList(); - + // Add atomic return variable if the predicate accesses to it + if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) { + addAtomicReturn(semantics, construct); + } // Generate redundant header files newCode.add(COMMENT("Automatically generated code for potential commit point: " + construct.label)); newCode.add(COMMENT("Include redundant headers")); - newCode.add(INCLUDE(HEADER_THREADS)); - newCode.add(INCLUDE(HEADER_CDSTRACE)); + newCode.add(INCLUDE(HEADER_STDINT)); + newCode.add(INCLUDE(HEADER_CDSANNOTATE)); newCode.add(""); - // Some necessary function calls - + // Add annotation + newCode.add("if (" + construct.condition + ") {"); + String structName = "potential_cp_define", anno = "annotation_potential_cp_define"; + newCode.add(DECLARE(ANNO_POTENTIAL_CP_DEFINE, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + newCode.add(ASSIGN(structName, "label_num", labelNum)); + newCode.add(DECLARE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE)); + newCode.add(ASSIGN_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); + return newCode; + } + + public static ArrayList generateCPDefineCheck( + SemanticsChecker semantics, CPDefineCheckConstruct construct) { + ArrayList newCode = new ArrayList(); + // Add atomic return variable if the predicate accesses to it + if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) { + addAtomicReturn(semantics, construct); + } + // Generate redundant header files + newCode.add(COMMENT("Automatically generated code for commit point define check: " + + construct.label)); + newCode.add(COMMENT("Include redundant headers")); + newCode.add(INCLUDE(HEADER_STDINT)); + newCode.add(INCLUDE(HEADER_CDSANNOTATE)); + newCode.add(""); + // Add annotation + newCode.add("if (" + construct.condition + ") {"); + String structName = "cp_define_check", anno = "annotation_cp_define_check"; + newCode.add(DECLARE(ANNO_CP_DEFINE_CHECK, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + newCode.add(ASSIGN(structName, "label_num", labelNum)); + newCode.add(DECLARE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE_CHECK)); + newCode.add(ASSIGN_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); + return newCode; + } + + public static ArrayList generateCPDefine( + SemanticsChecker semantics, CPDefineConstruct construct) { + ArrayList newCode = new ArrayList(); + // Generate redundant header files + newCode.add(COMMENT("Automatically generated code for commit point define check: " + + construct.label)); + newCode.add(""); + // Add annotation + newCode.add("if (" + construct.condition + ") {"); + String structName = "cp_define", anno = "annotation_cp_define"; + newCode.add(DECLARE(ANNO_CP_DEFINE, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + newCode.add(ASSIGN(structName, "label_num", labelNum)); + newCode.add(DECLARE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE)); + newCode.add(ASSIGN_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); return newCode; } } diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/SemanticsChecker.java b/src/edu/uci/eecs/specCompiler/codeGenerator/SemanticsChecker.java index d09a61c..26647f6 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/SemanticsChecker.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/SemanticsChecker.java @@ -5,6 +5,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import edu.uci.eecs.specCompiler.grammerParser.ParseException; +import edu.uci.eecs.specCompiler.grammerParser.SpecParser; import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct; @@ -15,6 +17,7 @@ import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct; import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct; import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct; import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ParserUtils; import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo; import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor; @@ -25,7 +28,7 @@ public class SemanticsChecker { public final HashMap CPLabel2Construct; public final HashMap potentialCPLabel2Construct; public final HashMap interfaceName2Construct; - public final HashMap interfaceName2DefineConstruct; + public final HashMap interfaceName2DefineConstruct; public final HashMap> CPLabel2InterfaceConstruct; public final HashMap interface2Num; @@ -37,6 +40,10 @@ public class SemanticsChecker { private ArrayList entryPointConstructs; private ClassBeginConstruct classBeginConstruct; private ClassEndConstruct classEndConstruct; + + private String templateStr; + private String templateFullStr; + private String className; private int _interfaceNum; private int _hbLabelNum; @@ -48,7 +55,7 @@ public class SemanticsChecker { this.CPLabel2Construct = new HashMap(); this.potentialCPLabel2Construct = new HashMap(); this.interfaceName2Construct = new HashMap(); - this.interfaceName2DefineConstruct = new HashMap(); + this.interfaceName2DefineConstruct = new HashMap(); this.CPLabel2InterfaceConstruct = new HashMap>(); this.entryPointConstructs = new ArrayList(); this.classBeginConstruct = null; @@ -64,6 +71,30 @@ public class SemanticsChecker { _interfaceNum = 0; _hbLabelNum = 0; _commitPointNum = 0; + + templateStr = null; + templateFullStr = null; + className = null; + } + + public ClassBeginConstruct getClassBeginConstruct() { + return this.classBeginConstruct; + } + + public ClassEndConstruct getClassEndConstruct() { + return this.classEndConstruct; + } + + public String getTemplateFullStr() { + return this.templateFullStr; + } + + public String getTemplateStr() { + return this.templateStr; + } + + public String getClassName() { + return this.className; } public HashMap> getHBConditions() { @@ -223,9 +254,20 @@ public class SemanticsChecker { throw new SemanticsCheckerException( "Interface define label duplicates!"); } - interfaceName2DefineConstruct.put(name, construct); + interfaceName2DefineConstruct.put(name, theConstruct); } else if (construct instanceof ClassBeginConstruct) { classBeginConstruct = (ClassBeginConstruct) construct; + ArrayList content = srcFilesInfo.get(classBeginConstruct.file).content; + String firstLine = content.get(classBeginConstruct.beginLineNum), secondLine; + if (firstLine.startsWith("template")) { + secondLine = content.get(classBeginConstruct.beginLineNum + 1); + templateFullStr = firstLine; + templateStr = ParserUtils.getTemplateStr(firstLine); + className = ParserUtils.getClassName(secondLine); + } else { + className = ParserUtils.getClassName(firstLine); + } + } else if (construct instanceof ClassEndConstruct) { classEndConstruct = (ClassEndConstruct) construct; } diff --git a/src/edu/uci/eecs/specCompiler/specExtraction/FunctionHeader.java b/src/edu/uci/eecs/specCompiler/specExtraction/FunctionHeader.java index 54924ff..f8e84bc 100644 --- a/src/edu/uci/eecs/specCompiler/specExtraction/FunctionHeader.java +++ b/src/edu/uci/eecs/specCompiler/specExtraction/FunctionHeader.java @@ -15,6 +15,34 @@ public class FunctionHeader { } public String toString() { - return "Ret: " + returnType + "\n" + qualifiedName + "\n" + args; + String res = returnType + " " + qualifiedName.fullName + "("; + if (args.size() >= 1) { + res = res + args.get(0); + } + for (int i = 1; i < args.size(); i++) { + res = res + ", " + args.get(i); + } + res = res + ")"; + return res; + } + + public FunctionHeader getRenamedHeader(String prefix) { + String newFullName = qualifiedName.qualifiedName + prefix + "_" + + qualifiedName.bareName; + FunctionHeader newHeader = new FunctionHeader(returnType, + new QualifiedName(newFullName), args); + return newHeader; + } + + public String getRenamedCall(String prefix) { + String res = prefix + "_" + qualifiedName.fullName + "("; + if (args.size() >= 1) { + res = res + args.get(0).name; + } + for (int i = 1; i < args.size(); i++) { + res = res + ", " + args.get(i).name; + } + res = res + ")"; + return res; } } diff --git a/src/edu/uci/eecs/specCompiler/specExtraction/ParserUtils.java b/src/edu/uci/eecs/specCompiler/specExtraction/ParserUtils.java index 0ce5332..61d0da7 100644 --- a/src/edu/uci/eecs/specCompiler/specExtraction/ParserUtils.java +++ b/src/edu/uci/eecs/specCompiler/specExtraction/ParserUtils.java @@ -2,6 +2,7 @@ package edu.uci.eecs.specCompiler.specExtraction; import java.util.ArrayList; +import edu.uci.eecs.specCompiler.codeGenerator.SemanticsChecker; import edu.uci.eecs.specCompiler.grammerParser.ParseException; import edu.uci.eecs.specCompiler.grammerParser.SpecParser; @@ -24,7 +25,7 @@ public class ParserUtils { else return line.substring(i, j + 1); } - + public static String array2Str(ArrayList code) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < code.size(); i++) { @@ -32,4 +33,25 @@ public class ParserUtils { } return sb.toString(); } + + public static String getClassName(String classDefineLine) { + IDExtractor extractor = new IDExtractor(classDefineLine, + classDefineLine.length() - 1); + return extractor.getPrevID(); + } + + public static String getTemplateStr(String templateLine) { + String templateStr = null; + try { + ArrayList args = SpecParser.getTemplateArg(templateLine); + templateStr = "<" + args.get(1); + for (int i = 1; i < args.size() / 2; i++) { + templateStr = templateStr + ", " + args.get(i * 2 + 1); + } + templateStr = templateStr + ">"; + } catch (ParseException e) { + e.printStackTrace(); + } + return templateStr; + } } diff --git a/src/edu/uci/eecs/specCompiler/specExtraction/QualifiedName.java b/src/edu/uci/eecs/specCompiler/specExtraction/QualifiedName.java index 692b297..8b912b0 100644 --- a/src/edu/uci/eecs/specCompiler/specExtraction/QualifiedName.java +++ b/src/edu/uci/eecs/specCompiler/specExtraction/QualifiedName.java @@ -3,14 +3,16 @@ package edu.uci.eecs.specCompiler.specExtraction; public class QualifiedName { public final String fullName; public final String bareName; + public final String qualifiedName; public QualifiedName(String fullName) { this.fullName = fullName; this.bareName = getBareName(); + this.qualifiedName = getQualifiedName(); } private String getBareName() { - int beginIdx, endIdx; + int beginIdx; beginIdx = fullName.lastIndexOf(':'); if (beginIdx == -1) return fullName; @@ -18,6 +20,13 @@ public class QualifiedName { return fullName.substring(beginIdx + 1); } + private String getQualifiedName() { + int endIdx = fullName.lastIndexOf(bareName); + if (endIdx == 0) + return ""; + return fullName.substring(0, endIdx); + } + public String toString() { return fullName + "\n" + bareName; } diff --git a/test.cc b/test.cc new file mode 100644 index 0000000..64a4e3b --- /dev/null +++ b/test.cc @@ -0,0 +1,18 @@ +class A { + public: + A() { + } + +}; + + +int main() { + A a; + if (true) { + int i = 5; + } + if (true) { + int i = 1; + } + return 1; +} -- 2.34.1