Fix bug: allow use, as lvalues, structures/arrays inside FBs (e.g. fb1.struct1.r := 33.3).
--- 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"
--- 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);
--- 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);
--- 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);