# HG changeset patch # User Mario de Sousa # Date 1328292980 0 # Node ID c8e6cf57324a40d6de33c0bbe130390bc9967aeb # Parent 43d73e28eca873daca10b0bc82f119a15b7c9439 Print error messages when datatype erros found in ST function/FB calls. diff -r 43d73e28eca8 -r c8e6cf57324a stage3/datatype_functions.cc --- a/stage3/datatype_functions.cc Fri Feb 03 14:43:14 2012 +0000 +++ b/stage3/datatype_functions.cc Fri Feb 03 18:16:20 2012 +0000 @@ -148,27 +148,17 @@ { NULL, NULL, NULL }, }; -/* NOTE on data type handling and literals... - * ========================================== - * - * Literals that are explicitly type cast - * e.g.: BYTE#42 - * INT#65 - * TIME#45h23m - * etc... - * are NOT considered literals in the following code. - * Since they are type cast, and their data type is fixed and well known, - * they are treated as a variable of that data type (except when determining lvalues) - * In other words, when calling search_constant_type_c on these constants, it returns - * a xxxxx_type_name_c, and not one of the xxxx_literal_c ! - * - * When the following code handles a literal, it is really a literal of unknown data type. - * e.g. 42, may be considered an int, a byte, a word, etc... - * - * NOTE: type_symbol == NULL is valid! - * This will occur, for example, when and undefined/undeclared symbolic_variable is used in the program. - * This will not be of any type, so we always return false. +/* Search for a datatype inside a candidate_datatypes list. + * Returns: position of datatype in the list, or -1 if not found. */ +int search_in_datatype_list(symbol_c *datatype, std::vector candidate_datatypes) { + for(unsigned int i = 0; i < candidate_datatypes.size(); i++) + if (is_type_equal(datatype, candidate_datatypes[i])) + return i; + /* Not found ! */ + return -1; +} + /* A helper function... */ bool is_ANY_ELEMENTARY_type(symbol_c *type_symbol) { @@ -332,7 +322,7 @@ if (type_symbol == NULL) {return false;} if (is_ANY_INT_type (type_symbol)) {return true;} if (is_ANY_SAFEINT_type(type_symbol)) {return true;} - if (is_literal_integer_type(type_symbol)) {return true;} +// if (is_literal_integer_type(type_symbol)) {return true;} return false; } @@ -357,7 +347,7 @@ if (type_symbol == NULL) {return false;} if (is_ANY_REAL_type (type_symbol)) {return true;} if (is_ANY_SAFEREAL_type(type_symbol)) {return true;} - if (is_literal_real_type(type_symbol)) {return true;} +// if (is_literal_real_type(type_symbol)) {return true;} return false; } @@ -388,8 +378,8 @@ if (type_symbol == NULL) {return false;} if (is_ANY_BIT_type (type_symbol)) {return true;} if (is_ANY_SAFEBIT_type(type_symbol)) {return true;} - if (is_nonneg_literal_integer_type(type_symbol)) {return true;} - if (is_literal_bool_type(type_symbol)) {return true;} +// if (is_nonneg_literal_integer_type(type_symbol)) {return true;} +// if (is_literal_bool_type(type_symbol)) {return true;} return false; } @@ -412,10 +402,13 @@ if (type_symbol == NULL) {return false;} if (is_BOOL_type (type_symbol)) {return true;} if (is_SAFEBOOL_type(type_symbol)) {return true;} - if (is_literal_bool_type(type_symbol)) {return true;} - return false; -} - +// if (is_literal_bool_type(type_symbol)) {return true;} + return false; +} + + + +#if 0 /* A helper function... */ bool is_literal_integer_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} @@ -604,6 +597,7 @@ if (first_type == NULL || second_type == NULL) {return false;} return (NULL != common_type(first_type, second_type)); } +#endif bool is_type_equal(symbol_c *first_type, symbol_c *second_type) { diff -r 43d73e28eca8 -r c8e6cf57324a stage3/datatype_functions.hh --- a/stage3/datatype_functions.hh Fri Feb 03 14:43:14 2012 +0000 +++ b/stage3/datatype_functions.hh Fri Feb 03 18:16:20 2012 +0000 @@ -46,6 +46,11 @@ extern const struct widen_entry widen_MUL_table[]; extern const struct widen_entry widen_DIV_table[]; +/* Search for a datatype inside a candidate_datatypes list. + * Returns: position of datatype in the list, or -1 if not found. + */ +int search_in_datatype_list(symbol_c *datatype, std::vector candidate_datatypes); + /* A helper function... */ bool is_ANY_ELEMENTARY_type (symbol_c *type_symbol); bool is_ANY_SAFEELEMENTARY_type (symbol_c *type_symbol); @@ -83,6 +88,7 @@ bool is_SAFEBOOL_type (symbol_c *type_symbol); bool is_ANY_BOOL_compatible (symbol_c *type_symbol); +#if 0 bool is_nonneg_literal_integer_type (symbol_c *type_symbol); bool is_literal_integer_type (symbol_c *type_symbol); bool is_literal_real_type (symbol_c *type_symbol); @@ -102,9 +108,11 @@ symbol_c *common_type(symbol_c *first_type, symbol_c *second_type); bool is_valid_assignment(symbol_c *var_type, symbol_c *value_type); bool is_compatible_type(symbol_c *first_type, symbol_c *second_type); +#endif + bool is_type_equal(symbol_c *first_type, symbol_c *second_type); -typedef bool (*helper_function_t) (symbol_c *type_symbol); /* a pointer to a function! */ +// typedef bool (*helper_function_t) (symbol_c *type_symbol); /* a pointer to a function! */ diff -r 43d73e28eca8 -r c8e6cf57324a stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Fri Feb 03 14:43:14 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Fri Feb 03 18:16:20 2012 +0000 @@ -54,6 +54,17 @@ narrow_candidate_datatypes_c::~narrow_candidate_datatypes_c(void) { } + +/* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */ +static void set_datatype(symbol_c *datatype, symbol_c *symbol) { + symbol->datatype = NULL; + if (search_in_datatype_list(datatype, symbol->candidate_datatypes) >= 0) + symbol->datatype = datatype; +} + + + + bool narrow_candidate_datatypes_c::is_widening_compatible(symbol_c *left_type, symbol_c *right_type, symbol_c *result_type, const struct widen_entry widen_table[]) { for (int k = 0; NULL != widen_table[k].left; k++) { if ((typeid(*left_type) == typeid(*widen_table[k].left)) @@ -95,9 +106,11 @@ /* Note that if the call has more parameters than those declared in the function/FB declaration, * we may be setting this to NULL! */ - call_param_value->datatype = base_type(fp_iterator.param_type()); - if ((NULL != param_name) && (NULL == call_param_value->datatype)) ERROR; - if ((NULL == param_name) && (NULL != call_param_value->datatype)) ERROR; + symbol_c *desired_datatype = base_type(fp_iterator.param_type()); + if ((NULL != param_name) && (NULL == desired_datatype)) ERROR; + if ((NULL == param_name) && (NULL != desired_datatype)) ERROR; + + set_datatype(desired_datatype, call_param_value); call_param_value->accept(*this); if (NULL != param_name) @@ -145,10 +158,11 @@ * an invalid FB call (call with parameters that do not exist on the FB declaration). * For this reason, the param_name may come out as NULL! */ - call_param_value->datatype = base_type(fp_iterator.param_type()); - if ((NULL != param_name) && (NULL == call_param_value->datatype)) ERROR; - if ((NULL == param_name) && (NULL != call_param_value->datatype)) ERROR; - + symbol_c *desired_datatype = base_type(fp_iterator.param_type()); + if ((NULL != param_name) && (NULL == desired_datatype)) ERROR; + if ((NULL == param_name) && (NULL != desired_datatype)) ERROR; + + set_datatype(desired_datatype, call_param_value); call_param_value->accept(*this); if (NULL != param_name) diff -r 43d73e28eca8 -r c8e6cf57324a stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Fri Feb 03 14:43:14 2012 +0000 +++ b/stage3/print_datatypes_error.cc Fri Feb 03 18:16:20 2012 +0000 @@ -1016,24 +1016,27 @@ void *print_datatypes_error_c::visit(function_invocation_c *symbol) { list_c *parameter_list; - function_declaration_c * f_decl; - - if (NULL != symbol->datatype) return NULL; + if (NULL != symbol->formal_param_list) parameter_list = (list_c *)symbol->formal_param_list; else if (NULL != symbol->nonformal_param_list) parameter_list = (list_c *)symbol->nonformal_param_list; else ERROR; + parameter_list->accept(*this); - if (symbol->candidate_datatypes.size() == 0) { - identifier_c *fname = (identifier_c *)symbol->function_name; - f_decl = (function_declaration_c *)symbol->called_function_declaration; - /* - * Manuele: In the future we have to test parameter number - * and show a specific message. - */ - STAGE3_ERROR(symbol, symbol, "No matching overloaded '%s' function call.", fname->value); - } + + if (symbol->candidate_datatypes.size() == 0) { + /* No compatible function exists */ + STAGE3_ERROR(symbol, symbol, "Invalid parameters in function invocation: %s\n", ((identifier_c *)symbol->function_name)->value); + } +#if 0 + else + if (NULL == symbol->datatype) { + /* One or compatible functions exists, but none chosen! */ + STAGE3_ERROR(symbol, symbol, "Invalid parameters in function invocation: %s\n", f_name->value); + } +#endif + return NULL; } @@ -1055,6 +1058,42 @@ return NULL; } + +/*****************************************/ +/* B 3.2.2 Subprogram Control Statements */ +/*****************************************/ +/* fb_name '(' [param_assignment_list] ')' */ +/* formal_param_list -> may be NULL ! */ +/* nonformal_param_list -> may be NULL ! */ +/* NOTES: + * The parameter 'called_fb_declaration'... + * ...is used to pass data between two passes of stage 3. + * (actually set in fill_candidate_datatypes_c, and used in narrow_candidate_datatypes_c and print_datatypes_error_c). + * This allows fill_candidate_datatypes_c to figure out whether it is a valid FB call, + * and let the other classes handle it aproproately. + * It could also be used in stage 4, if required. + */ +// SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;) +void *print_datatypes_error_c::visit(fb_invocation_c *symbol) { + list_c *parameter_list; + + if (NULL != symbol->formal_param_list) + parameter_list = (list_c *)symbol->formal_param_list; + else if (NULL != symbol->nonformal_param_list) + parameter_list = (list_c *)symbol->nonformal_param_list; + else ERROR; + + parameter_list->accept(*this); + + if (NULL == symbol->called_fb_declaration) { + /* Invalid parameters for FB call! */ + STAGE3_ERROR(symbol, symbol, "Invalid parameters in FB invocation: %s\n", ((identifier_c *)symbol->fb_name)->value); + } + + return NULL; +} + + /********************************/ /* B 3.2.3 Selection Statements */ /********************************/ diff -r 43d73e28eca8 -r c8e6cf57324a stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Fri Feb 03 14:43:14 2012 +0000 +++ b/stage3/print_datatypes_error.hh Fri Feb 03 18:16:20 2012 +0000 @@ -273,7 +273,7 @@ /*****************************************/ /* B 3.2.2 Subprogram Control Statements */ /*****************************************/ - //void *visit(fb_invocation_c *symbol); + void *visit(fb_invocation_c *symbol); /********************************/ /* B 3.2.3 Selection Statements */