Implicitly defined array datatypes use new naming method (greatly simplifies stage 4 code).
authormjsousa
Sun, 20 Jul 2014 16:45:45 +0100
changeset 913 1c74da17cb61
parent 912 252a69d6ecae
child 914 be6c89943079
Implicitly defined array datatypes use new naming method (greatly simplifies stage 4 code).
absyntax/absyntax.hh
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_typedecl.cc
stage4/generate_c/generate_c_vardecl.cc
--- a/absyntax/absyntax.hh	Sun Jul 20 03:14:57 2014 +0100
+++ b/absyntax/absyntax.hh	Sun Jul 20 16:45:45 2014 +0100
@@ -107,9 +107,9 @@
     virtual const char *absyntax_cname(void) {return "symbol_c";};
 
     /*
-     * Line number for the purposes of error checking.
-     * Annotated (inserted) by stage1_2
-     */
+     * Annotations produced during stage 1_2
+     */    
+    /* Line number for the purposes of error checking.  */
     int first_line;
     int first_column;
     const char *first_file;  /* filename referenced by first line/column */
@@ -171,6 +171,16 @@
      */
     typedef std::multimap<std::string, symbol_c *, nocasecmp_c> enumvalue_symtable_t;
     
+    /*
+     * Annotations produced during stage 4
+     */
+    /* Since we support several distinct stage_4 implementations, having explicit entries for each
+     * possible use would quickly get out of hand.
+     * We therefore simply add a map, that each stage 4 may use for all its needs.
+     */
+    typedef std::map<std::string, symbol_c *> anotations_map_t;
+    anotations_map_t anotations_map;
+    
 
   public:
     /* default constructor */
--- a/stage4/generate_c/generate_c.cc	Sun Jul 20 03:14:57 2014 +0100
+++ b/stage4/generate_c/generate_c.cc	Sun Jul 20 16:45:45 2014 +0100
@@ -754,26 +754,31 @@
 /***********************************************************************/
 
 
