# HG changeset patch # User Manuele Conti # Date 1342256966 -7200 # Node ID a45a62dd6df9c28d38ab759cdf36a81dcddf3167 # Parent 456add88d64cbc0c9bf31d996511fbc89f90ea6a Add remove_from_candidate_datatype_list method using constant_folding results. diff -r 456add88d64c -r a45a62dd6df9 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Tue Jun 19 18:55:43 2012 +0100 +++ b/stage3/constant_folding.cc Sat Jul 14 11:09:26 2012 +0200 @@ -201,8 +201,8 @@ if ((symbol->const_value_##dtype) == NULL) ERROR; \ (symbol->const_value_##dtype)->status = symbol_c::cs_undefined; -#define SET_CVALUE(dtype, symbol, new_value) ((symbol)->const_value_##dtype->value) = new_value; ((symbol)->const_value_##dtype->status) = symbol_c::cs_const_value; -#define GET_CVALUE(dtype, symbol) ((symbol)->const_value_##dtype->value) +#define SET_CVALUE(dtype, symbol, new_value) ((symbol)->const_value_##dtype->value) = new_value; ((symbol)->const_value_##dtype->status) = symbol_c::cs_const_value; +#define GET_CVALUE(dtype, symbol) ((symbol)->const_value_##dtype->value) #define SET_OVFLOW(dtype, symbol) ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow /* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */ #define VALID_CVALUE(dtype, symbol) ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status)) diff -r 456add88d64c -r a45a62dd6df9 stage3/datatype_functions.cc --- a/stage3/datatype_functions.cc Tue Jun 19 18:55:43 2012 +0100 +++ b/stage3/datatype_functions.cc Sat Jul 14 11:09:26 2012 +0200 @@ -409,9 +409,22 @@ return -1; } - - - +/* Remove a datatype inside a candidate_datatypes list. + * Returns: If successful it returns true, false otherwise. + */ +bool remove_from_candidate_datatype_list(symbol_c *datatype, std::vector &candidate_datatypes) { + unsigned int ofs; + if (NULL == datatype) + return false; + for(ofs = 0; ofs < candidate_datatypes.size(); ofs++) + if (is_type_equal(datatype, candidate_datatypes[ofs])) + break; + if (ofs < candidate_datatypes.size()) { + candidate_datatypes.erase(candidate_datatypes.begin() + ofs); + return true; + } + return false; +} diff -r 456add88d64c -r a45a62dd6df9 stage3/datatype_functions.hh --- a/stage3/datatype_functions.hh Tue Jun 19 18:55:43 2012 +0100 +++ b/stage3/datatype_functions.hh Sat Jul 14 11:09:26 2012 +0200 @@ -144,6 +144,11 @@ */ int search_in_candidate_datatype_list(symbol_c *datatype, std::vector candidate_datatypes); +/* Remove a datatype inside a candidate_datatypes list. + * Returns: If successful it returns true, false otherwise. + */ +bool remove_from_candidate_datatype_list(symbol_c *datatype, std::vector &candidate_datatypes); + /* Intersect two candidate_datatype_lists. * Remove from list1 (origin, dest.) all elements that are not found in list2 (with). * In essence, list1 will contain the result of the intersection of list1 with list2. diff -r 456add88d64c -r a45a62dd6df9 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Jun 19 18:55:43 2012 +0100 +++ b/stage3/fill_candidate_datatypes.cc Sat Jul 14 11:09:26 2012 +0200 @@ -63,6 +63,11 @@ #include #include +#define GET_CVALUE(dtype, symbol) ((symbol)->const_value_##dtype->value) +#define IS_UNDEF(dtype, symbol) (NULL == (symbol)->const_value_##dtype) +#define VALID_CVALUE(dtype, symbol) ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status)) +#define IS_OVERFLOW(dtype, symbol) (symbol_c::cs_overflow == (symbol)->const_value_##dtype->status) + /* set to 1 to see debug info during execution */ static int debug = 0; @@ -106,6 +111,120 @@ add_datatype_to_candidate_list(symbol, datatype2); return true; } + +void fill_candidate_datatypes_c::remove_incompatible_datatypes(symbol_c *symbol) { + /* Remove unsigned data types */ + if (! IS_UNDEF( uint64, symbol)) { + if (VALID_CVALUE( uint64, symbol)) { + uint64_t value = GET_CVALUE(uint64, symbol); + if (value > 1) { + remove_from_candidate_datatype_list(&search_constant_type_c::bool_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebool_type_name, symbol->candidate_datatypes); + } + if (value > UINT8_MAX ) { + remove_from_candidate_datatype_list(&search_constant_type_c::usint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeusint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::byte_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebyte_type_name, symbol->candidate_datatypes); + } + if (value > UINT16_MAX ) { + remove_from_candidate_datatype_list(&search_constant_type_c::uint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeuint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::word_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeword_type_name, symbol->candidate_datatypes); + } + if (value > UINT32_MAX ) { + remove_from_candidate_datatype_list(&search_constant_type_c::udint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeudint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::dword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safedword_type_name, symbol->candidate_datatypes); + } + } + if (IS_OVERFLOW( uint64, symbol)) { + remove_from_candidate_datatype_list(&search_constant_type_c::bool_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebool_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::usint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeusint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::byte_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebyte_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::uint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeuint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::word_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::udint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeudint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::dword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safedword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::ulint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeulint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::lword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safelword_type_name, symbol->candidate_datatypes); + } + } + /* Remove signed data types */ + if (! IS_UNDEF( int64, symbol)) { + if (VALID_CVALUE( int64, symbol)) { + int64_t value = GET_CVALUE(int64, symbol); + if (value < 0 || value > 1) { + remove_from_candidate_datatype_list(&search_constant_type_c::bool_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebool_type_name, symbol->candidate_datatypes); + } + if ((value < INT8_MIN ) || (value > INT8_MAX )) { + remove_from_candidate_datatype_list(&search_constant_type_c::sint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safesint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::byte_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebyte_type_name, symbol->candidate_datatypes); + } + if ((value < INT16_MIN ) || (value > INT16_MAX)) { + remove_from_candidate_datatype_list(&search_constant_type_c::int_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::word_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeword_type_name, symbol->candidate_datatypes); + } + if ((value < INT32_MIN ) || (value > INT32_MAX)) { + remove_from_candidate_datatype_list(&search_constant_type_c::dint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safedint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::dword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safedword_type_name, symbol->candidate_datatypes); + } + } + if (IS_OVERFLOW( int64, symbol)) { + /* Not exist a valid signed integer data types it can represent the current value */ + remove_from_candidate_datatype_list(&search_constant_type_c::sint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safesint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::int_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::dint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safedint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::lint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safelint_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::byte_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safebyte_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::word_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safeword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::dword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safedword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::lword_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safelword_type_name, symbol->candidate_datatypes); + } + } + /* Remove floating point data types */ + if (! IS_UNDEF( real64, symbol)) { + if (VALID_CVALUE( real64, symbol)) { + real64_t value = GET_CVALUE(real64, symbol); + /* We need a way to understand when lost precision happen and overflow for single precision. + * In this way we can remove REAL data type when a value has a mantissa or exponent too large. + */ + } + if (IS_OVERFLOW( real64, symbol)) { + /* Not exist a valid real data types that it can represent the current value */ + remove_from_candidate_datatype_list(&search_constant_type_c::real_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safereal_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::lreal_type_name, symbol->candidate_datatypes); + remove_from_candidate_datatype_list(&search_constant_type_c::safelreal_type_name, symbol->candidate_datatypes); + } + } +} /* returns true if compatible function/FB invocation, otherwise returns false */ @@ -348,7 +467,7 @@ for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) /* NOTE: add_datatype_to_candidate_list() will only really add the datatype if it is != NULL !!! */ add_datatype_to_candidate_list(symbol, widening_conversion(l_expr->candidate_datatypes[i], r_expr->candidate_datatypes[j], widen_table)); - + remove_incompatible_datatypes(symbol); if (debug) std::cout << "[" << l_expr->candidate_datatypes.size() << "," << r_expr->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n"; return NULL; } @@ -382,36 +501,20 @@ #define sizeoftype(symbol) get_sizeof_datatype_c::getsize(symbol) void *fill_candidate_datatypes_c::handle_any_integer(symbol_c *symbol) { - int calc_size = sizeoftype(symbol); - - if (calc_size <= sizeoftype(&search_constant_type_c::bool_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::bool_type_name, &search_constant_type_c::safebool_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::byte_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::byte_type_name, &search_constant_type_c::safebyte_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::word_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::word_type_name, &search_constant_type_c::safeword_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::dword_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dword_type_name, &search_constant_type_c::safedword_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::lword_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lword_type_name, &search_constant_type_c::safelword_type_name); - - if (calc_size < sizeoftype(&search_constant_type_c::sint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::sint_type_name, &search_constant_type_c::safesint_type_name); - if (calc_size < sizeoftype(&search_constant_type_c::int_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::int_type_name, &search_constant_type_c::safeint_type_name); - if (calc_size < sizeoftype(&search_constant_type_c::dint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dint_type_name, &search_constant_type_c::safedint_type_name); - if (calc_size < sizeoftype(&search_constant_type_c::lint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lint_type_name, &search_constant_type_c::safelint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::usint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::usint_type_name, &search_constant_type_c::safeusint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::uint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::uint_type_name, &search_constant_type_c::safeuint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::udint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::udint_type_name, &search_constant_type_c::safeudint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::ulint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::ulint_type_name, &search_constant_type_c::safeulint_type_name); - + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::bool_type_name, &search_constant_type_c::safebool_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::byte_type_name, &search_constant_type_c::safebyte_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::word_type_name, &search_constant_type_c::safeword_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dword_type_name, &search_constant_type_c::safedword_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lword_type_name, &search_constant_type_c::safelword_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::sint_type_name, &search_constant_type_c::safesint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::int_type_name, &search_constant_type_c::safeint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dint_type_name, &search_constant_type_c::safedint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lint_type_name, &search_constant_type_c::safelint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::usint_type_name, &search_constant_type_c::safeusint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::uint_type_name, &search_constant_type_c::safeuint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::udint_type_name, &search_constant_type_c::safeudint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::ulint_type_name, &search_constant_type_c::safeulint_type_name); + remove_incompatible_datatypes(symbol); if (debug) std::cout << "ANY_INT [" << symbol->candidate_datatypes.size()<< "]" << std::endl; return NULL; } @@ -419,12 +522,9 @@ void *fill_candidate_datatypes_c::handle_any_real(symbol_c *symbol) { - int calc_size = sizeoftype(symbol); - - if (calc_size <= sizeoftype(&search_constant_type_c::real_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::real_type_name, &search_constant_type_c::safereal_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::lreal_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lreal_type_name, &search_constant_type_c::safelreal_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::real_type_name, &search_constant_type_c::safereal_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lreal_type_name, &search_constant_type_c::safelreal_type_name); + remove_incompatible_datatypes(symbol); if (debug) std::cout << "ANY_REAL [" << symbol->candidate_datatypes.size() << "]" << std::endl; return NULL; } @@ -435,6 +535,7 @@ symbol_value->accept(*this); if (search_in_candidate_datatype_list(symbol_type, symbol_value->candidate_datatypes) >= 0) add_datatype_to_candidate_list(symbol, symbol_type); + remove_incompatible_datatypes(symbol); if (debug) std::cout << "XXX_LITERAL [" << symbol->candidate_datatypes.size() << "]\n"; return NULL; } @@ -447,16 +548,11 @@ void *fill_candidate_datatypes_c::visit(neg_integer_c *symbol) { - int calc_size = sizeoftype(symbol); - - if (calc_size <= sizeoftype(&search_constant_type_c::int_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::int_type_name, &search_constant_type_c::safeint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::sint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::sint_type_name, &search_constant_type_c::safesint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::dint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dint_type_name, &search_constant_type_c::safedint_type_name); - if (calc_size <= sizeoftype(&search_constant_type_c::lint_type_name)) - add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lint_type_name, &search_constant_type_c::safelint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::int_type_name, &search_constant_type_c::safeint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::sint_type_name, &search_constant_type_c::safesint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dint_type_name, &search_constant_type_c::safedint_type_name); + add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::lint_type_name, &search_constant_type_c::safelint_type_name); + remove_incompatible_datatypes(symbol); if (debug) std::cout << "neg ANY_INT [" << symbol->candidate_datatypes.size() << "]" << std::endl; return NULL; } @@ -493,11 +589,13 @@ void *fill_candidate_datatypes_c::visit(boolean_true_c *symbol) { add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::bool_type_name, &search_constant_type_c::safebool_type_name); + remove_incompatible_datatypes(symbol); return NULL; } void *fill_candidate_datatypes_c::visit(boolean_false_c *symbol) { add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::bool_type_name, &search_constant_type_c::safebool_type_name); + remove_incompatible_datatypes(symbol); return NULL; } @@ -506,6 +604,7 @@ /*******************************/ void *fill_candidate_datatypes_c::visit(double_byte_character_string_c *symbol) { add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::wstring_type_name, &search_constant_type_c::safewstring_type_name); + remove_incompatible_datatypes(symbol); return NULL; } @@ -1324,7 +1423,11 @@ * functions if the input parameters are all literals (e.g. ADD(42, 42)). This * means this class will be more difficult than it appears at first. */ -void *fill_candidate_datatypes_c::visit( add_expression_c *symbol) {return handle_binary_expression(widen_ADD_table, symbol, symbol->l_exp, symbol->r_exp);} +void *fill_candidate_datatypes_c::visit( add_expression_c *symbol) { + void *ret = handle_binary_expression(widen_ADD_table, symbol, symbol->l_exp, symbol->r_exp); + remove_incompatible_datatypes(symbol); + return ret; +} void *fill_candidate_datatypes_c::visit( sub_expression_c *symbol) {return handle_binary_expression(widen_SUB_table, symbol, symbol->l_exp, symbol->r_exp);} void *fill_candidate_datatypes_c::visit( mul_expression_c *symbol) {return handle_binary_expression(widen_MUL_table, symbol, symbol->l_exp, symbol->r_exp);} void *fill_candidate_datatypes_c::visit( div_expression_c *symbol) {return handle_binary_expression(widen_DIV_table, symbol, symbol->l_exp, symbol->r_exp);} diff -r 456add88d64c -r a45a62dd6df9 stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Tue Jun 19 18:55:43 2012 +0100 +++ b/stage3/fill_candidate_datatypes.hh Sat Jul 14 11:09:26 2012 +0200 @@ -111,6 +111,7 @@ /* Returns true if it really did add the datatype to the list, or false if it was already present in the list! */ bool add_datatype_to_candidate_list (symbol_c *symbol, symbol_c *datatype); bool add_2datatypes_to_candidate_list(symbol_c *symbol, symbol_c *datatype1, symbol_c *datatype2); + void remove_incompatible_datatypes(symbol_c *symbol); public: