merge
authorMario de Sousa <msousa@fe.up.pt>
Sun, 16 Apr 2017 08:46:58 +0100
changeset 1049 4d7183013481
parent 1048 37966f855bed (diff)
parent 1039 52f63e622604 (current diff)
child 1050 bdc21971f95d
merge
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_st.cc
--- a/absyntax/absyntax.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax/absyntax.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -58,6 +58,7 @@
   this->last_column  = last_column;
   this->last_order   = last_order;
   this->parent       = NULL;
+  this->token        = NULL;
   this->datatype     = NULL;
   this->scope        = NULL;
 }
@@ -69,6 +70,7 @@
                  int ll, int lc, const char *lfile, long int lorder)
   :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder) {
   this->value = value;
+  this->token = this; // every token is its own reference token.
 //  printf("New token: %s\n", value);
 }
 
@@ -83,7 +85,7 @@
                int ll, int lc, const char *lfile, long int lorder)
   :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) {
   n = 0;
-  elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*));
+  elements = (element_entry_t*)malloc(LIST_CAP_INIT*sizeof(element_entry_t));
   if (NULL == elements) ERROR_MSG("out of memory");
 }
 
@@ -93,20 +95,59 @@
                int ll, int lc, const char *lfile, long int lorder)
   :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) { 
   n = 0;
-  elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*));
+  elements = (element_entry_t*)malloc(LIST_CAP_INIT*sizeof(element_entry_t));
   if (NULL == elements) ERROR_MSG("out of memory");
   add_element(elem); 
 }
 
 
+/*******************************************/    
+/* get element in position pos of the list */
+/*******************************************/    
+symbol_c *list_c::get_element(int pos) {return elements[pos].symbol;}
+
+
+
+/******************************************/    
+/* find element associated to token value */
+/******************************************/    
+symbol_c *list_c::find_element(symbol_c *token) {
+  token_c *t = dynamic_cast<token_c *>(token);
+  if (t == NULL) ERROR;
+  return find_element((const char *)t->value);  
+}
+
+symbol_c *list_c::find_element(const char *token_value) {
+  // We could use strcasecmp(), but it's best to always use the same 
+  // method of string comparison throughout matiec
+  nocasecmp_c ncc; 
+  for (int i = 0; i < n; i++) 
+    if (!ncc(elements[i].token_value, token_value))
+      return elements[i].symbol;
+
+  return NULL; // not found
+}
+
+    
+/***********************************************/    
 /* append a new element to the end of the list */
-void list_c::add_element(symbol_c *elem) {
-  // printf("list_c::add_element()\n");
+/***********************************************/    
+void list_c::add_element(symbol_c *elem) {add_element(elem, elem);}
+
+void list_c::add_element(symbol_c *elem, symbol_c *token) {
+  token_c *t =  (token == NULL)? NULL : token->token;
+  add_element(elem, (t == NULL)? NULL : t->value);
+}
+
+void list_c::add_element(symbol_c *elem, const char *token_value) {
   if (c <= n)
-    if (!(elements=(symbol_c**)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(symbol_c *))))
+    if (!(elements=(element_entry_t*)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(element_entry_t))))
       ERROR_MSG("out of memory");
-  elements[n++] = elem;
- 
+  //elements[n++] = {token_value, elem};  // only available from C++11 onwards, best not use it for now.
+  elements[n].symbol      = elem;
+  elements[n].token_value = token_value;
+  n++;
+  
   if (NULL == elem) return;
   /* Sometimes add_element() is called in stage3 or stage4 to temporarily add an AST symbol to the list.
    * Since this symbol already belongs in some other place in the aST, it will have the 'parent' pointer set, 
@@ -143,10 +184,21 @@
   }
 }
 
+
+/*********************************************/    
 /* insert a new element before position pos. */
+/*********************************************/    
 /* To insert into the begining of list, call with pos=0  */
 /* To insert into the end of list, call with pos=list->n */
-void list_c::insert_element(symbol_c *elem, int pos) {
+
+void list_c::insert_element(symbol_c *elem, int pos) {insert_element(elem, elem, pos);}
+
+void list_c::insert_element(symbol_c *elem, symbol_c *token, int pos) {
+  token_c *t    =  (token == NULL)? NULL : token->token;
+  insert_element(elem, (t == NULL)? NULL : t->value, pos);
+}
+
+void list_c::insert_element(symbol_c *elem, const char *token_value, int pos) {
   if((pos<0) || (n<pos)) ERROR;
   
   /* add new element to end of list. Basically alocate required memory... */
@@ -155,12 +207,15 @@
   /* if not inserting into end position, shift all elements up one position, to open up a slot in pos for new element */
   if(pos < (n-1)){ 
     for(int i=n-2 ; i>=pos ; --i) elements[i+1] = elements[i];
-    elements[pos] = elem;
-  }
-}
-
-
+    elements[pos].symbol      = elem;
+    elements[pos].token_value = token_value;
+  }
+}
+
+
+/***********************************/    
 /* remove element at position pos. */
+/***********************************/    
 void list_c::remove_element(int pos) {
   if((pos<0) || (n<=pos)) ERROR;
   
@@ -168,12 +223,14 @@
   for (int i = pos; i < n-1; i++) elements[i] = elements[i+1];
   /* corrent the new size */
   n--;
-  /* elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *)); */
+  /* elements = (symbol_c **)realloc(elements, n * sizeof(element_entry_t)); */
   /* TODO: adjust the location parameters, taking into account the removed element. */
 }
 
 
-/* remove element at position pos. */
+/**********************************/    
+/* Remove all elements from list. */
+/**********************************/    
 void list_c::clear(void) {
   n = 0;
   /* TODO: adjust the location parameters, taking into account the removed element. */
--- a/absyntax/absyntax.hh	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax/absyntax.hh	Sun Apr 16 08:46:58 2017 +0100
@@ -154,7 +154,8 @@
       {return (_int64.is_valid() || _uint64.is_valid() || _real64.is_valid() || _bool.is_valid());}   
 };
 
