fixed bugs
[cdsspec-compiler.git] / src / edu / uci / eecs / specCompiler / codeGenerator / CodeVariables.java
1 package edu.uci.eecs.specCompiler.codeGenerator;
2
3 import java.util.ArrayList;
4 import java.util.HashSet;
5 import java.io.File;
6
7 import edu.uci.eecs.specCompiler.grammerParser.ParseException;
8 import edu.uci.eecs.specCompiler.grammerParser.SpecParser;
9 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
10 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
11 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
12 import edu.uci.eecs.specCompiler.specExtraction.Construct;
13 import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
14 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
15 import edu.uci.eecs.specCompiler.specExtraction.IDExtractor;
16 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
17 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
18 import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
19 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
20 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
21 import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
22 import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
23
24 public class CodeVariables {
25         // C++ code or library
26         public static final String HEADER_THREADS = "<threads.h>";
27         public static final String HEADER_STDINT = "<stdint.h>";
28         public static final String ThreadIDType = "thrd_t";
29         public static final String GET_THREAD_ID = "thrd_current";
30         public static final String BOOLEAN = "bool";
31         public static final String UINT64 = "uint64_t";
32
33         // Model checker code
34         public static final String HEADER_CDSANNOTATE = "<cdsannotate.h>";
35         public static final String HEADER_SPECANNOTATION = "<specannotation.h>";
36         public static final String HEADER_CDSTRACE = "<cdstrace.h>";
37         public static final String CDSAnnotate = "cdsannotate";
38         public static final String CDSAnnotateType = "SPEC_ANALYSIS";
39         public static final String IDType = "id_t";
40
41         public static final String SPEC_ANNO_TYPE = "spec_anno_type";
42         public static final String SPEC_ANNO_TYPE_HB_INIT = "HB_INIT";
43         public static final String SPEC_ANNO_TYPE_INTERFACE_BEGIN = "INTERFACE_BEGIN";
44         public static final String SPEC_ANNO_TYPE_HB_CONDITION = "HB_CONDITION";
45         public static final String SPEC_ANNO_TYPE_INTERFACE_END = "INTERFACE_END";
46         public static final String SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE = "POTENTIAL_CP_DEFINE";
47         public static final String SPEC_ANNO_TYPE_CP_DEFINE_CHECK = "CP_DEFINE_CHECK";
48         public static final String SPEC_ANNO_TYPE_CP_DEFINE = "CP_DEFINE";
49         public static final String SPEC_ANNOTATION = "spec_annotation";
50         public static final String SPEC_ANNOTATION_FIELD_TYPE = "type";
51         public static final String SPEC_ANNOTATION_FIELD_ANNO = "annotation";
52
53         public static final String ANNO_HB_INIT = "anno_hb_init";
54         public static final String ANNO_INTERFACE_BEGIN = "anno_interface_begin";
55         public static final String ANNO_INTERFACE_END = "anno_interface_end";
56         public static final String ANNO_POTENTIAL_CP_DEFINE = "anno_potentail_cp_define";
57         public static final String ANNO_CP_DEFINE = "anno_cp_define";
58         public static final String ANNO_CP_DEFINE_CHECK = "anno_cp_define_check";
59         public static final String ANNO_HB_CONDITION = "anno_hb_condition";
60
61         // Specification variables
62         public static final String SPEC_INTERFACE_WRAPPER = "__wrapper_";
63         public static final String DEFAULT_ID = "0";
64
65         // Specification library
66         public static final String HEADER_SPEC_LIB = "<spec_lib.h>";
67         public static final String SPEC_QUEUE = "spec_queue";
68         public static final String SPEC_STACK = "spec_stack";
69         public static final String SPEC_DEQUE = "spec_deque";
70         public static final String SPEC_HASHTABLE = "spec_hashtable";
71         public static final String SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable";
72         public static final String SPEC_TAG = "spec_tag";
73         public static final String SPEC_TAG_CURRENT = "current";
74         public static final String SPEC_TAG_NEXT = "next";
75
76         // Macro
77         public static final String MACRO_ID = "__ID__";
78         public static final String MACRO_COND = "__COND_SAT__";
79         public static final String MACRO_RETURN = "__RET__";
80         public static final String MACRO_ATOMIC_RETURN = "__ATOMIC_RET__";
81
82         public static void printCode(ArrayList<String> code) {
83                 for (int i = 0; i < code.size(); i++) {
84                         System.out.println(code.get(i));
85                 }
86         }
87
88         private static String COMMENT(String comment) {
89                 return "/* " + comment + " */";
90         }
91
92         private static String INCLUDE(String header) {
93                 return "#include " + header;
94         }
95
96         private static String DEFINE(String left, String right) {
97                 return "#define " + left + " " + right;
98         }
99
100         private static String UNDEFINE(String macro) {
101                 return "#undef " + macro;
102         }
103
104         private static String GET_FIELD_BY_PTR(String ptr, String field) {
105                 return ptr + "->" + field;
106         }
107
108         private static String GET_FIELD(String var, String field) {
109                 return var + "->" + field;
110         }
111
112         private static String BRACE(String val) {
113                 return "(" + val + ")";
114         }
115
116         private static String ASSIGN(String structName, String field, String val) {
117                 return structName + "." + field + " = " + val + ";";
118         }
119
120         private static String ASSIGN(String varName, String val) {
121                 return varName + " = " + val + ";";
122         }
123
124         private static String ASSIGN_PTR(String structName, String field, String val) {
125                 return structName + "." + field + " = &" + val + ";";
126         }
127
128         private static String ASSIGN_TO_PTR(String structName, String field,
129                         String val) {
130                 return structName + "->" + field + " = " + val + ";";
131         }
132
133         private static String DECLARE(String type, String name) {
134                 return type + " " + name + ";";
135         }
136
137         private static String DECLARE(VariableDeclaration varDecl) {
138                 String type = varDecl.type, name = varDecl.name;
139                 return type + " " + name + ";";
140         }
141
142         private static String DECLARE_DEFINE(String type, String var, String val) {
143                 return type + " " + var + " = " + val + ";";
144         }
145
146         private static String ANNOTATE(String structName) {
147                 return CDSAnnotate + "(" + CDSAnnotateType + ", &" + structName + ");";
148         }
149
150         private static ArrayList<String> DEFINE_INFO_STRUCT(String interfaceName,
151                         FunctionHeader funcDecl) {
152                 ArrayList<String> code = new ArrayList<String>();
153                 code.add("typedef struct " + interfaceName + "_info {");
154                 code.add(DECLARE(funcDecl.returnType, MACRO_RETURN));
155                 for (int i = 0; i < funcDecl.args.size(); i++) {
156                         code.add(DECLARE(funcDecl.args.get(i)));
157                 }
158                 code.add("} " + interfaceName + "_info {");
159                 return code;
160         }
161
162         private static ArrayList<String> DEFINE_ID_FUNC(String interfaceName,
163                         String idCode) {
164                 ArrayList<String> code = new ArrayList<String>();
165                 code.add("static " + IDType + " " + interfaceName + "_id() {");
166                 if (!idCode.equals("")) {
167                         code.add(DECLARE_DEFINE(IDType, MACRO_ID, idCode));
168                 } else {
169                         code.add(DECLARE_DEFINE(IDType, MACRO_ID, DEFAULT_ID));
170                 }
171                 code.add("return " + MACRO_ID + ";");
172                 code.add("}");
173                 return code;
174         }
175
176         private static ArrayList<String> DEFINE_CHECK_ACTION_FUNC(
177                         InterfaceConstruct construct, FunctionHeader header) {
178                 String interfaceName = construct.name;
179                 ArrayList<String> code = new ArrayList<String>();
180                 code.add("static bool " + interfaceName + "_check_action(void *info, "
181                                 + IDType + " " + MACRO_ID + ") {");
182                 code.add(DECLARE("bool", "check_passed"));
183                 String infoStructType = interfaceName + "_info", infoStructName = "theInfo";
184                 code.add(DECLARE_DEFINE(infoStructType + "*", infoStructName,
185                                 BRACE(infoStructType) + "info"));
186                 code.add((DECLARE_DEFINE(header.returnType, MACRO_RETURN,
187                                 GET_FIELD_BY_PTR(infoStructName, MACRO_RETURN))));
188                 for (int i = 0; i < header.args.size(); i++) {
189                         String type = header.args.get(i).type, var = header.args.get(i).name;
190                         code.add((DECLARE_DEFINE(type, var,
191                                         GET_FIELD_BY_PTR(infoStructName, var))));
192                 }
193                 code.add("");
194                 // __COND_SAT
195                 if (!construct.condition.equals("")) {
196                         code.add(DECLARE_DEFINE("bool", MACRO_COND, construct.condition));
197                 }
198                 // Check
199                 if (!construct.check.equals("")) {
200                         code.add(ASSIGN("check_passed", construct.check));
201                         code.add("if (!check_passed) return false;");
202                 }
203                 // Action
204                 if (construct.action.size() > 0) {
205                         code.addAll(construct.action);
206                 }
207                 // Post_check
208                 if (!construct.postCheck.equals("")) {
209                         code.add(ASSIGN("check_passed", construct.postCheck));
210                         code.add("if (!check_passed) return false;");
211                 }
212                 // Post_action
213                 if (construct.postAction.size() > 0) {
214                         code.addAll(construct.postAction);
215                 }
216
217                 code.add("}");
218
219                 return code;
220         }
221
222         private static HashSet<String> getAllHeaders(SemanticsChecker semantics) {
223                 HashSet<String> headers = new HashSet<String>();
224                 for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
225                         File f = semantics.interfaceName2Construct.get(interfaceName).file;
226                         headers.addAll(semantics.srcFilesInfo.get(f).headers);
227                 }
228                 return headers;
229         }
230
231         private static void makeFunctionStatic(ArrayList<String> funcDefine) {
232                 String headLine = funcDefine.get(0);
233                 headLine = "static " + headLine;
234                 funcDefine.set(0, headLine);
235         }
236
237         private static String makeVariablesStatic(VariableDeclaration varDecl) {
238                 String res = "static " + varDecl.type + " " + varDecl.name + ";";
239                 return res;
240         }
241
242         private static FunctionHeader getFunctionHeader(SemanticsChecker semantics,
243                         Construct construct) {
244                 ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
245                 String headerLine = content.get(construct.beginLineNum);
246                 if (headerLine.startsWith("template")) {
247                         headerLine = content.get(construct.beginLineNum + 1);
248                 }
249                 headerLine = headerLine.substring(0, headerLine.indexOf(')') + 1);
250                 try {
251                         return SpecParser.parseFuncHeader(headerLine);
252                 } catch (ParseException e) {
253                         e.printStackTrace();
254                 }
255                 return null;
256         }
257
258         public static ArrayList<String> generateGlobalVarDeclaration(
259                         SemanticsChecker semantics, GlobalConstruct construct) {
260                 ArrayList<String> newCode = new ArrayList<String>();
261                 HashSet<String> allHeaders = getAllHeaders(semantics);
262
263                 // All headers needed by the interface decalration
264                 newCode.add(COMMENT("Include all the header files that contains the interface declaration"));
265                 for (String header : allHeaders) {
266                         newCode.add(INCLUDE(header));
267                 }
268                 newCode.add("");
269                 // Other necessary headers
270                 newCode.add(INCLUDE(HEADER_STDINT));
271                 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
272                 newCode.add(INCLUDE(HEADER_SPEC_LIB));
273                 newCode.add("");
274
275                 SequentialDefineSubConstruct code = construct.code;
276                 // User-defined structs first
277                 newCode.add(COMMENT("All other user-defined structs"));
278                 ArrayList<ArrayList<String>> declareStructs = code.declareStructs;
279                 for (int i = 0; i < declareStructs.size(); i++) {
280                         ArrayList<String> declareStruct = declareStructs.get(i);
281                         newCode.addAll(declareStruct);
282                         newCode.add("");
283                 }
284                 // User-defined functions
285                 newCode.add(COMMENT("All other user-defined functions"));
286                 ArrayList<ArrayList<String>> defineFuncs = code.defineFuncs;
287                 for (int i = 0; i < defineFuncs.size(); i++) {
288                         ArrayList<String> defineFunc = defineFuncs.get(i);
289                         makeFunctionStatic(defineFunc);
290                         newCode.addAll(defineFunc);
291                         newCode.add("");
292                 }
293
294                 for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
295                         InterfaceConstruct iConstruct = semantics.interfaceName2Construct
296                                         .get(interfaceName);
297                         FunctionHeader funcHeader = getFunctionHeader(semantics, iConstruct);
298                         // Define necessary info structure
299                         newCode.add(COMMENT("Definition of interface info struct: "
300                                         + interfaceName));
301                         newCode.addAll(DEFINE_INFO_STRUCT(interfaceName, funcHeader));
302                         newCode.add(COMMENT("End of info struct definition: "
303                                         + interfaceName));
304                         newCode.add("");
305
306                         // Define ID function
307                         newCode.add(COMMENT("ID function of interface: " + interfaceName));
308                         newCode.addAll(DEFINE_ID_FUNC(interfaceName, iConstruct.idCode));
309                         newCode.add(COMMENT("End of ID function: + " + interfaceName));
310                         newCode.add("");
311
312                         // Define check_action function
313                         newCode.add(COMMENT("Check action function of interface: "
314                                         + interfaceName));
315                         newCode.addAll(DEFINE_CHECK_ACTION_FUNC(iConstruct, funcHeader));
316                         newCode.add(COMMENT("End of check action function: + "
317                                         + interfaceName));
318                         newCode.add("");
319                 }
320                 // Interface function pointer table
321                 String interfaceSize = Integer
322                                 .toString(semantics.interfaceName2Construct.size());
323                 newCode.add(DEFINE("INTERFACE_SIZE", interfaceSize));
324                 newCode.add(DECLARE("void**", "func_ptr_table"));
325                 // User-defined variables
326                 ArrayList<VariableDeclaration> varDecls = code.declareVar;
327                 for (int i = 0; i < varDecls.size(); i++) {
328                         VariableDeclaration varDecl = varDecls.get(i);
329                         // Don't forget to make them static
330                         newCode.add(makeVariablesStatic(varDecl));
331                 }
332
333                 newCode.add("");
334                 newCode.add(COMMENT("Define function for sequential code initialization"));
335                 newCode.add("static void __sequential_init() {");
336                 // Init func_ptr_table
337                 newCode.add(COMMENT("Init func_ptr_table"));
338                 newCode.add(ASSIGN("func_ptr_table",
339                                 "(void**) malloc(sizeof(void*) * 2)"));
340                 for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
341                         String interfaceNum = Integer.toString(semantics.interface2Num
342                                         .get(interfaceName));
343                         newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + "]",
344                                         "(void*) &" + interfaceName + "_id"));
345                         newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + " + 1]",
346                                         "(void*) &" + interfaceName + "_check_action"));
347                 }
348                 newCode.add("");
349                 // Init user-defined variables
350                 newCode.addAll(construct.code.initVar);
351                 // Pass Happens-before relationship
352                 generateHBInitAnnotation(semantics);
353                 newCode.add("}");
354                 newCode.add(COMMENT("End of Global construct generation in class"));
355
356                 printCode(newCode);
357                 return newCode;
358         }
359
360         public static ArrayList<String> generateStaticVarDefine(
361                         SemanticsChecker semantics, GlobalConstruct construct) {
362                 ArrayList<String> newCode = new ArrayList<String>();
363                 String className = semantics.getClassName();
364                 if (className == null)
365                         return newCode; // No need to define any static variables
366                 String templateList = semantics.getTemplateStr();
367                 String varPrefix;
368                 if (templateList == null) {
369                         varPrefix = className + "::";
370                 } else {
371                         varPrefix = className + templateList + "::";
372                 }
373                 String templateDecl = semantics.getTemplateFullStr();
374                 if (templateList == null) {
375                         newCode.add(DECLARE("void**", varPrefix + "func_ptr_table"));
376                         for (int i = 0; i < construct.code.declareVar.size(); i++) {
377                                 VariableDeclaration varDecl = construct.code.declareVar.get(i);
378                                 newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name));
379                         }
380                 } else {
381                         newCode.add(templateDecl);
382                         newCode.add(DECLARE("void**", varPrefix + "func_ptr_table"));
383                         for (int i = 0; i < construct.code.declareVar.size(); i++) {
384                                 VariableDeclaration varDecl = construct.code.declareVar.get(i);
385                                 newCode.add(templateDecl);
386                                 newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name));
387                         }
388                 }
389                 return newCode;
390         }
391
392         private static ArrayList<String> generateHBInitAnnotation(
393                         SemanticsChecker semantics) {
394                 ArrayList<String> newCode = new ArrayList<String>();
395                 int hbConditionInitIdx = 0;
396                 for (ConditionalInterface left : semantics.getHBConditions().keySet()) {
397                         for (ConditionalInterface right : semantics.getHBConditions().get(
398                                         left)) {
399                                 String structVarName = "hbConditionInit" + hbConditionInitIdx;
400                                 String annotationVarName = "hb_init" + hbConditionInitIdx;
401                                 hbConditionInitIdx++;
402                                 String interfaceNumBefore = Integer
403                                                 .toString(semantics.interface2Num
404                                                                 .get(left.interfaceName)), hbLabelNumBefore = Integer
405                                                 .toString(semantics.hbLabel2Num
406                                                                 .get(left.hbConditionLabel)), interfaceNumAfter = Integer
407                                                 .toString(semantics.interface2Num
408                                                                 .get(right.interfaceName)), hbLabelNumAfter = Integer
409                                                 .toString(semantics.hbLabel2Num
410                                                                 .get(right.hbConditionLabel));
411                                 newCode.add(COMMENT(left + " -> " + right));
412
413                                 newCode.add(ANNO_HB_INIT + " " + structVarName + ";");
414                                 newCode.add(ASSIGN(structVarName, "interface_num_before",
415                                                 interfaceNumBefore));
416                                 newCode.add(ASSIGN(structVarName, "hb_condition_num_before",
417                                                 hbLabelNumBefore));
418                                 newCode.add(ASSIGN(structVarName, "interface_num_after",
419                                                 interfaceNumAfter));
420                                 newCode.add(ASSIGN(structVarName, "hb_condition_num_after",
421                                                 hbLabelNumAfter));
422
423                                 newCode.add(DECLARE(SPEC_ANNOTATION, annotationVarName));
424                                 newCode.add(ASSIGN(annotationVarName,
425                                                 SPEC_ANNOTATION_FIELD_TYPE, SPEC_ANNO_TYPE_HB_INIT));
426                                 newCode.add(ASSIGN_PTR(annotationVarName,
427                                                 SPEC_ANNOTATION_FIELD_ANNO, structVarName));
428                                 newCode.add(ANNOTATE(annotationVarName));
429                         }
430                 }
431                 return newCode;
432         }
433
434         public static ArrayList<String> generateEntryPointInitCall() {
435                 ArrayList<String> newCode = new ArrayList<String>(1);
436                 newCode.add("__sequential_init();");
437                 return newCode;
438         }
439
440         public static ArrayList<String> generateInterfaceWrapper(
441                         SemanticsChecker semantics, InterfaceConstruct construct) {
442                 ArrayList<String> newCode = new ArrayList<String>();
443                 String interfaceName = construct.name;
444                 // Generate necessary header file (might be redundant but never mind)
445                 newCode.add(INCLUDE(HEADER_THREADS));
446                 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
447                 newCode.add(INCLUDE(HEADER_SPECANNOTATION));
448                 newCode.add(INCLUDE(HEADER_SPEC_LIB));
449
450                 FunctionHeader header = getFunctionHeader(semantics, construct);
451                 String interfaceNum = Integer.toString(semantics.interface2Num
452                                 .get(construct.name));
453                 // Rename the interface
454                 renameInterface(semantics, construct);
455                 InterfaceDefineConstruct defineConstruct = semantics.interfaceName2DefineConstruct
456                                 .get(interfaceName);
457                 if (defineConstruct != null) {
458                         renameInterface(semantics, defineConstruct);
459                 }
460
461                 // Generate wrapper header
462                 newCode.add(header.toString() + " {");
463                 // Wrapper function body
464                 newCode.add(COMMENT("Interface begins"));
465                 // Interface begin
466                 String structName = "interface_begin";
467                 newCode.add(DECLARE(ANNO_INTERFACE_BEGIN, "interface_begin"));
468                 newCode.add(ASSIGN(structName, "interface_num", interfaceNum));
469                 String anno = "annotation_interface_begin";
470                 newCode.add(DECLARE(SPEC_ANNOTATION, anno));
471                 newCode.add(ASSIGN(structName, "type", SPEC_ANNO_TYPE_INTERFACE_BEGIN));
472                 newCode.add(ASSIGN_PTR(structName, "annotation", structName));
473                 newCode.add(ANNOTATE(anno));
474                 // Call original renamed function
475                 newCode.add(DECLARE_DEFINE(header.returnType, MACRO_RETURN,
476                                 header.getRenamedCall(SPEC_INTERFACE_WRAPPER)));
477                 // HB conditions
478                 for (String label : construct.hbConditions.keySet()) {
479                         String condition = construct.hbConditions.get(label);
480                         String hbCondNum = Integer.toString(semantics.interface2Num
481                                         .get(label));
482                         newCode.add("if " + BRACE(condition) + " {");
483                         structName = "hb_condition";
484                         newCode.add(DECLARE(ANNO_HB_CONDITION, structName));
485                         newCode.add(ASSIGN(structName, "interface_num", interfaceNum));
486
487                         newCode.add(ASSIGN(structName, "hb_condition_num", hbCondNum));
488                         anno = "annotation_hb_condition";
489                         newCode.add(DECLARE(SPEC_ANNOTATION, anno));
490                         newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION));
491                         newCode.add(ASSIGN_PTR(anno, "annotation", structName));
492                         newCode.add(ANNOTATE(anno));
493                 }
494                 // Interface end
495                 String infoStructType = interfaceName + "_info", infoName = "info";
496                 newCode.add(DECLARE_DEFINE(infoStructType, infoName,
497                                 BRACE(infoStructType + "*") + " malloc(sizeof("
498                                                 + infoStructType + "))"));
499                 newCode.add(ASSIGN_TO_PTR(infoName, MACRO_RETURN, MACRO_RETURN));
500                 for (int i = 0; i < header.args.size(); i++) {
501                         String argName = header.args.get(i).name;
502                         newCode.add(ASSIGN_TO_PTR(infoName, argName, argName));
503                 }
504                 structName = "interface_end";
505                 anno = "annoation_interface_end";
506                 newCode.add(DECLARE(ANNO_INTERFACE_END, structName));
507                 newCode.add(ASSIGN(structName, "interface_num", interfaceNum));
508                 newCode.add(ASSIGN(structName, "info", infoName));
509                 newCode.add(DECLARE(SPEC_ANNOTATION, anno));
510                 newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_INTERFACE_END));
511                 newCode.add(ASSIGN_PTR(anno, "annotation", structName));
512                 ANNOTATE(anno);
513                 // End of the wrapper function
514                 newCode.add("}");
515
516                 // printCode(newCode);
517                 return newCode;
518         }
519
520         public static void renameInterface(SemanticsChecker semantics,
521                         Construct construct) {
522                 FunctionHeader header = getFunctionHeader(semantics, construct);
523                 ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
524                 int lineNum = construct.beginLineNum;
525                 String headerLine = content.get(construct.beginLineNum);
526                 if (headerLine.startsWith("template")) {
527                         headerLine = content.get(construct.beginLineNum + 1);
528                         lineNum++;
529                 }
530                 String newLine = header.getRenamedHeader(SPEC_INTERFACE_WRAPPER)
531                                 .toString() + " {";
532                 content.set(lineNum, newLine);
533         }
534
535         public static void addAtomicReturn(SemanticsChecker semantics,
536                         Construct construct) {
537                 int lineNum = construct.beginLineNum - 1;
538                 ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
539                 String oldLine = content.get(lineNum);
540                 String newLine = "uint64_t " + MACRO_ATOMIC_RETURN + " = " + oldLine;
541                 content.set(lineNum, newLine);
542         }
543
544         public static ArrayList<String> generatePotentialCPDefine(
545                         SemanticsChecker semantics, PotentialCPDefineConstruct construct) {
546                 ArrayList<String> newCode = new ArrayList<String>();
547                 // Add atomic return variable if the predicate accesses to it
548                 if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
549                         addAtomicReturn(semantics, construct);
550                 }
551                 // Generate redundant header files
552                 newCode.add(COMMENT("Automatically generated code for potential commit point: "
553                                 + construct.label));
554                 newCode.add(COMMENT("Include redundant headers"));
555                 newCode.add(INCLUDE(HEADER_STDINT));
556                 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
557                 newCode.add("");
558                 // Add annotation
559                 newCode.add("if (" + construct.condition + ") {");
560                 String structName = "potential_cp_define", anno = "annotation_potential_cp_define";
561                 newCode.add(DECLARE(ANNO_POTENTIAL_CP_DEFINE, structName));
562                 String labelNum = Integer.toString(semantics.commitPointLabel2Num
563                                 .get(construct.label));
564                 newCode.add(ASSIGN(structName, "label_num", labelNum));
565                 newCode.add(DECLARE(SPEC_ANNOTATION, anno));
566                 newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE));
567                 newCode.add(ASSIGN_PTR(anno, "annotation", structName));
568                 newCode.add(ANNOTATE(anno));
569                 newCode.add("}");
570                 return newCode;
571         }
572
573         public static ArrayList<String> generateCPDefineCheck(
574                         SemanticsChecker semantics, CPDefineCheckConstruct construct) {
575                 ArrayList<String> newCode = new ArrayList<String>();
576                 // Add atomic return variable if the predicate accesses to it
577                 if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
578                         addAtomicReturn(semantics, construct);
579                 }
580                 // Generate redundant header files
581                 newCode.add(COMMENT("Automatically generated code for commit point define check: "
582                                 + construct.label));
583                 newCode.add(COMMENT("Include redundant headers"));
584                 newCode.add(INCLUDE(HEADER_STDINT));
585                 newCode.add(INCLUDE(HEADER_CDSANNOTATE));
586                 newCode.add("");
587                 // Add annotation
588                 newCode.add("if (" + construct.condition + ") {");
589                 String structName = "cp_define_check", anno = "annotation_cp_define_check";
590                 newCode.add(DECLARE(ANNO_CP_DEFINE_CHECK, structName));
591                 String labelNum = Integer.toString(semantics.commitPointLabel2Num
592                                 .get(construct.label));
593                 newCode.add(ASSIGN(structName, "label_num", labelNum));
594                 newCode.add(DECLARE(SPEC_ANNOTATION, anno));
595                 newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE_CHECK));
596                 newCode.add(ASSIGN_PTR(anno, "annotation", structName));
597                 newCode.add(ANNOTATE(anno));
598                 newCode.add("}");
599                 return newCode;
600         }
601
602         public static ArrayList<String> generateCPDefine(
603                         SemanticsChecker semantics, CPDefineConstruct construct) {
604                 ArrayList<String> newCode = new ArrayList<String>();
605                 // Generate redundant header files
606                 newCode.add(COMMENT("Automatically generated code for commit point define check: "
607                                 + construct.label));
608                 newCode.add("");
609                 // Add annotation
610                 newCode.add("if (" + construct.condition + ") {");
611                 String structName = "cp_define", anno = "annotation_cp_define";
612                 newCode.add(DECLARE(ANNO_CP_DEFINE, structName));
613                 String labelNum = Integer.toString(semantics.commitPointLabel2Num
614                                 .get(construct.label));
615                 newCode.add(ASSIGN(structName, "label_num", labelNum));
616                 newCode.add(DECLARE(SPEC_ANNOTATION, anno));
617                 newCode.add(ASSIGN(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE));
618                 newCode.add(ASSIGN_PTR(anno, "annotation", structName));
619                 newCode.add(ANNOTATE(anno));
620                 newCode.add("}");
621                 return newCode;
622         }
623 }