diff -r e9bde0aa93ed -r 8da635655f37 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Jul 29 13:39:40 2014 +0100 +++ b/stage3/fill_candidate_datatypes.cc Thu Jul 31 17:49:44 2014 +0100 @@ -662,13 +662,15 @@ /* handle the two equality comparison operations, i.e. = (euqal) and != (not equal) */ /* This function is special, as it will also allow enumeration data types to be compared, with the result being a BOOL data type! - * This possibility os not expressed in the 'widening' tables, so we need to hard code it here + * It will also allow to REF_TO datatypes to be compared. + * These possibilities are not expressed in the 'widening' tables, so we need to hard code it here */ void *fill_candidate_datatypes_c::handle_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) { handle_binary_expression(widen_table, symbol, l_expr, r_expr); for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) { - if ((l_expr->candidate_datatypes[i] == r_expr->candidate_datatypes[j]) && get_datatype_info_c::is_enumerated(l_expr->candidate_datatypes[i])) + if ( (get_datatype_info_c::is_enumerated(l_expr->candidate_datatypes[i]) && (l_expr->candidate_datatypes[i] == r_expr->candidate_datatypes[j])) + || (get_datatype_info_c::is_ref_to (l_expr->candidate_datatypes[i]) && get_datatype_info_c::is_type_equal(l_expr->candidate_datatypes[i], r_expr->candidate_datatypes[j]))) add_datatype_to_candidate_list(symbol, &get_datatype_info_c::bool_type_name); } return NULL; @@ -689,15 +691,48 @@ /***************************/ /* main entry function! */ void *fill_candidate_datatypes_c::visit(library_c *symbol) { - symbol->accept(populate_globalenumvalue_symtable); - /* Now let the base class iterator_visitor_c iterate through all the library elements */ - return iterator_visitor_c::visit(symbol); + symbol->accept(populate_globalenumvalue_symtable); + /* Now let the base class iterator_visitor_c iterate through all the library elements */ + return iterator_visitor_c::visit(symbol); } /*********************/ /* B 1.2 - Constants */ /*********************/ +/*********************************/ +/* B 1.2.XX - Reference Literals */ +/*********************************/ +/* defined in IEC 61131-3 v3 - Basically the 'NULL' keyword! */ +void *fill_candidate_datatypes_c::visit(ref_value_null_literal_c *symbol) { + /* 'NULL' does not have any specific datatype. It is compatible with any reference, i.e. REF_TO + * The fill_candidate_datatypes / narrow_candidate_datatypes algorithm would require us to add + * as possible datatypes all the REF_TO . To do this we would need to go through the list of all + * user declared datatypes, as well as all the elementary datatypes. This is easily done by using the + * type_symtable symbol table declared in absyntax_utils.hh. + * + * for(int i=0; il_exp->accept(*this); symbol->r_exp->accept(*this); for (unsigned int i = 0; i < symbol->l_exp->candidate_datatypes.size(); i++) { @@ -2009,7 +2043,7 @@ left_type = symbol->l_exp->candidate_datatypes[i]; right_type = symbol->r_exp->candidate_datatypes[j]; if (get_datatype_info_c::is_type_equal(left_type, right_type)) - add_datatype_to_candidate_list(symbol, left_type); + add_datatype_to_candidate_list(symbol, left_type); // NOTE: Must use left_type, as the right_type may be the 'NULL' reference! (see comment in visit(ref_value_null_literal_c)) */ } } if (debug) std::cout << ":= [" << symbol->l_exp->candidate_datatypes.size() << "," << symbol->r_exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n";