-class generate_c_datatypes_c: public generate_c_typedecl_c {
-  public:
-    typedef enum {
-      none_im,
-      arrayname_im,
-      arraydeclaration_im
-    } inlinearray_mode_t;
-
+identifier_c *generate_unique_id(symbol_c *clone = NULL) {
+  static int counter = 0;
+  
+  counter++;
+  int   len = snprintf(NULL, 0, "__UNIQUE_ID_%d", counter);
+  char *str = (char *)malloc(len+1);
+  if (snprintf(str, len+1, "__UNIQUE_ID_%d", counter) < 0) ERROR;
+  
+  identifier_c *id = new identifier_c(str);
+  if (NULL == id) ERROR;
+  if (NULL != clone)
+    *(dynamic_cast<symbol_c *>(id)) = *(dynamic_cast<symbol_c *>(clone));
+  return id;
+}
+
+
+
+class generate_c_datatypes_c: public iterator_visitor_c {
   private:
-    std::map<std::string, int> inline_array_defined;
-    std::string current_array_name;
-    inlinearray_mode_t current_mode;
-
+    generate_c_typedecl_c generate_c_typedecl;
   public:
     generate_c_datatypes_c(stage4out_c *s4o_incl_ptr)
-      : generate_c_typedecl_c(s4o_incl_ptr) {
-      current_mode = none_im;
+      : generate_c_typedecl(s4o_incl_ptr) {
     };
     virtual ~generate_c_datatypes_c(void) {
-      inline_array_defined.clear(); // Not really necessary...
     }
 
     /*************************/
@@ -782,20 +787,6 @@
     /*******************************************/
     /* B 1.1 - Letters, digits and identifiers */
     /*******************************************/
-    void *visit(identifier_c *symbol) {
-      switch (current_mode) {
-        case arrayname_im:
-          current_array_name += symbol->value;
-          break;
-        case arraydeclaration_im:
-          s4o_incl.print(symbol->value);
-          break;
-        default:
-          return generate_c_base_c::visit(symbol);
-          break;
-      }
-      return NULL;
-    }
 
     /**********************/
     /* B.1.3 - Data types */
@@ -803,389 +794,68 @@
     /***********************************/
     /* B 1.3.1 - Elementary Data Types */
     /***********************************/
-
-    #define HANDLE_ELEMENTARY_DATA_TYPE(datatype_symbol, datatype_name)\
-    void *visit(datatype_symbol *symbol) {\
-      switch (current_mode) {\
-        case arrayname_im:\
-          current_array_name += datatype_name;\
-          break;\
-        case arraydeclaration_im:\
-          s4o_incl.print(datatype_name);\
-          break;\
-        default:\
-          return generate_c_base_c::visit(symbol);\
-          break;\
-      }\
-      return NULL;\
-    }
-
-    HANDLE_ELEMENTARY_DATA_TYPE(time_type_name_c, "TIME")
-    HANDLE_ELEMENTARY_DATA_TYPE(bool_type_name_c, "BOOL")
-    HANDLE_ELEMENTARY_DATA_TYPE(sint_type_name_c, "SINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(int_type_name_c, "INT")
-    HANDLE_ELEMENTARY_DATA_TYPE(dint_type_name_c, "DINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(lint_type_name_c, "LINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(usint_type_name_c, "USINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(uint_type_name_c, "UINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(udint_type_name_c, "UDINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(ulint_type_name_c, "ULINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(real_type_name_c, "REAL")
-    HANDLE_ELEMENTARY_DATA_TYPE(lreal_type_name_c, "LREAL")
-    HANDLE_ELEMENTARY_DATA_TYPE(date_type_name_c, "DATE")
-    HANDLE_ELEMENTARY_DATA_TYPE(tod_type_name_c, "TOD")
-    HANDLE_ELEMENTARY_DATA_TYPE(dt_type_name_c, "DT")
-    HANDLE_ELEMENTARY_DATA_TYPE(byte_type_name_c, "BYTE")
-    HANDLE_ELEMENTARY_DATA_TYPE(word_type_name_c, "WORD")
-    HANDLE_ELEMENTARY_DATA_TYPE(dword_type_name_c, "DWORD")
-    HANDLE_ELEMENTARY_DATA_TYPE(lword_type_name_c, "LWORD")
-    HANDLE_ELEMENTARY_DATA_TYPE(string_type_name_c, "STRING")
-    HANDLE_ELEMENTARY_DATA_TYPE(wstring_type_name_c, "WSTRING")
-
-    HANDLE_ELEMENTARY_DATA_TYPE(safetime_type_name_c, "TIME")
-    HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL")
-    HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL")
-    HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL")
-    HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE")
-    HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD")
-    HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT")
-    HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE")
-    HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD")
-    HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD")
-    HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD")
-    HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING")
-    HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING")
-
     /***********************************/
     /* B 1.3.2 - Generic Data Types    */
     /***********************************/
 
-    /*  structure_type_name ':' structure_specification */
-    //SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
-    void *visit(structure_type_declaration_c *symbol) {
-      current_mode = arraydeclaration_im;
-      symbol->structure_specification->accept(*this);
-      current_mode = arrayname_im;
-      generate_c_typedecl_c::visit(symbol);
-      current_mode = none_im;
-      return NULL;
-    }
-
-    /* helper symbol for structure_declaration */
-    /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
-    /* structure_element_declaration_list structure_element_declaration ';' */
-    //SYM_LIST(structure_element_declaration_list_c)
-    void *visit(structure_element_declaration_list_c *symbol) {
-      switch (current_mode) {
-        case arraydeclaration_im:
-          iterator_visitor_c::visit(symbol);
-          break;
-        default:
-          generate_c_typedecl_c::visit(symbol);
-          break;
-      }
-      return NULL;
-    }
-
-    /*  structure_element_name ':' spec_init */
-    //SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init)
-    void *visit(structure_element_declaration_c *symbol) {
-      switch (current_mode) {
-        case arraydeclaration_im:
-          {
-            array_spec_init_c *spec_init = dynamic_cast<array_spec_init_c*>(symbol->spec_init);
-            if (spec_init != NULL) {
-              symbol->spec_init->accept(*this);
-            }
-          }
-          break;
-        default:
-          generate_c_typedecl_c::visit(symbol);
-          break;
-      }
-      return NULL;
-    }
-
     /******************************************/
     /* B 1.4.3 - Declaration & Initialization */
     /******************************************/
 
-    void *visit(input_declarations_c *symbol) {
-      symbol->input_declaration_list->accept(*this);
-      return NULL;
-    }
-
-    void *visit(edge_declaration_c *symbol) {
-      return NULL;
-    }
-
-    void *visit(en_param_declaration_c *symbol) {
-      return NULL;
-    }
-
-    void *visit(eno_param_declaration_c *symbol) {
-      return NULL;
-    }
-
-    void *visit(var1_init_decl_c *symbol) {
-      return NULL;
-    }
-
-    /*  var1_list ':' array_spec_init */
-    // SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)
-    void *visit(array_var_init_decl_c *symbol) {
-      current_mode = arraydeclaration_im;
-      symbol->array_spec_init->accept(*this);
-      current_mode = none_im;
-      return NULL;
-    }
+    void *visit(edge_declaration_c           *symbol) {return NULL;}
+    void *visit(en_param_declaration_c       *symbol) {return NULL;}
+    void *visit(eno_param_declaration_c      *symbol) {return NULL;}
+
+    void *visit(var1_init_decl_c             *symbol) {return NULL;}
 
     /* array_specification [ASSIGN array_initialization] */
     /* array_initialization may be NULL ! */
     void *visit(array_spec_init_c *symbol) {
-      switch (current_mode) {
-        case arraydeclaration_im:
-          {
-            array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
-            if (specification != NULL)
-              symbol->array_specification->accept(*this);
-          }
-          break;
-        case arrayname_im:
-          {
-            array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
-            if (specification != NULL)
-              symbol->array_specification->accept(*this);
-            identifier_c *name = dynamic_cast<identifier_c*>(symbol->array_specification);
-            if (name != NULL)
-              s4o_incl.print(name->value);
-          }
-          break;
-        default:
-          return generate_c_typedecl_c::visit(symbol);
-          break;
-      }
+      symbol->array_specification->accept(*this);
+      int implicit_id_count = symbol->array_specification->anotations_map.count("generate_c_annotaton__implicit_type_id");
+      if (implicit_id_count  > 1) ERROR;
+      if (implicit_id_count == 1)
+        symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = symbol->array_specification->anotations_map["generate_c_annotaton__implicit_type_id"];
       return NULL;
     }
 
     /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
     void *visit(array_specification_c *symbol) {
-      switch (current_mode) {
-        case arraydeclaration_im:
-          {
-            current_mode = arrayname_im;
-            std::map<std::string,int>::iterator definition;
-            current_array_name = "__";
-            symbol->non_generic_type_name->accept(*this);
-            symbol->array_subrange_list->accept(*this);
-            current_mode = arraydeclaration_im;
-
-            definition = inline_array_defined.find(current_array_name);
-            if (definition == inline_array_defined.end()) {
-              s4o_incl.print("__DECLARE_ARRAY_TYPE(");
-              s4o_incl.print(current_array_name);
-              s4o_incl.print(",");
-              symbol->non_generic_type_name->accept(*this);
-              s4o_incl.print(",");
-              symbol->array_subrange_list->accept(*this);
-              s4o_incl.print(")\n\n");
-
-              inline_array_defined[current_array_name] = 0; // insert an element, indicating this array type has been defined!
-            }
-          }
-          break;
-        case arrayname_im:
-          {
-              std::map<std::string,int>::iterator definition;
-              current_array_name = "__";
-              symbol->non_generic_type_name->accept(*this);
-              symbol->array_subrange_list->accept(*this);
-              s4o_incl.print(current_array_name);
-          }
-          break;
-        default:
-          return generate_c_typedecl_c::visit(symbol);
-          break;
-      }
-      return NULL;
-    }
-
-    /*  signed_integer DOTDOT signed_integer */
-    //SYM_REF2(subrange_c, lower_limit, upper_limit)
-    void *visit(subrange_c *symbol) {
-      switch (current_mode) {
-        case arrayname_im:
-          current_array_name += "_";
-          {
-            std::stringstream ss;
-            ss << symbol->dimension;
-            current_array_name += ss.str();
-          }
-          break;
-        case arraydeclaration_im:
-          s4o_incl.print("[");
-          s4o_incl.print(symbol->dimension);
-          s4o_incl.print("]");
-        default:
-          generate_c_typedecl_c::visit(symbol);
-          break;
-      }
-      return NULL;
-    }
-
+      identifier_c *id = generate_unique_id(symbol);
+      /* Warning: The following is dangerous... 
+       * We are asking the generate_c_typedecl_c visitor to visit a newly created array_type_declaration_c object
+       * that has not been through stage 3, and therefore does not have stage 3 annotations filled in.
+       * This will only work if generate_c_typedecl_c does ot depend on the stage 3 annotations!
+       */
+      array_spec_init_c        array_spec(symbol, NULL);
+      array_type_declaration_c array_decl(id, &array_spec);
+      array_decl.accept(generate_c_typedecl); // Must be done _before_ adding the annotation, due to the way generate_c_typedecl_c works
+      symbol->anotations_map["generate_c_annotaton__implicit_type_id"] = id;
+      return NULL;
+    }
+    
     /*  var1_list ':' initialized_structure */
     // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)
-    void *visit(structured_var_init_decl_c *symbol) {
-      return NULL;
-    }
+    void *visit(structured_var_init_decl_c   *symbol) {return NULL;}
 
     /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
     /* structure_initialization -> may be NULL ! */
-    void *visit(fb_name_decl_c *symbol) {
-      return NULL;
-    }
-
-    /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
-    /* option -> may be NULL ! */
-    void *visit(output_declarations_c *symbol) {
-      symbol->var_init_decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*  VAR_IN_OUT var_declaration_list END_VAR */
-    void *visit(input_output_declarations_c *symbol) {
-      symbol->var_declaration_list->accept(*this);
-      return NULL;
-    }
-
-    /*  var1_list ':' array_specification */
-    //SYM_REF2(array_var_declaration_c, var1_list, array_specification)
-    void *visit(array_var_declaration_c *symbol) {
-      array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
-      if (specification != NULL) {
-        current_mode = arraydeclaration_im;
-        symbol->array_specification->accept(*this);
-        current_mode = none_im;
-      }
-      return NULL;
-    }
+    void *visit(fb_name_decl_c               *symbol) {return NULL;}
 
     /*  var1_list ':' structure_type_name */
     //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name)
-    void *visit(structured_var_declaration_c *symbol) {
-      return NULL;
-    }
-
-    /* VAR [CONSTANT] var_init_decl_list END_VAR */
-    /* option -> may be NULL ! */
-    /* helper symbol for input_declarations */
-    void *visit(var_declarations_c *symbol) {
-      symbol->var_init_decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*  VAR RETAIN var_init_decl_list END_VAR */
-    void *visit(retentive_var_declarations_c *symbol) {
-      symbol->var_init_decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
-    /* option -> may be NULL ! */
-    //SYM_REF2(located_var_declarations_c, option, located_var_decl_list)
-    void *visit(located_var_declarations_c *symbol) {
-      symbol->located_var_decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*  [variable_name] location ':' located_var_spec_init */
-    /* variable_name -> may be NULL ! */
-    //SYM_REF4(located_var_decl_c, variable_name, location, located_var_spec_init, unused)
-    void *visit(located_var_decl_c *symbol) {
-      array_spec_init_c* array_spec_init = dynamic_cast<array_spec_init_c*>(symbol->located_var_spec_init);
-      if (array_spec_init != NULL) {
-        current_mode = arraydeclaration_im;
-        symbol->located_var_spec_init->accept(*this);
-        current_mode = none_im;
-      }
-      return NULL;
-    }
-
-    /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
-    /* option -> may be NULL ! */
-    //SYM_REF2(external_var_declarations_c, option, external_declaration_list)
-    void *visit(external_var_declarations_c *symbol) {
-      symbol->external_declaration_list->accept(*this);
-      return NULL;
-    }
-
-    /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
-    //SYM_REF2(external_declaration_c, global_var_name, specification)
-    void *visit(external_declaration_c *symbol) {
-      array_specification_c* array_specification = dynamic_cast<array_specification_c*>(symbol->specification);
-      if (array_specification != NULL) {
-        current_mode = arraydeclaration_im;
-        symbol->specification->accept(*this);
-        current_mode = none_im;
-      }
-      return NULL;
-    }
-
-    /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */
-    /* option -> may be NULL ! */
-    // SYM_REF2(global_var_declarations_c, option, global_var_decl_list)
-    void *visit(global_var_declarations_c *symbol) {
-      symbol->global_var_decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
-    /* type_specification ->may be NULL ! */
-    // SYM_REF2(global_var_decl_c, global_var_spec, type_specification)
-    void *visit(global_var_decl_c *symbol) {
-      array_spec_init_c* array_spec_init = dynamic_cast<array_spec_init_c*>(symbol->type_specification);
-      if (array_spec_init != NULL) {
-        current_mode = arraydeclaration_im;
-        symbol->type_specification->accept(*this);
-        current_mode = none_im;
-      }
-      return NULL;
-    }
-
-    void *visit(function_var_decls_c *symbol) {
-      symbol->decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*****************************/
-    /* B 1.5.2 - Function Blocks */
-    /*****************************/
-
-    /*  VAR_TEMP temp_var_decl_list END_VAR */
-    void *visit(temp_var_decls_c *symbol) {
-      symbol->var_decl_list->accept(*this);
-      return NULL;
-    }
-
-    /*  VAR NON_RETAIN var_init_decl_list END_VAR */
-    void *visit(non_retentive_var_decls_c *symbol) {
-      symbol->var_decl_list->accept(*this);
-      return NULL;
-    }
+    void *visit(structured_var_declaration_c *symbol) {return NULL;}
 
 };
 
 
 
 
+
+
+
+
+
 /***********************************************************************/
 /***********************************************************************/
 /***********************************************************************/
@@ -2485,15 +2155,17 @@
 
 class generate_c_c: public iterator_visitor_c {
   protected:
-    stage4out_c &s4o;
-    stage4out_c pous_s4o;
-    stage4out_c pous_incl_s4o;
-    stage4out_c located_variables_s4o;
-    stage4out_c variables_s4o;
+    stage4out_c                      &s4o;
+    stage4out_c                  pous_s4o;
+    stage4out_c             pous_incl_s4o;
+    stage4out_c     located_variables_s4o;
+    stage4out_c             variables_s4o;
+    
     generate_c_datatypes_c generate_c_datatypes;
-    generate_c_pous_c generate_c_pous;
-    
-    symbol_c *current_configuration;
+    generate_c_typedecl_c  generate_c_typedecl;
+    generate_c_pous_c      generate_c_pous;
+    
+    symbol_c   *current_configuration;
 
     const char *current_name;
     const char *current_builddir;
@@ -2509,7 +2181,8 @@
             pous_incl_s4o(builddir, "POUS", "h"),
             located_variables_s4o(builddir, "LOCATED_VARIABLES","h"),
             variables_s4o(builddir, "VARIABLES","csv"),
-            generate_c_datatypes(&pous_incl_s4o)
+            generate_c_datatypes(&pous_incl_s4o),
+            generate_c_typedecl (&pous_incl_s4o)
     {
       current_builddir = builddir;
       current_configuration = NULL;
@@ -2583,8 +2256,14 @@
 /* B 1.3.3 - Derived data types */
 /********************************/
     /*  TYPE type_declaration_list END_TYPE */
-    void *visit(data_type_declaration_c *symbol) {
-      symbol->accept(generate_c_datatypes);
+//   void *visit(data_type_declaration_c *symbol)  // handled by iterator_visitor_c
+
+    /* helper symbol for data_type_declaration */
+    void *visit(type_declaration_list_c *symbol) {
+      for(int i = 0; i < symbol->n; i++) {
+        symbol->elements[i]->accept(generate_c_datatypes);
+        symbol->elements[i]->accept(generate_c_typedecl);
+      }
       return NULL;
     }
 
--- a/stage4/generate_c/generate_c_typedecl.cc	Sun Jul 20 03:14:57 2014 +0100
+++ b/stage4/generate_c/generate_c_typedecl.cc	Sun Jul 20 16:45:45 2014 +0100
@@ -58,9 +58,6 @@
       none_bd,
       subrangebasetype_bd,
       subrangetest_bd,
-      arrayderiveddeclaration_bd,
-      arraybasetype_bd,
-      arraybasetypeincl_bd,
       arraysubrange_bd
     } basetypedeclaration_t;
 
@@ -322,78 +319,63 @@
 /*  identifier ':' array_spec_init */
 void *visit(array_type_declaration_c *symbol) {
   TRACE("array_type_declaration_c");
-  
   current_typedefinition = array_td;
   current_type_name = symbol->identifier;
 
-  array_is_derived = false;
-  current_basetypedeclaration = arrayderiveddeclaration_bd;
-  symbol->array_spec_init->accept(*this);
-  current_basetypedeclaration = none_bd;
-
-  if (array_is_derived)
+  int implicit_id_count = symbol->array_spec_init->anotations_map.count("generate_c_annotaton__implicit_type_id");
+  if (implicit_id_count  > 1) ERROR;
+  if (implicit_id_count == 1)
     s4o_incl.print("__DECLARE_DERIVED_TYPE(");
   else
     s4o_incl.print("__DECLARE_ARRAY_TYPE(");
   current_type_name->accept(*basedecl);
   s4o_incl.print(",");
-  current_basetypedeclaration = arraybasetypeincl_bd;
   symbol->array_spec_init->accept(*this);
-  current_basetypedeclaration = none_bd;
-  if (!array_is_derived) {
-    s4o_incl.print(",");
-    current_basetypedeclaration = arraysubrange_bd;
-    symbol->array_spec_init->accept(*this);
-    current_basetypedeclaration = none_bd;
-  }
   s4o_incl.print(")\n");
 
   current_type_name = NULL;
   current_typedefinition = none_td;
-
-  return NULL;
-}
+  return NULL;
+}
+
+
 
 /* array_specification [ASSIGN array_initialization] */
 /* array_initialization may be NULL ! */
 void *visit(array_spec_init_c *symbol) {
-  TRACE("array_spec_init_c");
-  
-  if (current_typedefinition == array_td) {
-    switch (current_basetypedeclaration) {
-      case arrayderiveddeclaration_bd:
-        array_is_derived = dynamic_cast<identifier_c *>(symbol->array_specification) != NULL;
-        break;
-      default:
-        if (array_is_derived)
-          symbol->array_specification->accept(*basedecl);
-        else
-          symbol->array_specification->accept(*this);
-        break;
-    }
+  TRACE("array_spec_init_c");  
+  int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id");
+  if (implicit_id_count  > 1) ERROR;
+  if (implicit_id_count == 1) {
+      /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype
+       * has already been defined. So, we simly print out the id of that C datatpe...
+       */
+    symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl);
+    return NULL;
   }
-  else {
-    symbol->array_specification->accept(*basedecl);
-  }
+//   if (current_typedefinition != array_td) {debug_c::print(symbol); ERROR;}
+  symbol->array_specification->accept(*this);
   return NULL;
 }
 
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
 void *visit(array_specification_c *symbol) {
   TRACE("array_specification_c");
-  switch (current_basetypedeclaration) {
-    case arraybasetype_bd:
-      symbol->non_generic_type_name->accept(*this);
-      break;
-    case arraybasetypeincl_bd:
-      symbol->non_generic_type_name->accept(*basedecl);
-      break;
-    case arraysubrange_bd:
-      symbol->array_subrange_list->accept(*this);
-      break;
-    default:
-      break;
+  int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id");
+  if (implicit_id_count  > 1) ERROR;
+  if (implicit_id_count == 1) {
+      /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype
+       * has already been defined. So, we simly print out the id of that C datatpe...
+       */
+    symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*basedecl);
+    return NULL;
   }
+  // The 2nd and 3rd argument of a call to the __DECLARE_ARRAY_TYPE macro!
+  symbol->non_generic_type_name->accept(*this);
+  s4o_incl.print(",");
+  current_basetypedeclaration = arraysubrange_bd;
+  symbol->array_subrange_list->accept(*this);
+  current_basetypedeclaration = none_bd;
   return NULL;
 }
 
@@ -670,7 +652,7 @@
   symbol->ref_type_name->accept(*basedecl);
   s4o_incl.print(", ");
   symbol->ref_spec_init->accept(*this);
-  s4o_incl.print(") ");
+  s4o_incl.print(")\n");
 
   current_type_name = NULL;
   current_typedefinition = none_td;
--- a/stage4/generate_c/generate_c_vardecl.cc	Sun Jul 20 03:14:57 2014 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc	Sun Jul 20 16:45:45 2014 +0100
@@ -58,6 +58,8 @@
     }
 };
 
+
+// Does this class really need to derive from generate_c_typedecl_c ???
 class generate_c_array_initialization_c: public generate_c_typedecl_c {
 
   public:
@@ -202,11 +204,18 @@
           array_default_value = type_initial_value_c::get(symbol->non_generic_type_name);
           if (array_default_value == NULL) ERROR;
           break;
-        case typedecl_am:
-          s4o.print("__");
-          symbol->non_generic_type_name->accept(*this);
-          symbol->array_subrange_list->accept(*this);
-          break;
+        case typedecl_am: {
+            int implicit_id_count = symbol->anotations_map.count("generate_c_annotaton__implicit_type_id");
+            if (implicit_id_count  > 1) ERROR;
+            if (implicit_id_count == 1)
+                /* this is part of an implicitly declared datatype (i.e. inside a variable decaration), for which an equivalent C datatype
+                 * has already been defined. So, we simly print out the id of that C datatpe...
+                 */
+              symbol->anotations_map["generate_c_annotaton__implicit_type_id"]->accept(*this);
+            else
+              symbol->non_generic_type_name->accept(*this);
+            break;
+          }
         default:
           symbol->array_subrange_list->accept(*this);
           break;
@@ -225,10 +234,6 @@
                          std::numeric_limits< unsigned long long int >::max());
           array_size *= symbol->dimension;
           break;
-        case typedecl_am:
-          s4o.print("_");
-          s4o.print(symbol->dimension);
-          break;
         default:
           break;
       }
@@ -1424,21 +1429,6 @@
   return NULL;
 }
 
-/* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
-void *visit(array_specification_c *symbol) {
-  s4o.print("__");
-  symbol->non_generic_type_name->accept(*this);
-  symbol->array_subrange_list->accept(*this);
-  return NULL;
-}
-
-/*  signed_integer DOTDOT signed_integer */
-//SYM_REF2(subrange_c, lower_limit, upper_limit)
-void *visit(subrange_c *symbol) {
-  s4o.print("_");
-  s4o.print(symbol->dimension);
-  return NULL;
-}
 
 /*  var1_list ':' initialized_structure */
 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)