-
+// A forward declaration
+class token_c;
 
 /* The base class of all symbols */
 class symbol_c {
@@ -167,7 +168,18 @@
      * Annotations produced during stage 1_2
      */    
     /* Points to the parent symbol in the AST, i.e. the symbol in the AST that will contain the current symbol */
-    symbol_c *parent; 
+    symbol_c *parent;
+    /* Some symbols may not be tokens, but may be clearly identified by a token.
+     * For e.g., a FUNCTION declaration is not itself a token, but may be clearly identified by the
+     * token_c object that contains it's name. Another example is an element in a STRUCT declaration,
+     * where the structure_element_declaration_c is not itself a token, but can be clearly identified
+     * by the structure_element_name
+     * To make it easier to find these tokens from the top level object, we will have the stage1_2 populate this
+     * token_c *token wherever it makes sense.
+     * NOTE: This was a late addition to the AST. Not all objects may be currently so populated.
+     *       If you need this please make sure the bison code is populating it correctly for your use case.
+     */
+    token_c  *token;
     
     /* Line number for the purposes of error checking.  */
     int first_line;
@@ -260,7 +272,14 @@
     virtual const char *absyntax_cname(void) {return "list_c";};
 
     int c,n; /* c: current capacity of list (malloc'd memory);  n: current number of elements in list */
-    symbol_c **elements;
+  private:
+//     symbol_c **elements;
+    typedef struct {
+      const char *token_value;
+      symbol_c   *symbol;
+    } element_entry_t;
+    element_entry_t *elements;
+    
 
   public:
     list_c(int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */
@@ -271,12 +290,22 @@
            int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */
            int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0  /* order in which it is read by lexcial analyser */
           );
+     /* get element in position pos of the list */
+    virtual symbol_c *get_element(int pos);
+     /* find element associated to token value */
+    virtual symbol_c *find_element(symbol_c   *token);
+    virtual symbol_c *find_element(const char *token_value);
      /* append a new element to the end of the list */
     virtual void add_element(symbol_c *elem);
+    virtual void add_element(symbol_c *elem, symbol_c   *token);
+    virtual void add_element(symbol_c *elem, const char *token_value);
      /* insert a new element before position pos. */
      /* To insert into the begining of list, call with pos=0  */
      /* To insert into the end of list, call with pos=list->n */
-    virtual void insert_element(symbol_c *elem, int pos = 0);
+    virtual void insert_element(symbol_c *elem, const char *token_value, int pos = 0);
+    virtual void insert_element(symbol_c *elem, symbol_c   *token,       int pos = 0);
+    virtual void insert_element(symbol_c *elem,                          int pos = 0);
+    //virtual void insert_element(symbol_c *elem, int pos, std::string map_ref);
      /* remove element at position pos. */
     virtual void remove_element(int pos = 0);
      /* remove all elements from list. Does not delete the elements in the list! */ 
--- a/absyntax/visitor.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax/visitor.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -168,7 +168,7 @@
 
 void *iterator_visitor_c::visit_list(list_c *list) {
   for(int i = 0; i < list->n; i++) {
-    list->elements[i]->accept(*this);
+    list->get_element(i)->accept(*this);
   }
   return NULL;
 }
@@ -310,7 +310,7 @@
 
 void *search_visitor_c::visit_list(list_c *list) {
   for(int i = 0; i < list->n; i++) {
-    void *res = list->elements[i]->accept(*this);
+    void *res = list->get_element(i)->accept(*this);
     if (res != NULL)
       return res;
   }
--- a/absyntax_utils/add_en_eno_param_decl.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/add_en_eno_param_decl.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -84,7 +84,7 @@
 
 void* add_en_eno_param_decl_c::iterate_list(list_c *list) {
   for (int i = 0; i < list->n; i++) {
-    list->elements[i]->accept(*this);
+    list->get_element(i)->accept(*this);
   }
   return NULL;
 }
--- a/absyntax_utils/array_dimension_iterator.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/array_dimension_iterator.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -64,7 +64,7 @@
 void* array_dimension_iterator_c::iterate_list(list_c *list) {
   void *res;
   for (int i = 0; i < list->n; i++) {
-    res = list->elements[i]->accept(*this);
+    res = list->get_element(i)->accept(*this);
     if (res != NULL)
         return res;
   }
--- a/absyntax_utils/case_element_iterator.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/case_element_iterator.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -78,7 +78,7 @@
 void* case_element_iterator_c::iterate_list(list_c *list) {
   void *res;
   for (int i = 0; i < list->n; i++) {
-    res = list->elements[i]->accept(*this);
+    res = list->get_element(i)->accept(*this);
     if (res != NULL)
         return res;
   }
--- a/absyntax_utils/function_call_param_iterator.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/function_call_param_iterator.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -67,7 +67,7 @@
   switch (current_operation) {
     case iterate_nf_op:
       for(int i = 0; i < list->n; i++) {
-        void *res = list->elements[i]->accept(*this);
+        void *res = list->get_element(i)->accept(*this);
         if (NULL != res) {
           /* It went through the handle_parameter_assignment() function,
            * and is therefore a parameter assignment (<param> = <value>),
@@ -77,7 +77,7 @@
         } else {
           param_count++;
           if (param_count == iterate_nf_next_param) {
-            return list->elements[i];
+            return list->get_element(i);
           }
         }
       }
@@ -86,7 +86,7 @@
 
     case iterate_f_op:
       for(int i = 0; i < list->n; i++) {
-        void *res = list->elements[i]->accept(*this);
+        void *res = list->get_element(i)->accept(*this);
         if (NULL != res) {
           /* It went through the handle_parameter_assignment() function,
            * and is therefore a parameter assignment (<param> = <value>),
@@ -105,7 +105,7 @@
 
     case search_f_op:
       for(int i = 0; i < list->n; i++) {
-        void *res = list->elements[i]->accept(*this);
+        void *res = list->get_element(i)->accept(*this);
         if (res != NULL)
           return res;
       }
--- a/absyntax_utils/function_param_iterator.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/function_param_iterator.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -167,7 +167,7 @@
   switch (current_operation) {
     case iterate_op:
       if (next_param <= param_count + list->n)
-        return list->elements[next_param - param_count - 1];
+        return list->get_element(next_param - param_count - 1);
 
       /* the desired param is not on this list... */
       param_count += list->n;
@@ -175,7 +175,7 @@
 
     case search_op:
       for(int i = 0; i < list->n; i++) {
-        symbol_c *sym = list->elements[i];
+        symbol_c *sym = list->get_element(i);
         extensible_input_parameter_c *extensible_parameter = dynamic_cast<extensible_input_parameter_c *>(sym);
         if (extensible_parameter != NULL) {
           sym = extensible_parameter->var_name;
@@ -243,7 +243,7 @@
 void* function_param_iterator_c::iterate_list(list_c *list) {
   void *res;
   for (int i = 0; i < list->n; i++) {
-    res = list->elements[i]->accept(*this);
+    res = list->get_element(i)->accept(*this);
     if (res != NULL)
         return res;
   }
--- a/absyntax_utils/get_datatype_info.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/get_datatype_info.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -362,7 +362,7 @@
     void *visit(structure_element_declaration_list_c *symbol) {
       /* now search the structure declaration */
       for(int i = 0; i < symbol->n; i++) {
-        void *tmp = symbol->elements[i]->accept(*this);
+        void *tmp = symbol->get_element(i)->accept(*this);
         if (NULL != tmp) return tmp;
       }
       return NULL; // not found!!
@@ -713,8 +713,8 @@
   
   // comparison of each subrange start and end elements
   for (int i = 0; i < subrange_list_1->n; i++) {
-    subrange_c *subrange_1 = dynamic_cast<subrange_c *>(subrange_list_1->elements[i]);
-    subrange_c *subrange_2 = dynamic_cast<subrange_c *>(subrange_list_2->elements[i]);
+    subrange_c *subrange_1 = dynamic_cast<subrange_c *>(subrange_list_1->get_element(i));
+    subrange_c *subrange_2 = dynamic_cast<subrange_c *>(subrange_list_2->get_element(i));
     if ((NULL == subrange_1) || (NULL == subrange_2)) ERROR;
     
     /* check whether the subranges have the same values, using the result of the constant folding agorithm.
--- a/absyntax_utils/search_base_type.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/search_base_type.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -255,7 +255,7 @@
 }
 
 /*  signed_integer DOTDOT signed_integer */
-void *search_base_type_c::visit(subrange_c *symbol)                                     {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(subrange_c *symbol)                           {ERROR; return NULL;} /* should never get called... */
 
 /*  enumerated_type_name ':' enumerated_spec_init */
 void *search_base_type_c::visit(enumerated_type_declaration_c *symbol) {
@@ -293,7 +293,7 @@
 
 /* enumerated_type_name '#' identifier */
 // SYM_REF2(enumerated_value_c, type, value)
-void *search_base_type_c::visit(enumerated_value_c *symbol)                             {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(enumerated_value_c *symbol)                   {ERROR; return NULL;} /* should never get called... */
 
 /*  identifier ':' array_spec_init */
 void *search_base_type_c::visit(array_type_declaration_c *symbol) {
@@ -312,20 +312,20 @@
 }
 
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
-void *search_base_type_c::visit(array_specification_c *symbol)                          {return (void *)symbol;}
+void *search_base_type_c::visit(array_specification_c *symbol)                {return (void *)symbol;}
 
 /* helper symbol for array_specification */
 /* array_subrange_list ',' subrange */
-void *search_base_type_c::visit(array_subrange_list_c *symbol)                          {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(array_subrange_list_c *symbol)                {ERROR; return NULL;} /* should never get called... */
 
 /* array_initialization:  '[' array_initial_elements_list ']' */
 /* helper symbol for array_initialization */
 /* array_initial_elements_list ',' array_initial_elements */
-void *search_base_type_c::visit(array_initial_elements_list_c *symbol)                  {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(array_initial_elements_list_c *symbol)        {ERROR; return NULL;} /* should never get called... */
 
 /* integer '(' [array_initial_element] ')' */
 /* array_initial_element may be NULL ! */
-void *search_base_type_c::visit(array_initial_elements_c *symbol)                       {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(array_initial_elements_c *symbol)             {ERROR; return NULL;} /* should never get called... */
 
 /*  structure_type_name ':' structure_specification */
 /* NOTE: structure_specification will point to either a
@@ -339,31 +339,27 @@
 }
 
 /*  var1_list ':' structure_type_name */
-void *search_base_type_c::visit(structured_var_declaration_c *symbol) {
-	return symbol;
-}
+void *search_base_type_c::visit(structured_var_declaration_c *symbol)         {return symbol;}
 
 /* structure_type_name ASSIGN structure_initialization */
 /* structure_initialization may be NULL ! */
-void *search_base_type_c::visit(initialized_structure_c *symbol)	{
-  return symbol->structure_type_name->accept(*this);
-}
+void *search_base_type_c::visit(initialized_structure_c *symbol)              {return symbol->structure_type_name->accept(*this);}
 
 /* helper symbol for structure_declaration */
 /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
 /* structure_element_declaration_list structure_element_declaration ';' */
-void *search_base_type_c::visit(structure_element_declaration_list_c *symbol)           {return (void *)symbol;}
+void *search_base_type_c::visit(structure_element_declaration_list_c *symbol) {return (void *)symbol;}
 
 /*  structure_element_name ':' *_spec_init */
-void *search_base_type_c::visit(structure_element_declaration_c *symbol)                {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(structure_element_declaration_c *symbol)      {return symbol->spec_init->accept(*this);}
 
 /* helper symbol for structure_initialization */
 /* structure_initialization: '(' structure_element_initialization_list ')' */
 /* structure_element_initialization_list ',' structure_element_initialization */
-void *search_base_type_c::visit(structure_element_initialization_list_c *symbol)        {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(structure_element_initialization_list_c *symbol) {ERROR; return NULL;} /* should never get called... */
 
 /*  structure_element_name ASSIGN value */
-void *search_base_type_c::visit(structure_element_initialization_c *symbol)             {ERROR; return NULL;} /* should never get called... */
+void *search_base_type_c::visit(structure_element_initialization_c *symbol)   {ERROR; return NULL;} /* should never get called... */
 
 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
 /*
@@ -372,7 +368,7 @@
 					string_type_declaration_size,
 					string_type_declaration_init) // may be == NULL!
 */
-void *search_base_type_c::visit(string_type_declaration_c *symbol)                      {return (void *)symbol;}
+void *search_base_type_c::visit(string_type_declaration_c *symbol)            {return (void *)symbol;}
 
 
 /*  function_block_type_name ASSIGN structure_initialization */
@@ -386,15 +382,13 @@
 
 /* ref_spec:  REF_TO (non_generic_type_name | function_block_type_name) */
 // SYM_REF1(ref_spec_c, type_name)
-void *search_base_type_c::visit(ref_spec_c *symbol)                                     {return (void *)symbol;}
+void *search_base_type_c::visit(ref_spec_c *symbol)                           {return (void *)symbol;}
 
 /* For the moment, we do not support initialising reference data types */
 /* ref_spec_init: ref_spec [ ASSIGN ref_initialization ]; */ 
 /* NOTE: ref_initialization may be NULL!! */
 // SYM_REF2(ref_spec_init_c, ref_spec, ref_initialization)
-void *search_base_type_c::visit(ref_spec_init_c *symbol) {
-  return symbol->ref_spec->accept(*this);
-}
+void *search_base_type_c::visit(ref_spec_init_c *symbol)                      {return symbol->ref_spec->accept(*this);}
 
 /* ref_type_decl: identifier ':' ref_spec_init */
 // SYM_REF2(ref_type_decl_c, ref_type_name, ref_spec_init)
@@ -410,9 +404,7 @@
 /*****************************/
 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
-void *search_base_type_c::visit(function_block_declaration_c *symbol)                   {
-	return (void *)symbol;
-}
+void *search_base_type_c::visit(function_block_declaration_c *symbol)         {return (void *)symbol;}
 
 
 
--- a/absyntax_utils/search_fb_instance_decl.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/search_fb_instance_decl.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -95,7 +95,7 @@
 void *search_fb_instance_decl_c::visit(fb_name_list_c *symbol) {
   list_c *list = symbol;
   for(int i = 0; i < list->n; i++) {
-    if (compare_identifiers(list->elements[i], search_name) == 0)
+    if (compare_identifiers(list->get_element(i), search_name) == 0)
   /* by now, current_fb_declaration should be != NULL */
       return current_fb_type_name;
   }
--- a/absyntax_utils/search_var_instance_decl.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/search_var_instance_decl.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -313,7 +313,7 @@
 void *search_var_instance_decl_c::visit(var1_list_c *symbol) {
   list_c *list = symbol;
   for(int i = 0; i < list->n; i++) {
-    if (compare_identifiers(list->elements[i], search_name) == 0)
+    if (compare_identifiers(list->get_element(i), search_name) == 0)
    /* by now, current_type_decl should be != NULL */
       return current_type_decl;
   }
@@ -335,7 +335,7 @@
 void *search_var_instance_decl_c::visit(fb_name_list_c *symbol) {
   list_c *list = symbol;
   for(int i = 0; i < list->n; i++) {
-    if (compare_identifiers(list->elements[i], search_name) == 0)
+    if (compare_identifiers(list->get_element(i), search_name) == 0)
     /* by now, current_fb_declaration should be != NULL */
       return current_type_decl;
   }
@@ -409,7 +409,7 @@
 void *search_var_instance_decl_c::visit(global_var_list_c *symbol) {
   list_c *list = symbol;
   for(int i = 0; i < list->n; i++) {
-    if (compare_identifiers(list->elements[i], search_name) == 0)
+    if (compare_identifiers(list->get_element(i), search_name) == 0)
       /* by now, current_type_decl should be != NULL */
       return current_type_decl;
   }
--- a/absyntax_utils/search_varfb_instance_type.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/search_varfb_instance_type.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -244,7 +244,7 @@
 
   /* now search the structure declaration */
   for(int i = 0; i < symbol->n; i++) {
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
   }
 
   return NULL;
--- a/absyntax_utils/type_initial_value.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/absyntax_utils/type_initial_value.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -224,7 +224,7 @@
   /* stage1_2 never creates an enumerated_value_list_c with no entries. If this occurs, then something must have changed! */
   if (symbol->n <= 0) ERROR;
  /* if no initial value explicitly given, then use the lowest value of the subrange */
-  return (void *)symbol->elements[0];
+  return (void *)symbol->get_element(0);
 }
 /* enumerated_type_name '#' identifier */
 // SYM_REF2(enumerated_value_c, type, value)
--- a/stage1_2/create_enumtype_conversion_functions.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage1_2/create_enumtype_conversion_functions.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -119,7 +119,7 @@
     currentTokenList.clear();
     list = (list_c *)symbol;
     for (int i = 0; i < list->n; i++) {
-        list->elements[i]->accept(*this);
+        list->get_element(i)->accept(*this);
         currentTokenList.push_back(currentToken);
     }
 
--- a/stage1_2/iec_bison.yy	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage1_2/iec_bison.yy	Sun Apr 16 08:46:58 2017 +0100
@@ -119,7 +119,7 @@
 #define FOR_EACH_ELEMENT(elem, list, code) {		\
   symbol_c *elem;					\
   for(int i = 0; i < list->n; i++) {			\
-    elem = list->elements[i];				\
+    elem = list->get_element(i);			\
     code;						\
   }							\
 }
@@ -3213,15 +3213,15 @@
 
 structure_element_declaration:
   structure_element_name ':' simple_spec_init
-	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
+	{$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;}
 | structure_element_name ':' subrange_spec_init
-	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
+	{$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;}
 | structure_element_name ':' enumerated_spec_init
-	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
+	{$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;}
 | structure_element_name ':' array_spec_init
-	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
+	{$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;}
 | structure_element_name ':' initialized_structure
-	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
+	{$$ = new structure_element_declaration_c($1, $3, locloc(@$)); $$->token = $1->token;}
 | structure_element_name ':' ref_spec_init                              /* non standard extension: Allow use of struct elements storing REF_TO datatypes (either using REF_TO or a previosuly declared ref type) */
 	{ $$ = new structure_element_declaration_c($1, $3, locloc(@$));
 	  if (!allow_ref_to_in_derived_datatypes) {
--- a/stage3/array_range_check.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/array_range_check.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -133,38 +133,38 @@
       return;
 
     /* Check lower limit */
-    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit))
-      if ( GET_CVALUE( int64, l->elements[i]) < GET_CVALUE( int64, dimension->lower_limit) )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRId64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)); continue;}
-
-    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit))
-      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->elements[i])) > 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRIu64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
-
-    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit))
-      if ( GET_CVALUE(uint64, l->elements[i])   <  GET_CVALUE(uint64, dimension->lower_limit))
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRIu64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
-
-    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit))
-      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRId64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)); continue;}
+    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
+      if ( GET_CVALUE( int64, l->get_element(i)) < GET_CVALUE( int64, dimension->lower_limit) )
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
+
+    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
+      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->get_element(i))) > 0 )
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be >= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
+
+    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->lower_limit))
+      if ( GET_CVALUE(uint64, l->get_element(i))   <  GET_CVALUE(uint64, dimension->lower_limit))
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->lower_limit)); continue;}
+
+    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->lower_limit))
+      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be >= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->lower_limit)); continue;}
 
     /* Repeat the same check, now for upper limit */
