Fill in the symbol.datatype annotation in symbol classes used in derived data type declarations.
authorMario de Sousa <msousa@fe.up.pt>
Wed, 23 Jan 2013 13:46:11 +0000
changeset 806 f218434eeaf8
parent 805 b737cfc92614
child 807 4d71292f8732
Fill in the symbol.datatype annotation in symbol classes used in derived data type declarations.
stage3/fill_candidate_datatypes.cc
stage3/fill_candidate_datatypes.hh
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
--- a/stage3/fill_candidate_datatypes.cc	Tue Jan 22 16:07:49 2013 +0000
+++ b/stage3/fill_candidate_datatypes.cc	Wed Jan 23 13:46:11 2013 +0000
@@ -798,6 +798,69 @@
 /********************************/
 /* B 1.3.3 - Derived data types */
 /********************************/
+
+void *fill_candidate_datatypes_c::fill_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init) {
+  /* NOTE: Unlike the rest of the 'fill' algorithm that works using a bottom->up approach, when handling 
+   *       data type declarations (section B.1.3.3 - Derived data types) we use a top->bottom approach. 
+   *       This is intentional, and not a bug! Explanation follows...
+   *       Here we are essentially determining the base type of each defined data type. In many cases (especially structs,
+   *       enumerations, arrays, etc...), the datatype is its own base type. However, the derived datatype is stored in
+   *       multiple symbol_c classes (e.g. an enumeration uses enumerated_type_declaration_c, enumerated_spec_init_c,
+   *       enumerated_value_list_c, enumerated_value_c, ...). Several of these could be chosen to work as the canonical base datatype
+   *       symbol. Which symbol is used is really up to the search_base_type_c, and not this fill_candidate_datatypes_c.
+   *       Here we must right the code to handle whatever the search_base_type_c chooses to use as the canonical symbol to represent
+   *       the base datatype.
+   *       Since the base datatype may be (and sometimes/often/always(?) actually is) the top level symbol_c (an enumerated_type_declaration_c
+   *       in the case of the enumerations), it only makes sense to ask search_base_type_c for a basetype when we pass it the 
+   *       symbol in the highest level of the type declaration (the enumerated_type_declaration_c in the case of the enumerations).
+   *       For this reason, we determine the basetype at the top level, and send that info down to the bottom level of the data type 
+   *       declaration. In summary, a top->down algorithm!
+   */ 
+  add_datatype_to_candidate_list(symbol, base_type(symbol));
+  type_name->candidate_datatypes = symbol->candidate_datatypes;  // use top->down algorithm!!
+  spec_init->candidate_datatypes = symbol->candidate_datatypes;  // use top->down algorithm!!
+  spec_init->accept(*this);
+  return NULL;
+}
+
+
+void *fill_candidate_datatypes_c::fill_spec_init(symbol_c *symbol, symbol_c *type_spec, symbol_c *init_value) {
+	/* NOTE: The note in the fill_type_decl() function is also partially valid here, 
+	 *       i.e. here too we work using a top->down algorithm for the type_spec part, but a bottom->up algorithm
+	 *       for the init_value part!!
+	 */
+	/* NOTE: When a variable is declared inside a POU as, for example
+	 *         VAR
+	 *            a : ARRAY[9] OF REAL;
+	 *            e : ENUM (black, white, gray);
+	 *            s : STRUCT x, y: REAL; END_STRUCT
+	 *         END_VAR
+	 *      the anonymous datatype will be defined directly by the ***_spec_init_c, and will not have an
+	 *      ****_type_declaration_c. In these cases, the anonymous data type is its own basetype, and the
+	 *      ***_spec_init_c class will act as the canonical symbol that represents the (anonymous) basetype.
+	 *      
+	 *      This method must handle the above case, as well as the case in which the ***_spec_init_c is called
+	 *      from an ****_type_declaration_c.
+	 */
+	if (symbol->candidate_datatypes.size() == 0) // i.e., if this is an anonymous datatype!
+		add_datatype_to_candidate_list(symbol, base_type(symbol)); 
+	
+	// use top->down algorithm!!
+	type_spec->candidate_datatypes = symbol->candidate_datatypes;   
+	type_spec->accept(*this);
+	
+	// use bottom->up algorithm!!
+	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
+	 *       with located variables (AT %QW3.4 : WORD).
+	 */
+	// if (NULL != init_value) intersect_candidate_datatype_list(symbol /*origin, dest.*/, init_value /*with*/);
+	return NULL;
+}
+
+
 /*  TYPE type_declaration_list END_TYPE */
 // SYM_REF1(data_type_declaration_c, type_declaration_list)
 /* NOTE: Not required. already handled by iterator_visitor_c base class */
@@ -808,32 +871,25 @@
 
 /*  simple_type_name ':' simple_spec_init */
 // SYM_REF2(simple_type_declaration_c, simple_type_name, simple_spec_init)
-/* NOTE: Not required. already handled by iterator_visitor_c base class */
+void *fill_candidate_datatypes_c::visit(simple_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->simple_type_name, symbol->simple_spec_init);}
+  
 
 /* simple_specification ASSIGN constant */
 // SYM_REF2(simple_spec_init_c, simple_specification, constant)
-void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
-	if (NULL != symbol->constant) symbol->constant->accept(*this);
-	add_datatype_to_candidate_list(symbol->simple_specification, base_type(symbol->simple_specification));
-	symbol->candidate_datatypes = symbol->simple_specification->candidate_datatypes;
-	/* NOTE: Even if the constant and the type are of incompatible data types, we let the
-	 *       simple_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
-	 *       with located variables (AT %QW3.4 : WORD).
-	 */
-	// if (NULL != symbol->constant) intersect_candidate_datatype_list(symbol /*origin, dest.*/, symbol->constant /*with*/);
-	return NULL;
-}
+void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->simple_specification, symbol->constant);}
 
 
 /*  subrange_type_name ':' subrange_spec_init */
 // SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init)
+void *fill_candidate_datatypes_c::visit(subrange_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->subrange_type_name, symbol->subrange_spec_init);}
 
 /* subrange_specification ASSIGN signed_integer */
 // SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer)
+void *fill_candidate_datatypes_c::visit(subrange_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->subrange_specification, symbol->signed_integer);}
 
 /*  integer_type_name '(' subrange')' */
 // SYM_REF2(subrange_specification_c, integer_type_name, subrange)
+// NOTE: not needed! Iterator visitor already handles this!
 
 /*  signed_integer DOTDOT signed_integer */
 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
@@ -854,41 +910,25 @@
 
 /*  enumerated_type_name ':' enumerated_spec_init */
 // SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init)
-void *fill_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {
-  current_enumerated_spec_type = base_type(symbol);
-  add_datatype_to_candidate_list(symbol,                       current_enumerated_spec_type);
-  add_datatype_to_candidate_list(symbol->enumerated_type_name, current_enumerated_spec_type);
-  symbol->enumerated_spec_init->accept(*this);
-  current_enumerated_spec_type = NULL;  
-  return NULL;
-}
+void *fill_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->enumerated_type_name, symbol->enumerated_spec_init);}
 
 
 /* enumerated_specification ASSIGN enumerated_value */
 // SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value)
