207 void remove_forward_dependencies_c::print_circ_error(library_c *symbol) { |
207 void remove_forward_dependencies_c::print_circ_error(library_c *symbol) { |
208 /* Note that we only print Functions and FBs, as Programs and Configurations cannot contain circular references due to syntax rules */ |
208 /* Note that we only print Functions and FBs, as Programs and Configurations cannot contain circular references due to syntax rules */ |
209 /* Note too that circular references in derived datatypes is also not possible due to sytax! */ |
209 /* Note too that circular references in derived datatypes is also not possible due to sytax! */ |
210 int initial_error_count = error_count; |
210 int initial_error_count = error_count; |
211 for (int i = 0; i < symbol->n; i++) |
211 for (int i = 0; i < symbol->n; i++) |
212 if ( (inserted_symbols.find(symbol->elements[i]) == inserted_symbols.end()) // if not copied to new AST |
212 if ( (inserted_symbols.find(symbol->get_element(i)) == inserted_symbols.end()) // if not copied to new AST |
213 &&( (NULL != dynamic_cast <function_block_declaration_c *>(symbol->elements[i])) // and (is a FB |
213 &&( (NULL != dynamic_cast <function_block_declaration_c *>(symbol->get_element(i))) // and (is a FB |
214 ||(NULL != dynamic_cast < function_declaration_c *>(symbol->elements[i])))) // or a Function) |
214 ||(NULL != dynamic_cast < function_declaration_c *>(symbol->get_element(i))))) // or a Function) |
215 STAGE3_ERROR(0, symbol->elements[i], symbol->elements[i], "POU (%s) contains a self-reference and/or belongs in a circular referencing loop", get_datatype_info_c::get_id_str(symbol->elements[i])); |
215 STAGE3_ERROR(0, symbol->get_element(i), symbol->get_element(i), "POU (%s) contains a self-reference and/or belongs in a circular referencing loop", get_datatype_info_c::get_id_str(symbol->get_element(i))); |
216 if (error_count == initial_error_count) ERROR; // We were unable to determine which POUs contain the circular references!! |
216 if (error_count == initial_error_count) ERROR; // We were unable to determine which POUs contain the circular references!! |
217 } |
217 } |
218 |
218 |
219 |
219 |
220 /***************************/ |
220 /***************************/ |
226 /* this method is the expected entry point for this visitor, and implements the main algorithm of the visitor */ |
226 /* this method is the expected entry point for this visitor, and implements the main algorithm of the visitor */ |
227 |
227 |
228 /* first insert all the derived datatype declarations, in the same order by which they are delcared in the original AST */ |
228 /* first insert all the derived datatype declarations, in the same order by which they are delcared in the original AST */ |
229 /* Since IEC 61131-3 does not allow FBs in arrays or structures, it is actually safe to place all the datatypes before all the POUs! */ |
229 /* Since IEC 61131-3 does not allow FBs in arrays or structures, it is actually safe to place all the datatypes before all the POUs! */ |
230 for (int i = 0; i < symbol->n; i++) |
230 for (int i = 0; i < symbol->n; i++) |
231 if (NULL != dynamic_cast <data_type_declaration_c *>(symbol->elements[i])) |
231 if (NULL != dynamic_cast <data_type_declaration_c *>(symbol->get_element(i))) |
232 new_tree->add_element(symbol->elements[i]); |
232 new_tree->add_element(symbol->get_element(i)); |
233 |
233 |
234 /* now do the POUs, in whatever order is necessary to guarantee no forward references. */ |
234 /* now do the POUs, in whatever order is necessary to guarantee no forward references. */ |
235 long long int old_tree_pou_count = pou_count_c::get_count(symbol); |
235 long long int old_tree_pou_count = pou_count_c::get_count(symbol); |
236 // if no code generation pragma exists before the first entry in the library, the default is to enable code generation. |
236 // if no code generation pragma exists before the first entry in the library, the default is to enable code generation. |
237 enable_code_generation_pragma_c *default_code_generation_pragma = new enable_code_generation_pragma_c; |
237 enable_code_generation_pragma_c *default_code_generation_pragma = new enable_code_generation_pragma_c; |
239 cycle_count = 0; |
239 cycle_count = 0; |
240 do { |
240 do { |
241 cycle_count++; |
241 cycle_count++; |
242 prev_n = new_tree->n; |
242 prev_n = new_tree->n; |
243 current_code_generation_pragma = default_code_generation_pragma; |
243 current_code_generation_pragma = default_code_generation_pragma; |
244 for (int i = 0; i < symbol->n; i++) symbol->elements[i]->accept(*this); |
244 for (int i = 0; i < symbol->n; i++) symbol->get_element(i)->accept(*this); |
245 } while (prev_n != new_tree->n); // repeat while new elementns are still being added to the new AST |
245 } while (prev_n != new_tree->n); // repeat while new elementns are still being added to the new AST |
246 |
246 |
247 if (old_tree_pou_count != pou_count_c::get_count(new_tree)) |
247 if (old_tree_pou_count != pou_count_c::get_count(new_tree)) |
248 print_circ_error(symbol); |
248 print_circ_error(symbol); |
249 |
249 |