-    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit))
-      if ( GET_CVALUE( int64, l->elements[i])   >  GET_CVALUE( int64, dimension->upper_limit))
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRId64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)); continue;}
-
-    if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit))
-      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->elements[i])) < 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRIu64").", GET_CVALUE( int64, l->elements[i]), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
-
-    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit))
-      if ( GET_CVALUE(uint64, l->elements[i])   >  GET_CVALUE(uint64, dimension->upper_limit))
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRIu64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
+    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
+      if ( GET_CVALUE( int64, l->get_element(i))   >  GET_CVALUE( int64, dimension->upper_limit))
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRId64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
+
+    if ( VALID_CVALUE( int64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
+      if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->get_element(i))) < 0 )
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRId64", should be <= %"PRIu64").", GET_CVALUE( int64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
+
+    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE(uint64, dimension->upper_limit))
+      if ( GET_CVALUE(uint64, l->get_element(i))   >  GET_CVALUE(uint64, dimension->upper_limit))
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRIu64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE(uint64, dimension->upper_limit)); continue;}
       
-    if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit))
-      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRId64").", GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)); continue;}
+    if ( VALID_CVALUE(uint64, l->get_element(i)) && VALID_CVALUE( int64, dimension->upper_limit))
+      if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (using constant value of %"PRIu64", should be <= %"PRId64").", GET_CVALUE(uint64, l->get_element(i)), GET_CVALUE( int64, dimension->upper_limit)); continue;}
       
   }
 }