-void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {
-  /* If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration)
-   * then the symbol->datatype has not yet been set by the previous visit(enumerated_spec_init_c) method!
-   */
-  if (NULL == current_enumerated_spec_type)
-    current_enumerated_spec_type = base_type(symbol);  
-  add_datatype_to_candidate_list(symbol, current_enumerated_spec_type);
-  symbol->enumerated_specification->accept(*this); /* calls enumerated_value_list_c (or identifier_c, which we ignore!) visit method */
-  current_enumerated_spec_type = NULL;  
-  if (NULL != symbol->enumerated_value) symbol->enumerated_value->accept(*this);
-  return NULL;
-}
+// NOTE: enumerated_specification is either an enumerated_value_list_c or identifier_c.
+void *fill_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->enumerated_specification, symbol->enumerated_value);}
+
 
 /* helper symbol for enumerated_specification->enumerated_spec_init */
 /* enumerated_value_list ',' enumerated_value */
 // SYM_LIST(enumerated_value_list_c)
 void *fill_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) {
-  if (NULL == current_enumerated_spec_type) ERROR;  
-  add_datatype_to_candidate_list(symbol, current_enumerated_spec_type);
+  if (symbol->candidate_datatypes.size() != 1) ERROR;
+  symbol_c *current_enumerated_spec_type = symbol->candidate_datatypes[0];
   
   /* 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);
+    add_datatype_to_candidate_list(symbol->elements[i], current_enumerated_spec_type); // top->down algorithm!!
 
   return NULL;  
 }
@@ -969,10 +1009,12 @@
 
 /*  identifier ':' array_spec_init */
 // SYM_REF2(array_type_declaration_c, identifier, array_spec_init)
+void *fill_candidate_datatypes_c::visit(array_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->identifier, symbol->array_spec_init);}
 
 /* array_specification [ASSIGN array_initialization} */
 /* array_initialization may be NULL ! */
 // SYM_REF2(array_spec_init_c, array_specification, array_initialization)
+void *fill_candidate_datatypes_c::visit(array_spec_init_c *symbol) {return fill_spec_init(symbol, symbol->array_specification, symbol->array_initialization);}
 
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
 // SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name)
@@ -992,10 +1034,12 @@
 
 /*  structure_type_name ':' structure_specification */
 // SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
+void *fill_candidate_datatypes_c::visit(structure_type_declaration_c *symbol) {return fill_type_decl(symbol, symbol->structure_type_name, symbol->structure_specification);}
 
 /* structure_type_name ASSIGN structure_initialization */
 /* structure_initialization may be NULL ! */
 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
+void *fill_candidate_datatypes_c::visit(initialized_structure_c *symbol) {return fill_spec_init(symbol, symbol->structure_type_name, symbol->structure_initialization);}
 
 /* helper symbol for structure_declaration */
 /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
--- a/stage3/fill_candidate_datatypes.hh	Tue Jan 22 16:07:49 2013 +0000
+++ b/stage3/fill_candidate_datatypes.hh	Wed Jan 23 13:46:11 2013 +0000
@@ -94,6 +94,8 @@
     void *handle_binary_expression  (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
     void *handle_binary_operator    (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
     void *handle_conditional_il_flow_control_operator(symbol_c *symbol);
+    void *fill_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init);
+    void *fill_spec_init(symbol_c *symbol, symbol_c *type_spec, symbol_c *init_value);
     
     /* a helper function... */
     symbol_c *base_type(symbol_c *symbol);    
@@ -169,24 +171,24 @@
     /********************************/
 //  void *visit(data_type_declaration_c *symbol);   /* Not required. already handled by iterator_visitor_c base class */
 //  void *visit(type_declaration_list_c *symbol);   /* Not required. already handled by iterator_visitor_c base class */
-//  void *visit(simple_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */
+    void *visit(simple_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */
     void *visit(simple_spec_init_c *symbol);
-//  void *visit(subrange_type_declaration_c *symbol);
-//  void *visit(subrange_spec_init_c *symbol);
+    void *visit(subrange_type_declaration_c *symbol);
+    void *visit(subrange_spec_init_c *symbol);
 //  void *visit(subrange_specification_c *symbol);
     void *visit(subrange_c *symbol);
     void *visit(enumerated_type_declaration_c *symbol);
     void *visit(enumerated_spec_init_c *symbol);
     void *visit(enumerated_value_list_c *symbol);
     void *visit(enumerated_value_c *symbol);
-//  void *visit(array_type_declaration_c *symbol);
-//  void *visit(array_spec_init_c *symbol);
+    void *visit(array_type_declaration_c *symbol);
+    void *visit(array_spec_init_c *symbol);
 //  void *visit(array_specification_c *symbol);
 //  void *visit(array_subrange_list_c *symbol);
 //  void *visit(array_initial_elements_list_c *symbol);
 //  void *visit(array_initial_elements_c *symbol);
-//  void *visit(structure_type_declaration_c *symbol);
-//  void *visit(initialized_structure_c *symbol);
+    void *visit(structure_type_declaration_c *symbol);
+    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);
--- a/stage3/narrow_candidate_datatypes.cc	Tue Jan 22 16:07:49 2013 +0000
+++ b/stage3/narrow_candidate_datatypes.cc	Wed Jan 23 13:46:11 2013 +0000
@@ -477,6 +477,36 @@
 /********************************/
 /* B 1.3.3 - Derived data types */
 /********************************/
+void *narrow_candidate_datatypes_c::narrow_spec_init(symbol_c *symbol, symbol_c *type_decl, symbol_c *init_value) {
+	// If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration)
+	// then the symbol->datatype has not yet been set by the previous visit(type_decl) method, because it does not exist!
+	// So we set the datatype ourselves!
+	if ((NULL == symbol->datatype) && (symbol->candidate_datatypes.size() == 1))
+		symbol->datatype = symbol->candidate_datatypes[0];
+  
+	set_datatype(symbol->datatype, type_decl);
+	type_decl->accept(*this);
+
+	if (NULL != init_value) {
+		set_datatype(symbol->datatype, init_value);
+		init_value->accept(*this);
+	}
+	return NULL;
+}
+
+
+void *narrow_candidate_datatypes_c::narrow_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init) {
+	if (symbol->candidate_datatypes.size() == 1) {
+		symbol->datatype = symbol->candidate_datatypes[0];
+  
+		set_datatype(symbol->datatype, type_name);
+		set_datatype(symbol->datatype, spec_init);
+		spec_init->accept(*this);
+	}
+	return NULL;
+}
+
+
 /*  TYPE type_declaration_list END_TYPE */
 // SYM_REF1(data_type_declaration_c, type_declaration_list)
 /* NOTE: Not required. already handled by iterator_visitor_c base class */
