Fix bug with overloaded function due to literal input values
authorlaurent
Fri, 24 Feb 2012 14:16:51 +0100
changeset 406 6381589697ff
parent 405 7b5d67d1aeef
child 407 2d77f0f77773
child 498 0637a4490c8c
Fix bug with overloaded function due to literal input values
absyntax/absyntax.def
stage3/visit_expression_type.cc
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_c/generate_c_st.cc
--- 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;)
 
 
 /********************/
--- 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.");
--- 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;
     }
--- 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);
       }
     }  
--- 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
--- 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);
     }
   }