--- a/stage3/case_elements_check.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/case_elements_check.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -242,7 +242,7 @@
 // SYM_LIST(case_list_c)
 void *case_elements_check_c::visit(case_list_c *symbol) {
   for (int i = 0; i < symbol->n; i++)
-    case_elements_list.push_back(symbol->elements[i]);
+    case_elements_list.push_back(symbol->get_element(i));
   return NULL;
 }
 
--- a/stage3/constant_folding.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/constant_folding.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -1038,7 +1038,7 @@
    */
   if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to!
   if  (NULL != symbol->il_operand)
-    symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->elements[0]->const_value;
+    symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->get_element(0)->const_value;
 
   return NULL;
 }
@@ -1089,10 +1089,10 @@
     return NULL;  /* List is empty! Nothing to do. */
     
   for(int i = 0; i < symbol->n; i++)
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
 
   /* This object has (inherits) the same cvalues as the il_jump_operator */
-  symbol->const_value = symbol->elements[symbol->n-1]->const_value;
+  symbol->const_value = symbol->get_element(symbol->n-1)->const_value;
   return NULL;
 }
 
@@ -1367,8 +1367,8 @@
   
   for (i = 0; i < symbol->n; i++) {
     // first analyse the configurations
-    if (NULL != dynamic_cast<configuration_declaration_c *>(symbol->elements[i]))
-      symbol->elements[i]->accept(*this);
+    if (NULL != dynamic_cast<configuration_declaration_c *>(symbol->get_element(i)))
+      symbol->get_element(i)->accept(*this);
   }
 
   for (i = 0; i < symbol->n; i++) {
@@ -1377,8 +1377,8 @@
      *       loop. However, this is OK as the only difference would be how the VAR_EXTERN are handled,
      *       and that is taken care of in the visit(external_declaration_c) visitor!
      */
-    if (NULL == dynamic_cast<configuration_declaration_c *>(symbol->elements[i]))
-      symbol->elements[i]->accept(*this);
+    if (NULL == dynamic_cast<configuration_declaration_c *>(symbol->get_element(i)))
+      symbol->get_element(i)->accept(*this);
   }
   
   return NULL;
@@ -1465,14 +1465,14 @@
   list_c *list = dynamic_cast<list_c *>(var_list);
   if (NULL == list) ERROR;
   for (int i = 0; i < list->n; i++) {
-    token_c *var_name = dynamic_cast<token_c *>(list->elements[i]);
+    token_c *var_name = dynamic_cast<token_c *>(list->get_element(i));
     if (NULL == var_name) {
-      if (NULL != dynamic_cast<extensible_input_parameter_c *>(list->elements[i]))
+      if (NULL != dynamic_cast<extensible_input_parameter_c *>(list->get_element(i)))
         continue; // this is an extensible standard function. Ignore this variable, and continue!
-      // debug_c::print(list->elements[i]);
+      // debug_c::print(list->get_element(i));
       ERROR;
     }
-    list->elements[i]->const_value = init_value->const_value;
+    list->get_element(i)->const_value = init_value->const_value;
     if (fixed_init_value_) {
       (*values)[var_name->value] = init_value->const_value;
       if (is_global_var)
--- a/stage3/fill_candidate_datatypes.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/fill_candidate_datatypes.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -958,7 +958,15 @@
 	type_spec->accept(*this);
 	
 	// use bottom->up algorithm!!
-	if (NULL != init_value) init_value->accept(*this);  
+	/* NOTE: In special cases we will run a modified bottom->up algorithm, i.e. with a top->down indication of 
+	 *       tentative candidate_datatypes... 
+	 *       (e.g. structure_element_initialization_list_c). The tentative candidate_datatypes (a list of
+	 *       candidate_datatypes to consider while running the bottom->up algorithm) will actually be the
+	 *       datatypes in symbol->parent->candidate_datatpes
+	 *       This implies that we can only run this bottom->up algorithm on the initial values _after_
+	 *       having set the symbol->candidate_datatpes of the type specification (i.e. the symbol parameter)
+	 */
+	if (NULL != init_value)  init_value->accept(*this);
 	/* NOTE: Even if the constant and the type are of incompatible data types, we let the
 	 *       ***_spec_init_c object inherit the data type of the type declaration (simple_specification)
 	 *       This will let us produce more informative error messages when checking data type compatibility
@@ -1036,7 +1044,7 @@
   
   /* We already know the datatype of the enumerated_value(s) in the list, so we set them directly instead of recursively calling the enumerated_value_c visit method! */
   for(int i = 0; i < symbol->n; i++)
-    add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); // top->down algorithm!!
+    add_datatype_to_candidate_list(symbol->get_element(i), current_enumerated_spec_type); // top->down algorithm!!
 
   return NULL;  
 }
@@ -1163,9 +1171,56 @@
 /* structure_initialization: '(' structure_element_initialization_list ')' */
 /* structure_element_initialization_list ',' structure_element_initialization */
 // SYM_LIST(structure_element_initialization_list_c)
+void *fill_candidate_datatypes_c::visit(structure_element_initialization_list_c *symbol) {
+	// use bottom->up algorithm -> first let all elements determine their candidate_datatypes
+	iterator_visitor_c::visit(symbol); // call visit(structure_element_initialization_c *) on all elements
+
+	for (unsigned int i = 0; i < symbol->parent->candidate_datatypes.size(); i++) { // size() should always be 1 here -> a single structure or FB type!
+		// assume symbol->parent->candidate_datatypes[i] is a FB type
+		search_varfb_instance_type_c search_varfb_instance_type(symbol->parent->candidate_datatypes[i]);
+		// assume symbol->parent->candidate_datatypes[i] is a STRUCT data type
+		structure_element_declaration_list_c *struct_decl = dynamic_cast<structure_element_declaration_list_c *>(symbol->parent->candidate_datatypes[i]);
+		// flag indicating all struct_elem->structure_element_name are structure elements found in the symbol->parent->candidate_datatypes[i] datatype
+		int flag_all_elem_ok = 1; // assume all found
+		for (int k = 0; k < symbol->n; k++) {
+			structure_element_initialization_c *struct_elem = dynamic_cast<structure_element_initialization_c *>(symbol->get_element(k));
+			if (struct_elem == NULL) ERROR;
+			
+			// assume symbol->parent is a FB type...
+			symbol_c *type = NULL;
+			if (struct_decl != NULL) {
+				// search in the struct!!
+				type = search_base_type_c::get_basetype_decl(struct_decl->find_element(struct_elem->structure_element_name));
+			} else {
+				// parent is a FB type. Lets search there!!
+				type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name);
+			}
+			if (!get_datatype_info_c::is_ANY_ELEMENTARY(type) && get_datatype_info_c::is_type_valid(type)) {
+				// for non-elementary datatypes, we must use a top->down algorithm!!
+				add_datatype_to_candidate_list(struct_elem, type); 
+				struct_elem->accept(*this);
+			}
+			if (search_in_candidate_datatype_list(type, struct_elem->candidate_datatypes) < 0) {
+				flag_all_elem_ok = 0; // the necessary datatype for structure init element is not a candidate_datatype of that element
+			}
+		}
+		if (flag_all_elem_ok) {
+			add_datatype_to_candidate_list(symbol, symbol->parent->candidate_datatypes[i]);
+		}
+	}
+	return NULL;
+}
+
 
 /*  structure_element_name ASSIGN value */
 // SYM_REF2(structure_element_initialization_c, structure_element_name, value)
+void *fill_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) {
+	symbol->value->accept(*this);
+	symbol->candidate_datatypes = symbol->value->candidate_datatypes;
+	// Note that candidate_datatypes of symbol->structure_element_name are left empty!
+	return NULL;
+}
+
 
 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
 // SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) 
@@ -1369,7 +1424,7 @@
 
 // NOTE: this method is not required since fill_candidate_datatypes_c inherits from iterator_visitor_c. TODO: delete this method!
 void *fill_candidate_datatypes_c::visit(var1_list_c *symbol) {
-  for(int i = 0; i < symbol->n; i++) {symbol->elements[i]->accept(*this);}
+  for(int i = 0; i < symbol->n; i++) {symbol->get_element(i)->accept(*this);}
   return NULL;
 }  
 
@@ -1648,7 +1703,7 @@
 	 */
 	for(int j = 0; j < 2; j++) {
 		for(int i = 0; i < symbol->n; i++) {
-			symbol->elements[i]->accept(*this);
+			symbol->get_element(i)->accept(*this);
 		}
 	}
 	return NULL;