@@ -487,41 +517,37 @@
 
 /*  simple_type_name ':' simple_spec_init */
 // SYM_REF2(simple_type_declaration_c, simple_type_name, simple_spec_init)
-/* NOTE: Not required. already handled by iterator_visitor_c base class */
+void *narrow_candidate_datatypes_c::visit(simple_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->simple_type_name, symbol->simple_spec_init);}
 
 /* simple_specification ASSIGN constant */
 // SYM_REF2(simple_spec_init_c, simple_specification, constant)
-void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {
-	if (symbol->candidate_datatypes.size() == 1)
-	  symbol->datatype = symbol->candidate_datatypes[0];
-	  
-	if (symbol->simple_specification->candidate_datatypes.size() == 1)
-	  symbol->simple_specification->datatype = symbol->simple_specification->candidate_datatypes[0];
-
-	if (NULL != symbol->constant) {
-		set_datatype(symbol->datatype, symbol->constant);
-		symbol->constant->accept(*this);
-	}
-	return NULL;
-}
-
+void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->simple_specification, symbol->constant);}
 
 /*  subrange_type_name ':' subrange_spec_init */
 // SYM_REF2(subrange_type_declaration_c, subrange_type_name, subrange_spec_init)
+void *narrow_candidate_datatypes_c::visit(subrange_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->subrange_type_name, symbol->subrange_spec_init);}
 
 /* subrange_specification ASSIGN signed_integer */
 // SYM_REF2(subrange_spec_init_c, subrange_specification, signed_integer)
+void *narrow_candidate_datatypes_c::visit(subrange_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->subrange_specification, symbol->signed_integer);}
 
 /*  integer_type_name '(' subrange')' */
 // SYM_REF2(subrange_specification_c, integer_type_name, subrange)
+void *narrow_candidate_datatypes_c::visit(subrange_specification_c *symbol) {
+	set_datatype(symbol->datatype, symbol->integer_type_name);
+	symbol->integer_type_name->accept(*this);
+	set_datatype(symbol->datatype, symbol->integer_type_name);
+	symbol->integer_type_name->accept(*this);
+	return NULL;
+}
 
 /*  signed_integer DOTDOT signed_integer */
 /* dimension will be filled in during stage 3 (array_range_check_c) with the number of elements in this subrange */
 // SYM_REF2(subrange_c, lower_limit, upper_limit, unsigned long long int dimension;)
 void *narrow_candidate_datatypes_c::visit(subrange_c *symbol) {
-	symbol->lower_limit->datatype = symbol->datatype;
+	set_datatype(symbol->datatype, symbol->lower_limit);
 	symbol->lower_limit->accept(*this);
-	symbol->upper_limit->datatype = symbol->datatype;
+	set_datatype(symbol->datatype, symbol->upper_limit);
 	symbol->upper_limit->accept(*this);
 	return NULL;
 }
@@ -529,49 +555,20 @@
 
 /*  enumerated_type_name ':' enumerated_spec_init */
 // SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init)
-void *narrow_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {
-  if (symbol->candidate_datatypes.size() != 1) ERROR;
-  
-  symbol->datatype = symbol->candidate_datatypes[0];
-  set_datatype(symbol->datatype, symbol->enumerated_type_name);
-  set_datatype(symbol->datatype, symbol->enumerated_spec_init);
-  
-  symbol->enumerated_spec_init->accept(*this);
-  return NULL;
-}
+void *narrow_candidate_datatypes_c::visit(enumerated_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->enumerated_type_name, symbol->enumerated_spec_init);}
 
 
 /* enumerated_specification ASSIGN enumerated_value */
 // SYM_REF2(enumerated_spec_init_c, enumerated_specification, enumerated_value)
-void *narrow_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {
-  /* If we are handling an anonymous datatype (i.e. a datatype implicitly declared inside a VAR ... END_VAR declaration)
-   * then the symbol->datatype has not yet been set by the previous visit(enumerated_spec_init_c) method!
-   */
-  if (NULL == symbol->datatype) {
-    if (symbol->candidate_datatypes.size() != 1) ERROR;
-    symbol->datatype = symbol->candidate_datatypes[0];
-  }
-  set_datatype(symbol->datatype, symbol->enumerated_specification);
-  if (NULL != symbol->enumerated_value) 
-    set_datatype(symbol->datatype, symbol->enumerated_value);
-
-  symbol->enumerated_specification->accept(*this); /* calls enumerated_value_list_c (or identifier_c, which we ignore!) visit method */
-  return NULL;
-}
+void *narrow_candidate_datatypes_c::visit(enumerated_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->enumerated_specification, symbol->enumerated_value);}
 
 /* helper symbol for enumerated_specification->enumerated_spec_init */
 /* enumerated_value_list ',' enumerated_value */
 // SYM_LIST(enumerated_value_list_c)
 void *narrow_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) {
-  if (NULL == symbol->datatype) ERROR;
-  
-  for(int i = 0; i < symbol->n; i++) {
-    /* the enumerated_value_c objects to which this list points to has both the datatype and the candidate_datatype_list filled in, so we 
-     * call set_datatype() instead of setting the datatype directly!
-     */
-    set_datatype(symbol->datatype, symbol->elements[i]);
-    if (NULL == symbol->elements[i]->datatype) ERROR;
-  }
+//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 ???  
   return NULL;  
 }
 
@@ -583,49 +580,61 @@
 
 /*  identifier ':' array_spec_init */
 // SYM_REF2(array_type_declaration_c, identifier, array_spec_init)
+void *narrow_candidate_datatypes_c::visit(array_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->identifier, symbol->array_spec_init);}
 
 /* array_specification [ASSIGN array_initialization} */
 /* array_initialization may be NULL ! */
 // SYM_REF2(array_spec_init_c, array_specification, array_initialization)
+void *narrow_candidate_datatypes_c::visit(array_spec_init_c *symbol) {return narrow_spec_init(symbol, symbol->array_specification, symbol->array_initialization);}
 
 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
 // SYM_REF2(array_specification_c, array_subrange_list, non_generic_type_name)
+// Not needed!!
 
 /* helper symbol for array_specification */
 /* array_subrange_list ',' subrange */
 // SYM_LIST(array_subrange_list_c)
