35 * |
35 * |
36 * We currently only do this for IL code. |
36 * We currently only do this for IL code. |
37 * This class will annotate the abstract syntax tree, by filling in the |
37 * This class will annotate the abstract syntax tree, by filling in the |
38 * prev_il_instruction variable in the il_instruction_c, so it points to |
38 * prev_il_instruction variable in the il_instruction_c, so it points to |
39 * the previous il_instruction_c object in the instruction list instruction_list_c. |
39 * the previous il_instruction_c object in the instruction list instruction_list_c. |
|
40 * |
|
41 * The result will essentially be a linked list of il_instruction_c objects, each |
|
42 * pointing to the previous il_instruction_c object. |
|
43 * |
|
44 * The reality is we will get several independent and isolated linked lists |
|
45 * (actually, once we process labels correctly, this will become a graph): |
|
46 * one for each block of IL code (e.g. inside a Function, FB or Program). |
|
47 * Additionally, when the IL code has an expression (expression_c object), we will actually |
|
48 * have one more isolated linked list for the IL code inside that expression. |
|
49 * |
|
50 * e.g. |
|
51 * line_1: LD 1 |
|
52 * line_2: ADD (42 |
|
53 * line_3: ADD B |
|
54 * line_4: ADD C |
|
55 * line_5: ) |
|
56 * line_6: ADD D |
|
57 * line_7: ST E |
|
58 * |
|
59 * will result in two independent linked lists: |
|
60 * main list: line_7 -> line_6 -> line2 -> line_1 |
|
61 * expr list: lin4_4 -> line_3 -> (operand of line_2, i.e. '42') |
|
62 * |
|
63 * |
|
64 * In the main list, each: |
|
65 * line_x: IL_operation IL_operand |
|
66 * is encoded as |
|
67 * il_instruction_c(label, il_incomplete_instruction) |
|
68 * these il_instruction_c objects will point back to the previous il_instruction_c object. |
|
69 * |
|
70 * In the expr list, each |
|
71 * line_x: IL_operation IL_operand |
|
72 * is encoded as |
|
73 * il_simple_instruction_c(il_simple_instruction) |
|
74 * these il_simple_instruction_c objects will point back to the previous il_simple_instruction_c object, |
|
75 * except the for the first il_simple_instruction_c object in the list, which will point back to |
|
76 * the first il_operand (in the above example, '42'), or NULL is it does not exist. |
|
77 * |
|
78 * |
|
79 * label: |
|
80 * identifier_c |
|
81 * |
|
82 * il_incomplete_instruction: |
|
83 * il_simple_operation (il_simple_operation_c, il_function_call_c) |
|
84 * | il_expression (il_expression_c) |
|
85 * | il_jump_operation (il_jump_operation_c) |
|
86 * | il_fb_call (il_fb_call_c) |
|
87 * | il_formal_funct_call (il_formal_funct_call_c) |
|
88 * | il_return_operator (RET_operator_c, RETC_operator_c, RETCN_operator_c) |
|
89 * |
|
90 * |
|
91 * il_expression_c(il_expr_operator, il_operand, simple_instr_list) |
|
92 * |
|
93 * il_operand: |
|
94 * variable (symbolic_variable_c, direct_variable_c, array_variable_c, structured_variable_c) |
|
95 * | enumerated_value (enumerated_value_c) |
|
96 * | constant (lots of literal classes _c) |
|
97 * |
|
98 * simple_instr_list: |
|
99 * list of il_simple_instruction |
|
100 * |
|
101 * il_simple_instruction: |
|
102 * il_simple_operation (il_simple_operation_c) |
|
103 * | il_expression (il_expression_c) |
|
104 * | il_formal_funct_call (il_formal_funct_call_c) |
|
105 * |
40 */ |
106 */ |
41 |
107 |
42 #include "flow_control_analysis.hh" |
108 #include "flow_control_analysis.hh" |
43 |
109 |
44 |
110 |
126 void *flow_control_analysis_c::visit(il_instruction_c *symbol) { |
192 void *flow_control_analysis_c::visit(il_instruction_c *symbol) { |
127 symbol->prev_il_instruction = prev_il_instruction; |
193 symbol->prev_il_instruction = prev_il_instruction; |
128 /* TODO: handle labels correctly! |
194 /* TODO: handle labels correctly! |
129 * |
195 * |
130 * Don't forget to handle multiple consecutive lables too! |
196 * Don't forget to handle multiple consecutive lables too! |
131 * label2: |
197 * label2: |
132 * label3: |
198 * label3: |
133 * label4: |
199 * label4: |
134 * LD I |
200 * LD I |
135 */ |
201 */ |
|
202 /* NOTE: the following recursive call will mess up the value in the |
|
203 * this->prev_il_instruction variable, so be sure not to use it |
|
204 * after the return of symbol->il_instruction->accept(*this); |
|
205 */ |
|
206 /* check if it is an il_expression_c, and if so, handle it correctly */ |
136 if (NULL != symbol->il_instruction) |
207 if (NULL != symbol->il_instruction) |
137 symbol->il_instruction->accept(*this); |
208 symbol->il_instruction->accept(*this); |
138 return NULL; |
209 return NULL; |
139 } |
210 } |
140 |
211 |
141 |
212 |
142 #if 0 |
213 #if 0 |
143 /* | function_name [il_operand_list] */ |
214 /* | function_name [il_operand_list] */ |
144 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
215 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
145 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
216 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
146 void *flow_control_analysis_c::visit(il_function_call_c *symbol) { |
217 void *flow_control_analysis_c::visit(il_function_call_c *symbol) { |
147 return NULL; |
218 return NULL; |
148 } |
219 } |
|
220 #endif |
149 |
221 |
150 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
222 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
151 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
223 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
152 void *flow_control_analysis_c::visit(il_expression_c *symbol) { |
224 void *flow_control_analysis_c::visit(il_expression_c *symbol) { |
153 return NULL; |
225 if(NULL == symbol->simple_instr_list) |
154 } |
226 /* nothing to do... */ |
155 |
227 return NULL; |
|
228 |
|
229 prev_il_instruction = symbol->il_operand; |
|
230 symbol->simple_instr_list->accept(*this); |
|
231 return NULL; |
|
232 } |
|
233 |
|
234 |
|
235 #if 0 |
156 /* il_call_operator prev_declared_fb_name |
236 /* il_call_operator prev_declared_fb_name |
157 * | il_call_operator prev_declared_fb_name '(' ')' |
237 * | il_call_operator prev_declared_fb_name '(' ')' |
158 * | il_call_operator prev_declared_fb_name '(' eol_list ')' |
238 * | il_call_operator prev_declared_fb_name '(' eol_list ')' |
159 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
239 * | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
160 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
240 * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
174 } |
254 } |
175 #endif |
255 #endif |
176 |
256 |
177 |
257 |
178 // void *visit(il_operand_list_c *symbol); |
258 // void *visit(il_operand_list_c *symbol); |
179 |
|
180 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) { |
259 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) { |
181 for(int i = 0; i < symbol->n; i++) { |
260 /* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */ |
182 prev_il_instruction = NULL; |
261 for(int i = 1; i < symbol->n; i++) { |
183 if (i > 0) prev_il_instruction = symbol->elements[i-1]; |
262 /* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */ |
|
263 if (i>0) prev_il_instruction = symbol->elements[i-1]; |
184 symbol->elements[i]->accept(*this); |
264 symbol->elements[i]->accept(*this); |
185 } |
265 } |
186 return NULL; |
266 return NULL; |
187 } |
267 } |
|
268 |
|
269 |
|
270 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
|
271 void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) { |
|
272 symbol->prev_il_instruction = prev_il_instruction; |
|
273 return NULL; |
|
274 } |
|
275 |
188 |
276 |
189 /* |
277 /* |
190 void *visit(il_param_list_c *symbol); |
278 void *visit(il_param_list_c *symbol); |
191 void *visit(il_param_assignment_c *symbol); |
279 void *visit(il_param_assignment_c *symbol); |
192 void *visit(il_param_out_assignment_c *symbol); |
280 void *visit(il_param_out_assignment_c *symbol); |