@@ -1763,7 +1818,7 @@
    */
   if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to!
   if  (NULL != symbol->il_operand)
-    symbol->il_operand->candidate_datatypes = ((list_c *)symbol->simple_instr_list)->elements[0]->candidate_datatypes;
+    symbol->il_operand->candidate_datatypes = ((list_c *)symbol->simple_instr_list)->get_element(0)->candidate_datatypes;
   
   /* Now check the if the data type semantics of operation are correct,  */
   il_operand = symbol->simple_instr_list;
@@ -1860,10 +1915,10 @@
     return NULL;  /* List is empty! Nothing to do. */
     
   for(int i = 0; i < symbol->n; i++)
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
 
   /* This object has (inherits) the same candidate datatypes as the last il_instruction */
-  symbol->candidate_datatypes = symbol->elements[symbol->n-1]->candidate_datatypes;
+  symbol->candidate_datatypes = symbol->get_element(symbol->n-1)->candidate_datatypes;
   
   if (debug) std::cout << "simple_instr_list_c [" << symbol->candidate_datatypes.size() << "] result.\n";
   return NULL;
--- a/stage3/fill_candidate_datatypes.hh	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/fill_candidate_datatypes.hh	Sun Apr 16 08:46:58 2017 +0100
@@ -211,8 +211,8 @@
     void *visit(initialized_structure_c *symbol);
 //  void *visit(structure_element_declaration_list_c *symbol);
 //  void *visit(structure_element_declaration_c *symbol);
-//  void *visit(structure_element_initialization_list_c *symbol);
-//  void *visit(structure_element_initialization_c *symbol);
+    void *visit(structure_element_initialization_list_c *symbol);
+    void *visit(structure_element_initialization_c *symbol);
 //  void *visit(string_type_declaration_c *symbol);
     void *visit(fb_spec_init_c *symbol);
       
--- a/stage3/flow_control_analysis.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/flow_control_analysis.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -218,8 +218,8 @@
 	prev_il_instruction_is_JMP_or_RET = false;
 	for(int i = 0; i < symbol->n; i++) {
 		prev_il_instruction = NULL;
-		if (i > 0) prev_il_instruction = symbol->elements[i-1];
-		curr_il_instruction = symbol->elements[i];
+		if (i > 0) prev_il_instruction = symbol->get_element(i-1);
+		curr_il_instruction = symbol->get_element(i);
 		curr_il_instruction->accept(*this);
 		curr_il_instruction = NULL;
 	}
@@ -310,8 +310,8 @@
 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
 	for(int i = 0; i < symbol->n; i++) {
 		/* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */
-		if (i>0) prev_il_instruction = symbol->elements[i-1];
-		symbol->elements[i]->accept(*this);
+		if (i>0) prev_il_instruction = symbol->get_element(i-1);
+		symbol->get_element(i)->accept(*this);
 	}
 	return NULL;
 }
--- a/stage3/forced_narrow_candidate_datatypes.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/forced_narrow_candidate_datatypes.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -161,7 +161,7 @@
 void *forced_narrow_candidate_datatypes_c::visit(instruction_list_c *symbol) {
   for(int j = 0; j < 2; j++) {
     for(int i = symbol->n-1; i >= 0; i--) {
-      symbol->elements[i]->accept(*this);
+      symbol->get_element(i)->accept(*this);
     }
   }
 
@@ -171,7 +171,7 @@
    */
   /*
   for(int i = symbol->n-1; i >= 0; i--) {
-    if (NULL == symbol->elements[i]->datatype)
+    if (NULL == symbol->get_element(i)->datatype)
       ERROR;
   }
   */
--- a/stage3/narrow_candidate_datatypes.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/narrow_candidate_datatypes.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -609,8 +609,8 @@
 // SYM_LIST(enumerated_value_list_c)
 void *narrow_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) {
 //if (NULL == symbol->datatype) ERROR;  // Comented out-> Reserve this check for the print_datatypes_error_c ???  
-  for(int i = 0; i < symbol->n; i++) set_datatype(symbol->datatype, symbol->elements[i]);
-//for(int i = 0; i < symbol->n; i++) if (NULL == symbol->elements[i]->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ???  
+  for(int i = 0; i < symbol->n; i++) set_datatype(symbol->datatype, symbol->get_element(i));
+//for(int i = 0; i < symbol->n; i++) if (NULL == symbol->get_element(i)->datatype) ERROR; // Comented out-> Reserve this check for the print_datatypes_error_c ???  
   return NULL;  
 }
 
@@ -672,11 +672,45 @@
 /* structure_initialization: '(' structure_element_initialization_list ')' */
 /* structure_element_initialization_list ',' structure_element_initialization */
 // SYM_LIST(structure_element_initialization_list_c)
-// Not needed ???
+void *narrow_candidate_datatypes_c::visit(structure_element_initialization_list_c *symbol) {
+	symbol_c *type = NULL;
+
+	 // first try to narrow with the correct type, if valid.
+	if (!get_datatype_info_c::is_type_valid(type)) type = symbol->datatype;
+	 // to reduce number of error messages, we try to narrow with parent's spec_init->datatype
+	if (!get_datatype_info_c::is_type_valid(type)) type = symbol->parent->datatype;
+
+	if (get_datatype_info_c::is_type_valid(type)) {
+		// We need to iterate and determine the required datatype of each structure element
+		// assume type is a FB type
+		search_varfb_instance_type_c search_varfb_instance_type(type);
+		// assume type is a STRUCT type
+		structure_element_declaration_list_c *struct_decl = dynamic_cast<structure_element_declaration_list_c *>(type);
+		for (int k = 0; k < symbol->n; k++) {
+			structure_element_initialization_c *struct_elem = (structure_element_initialization_c *)symbol->get_element(k);
+			symbol_c *type = NULL;
+			if (struct_decl == NULL) {
+				// type is not a struct. Must be a FB.
+				type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name);
+			} else {
+				// type is a struct.
+				type = search_base_type_c::get_basetype_decl(struct_decl->find_element(struct_elem->structure_element_name));
+			}
+			set_datatype(type, struct_elem);
+			struct_elem->accept(*this);
+			/* We do best effort narrowing, even in the presence of errors, to reduce number of error messages
+			 * so the following two assertions are not always met.
+			 */
+			// if (!get_datatype_info_c::is_type_valid(type)) ERROR;  
+			// if (struct_elem->datatype == NULL) ERROR; // should never occur. Already checked in fill_candidate_datatypes_c
+		}
+	}
+	return NULL;
+}
 
 /*  structure_element_name ASSIGN value */
 // SYM_REF2(structure_element_initialization_c, structure_element_name, value)
-// Not needed ???
+void *narrow_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) {set_datatype(symbol->datatype, symbol->value); symbol->value->accept(*this); return NULL;}
 
 /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
 // SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) 