+// Not needed ??
 
 /* array_initialization:  '[' array_initial_elements_list ']' */
 /* helper symbol for array_initialization */
 /* array_initial_elements_list ',' array_initial_elements */
 // SYM_LIST(array_initial_elements_list_c)
+// Not needed ???
 
 /* integer '(' [array_initial_element] ')' */
 /* array_initial_element may be NULL ! */
 // SYM_REF2(array_initial_elements_c, integer, array_initial_element)
+// Not needed ???
 
 /*  structure_type_name ':' structure_specification */
 // SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
+void *narrow_candidate_datatypes_c::visit(structure_type_declaration_c *symbol) {return narrow_type_decl(symbol, symbol->structure_type_name, symbol->structure_specification);}
 
 /* structure_type_name ASSIGN structure_initialization */
 /* structure_initialization may be NULL ! */
 // SYM_REF2(initialized_structure_c, structure_type_name, structure_initialization)
+void *narrow_candidate_datatypes_c::visit(initialized_structure_c *symbol) {return narrow_spec_init(symbol, symbol->structure_type_name, symbol->structure_initialization);}
 
 /* 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)
+// Not needed ???
 
 /*  structure_element_name ':' *_spec_init */
 // SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init)
+// Not needed ???
 
 /* helper symbol for structure_initialization */
 /* structure_initialization: '(' structure_element_initialization_list ')' */
 /* structure_element_initialization_list ',' structure_element_initialization */
 // SYM_LIST(structure_element_initialization_list_c)
+// Not needed ???
 
 /*  structure_element_name ASSIGN value */
 // SYM_REF2(structure_element_initialization_c, structure_element_name, value)
+// Not needed ???
 
 /*  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! */) 
--- a/stage3/narrow_candidate_datatypes.hh	Tue Jan 22 16:07:49 2013 +0000
+++ b/stage3/narrow_candidate_datatypes.hh	Wed Jan 23 13:46:11 2013 +0000
@@ -81,6 +81,9 @@
     void *narrow_binary_expression  (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL, bool allow_enums = false);
     void *narrow_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL);
 
+    void *narrow_spec_init(symbol_c *symbol, symbol_c *type_decl, symbol_c *init_value);
+    void *narrow_type_decl(symbol_c *symbol, symbol_c *type_name, symbol_c *spec_init);
+
     void *narrow_conditional_flow_control_IL_instruction(symbol_c *symbol);
 
 
@@ -150,24 +153,24 @@
     /********************************/
 //  void *visit(data_type_declaration_c *symbol);   /* Not required. already handled by iterator_visitor_c base class */
 //  void *visit(type_declaration_list_c *symbol);   /* Not required. already handled by iterator_visitor_c base class */
-//  void *visit(simple_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */
+    void *visit(simple_type_declaration_c *symbol); /* Not required. already handled by iterator_visitor_c base class */
     void *visit(simple_spec_init_c *symbol);
-//  void *visit(subrange_type_declaration_c *symbol);
-//  void *visit(subrange_spec_init_c *symbol);
-//  void *visit(subrange_specification_c *symbol);
+    void *visit(subrange_type_declaration_c *symbol);
+    void *visit(subrange_spec_init_c *symbol);
+    void *visit(subrange_specification_c *symbol);
     void *visit(subrange_c *symbol);
     void *visit(enumerated_type_declaration_c *symbol);
     void *visit(enumerated_spec_init_c *symbol);
     void *visit(enumerated_value_list_c *symbol);
 //  void *visit(enumerated_value_c *symbol);        /* Not required */
-//  void *visit(array_type_declaration_c *symbol);
-//  void *visit(array_spec_init_c *symbol);
+    void *visit(array_type_declaration_c *symbol);
+    void *visit(array_spec_init_c *symbol);
 //  void *visit(array_specification_c *symbol);
 //  void *visit(array_subrange_list_c *symbol);
 //  void *visit(array_initial_elements_list_c *symbol);
 //  void *visit(array_initial_elements_c *symbol);
-//  void *visit(structure_type_declaration_c *symbol);
-//  void *visit(initialized_structure_c *symbol);
+    void *visit(structure_type_declaration_c *symbol);
+    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);