Fix bug: allow use, as lvalues, structures/arrays inside FBs (e.g. fb1.struct1.r := 33.3).
authorMario de Sousa <msousa@fe.up.pt>
Thu, 19 Dec 2013 19:38:29 +0000
changeset 852 efb44e892582
parent 851 2c59c2b8fca4
child 853 818c4ac5d64d
Fix bug: allow use, as lvalues, structures/arrays inside FBs (e.g. fb1.struct1.r := 33.3).
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_c/generate_c_st.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"
--- 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);