@@ -754,11 +788,11 @@
 // SYM_LIST(subscript_list_c)
 void *narrow_candidate_datatypes_c::visit(subscript_list_c *symbol) {
 	for (int i = 0; i < symbol->n; i++) {
-		for (unsigned int k = 0; k < symbol->elements[i]->candidate_datatypes.size(); k++) {
-			if (get_datatype_info_c::is_ANY_INT(symbol->elements[i]->candidate_datatypes[k]))
-				symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[k];
+		for (unsigned int k = 0; k < symbol->get_element(i)->candidate_datatypes.size(); k++) {
+			if (get_datatype_info_c::is_ANY_INT(symbol->get_element(i)->candidate_datatypes[k]))
+				symbol->get_element(i)->datatype = symbol->get_element(i)->candidate_datatypes[k];
 		}
-		symbol->elements[i]->accept(*this);
+		symbol->get_element(i)->accept(*this);
 	}
 	return NULL;  
 }
@@ -828,8 +862,8 @@
 void *narrow_candidate_datatypes_c::visit(var1_list_c *symbol) {
 #if 0   /* We don't really need to set the datatype of each variable. We just check the declaration itself! */
   for(int i = 0; i < symbol->n; i++) {
-    if (symbol->elements[i]->candidate_datatypes.size() == 1)
-      symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[0];
+    if (symbol->get_element(i)->candidate_datatypes.size() == 1)
+      symbol->get_element(i)->datatype = symbol->get_element(i)->candidate_datatypes[0];
   }
 #endif
   return NULL;
@@ -1008,7 +1042,7 @@
 	 */
 	for(int j = 0; j < 2; j++) {
 		for(int i = symbol->n-1; i >= 0; i--) {
-			symbol->elements[i]->accept(*this);
+			symbol->get_element(i)->accept(*this);
 		}
 	}
 	return NULL;
@@ -1123,7 +1157,7 @@
    */
   if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to!
   if  (NULL != symbol->il_operand)
-    symbol->il_operand->datatype = ((list_c *)symbol->simple_instr_list)->elements[0]->datatype;
+    symbol->il_operand->datatype = ((list_c *)symbol->simple_instr_list)->get_element(0)->datatype;
   
   return NULL;
 }
@@ -1195,10 +1229,10 @@
 /* This object is referenced by il_expression_c objects */
 void *narrow_candidate_datatypes_c::visit(simple_instr_list_c *symbol) {
 	if (symbol->n > 0)
-		symbol->elements[symbol->n - 1]->datatype = symbol->datatype;
+		symbol->get_element(symbol->n - 1)->datatype = symbol->datatype;
 
 	for(int i = symbol->n-1; i >= 0; i--) {
-		symbol->elements[i]->accept(*this);
+		symbol->get_element(i)->accept(*this);
 	}
 	return NULL;
 }
@@ -1730,8 +1764,8 @@
 // SYM_LIST(case_element_list_c)
 void *narrow_candidate_datatypes_c::visit(case_element_list_c *symbol) {
 	for (int i = 0; i < symbol->n; i++) {
-		symbol->elements[i]->datatype = symbol->datatype;
-		symbol->elements[i]->accept(*this);
+		symbol->get_element(i)->datatype = symbol->datatype;
+		symbol->get_element(i)->accept(*this);
 	}
 	return NULL;
 }
@@ -1748,12 +1782,12 @@
 // SYM_LIST(case_list_c)
 void *narrow_candidate_datatypes_c::visit(case_list_c *symbol) {
 	for (int i = 0; i < symbol->n; i++) {
-		for (unsigned int k = 0; k < symbol->elements[i]->candidate_datatypes.size(); k++) {
-			if (get_datatype_info_c::is_type_equal(symbol->datatype, symbol->elements[i]->candidate_datatypes[k]))
-				symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[k];
+		for (unsigned int k = 0; k < symbol->get_element(i)->candidate_datatypes.size(); k++) {
+			if (get_datatype_info_c::is_type_equal(symbol->datatype, symbol->get_element(i)->candidate_datatypes[k]))
+				symbol->get_element(i)->datatype = symbol->get_element(i)->candidate_datatypes[k];
 		}
 		/* NOTE: this may be an integer, a subrange_c, or a enumerated value! */
-		symbol->elements[i]->accept(*this);
+		symbol->get_element(i)->accept(*this);
 	}
 	return NULL;
 }
--- a/stage3/narrow_candidate_datatypes.hh	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/narrow_candidate_datatypes.hh	Sun Apr 16 08:46:58 2017 +0100
@@ -185,8 +185,8 @@
     void *visit(initialized_structure_c *symbol);
 //  void *visit(structure_element_declaration_list_c *symbol);
 //  void *visit(structure_element_declaration_c *symbol);
-//  void *visit(structure_element_initialization_list_c *symbol);
-//  void *visit(structure_element_initialization_c *symbol);
+    void *visit(structure_element_initialization_list_c *symbol);
+    void *visit(structure_element_initialization_c *symbol);
 //  void *visit(string_type_declaration_c *symbol);
     void *visit(fb_spec_init_c *symbol);
       
--- a/stage3/print_datatypes_error.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/print_datatypes_error.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -545,6 +545,16 @@
 }
 
 
+
+void *print_datatypes_error_c::visit(structure_element_initialization_c *symbol) {
+	symbol->value->accept(*this);
+	if (!get_datatype_info_c::is_type_valid(symbol->datatype))
+		STAGE3_ERROR(0, symbol, symbol, "Initialization element identifier (%s) is not declared in referenced structure/FB scope, or is set to value of incompatible datatype.", 
+			                        symbol->structure_element_name->token->value);
+	return NULL;
+}
+
+    
 /*********************/
 /* B 1.4 - Variables */
 /*********************/
@@ -587,9 +597,9 @@
 void *print_datatypes_error_c::visit(subscript_list_c *symbol) {
 	for (int i = 0; i < symbol->n; i++) {
 		int start_error_count = error_count;
-		symbol->elements[i]->accept(*this);
+		symbol->get_element(i)->accept(*this);
 		/* The following error message will only get printed if the current_display_error_level is set higher than 0! */
-		if ((start_error_count == error_count) && (!get_datatype_info_c::is_type_valid(symbol->elements[i]->datatype)))
+		if ((start_error_count == error_count) && (!get_datatype_info_c::is_type_valid(symbol->get_element(i)->datatype)))
 			STAGE3_ERROR(0, symbol, symbol, "Invalid data type for array subscript field.");
 	}
 	return NULL;
--- a/stage3/print_datatypes_error.hh	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/print_datatypes_error.hh	Sun Apr 16 08:46:58 2017 +0100
@@ -161,6 +161,8 @@
     void *visit(simple_spec_init_c *symbol);
 //  void *visit(data_type_declaration_c *symbol); /* use base iterator_c method! */
     void *visit(enumerated_value_c *symbol);
+//  void *visit(structure_element_initialization_list_c *symbol);
+    void *visit(structure_element_initialization_c *symbol);
 
     /*********************/
     /* B 1.4 - Variables */
--- a/stage3/remove_forward_dependencies.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage3/remove_forward_dependencies.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -209,10 +209,10 @@
   /* Note too that circular references in derived datatypes is also not possible due to sytax!                                        */
   int initial_error_count = error_count;
   for (int i = 0; i < symbol->n; i++) 
-    if (   (inserted_symbols.find(symbol->elements[i]) == inserted_symbols.end())            // if not copied to new AST
-        &&(  (NULL != dynamic_cast <function_block_declaration_c *>(symbol->elements[i]))    // and (is a FB  
-           ||(NULL != dynamic_cast <      function_declaration_c *>(symbol->elements[i]))))  //      or a Function)
-      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]));
+    if (   (inserted_symbols.find(symbol->get_element(i)) == inserted_symbols.end())            // if not copied to new AST
+        &&(  (NULL != dynamic_cast <function_block_declaration_c *>(symbol->get_element(i)))    // and (is a FB  
+           ||(NULL != dynamic_cast <      function_declaration_c *>(symbol->get_element(i)))))  //      or a Function)
+      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)));
   if (error_count == initial_error_count) ERROR; // We were unable to determine which POUs contain the circular references!!
 }
 
@@ -228,8 +228,8 @@
   /* first insert all the derived datatype declarations, in the same order by which they are delcared in the original AST */
   /* 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! */
   for (int i = 0; i < symbol->n; i++) 
-    if (NULL != dynamic_cast <data_type_declaration_c *>(symbol->elements[i]))
-      new_tree->add_element(symbol->elements[i]);  
+    if (NULL != dynamic_cast <data_type_declaration_c *>(symbol->get_element(i)))
+      new_tree->add_element(symbol->get_element(i));  
 
   /* now do the POUs, in whatever order is necessary to guarantee no forward references. */    
   long long int old_tree_pou_count = pou_count_c::get_count(symbol);
@@ -241,7 +241,7 @@
     cycle_count++;
     prev_n = new_tree->n;
     current_code_generation_pragma = default_code_generation_pragma;
-    for (int i = 0; i < symbol->n; i++)  symbol->elements[i]->accept(*this);
+    for (int i = 0; i < symbol->n; i++)  symbol->get_element(i)->accept(*this);
   } while (prev_n != new_tree->n); // repeat while new elementns are still being added to the new AST
   
   if (old_tree_pou_count != pou_count_c::get_count(new_tree)) 
--- a/stage4/generate_c/generate_c.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -2191,7 +2191,7 @@
       pous_incl_s4o.print("#include \"accessor.h\"\n#include \"iec_std_lib.h\"\n\n");
 
       for(int i = 0; i < symbol->n; i++) {
-        symbol->elements[i]->accept(*this);
+        symbol->get_element(i)->accept(*this);
       }
 
       pous_incl_s4o.print("#endif //__POUS_H\n");
