# HG changeset patch # User laurent # Date 1330089411 -3600 # Node ID 6381589697ff71a2b1d4af1da2755feb57929b33 # Parent 7b5d67d1aeef21ec733187abe88f7222d4e210e0 Fix bug with overloaded function due to literal input values diff -r 7b5d67d1aeef -r 6381589697ff absyntax/absyntax.def --- a/absyntax/absyntax.def Tue Feb 21 22:31:38 2012 +0100 +++ b/absyntax/absyntax.def Fri Feb 24 14:16:51 2012 +0100 @@ -920,11 +920,11 @@ SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand) /* | function_name [il_operand_list] */ -/* NOTE: The parameters 'called_function_declaration' and 'overloaded_return_type' are used to pass +/* NOTE: The parameters 'called_function_declaration' is used to pass * data between the stage 3 and stage 4. * See the comment above function_invocation_c for more details */ -SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; symbol_c *overloaded_return_type; int extensible_param_count;) +SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ @@ -943,11 +943,11 @@ /* | function_name '(' eol_list [il_param_list] ')' */ -/* NOTE: The parameters 'called_function_declaration' and 'overloaded_return_type' are used to pass +/* NOTE: The parameters 'called_function_declaration' is used to pass * data between the stage 3 and stage 4. * See the comment above function_invocation_c for more details */ -SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; symbol_c *overloaded_return_type; int extensible_param_count;) +SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) /* | il_operand_list ',' il_operand */ SYM_LIST(il_operand_list_c) @@ -1047,7 +1047,7 @@ /* formal_param_list -> may be NULL ! */ /* nonformal_param_list -> may be NULL ! */ -/* NOTE: The parameters 'called_function_declaration' and 'overloaded_return_type' are used to pass +/* NOTE: The parameters 'called_function_declaration' is used to pass * data between the stage 3 and stage 4. * The IEC 61131-3 standard allows for overloaded standard functions. This means that some * function calls are not compeletely defined by the name of the function being called, @@ -1058,7 +1058,7 @@ * and again in stage 4), so stage 3 will store this infor in the parameter called_function_declaration * for stage 4 to use it later on. */ -SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; symbol_c *overloaded_return_type; int extensible_param_count;) +SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count;) /********************/ diff -r 7b5d67d1aeef -r 6381589697ff stage3/visit_expression_type.cc --- a/stage3/visit_expression_type.cc Tue Feb 21 22:31:38 2012 +0100 +++ b/stage3/visit_expression_type.cc Fri Feb 24 14:16:51 2012 +0100 @@ -584,11 +584,11 @@ symbol_c *visit_expression_type_c::overloaded_return_type(symbol_c *type) { if (is_ANY_INT_compatible(type)) - return &search_constant_type_c::ulint_type_name; + return &search_constant_type_c::ulint_type_name; else if (is_ANY_REAL_compatible(type)) - return &search_constant_type_c::lreal_type_name; + return &search_constant_type_c::lreal_type_name; else if (is_ANY_BIT_compatible(type)) - return &search_constant_type_c::lword_type_name; + return &search_constant_type_c::lword_type_name; return NULL; } @@ -1068,11 +1068,13 @@ symbol_c *return_data_type = NULL; symbol_c* fdecl_return_type; + symbol_c* overloaded_data_type = NULL; symbol->called_function_declaration = NULL; /* First find the declaration of the function being called! */ function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name); + function_symtable_t::iterator current; if (lower == function_symtable.end()) ERROR; int error_count = 0; @@ -1084,8 +1086,8 @@ /* This is a call to an overloaded function... */ error_count_ptr = &error_count; - for(; lower != upper; lower++) { - function_declaration_c *f_decl = function_symtable.get_value(lower); + for(current = lower; current != upper; current++) { + function_declaration_c *f_decl = function_symtable.get_value(current); check_nonformal_call(symbol, f_decl, true, error_count_ptr); @@ -1098,27 +1100,48 @@ fdecl_return_type = base_type(f_decl->type_name); if (symbol->called_function_declaration == NULL) { - /* Store the pointer to the declaration of the function being called. - * This data will be used by stage 4 to call the correct function. - * Mostly needed to disambiguate overloaded functions... - * See comments in absyntax.def for more details + /* Store the pointer to the declaration of the function being called. + * This data will be used by stage 4 to call the correct function. + * Mostly needed to disambiguate overloaded functions... + * See comments in absyntax.def for more details */ symbol->called_function_declaration = f_decl; - symbol->overloaded_return_type = NULL; - - /* determine the base data type returned by the function being called... */ - return_data_type = fdecl_return_type; - } - else if (typeid(*return_data_type) != typeid(*fdecl_return_type)){ - if (symbol->overloaded_return_type == NULL) - symbol->overloaded_return_type = overloaded_return_type(return_data_type); - return_data_type = common_literal(return_data_type, fdecl_return_type); - } + + /* determine the base data type returned by the function being called... */ + return_data_type = fdecl_return_type; + } + else if (typeid(*return_data_type) != typeid(*fdecl_return_type)){ + return_data_type = common_literal(return_data_type, fdecl_return_type); + overloaded_data_type = overloaded_return_type(return_data_type); + } if (NULL == return_data_type) ERROR; } } + if (overloaded_data_type != NULL) { + for(current = lower; current != upper; current++) { + function_declaration_c *f_decl = function_symtable.get_value(current); + + /* check semantics of data passed in the function call... */ + check_nonformal_call(symbol, f_decl, true, error_count_ptr); + + if (0 == error_count) { + + fdecl_return_type = base_type(f_decl->type_name); + + if (typeid(*overloaded_data_type) == typeid(*fdecl_return_type)){ + /* Store the pointer to the declaration of the function being called. + * This data will be used by stage 4 to call the correct function. + * Mostly needed to disambiguate overloaded functions... + * See comments in absyntax.def for more details + */ + symbol->called_function_declaration = f_decl; + } + } + } + } + if (NULL == return_data_type) { /* No compatible function was found for this function call */ STAGE3_ERROR(symbol, symbol, "Call to an overloaded function with invalid parameter type."); @@ -1249,10 +1272,12 @@ symbol_c *return_data_type = NULL; symbol_c* fdecl_return_type; + symbol_c *overloaded_data_type = NULL; symbol->called_function_declaration = NULL; function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name); + function_symtable_t::iterator current; if (lower == function_symtable.end()) { function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name); @@ -1269,8 +1294,8 @@ /* This is a call to an overloaded function... */ error_count_ptr = &error_count; - for(; lower != upper; lower++) { - function_declaration_c *f_decl = function_symtable.get_value(lower); + for(current = lower; current != upper; current++) { + function_declaration_c *f_decl = function_symtable.get_value(current); /* check semantics of data passed in the function call... */ check_formal_call(symbol, f_decl, error_count_ptr); @@ -1284,22 +1309,20 @@ fdecl_return_type = base_type(f_decl->type_name); if (symbol->called_function_declaration == NULL) { - /* Store the pointer to the declaration of the function being called. - * This data will be used by stage 4 to call the correct function. - * Mostly needed to disambiguate overloaded functions... - * See comments in absyntax.def for more details + /* Store the pointer to the declaration of the function being called. + * This data will be used by stage 4 to call the correct function. + * Mostly needed to disambiguate overloaded functions... + * See comments in absyntax.def for more details */ symbol->called_function_declaration = f_decl; - symbol->overloaded_return_type = NULL; - - /* determine the base data type returned by the function being called... */ - return_data_type = fdecl_return_type; - } - else if (typeid(*return_data_type) != typeid(*fdecl_return_type)){ - if (symbol->overloaded_return_type == NULL) - symbol->overloaded_return_type = overloaded_return_type(return_data_type); - return_data_type = common_literal(return_data_type, fdecl_return_type); - } + + /* determine the base data type returned by the function being called... */ + return_data_type = fdecl_return_type; + } + else if (typeid(*return_data_type) != typeid(*fdecl_return_type)){ + return_data_type = common_literal(return_data_type, fdecl_return_type); + overloaded_data_type = overloaded_return_type(return_data_type); + } /* the following should never occur. If it does, then we have a bug in the syntax parser (stage 2)... */ if (NULL == return_data_type) ERROR; @@ -1307,9 +1330,32 @@ } } + if (overloaded_data_type != NULL) { + for(current = lower; current != upper; current++) { + function_declaration_c *f_decl = function_symtable.get_value(current); + + /* check semantics of data passed in the function call... */ + check_formal_call(symbol, f_decl, error_count_ptr); + + if (0 == error_count) { + + fdecl_return_type = base_type(f_decl->type_name); + + if (typeid(*overloaded_data_type) == typeid(*fdecl_return_type)){ + /* Store the pointer to the declaration of the function being called. + * This data will be used by stage 4 to call the correct function. + * Mostly needed to disambiguate overloaded functions... + * See comments in absyntax.def for more details + */ + symbol->called_function_declaration = f_decl; + } + } + } + } + if (NULL == return_data_type) { - /* No compatible function was found for this function call */ - STAGE3_ERROR(symbol, symbol, "Call to an overloaded function with invalid parameter type."); + /* No compatible function was found for this function call */ + STAGE3_ERROR(symbol, symbol, "Call to an overloaded function with invalid parameter type."); } else { /* the data type of the data returned by the function, and stored in the il default variable... */ @@ -2067,16 +2113,18 @@ void *visit_expression_type_c::visit(function_invocation_c *symbol) { function_symtable_t::iterator lower = function_symtable.lower_bound(symbol->function_name); function_symtable_t::iterator upper = function_symtable.upper_bound(symbol->function_name); + function_symtable_t::iterator current; if (lower == function_symtable.end()) ERROR; symbol_c* return_data_type; symbol_c* fdecl_return_type; + symbol_c* overloaded_data_type = NULL; symbol->called_function_declaration = NULL; function_symtable_t::iterator second = lower; second++; if (second == upper) { - /* call to a function that is not overloaded. */ + /* call to a function that is not overloaded. */ /* now check the semantics of the function call... */ /* If the syntax parser is working correctly, exactly one of the * following two symbols will be NULL, while the other is != NULL. @@ -2090,16 +2138,15 @@ * See comments in absyntax.def for more details */ symbol->called_function_declaration = f_decl; - symbol->overloaded_return_type = NULL; return base_type(f_decl->type_name); } /* This is a call to an overloaded function... */ if (debug) printf("visit_expression_type_c::visit(function_invocation_c *symbol): FOUND CALL TO OVERLOADED FUNCTION!!\n"); - for(; lower != upper; lower++) { + for(current = lower; current != upper; current++) { if (debug) printf("visit_expression_type_c::visit(function_invocation_c *symbol): FOUND CALL TO OVERLOADED FUNCTION!! iterating...\n"); int error_count = 0; - function_declaration_c *f_decl = function_symtable.get_value(lower); + function_declaration_c *f_decl = function_symtable.get_value(current); if (symbol-> formal_param_list != NULL) check_formal_call (symbol, f_decl, &error_count); if (symbol->nonformal_param_list != NULL) check_nonformal_call(symbol, f_decl, false, &error_count); if (0 == error_count) { @@ -2113,23 +2160,43 @@ * See comments in absyntax.def for more details */ symbol->called_function_declaration = f_decl; - symbol->overloaded_return_type = NULL; /* determine the base data type returned by the function being called... */ return_data_type = fdecl_return_type; } else if (typeid(*return_data_type) != typeid(*fdecl_return_type)){ - if (symbol->overloaded_return_type == NULL) - symbol->overloaded_return_type = overloaded_return_type(return_data_type); - return_data_type = common_literal(return_data_type, fdecl_return_type); + return_data_type = common_literal(return_data_type, fdecl_return_type); + overloaded_data_type = overloaded_return_type(return_data_type); } if (NULL == return_data_type) ERROR; } } + if (overloaded_data_type != NULL) { + for(current = lower; current != upper; current++) { + function_declaration_c *f_decl = function_symtable.get_value(current); + int error_count = 0; + if (symbol-> formal_param_list != NULL) check_formal_call (symbol, f_decl, &error_count); + if (symbol->nonformal_param_list != NULL) check_nonformal_call(symbol, f_decl, false, &error_count); + if (0 == error_count) { + + fdecl_return_type = base_type(f_decl->type_name); + + if (typeid(*overloaded_data_type) == typeid(*fdecl_return_type)){ + /* Store the pointer to the declaration of the function being called. + * This data will be used by stage 4 to call the correct function. + * Mostly needed to disambiguate overloaded functions... + * See comments in absyntax.def for more details + */ + symbol->called_function_declaration = f_decl; + } + } + } + } + if (return_data_type != NULL) - return return_data_type; + return return_data_type; /* No compatible function was found for this function call */ STAGE3_ERROR(symbol, symbol, "Call to an overloaded function with invalid parameter type."); diff -r 7b5d67d1aeef -r 6381589697ff stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Tue Feb 21 22:31:38 2012 +0100 +++ b/stage4/generate_c/generate_c.cc Fri Feb 24 14:16:51 2012 +0100 @@ -182,7 +182,6 @@ class print_function_parameter_data_types_c: public generate_c_base_c { private: symbol_c *current_type; - symbol_c *return_type; bool_type_name_c tmp_bool; void print_list(symbol_c *var_list, symbol_c *data_type) { @@ -198,10 +197,9 @@ } public: - print_function_parameter_data_types_c(stage4out_c *s4o_ptr, symbol_c* return_type): + print_function_parameter_data_types_c(stage4out_c *s4o_ptr): generate_c_base_c(s4o_ptr) { current_type = NULL; - this->return_type = return_type; } /**************************************/ @@ -214,10 +212,7 @@ /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ void *visit(function_declaration_c *symbol) { /* return type */ - if (this->return_type == NULL) - symbol->type_name->accept(*this); - else - this->return_type->accept(*this); + symbol->type_name->accept(*this); symbol->var_declarations_list->accept(*this); return NULL; } diff -r 7b5d67d1aeef -r 6381589697ff stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Tue Feb 21 22:31:38 2012 +0100 +++ b/stage4/generate_c/generate_c_il.cc Fri Feb 24 14:16:51 2012 +0100 @@ -968,7 +968,7 @@ if (fdecl_mutiplicity == 2) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, symbol->overloaded_return_type); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } s4o.print_integer(fcall_number); @@ -979,7 +979,7 @@ if (fdecl_mutiplicity == 2) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, symbol->overloaded_return_type); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } } @@ -1376,7 +1376,7 @@ if (fdecl_mutiplicity == 2) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, symbol->overloaded_return_type); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } s4o.print_integer(fcall_number); @@ -1387,7 +1387,7 @@ if (fdecl_mutiplicity == 2) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, symbol->overloaded_return_type); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } } diff -r 7b5d67d1aeef -r 6381589697ff stage4/generate_c/generate_c_inlinefcall.cc --- a/stage4/generate_c/generate_c_inlinefcall.cc Tue Feb 21 22:31:38 2012 +0100 +++ b/stage4/generate_c/generate_c_inlinefcall.cc Fri Feb 24 14:16:51 2012 +0100 @@ -169,7 +169,7 @@ if (f_decl != NULL) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, function_type_prefix); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } if (function_type_suffix) { @@ -222,7 +222,7 @@ if (f_decl != NULL) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, function_type_prefix); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } @@ -492,10 +492,7 @@ /* determine the base data type returned by the function being called... */ search_base_type_c search_base_type; - if (symbol->overloaded_return_type == NULL) - function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type); - else - function_type_prefix = symbol->overloaded_return_type; + function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type); function_name = symbol->function_name; @@ -678,10 +675,7 @@ /* determine the base data type returned by the function being called... */ search_base_type_c search_base_type; - if (symbol->overloaded_return_type == NULL) - function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type); - else - function_type_prefix = symbol->overloaded_return_type; + function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type); if (NULL == function_type_prefix) ERROR; function_name = symbol->function_name; @@ -1050,10 +1044,7 @@ /* determine the base data type returned by the function being called... */ search_base_type_c search_base_type; - if (symbol->overloaded_return_type == NULL) - function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type); - else - function_type_prefix = symbol->overloaded_return_type; + function_type_prefix = (symbol_c *)f_decl->type_name->accept(search_base_type); if (NULL == function_type_prefix) ERROR; /* loop through each function parameter, find the value we should pass diff -r 7b5d67d1aeef -r 6381589697ff stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Tue Feb 21 22:31:38 2012 +0100 +++ b/stage4/generate_c/generate_c_st.cc Fri Feb 24 14:16:51 2012 +0100 @@ -782,7 +782,7 @@ if (fdecl_mutiplicity == 2) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, symbol->overloaded_return_type); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } s4o.print_integer(fcall_number); @@ -792,7 +792,7 @@ if (fdecl_mutiplicity == 2) { /* function being called is overloaded! */ s4o.print("__"); - print_function_parameter_data_types_c overloaded_func_suf(&s4o, symbol->overloaded_return_type); + print_function_parameter_data_types_c overloaded_func_suf(&s4o); f_decl->accept(overloaded_func_suf); } }