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);}