Fix datatype checking of enumerated datatype declarations. We now follow the fill->narrow algorithm correctly.
--- a/stage3/fill_candidate_datatypes.cc Wed Nov 14 13:10:05 2012 +0000
+++ b/stage3/fill_candidate_datatypes.cc Wed Nov 14 14:03:57 2012 +0000
@@ -879,13 +879,24 @@
/* enumerated_type_name ':' enumerated_spec_init */
// SYM_REF2(enumerated_type_declaration_c, enumerated_type_name, enumerated_spec_init)
-/* NOTE: Not required. already handled by iterator_visitor_c base class */
+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);
+ symbol->enumerated_spec_init->accept(*this);
+ current_enumerated_spec_type = NULL;
+ return NULL;
+}
/* 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) {
- current_enumerated_spec_type = 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);
@@ -897,8 +908,6 @@
// SYM_LIST(enumerated_value_list_c)
void *fill_candidate_datatypes_c::visit(enumerated_value_list_c *symbol) {
if (NULL == current_enumerated_spec_type) ERROR;
- current_enumerated_spec_type = base_type(current_enumerated_spec_type);
- if (NULL == current_enumerated_spec_type) ERROR;
/* 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++)
--- a/stage3/fill_candidate_datatypes.hh Wed Nov 14 13:10:05 2012 +0000
+++ b/stage3/fill_candidate_datatypes.hh Wed Nov 14 14:03:57 2012 +0000
@@ -175,7 +175,7 @@
// 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); /* Not required. already handled by iterator_visitor_c base class */
+ 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);
--- a/stage3/narrow_candidate_datatypes.cc Wed Nov 14 13:10:05 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.cc Wed Nov 14 14:03:57 2012 +0000
@@ -476,9 +476,11 @@
/* 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) {
- symbol->datatype = search_base_type_c::get_basetype_decl(symbol);
- symbol->enumerated_type_name->datatype = symbol->datatype;
- symbol->enumerated_spec_init->datatype = symbol->datatype;
+ 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;
@@ -491,15 +493,12 @@
/* 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)
- symbol->datatype = search_base_type_c::get_basetype_decl(symbol);
- symbol->enumerated_specification->datatype = symbol->datatype;
+ 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)
- /* the enumerated_value_c object 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!
- * If the desired datatype does not match the datatypes in the candidate list, then the source code has a bug that will be caught by
- * print_datatypes_error_c
- */
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 */