# HG changeset patch # User Mario de Sousa # Date 1387481909 0 # Node ID efb44e892582c9c6539cbcb51a26f5c0d208d096 # Parent 2c59c2b8fca4934b5705e774f1fb3df68fe7dc44 Fix bug: allow use, as lvalues, structures/arrays inside FBs (e.g. fb1.struct1.r := 33.3). diff -r 2c59c2b8fca4 -r efb44e892582 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Wed Dec 18 18:41:05 2013 +0000 +++ b/stage4/generate_c/generate_c.cc Thu Dec 19 19:38:29 2013 +0000 @@ -340,6 +340,70 @@ /***********************************************************************/ /***********************************************************************/ +/* A helper class that analyses if the datatype of a variable is 'complex'. */ +/* 'complex' means that it is either a strcuture or an array! */ +class analyse_variable_c: public null_visitor_c { + private: + static analyse_variable_c *singleton_; + bool contains_complex_type_res; + + public: + analyse_variable_c(void) {}; + + static bool is_complex_type(symbol_c *symbol) { + if (NULL == symbol) ERROR; + if (NULL == symbol->datatype) ERROR; + return ( get_datatype_info_c::is_structure(symbol->datatype) + || get_datatype_info_c::is_array (symbol->datatype) + ); + } + + /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */ + /* eg: + * fb1.fb2.fb3.real returns FALSE + * fb1.fb2.struct1.real returns TRUE + * struct1.real returns TRUE + */ + static bool contains_complex_type(symbol_c *symbol) { + if (NULL == singleton_) singleton_ = new analyse_variable_c(); + if (NULL == singleton_) ERROR; + if (NULL == symbol) ERROR; + if (NULL == symbol->datatype) ERROR; + + singleton_->contains_complex_type_res = false; + symbol->accept(*singleton_); + return singleton_->contains_complex_type_res; + } + + + /*************************************/ + /* B.1.4.2 Multi-element Variables */ + /*************************************/ + + // SYM_REF2(structured_variable_c, record_variable, field_selector) + void *visit(structured_variable_c *symbol) { + symbol->record_variable->accept(*this); + /* do not set the contains_complex_type_res to TRUE if this structured_variable_c is accessing a FB instance! */ + contains_complex_type_res |= get_datatype_info_c::is_structure(symbol->datatype); + return NULL; + } + + /* subscripted_variable '[' subscript_list ']' */ + //SYM_REF2(array_variable_c, subscripted_variable, subscript_list) + void *visit(array_variable_c *symbol) { + contains_complex_type_res |= true; + return NULL; + } + +}; + +analyse_variable_c *analyse_variable_c::singleton_ = NULL; + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + #include "generate_c_st.cc" #include "generate_c_il.cc" diff -r 2c59c2b8fca4 -r efb44e892582 stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Wed Dec 18 18:41:05 2013 +0000 +++ b/stage4/generate_c/generate_c_il.cc Thu Dec 19 19:38:29 2013 +0000 @@ -412,7 +412,7 @@ bool type_is_complex = false; if (fb_symbol == NULL) { unsigned int vartype = search_var_instance_decl->get_vartype(symbol); - type_is_complex = search_var_instance_decl->type_is_complex(symbol); + type_is_complex = analyse_variable_c::contains_complex_type(symbol); if (vartype == search_var_instance_decl_c::external_vt) { if (search_var_instance_decl->type_is_fb(symbol)) s4o.print(SET_EXTERNAL_FB); diff -r 2c59c2b8fca4 -r efb44e892582 stage4/generate_c/generate_c_inlinefcall.cc --- a/stage4/generate_c/generate_c_inlinefcall.cc Wed Dec 18 18:41:05 2013 +0000 +++ b/stage4/generate_c/generate_c_inlinefcall.cc Thu Dec 19 19:38:29 2013 +0000 @@ -285,7 +285,7 @@ s4o.print(","); wanted_variablegeneration = expression_vg; print_check_function(type, value, NULL, true); - if (search_var_instance_decl->type_is_complex(symbol)) { + if (analyse_variable_c::contains_complex_type(symbol)) { s4o.print(","); wanted_variablegeneration = complextype_suffix_vg; symbol->accept(*this); diff -r 2c59c2b8fca4 -r efb44e892582 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Wed Dec 18 18:41:05 2013 +0000 +++ b/stage4/generate_c/generate_c_st.cc Thu Dec 19 19:38:29 2013 +0000 @@ -166,6 +166,8 @@ return NULL; } + + void *print_setter(symbol_c* symbol, symbol_c* type, symbol_c* value, @@ -175,7 +177,7 @@ bool type_is_complex = false; if (fb_symbol == NULL) { unsigned int vartype = search_var_instance_decl->get_vartype(symbol); - type_is_complex = search_var_instance_decl->type_is_complex(symbol); + type_is_complex = analyse_variable_c::contains_complex_type(symbol); if (vartype == search_var_instance_decl_c::external_vt) { if (search_var_instance_decl->type_is_fb(symbol)) s4o.print(SET_EXTERNAL_FB);