@@ -2229,8 +2229,8 @@
     /* 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_implicit_typedecl);
-        symbol->elements[i]->accept(generate_c_typedecl);
+        symbol->get_element(i)->accept(generate_c_implicit_typedecl);
+        symbol->get_element(i)->accept(generate_c_typedecl);
       }
       return NULL;
     }
--- a/stage4/generate_c/generate_c_base.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_base.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -201,13 +201,13 @@
       if (list->n > 0) {
 //std::cout << "generate_c_base_c::print_list(n = " << list->n << ")   000\n";
         s4o.print(pre_elem_str);
-        list->elements[0]->accept(*visitor);
+        list->get_element(0)->accept(*visitor);
       }
 
       for(int i = 1; i < list->n; i++) {
 //std::cout << "generate_c_base_c::print_list   " << i << "\n";
         s4o.print(inter_elem_str);
-        list->elements[i]->accept(*visitor);
+        list->get_element(i)->accept(*visitor);
       }
 
       if (list->n > 0)
--- a/stage4/generate_c/generate_c_il.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_il.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -661,7 +661,7 @@
     if (dimension == NULL) ERROR;
 
     s4o.print("[(");
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
     s4o.print(") - (");
     dimension->accept(*this);
     s4o.print(")]");
@@ -711,9 +711,9 @@
   declare_implicit_variable_back();
   
   for(int i = 0; i < symbol->n; i++) {
-    print_line_directive(symbol->elements[i]);
+    print_line_directive(symbol->get_element(i));
     s4o.print(s4o.indent_spaces);
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
     s4o.print(";\n");
   }
   return NULL;
--- a/stage4/generate_c/generate_c_sfc.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_sfc.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -443,7 +443,7 @@
           for(int i = 0; i < symbol->n; i++) {
             s4o.print(GET_VAR);
             s4o.print("(");
-            print_step_argument(symbol->elements[i], "X");
+            print_step_argument(symbol->get_element(i), "X");
             s4o.print(")");
             if (i < symbol->n - 1) {
               s4o.print(" && ");
@@ -452,12 +452,12 @@
           break;
         case stepset_sg:
           for(int i = 0; i < symbol->n; i++) {
-            print_set_step(symbol->elements[i]);
+            print_set_step(symbol->get_element(i));
           }
           break;
         case stepreset_sg:
           for(int i = 0; i < symbol->n; i++) {
-            print_reset_step(symbol->elements[i]);
+            print_reset_step(symbol->get_element(i));
           }
           break;
         default:
@@ -710,8 +710,8 @@
       
       generate_c_sfc_elements->reset_transition_number();
       for(i = 0; i < symbol->n; i++) {
-        symbol->elements[i]->accept(*this);
-        generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::transitionlist_sg);
+        symbol->get_element(i)->accept(*this);
+        generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::transitionlist_sg);
       }
       
       s4o.print(s4o.indent_spaces +"INT i;\n");
@@ -853,7 +853,7 @@
       s4o.print(s4o.indent_spaces + "// Transitions reset steps\n");
       generate_c_sfc_elements->reset_transition_number();
       for(i = 0; i < symbol->n; i++) {
-        generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::stepreset_sg);
+        generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::stepreset_sg);
       }
       s4o.print("\n");
       
@@ -861,14 +861,14 @@
       s4o.print(s4o.indent_spaces + "// Transitions set steps\n");
       generate_c_sfc_elements->reset_transition_number();
       for(i = 0; i < symbol->n; i++) {
-        generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::stepset_sg);
+        generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::stepset_sg);
       }
       s4o.print("\n");
       
       /* generate step association */
       s4o.print(s4o.indent_spaces + "// Steps association\n");
       for(i = 0; i < symbol->n; i++) {
-        generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::actionassociation_sg);
+        generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::actionassociation_sg);
       }
       s4o.print("\n");
       
@@ -967,7 +967,7 @@
         }
       }
       for(i = 0; i < symbol->n; i++) {
-        generate_c_sfc_elements->generate(symbol->elements[i], generate_c_sfc_elements_c::actionbody_sg);
+        generate_c_sfc_elements->generate(symbol->get_element(i), generate_c_sfc_elements_c::actionbody_sg);
       }
       s4o.print("\n");
       
