Print error messages when datatype erros found in ST function/FB calls.
authorMario de Sousa <msousa@fe.up.pt>
Fri, 03 Feb 2012 18:16:20 +0000
changeset 425 c8e6cf57324a
parent 424 43d73e28eca8
child 426 78f31e12fc52
Print error messages when datatype erros found in ST function/FB calls.
stage3/datatype_functions.cc
stage3/datatype_functions.hh
stage3/narrow_candidate_datatypes.cc
stage3/print_datatypes_error.cc
stage3/print_datatypes_error.hh
--- 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 <symbol_c *> 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)
 {
--- 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 <symbol_c *> 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! */
 
 
 
--- 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) 
--- 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 */
 /********************************/
--- 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 */