# HG changeset patch # User Mario de Sousa # Date 1352901837 0 # Node ID 3700fd83e5de9fd82b4ba52408d3e52e7e5a9cb8 # Parent db5881e6facda4f46f0a19dd27671c7f5f6aa412 Fix datatype checking of enumerated datatype declarations. We now follow the fill->narrow algorithm correctly. diff -r db5881e6facd -r 3700fd83e5de stage3/fill_candidate_datatypes.cc --- 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++) diff -r db5881e6facd -r 3700fd83e5de stage3/fill_candidate_datatypes.hh --- 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); diff -r db5881e6facd -r 3700fd83e5de stage3/narrow_candidate_datatypes.cc --- 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 */