--- a/stage4/generate_c/generate_c_sfcdecl.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_sfcdecl.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -85,7 +85,7 @@
       switch (wanted_sfcdeclaration) {
         case sfcdecl_sd:
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           
           /* steps table declaration */
           s4o.print(s4o.indent_spaces + "STEP __step_list[");
@@ -120,7 +120,7 @@
           /* steps table count */
           wanted_sfcdeclaration = stepcount_sd;
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           s4o.print(s4o.indent_spaces);
           print_variable_prefix();
           s4o.print("__nb_steps = ");
@@ -141,12 +141,12 @@
           s4o.indent_left();
           s4o.print(s4o.indent_spaces + "}\n");
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           
           /* actions table count */
           wanted_sfcdeclaration = actioncount_sd;
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           s4o.print(s4o.indent_spaces);
           print_variable_prefix();
           s4o.print("__nb_actions = ");
@@ -170,7 +170,7 @@
           /* transitions table count */
           wanted_sfcdeclaration = transitioncount_sd;
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           s4o.print(s4o.indent_spaces);
           print_variable_prefix();
           s4o.print("__nb_transitions = ");
@@ -187,7 +187,7 @@
         case stepdef_sd:
           s4o.print("// Steps definitions\n");
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           s4o.print("\n");
           break;
         case actiondef_sd:
@@ -196,12 +196,12 @@
             // first fill up the this->variable_list variable!
             wanted_sfcdeclaration = actioncount_sd;
             for(int i = 0; i < symbol->n; i++)
-               symbol->elements[i]->accept(*this);
+               symbol->get_element(i)->accept(*this);
             action_number = 0; // reset the counter!
             wanted_sfcdeclaration = actiondef_sd;
             // Now do the defines for actions!
             for(int i = 0; i < symbol->n; i++)
-              symbol->elements[i]->accept(*this);
+              symbol->get_element(i)->accept(*this);
             // Now do the defines for actions that reference a variable instead of an action block!
             std::list<VARIABLE>::iterator pt;
             for(pt = variable_list.begin(); pt != variable_list.end(); pt++) {
@@ -219,18 +219,18 @@
         case stepundef_sd:
           s4o.print("// Steps undefinitions\n");
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           s4o.print("\n");
           break;
         case actionundef_sd:
           s4o.print("// Actions undefinitions\n");
           for(int i = 0; i < symbol->n; i++)
-            symbol->elements[i]->accept(*this);
+            symbol->get_element(i)->accept(*this);
           {
             // first fill up the this->variable_list variable!
             wanted_sfcdeclaration = actioncount_sd;
             for(int i = 0; i < symbol->n; i++)
-               symbol->elements[i]->accept(*this);
+               symbol->get_element(i)->accept(*this);
             wanted_sfcdeclaration = actionundef_sd;
             std::list<VARIABLE>::iterator pt;
             for(pt = variable_list.begin(); pt != variable_list.end(); pt++) {
--- a/stage4/generate_c/generate_c_st.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -422,7 +422,7 @@
     if (dimension == NULL) ERROR;
 
     s4o.print("[(");
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
     s4o.print(") - (");
     dimension->accept(*this);
     s4o.print(")]");
@@ -925,9 +925,9 @@
 /********************/
 void *visit(statement_list_c *symbol) {
   for(int i = 0; i < symbol->n; i++) {
-    print_line_directive(symbol->elements[i]);
+    print_line_directive(symbol->get_element(i));
     s4o.print(s4o.indent_spaces);
-    symbol->elements[i]->accept(*this);
+    symbol->get_element(i)->accept(*this);
     s4o.print(";\n");
   }
   return NULL;
@@ -1213,10 +1213,10 @@
      */
     if (0 != i)  s4o.print(" ||\n" + s4o.indent_spaces + "         ");
     s4o.print("(");
-    subrange_c *subrange = dynamic_cast<subrange_c *>(symbol->elements[i]);
+    subrange_c *subrange = dynamic_cast<subrange_c *>(symbol->get_element(i));
     if (NULL == subrange) {
       s4o.print("__case_expression == ");
-      symbol->elements[i]->accept(*this);
+      symbol->get_element(i)->accept(*this);
     } else {
       s4o.print("__case_expression >= ");
       subrange->lower_limit->accept(*this);
--- a/stage4/generate_c/generate_c_typedecl.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_typedecl.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -178,7 +178,7 @@
     /* helper symbol for array_specification */
     /* array_subrange_list ',' subrange */
     void *visit(array_subrange_list_c *symbol) {
-      for(int i = 0; i < symbol->n; i++) {symbol->elements[i]->accept(*this);}
+      for(int i = 0; i < symbol->n; i++) {symbol->get_element(i)->accept(*this);}
       return NULL;
     }
 
@@ -295,12 +295,12 @@
 
       if (list->n > 0) {
         s4o_incl.print(pre_elem_str);
-        list->elements[0]->accept(*this);
+        list->get_element(0)->accept(*this);
       }
 
       for(int i = 1; i < list->n; i++) {
         s4o_incl.print(inter_elem_str);
-        list->elements[i]->accept(*this);
+        list->get_element(i)->accept(*this);
       }
 
       if (list->n > 0)
--- a/stage4/generate_c/generate_c_vardecl.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -168,7 +168,7 @@
         s4o.print("(");
         print_variable_prefix();
         s4o.print(",");
-        symbol->elements[i]->accept(*this);
+        symbol->get_element(i)->accept(*this);
         s4o.print(",,temp);\n");
       }
       return NULL;
@@ -249,14 +249,14 @@
                 ERROR;
               if (defined_values_count > 0)
                 s4o.print(",");
-              symbol->elements[i]->accept(*this);
+              symbol->get_element(i)->accept(*this);
               defined_values_count++;
             }
             else {
-              array_initial_elements_c *array_initial_element = dynamic_cast<array_initial_elements_c *>(symbol->elements[i]);
+              array_initial_elements_c *array_initial_element = dynamic_cast<array_initial_elements_c *>(symbol->get_element(i));
             
               if (array_initial_element != NULL) {
-                symbol->elements[i]->accept(*this);
+                symbol->get_element(i)->accept(*this);
               }
             }
             current_initialization_count++;
@@ -414,7 +414,7 @@
     void *visit(structure_element_declaration_list_c *symbol) {
       void *res;
       for (int i = 0; i < symbol->n; i++) {
-        res = symbol->elements[i]->accept(*this);
+        res = symbol->get_element(i)->accept(*this);
         if (res != NULL)
           return res;
       }
@@ -472,7 +472,7 @@
     void *visit(structure_element_initialization_list_c *symbol) {
       void *res;
       for (int i = 0; i < symbol->n; i++) {
-        res = symbol->elements[i]->accept(*this);
+        res = symbol->get_element(i)->accept(*this);
         if (res != NULL)
           return res;
       }
@@ -599,7 +599,7 @@
         s4o.print("(");
         print_variable_prefix();
         s4o.print(",");
-        symbol->elements[i]->accept(*this);
+        symbol->get_element(i)->accept(*this);
         s4o.print(",,temp);\n");
       }
       return NULL;
@@ -974,8 +974,13 @@
       if (NULL == init_list) ERROR;
       
       for (int i = 0; i < init_list->n; i++) {
-        structure_element_initialization_c *init_list_elem = dynamic_cast<structure_element_initialization_c *>(init_list->elements[i]);
+        structure_element_initialization_c *init_list_elem = dynamic_cast<structure_element_initialization_c *>(init_list->get_element(i));
         if (NULL == init_list_elem) ERROR;
+        if (!get_datatype_info_c::is_ANY_ELEMENTARY(init_list_elem->value->datatype)) {
+          STAGE4_ERROR(init_list_elem, init_list_elem, 
+                       "C code generation does not yet support initializing FB/structures with non-elementary values.");
+          ERROR;
+        }
         s4o.print("\n");
         s4o.print(s4o.indent_spaces);
         s4o.print(INIT_VAR);
@@ -1030,20 +1035,20 @@
             print_variable_prefix();
             s4o.print(",");
           }
-          list->elements[i]->accept(*this);
+          list->get_element(i)->accept(*this);
           if (wanted_varformat != local_vf) {
             if (wanted_varformat == localinit_vf &&
                 (current_vartype & inoutput_vt) != 0) {
               s4o.print(";\n");
               s4o.print(s4o.indent_spaces);
               s4o.print("if (__");
-              list->elements[i]->accept(*this);
+              list->get_element(i)->accept(*this);
               s4o.print(" != NULL) {\n");
               s4o.indent_right();
               s4o.print(s4o.indent_spaces);
-              list->elements[i]->accept(*this);
+              list->get_element(i)->accept(*this);
               s4o.print(" = *__");
-              list->elements[i]->accept(*this);
+              list->get_element(i)->accept(*this);
               s4o.print(";\n");
               s4o.indent_left();
               s4o.print(s4o.indent_spaces);
@@ -1058,7 +1063,7 @@
               this->current_var_init_symbol->accept(*this);
               s4o.print(";\n");
               s4o.print(s4o.indent_spaces);
-              list->elements[i]->accept(*this);
+              list->get_element(i)->accept(*this);
               s4o.print(" = temp;\n");
               s4o.indent_left();
               s4o.print(s4o.indent_spaces);
@@ -1094,7 +1099,7 @@
             s4o.print(" *__");
           else
             s4o.print(" ");
-          list->elements[i]->accept(*this);
+          list->get_element(i)->accept(*this);
           /* We do not print the initial value at function declaration!
            * It is up to the caller to pass the correct default value
            * if none is specified in the ST source code
@@ -1109,13 +1114,13 @@
         for(int i = 0; i < list->n; i++) {
           if ((current_vartype & (output_vt | inoutput_vt)) != 0) {
             s4o.print(s4o.indent_spaces + "if (__");
-            list->elements[i]->accept(*this);
+            list->get_element(i)->accept(*this);
             s4o.print(" != NULL) {\n");
             s4o.indent_right();
             s4o.print(s4o.indent_spaces + "*__");
-            list->elements[i]->accept(*this);
+            list->get_element(i)->accept(*this);
             s4o.print(" = ");
-            list->elements[i]->accept(*this);
+            list->get_element(i)->accept(*this);
             s4o.print(";\n");
             s4o.indent_left();
             s4o.print(s4o.indent_spaces + "}\n");
@@ -1139,7 +1144,7 @@
             s4o.print(FB_INIT_SUFFIX);
             s4o.print("(&");
             this->print_variable_prefix();
-            list->elements[i]->accept(*this);
+            list->get_element(i)->accept(*this);
             print_retain();
             s4o.print(");");
             if (this->current_var_init_symbol != NULL) {
@@ -1152,7 +1157,7 @@
                * __INIT_VAR(data__->my_fb.var1, __INT_LITERAL(42), retain);
                * __INIT_VAR(data__->my_fb.var1, __STRING_LITERAL("hello"), retain);
                */  
-              print_fb_explicit_initial_values(list->elements[i], this->current_var_init_symbol);
+              print_fb_explicit_initial_values(list->get_element(i), this->current_var_init_symbol);
             }
           }
           else if (this->current_var_init_symbol != NULL) {
@@ -1160,7 +1165,7 @@
             s4o.print(INIT_VAR);
             s4o.print("(");
             this->print_variable_prefix();
-            list->elements[i]->accept(*this);
+            list->get_element(i)->accept(*this);
             s4o.print(",");
             this->current_var_init_symbol->accept(*this);
             print_retain();
@@ -2157,7 +2162,7 @@
         if(this->resource_name != NULL)
             this->resource_name->accept(*this);
         s4o.print(",");
-        list->elements[i]->accept(*this);
+        list->get_element(i)->accept(*this);
         s4o.print(")\n");
       }
       break;
@@ -2174,7 +2179,7 @@
           s4o.print("(");
           this->current_var_type_symbol->accept(*this);
           s4o.print(",");
-          list->elements[i]->accept(*this);
+          list->get_element(i)->accept(*this);
           if (this->current_var_init_symbol != NULL) {
             s4o.print(",");
             s4o.print(INITIAL_VALUE);
@@ -2196,7 +2201,7 @@
             this->globalnamespace->accept(*this);
             s4o.print("::");
           }
-          list->elements[i]->accept(*this);
+          list->get_element(i)->accept(*this);
 
           if (this->current_var_init_symbol != NULL) {
             s4o.print(" = ");
@@ -2219,7 +2224,7 @@
         s4o.print("(");
         this->current_var_type_symbol->accept(*this);
         s4o.print(",");
-        list->elements[i]->accept(*this);
+        list->get_element(i)->accept(*this);
         s4o.print(")\n");
       }
       break;
--- a/stage4/generate_c/generate_var_list.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_c/generate_var_list.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -289,7 +289,7 @@
       if (list == NULL) ERROR;
 
       for(int i = 0; i < list->n; i++) {
-        declare_variable(list->elements[i]);
+        declare_variable(list->get_element(i));
       }
     }
     
@@ -793,7 +793,7 @@
 
     void *visit(structure_element_declaration_list_c *symbol) {
       for(int i = 0; i < symbol->n; i++) {
-        symbol->elements[i]->accept(*this);
+        symbol->get_element(i)->accept(*this);
       }
       return NULL;
     }
@@ -860,7 +860,7 @@
       transition_number = 0;
       action_number = 0;
       for(int i = 0; i < symbol->n; i++) {
-        symbol->elements[i]->accept(*this);
+        symbol->get_element(i)->accept(*this);
       }
       return NULL;
     }
@@ -937,7 +937,7 @@
     //SYM_LIST(step_name_list_c)
     void *visit(step_name_list_c *symbol) {
       for(int i = 0; i < symbol->n; i++) {
-        symbol->elements[i]->accept(*this);
+        symbol->get_element(i)->accept(*this);
         if (i < symbol->n - 1)
           s4o.print(",");
       }
--- a/stage4/generate_iec/generate_iec.cc	Wed Apr 12 08:44:42 2017 +0100
+++ b/stage4/generate_iec/generate_iec.cc	Sun Apr 16 08:46:58 2017 +0100
@@ -164,12 +164,12 @@
 			       std::string post_elem_str = "") {
   if (list->n > 0) {
     s4o.print(pre_elem_str);
-    list->elements[0]->accept(*this);
+    list->get_element(0)->accept(*this);
   }
 
   for(int i = 1; i < list->n; i++) {
     s4o.print(inter_elem_str);
-    list->elements[i]->accept(*this);
+    list->get_element(i)->accept(*this);
   }
 
   if (list->n > 0)