--- a/stage3/print_datatypes_error.cc Thu Feb 23 13:25:49 2012 +0000
+++ b/stage3/print_datatypes_error.cc Sat Feb 25 19:16:35 2012 +0000
@@ -183,6 +183,8 @@
fcall_data.nonformal_operand_list->accept(*this);
if (f_decl)
for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) {
+ /* TODO: verify if it is lvalue when INOUT or OUTPUT parameters! */
+
if (NULL == param_value->datatype) {
function_invocation_error = true;
STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value);
@@ -203,31 +205,57 @@
return;
}
+
+
void print_datatypes_error_c::handle_implicit_il_fb_invocation(symbol_c *il_operator, const char *param_name, symbol_c *called_fb_declaration) {
if (NULL == il_operand) {
STAGE3_ERROR(0, il_operator, il_operator, "Missing operand for FB call operator '%s'.", param_name);
return;
}
+ il_operand->accept(*this);
+
if (NULL == called_fb_declaration) {
- STAGE3_ERROR(0, il_operand, il_operand, "Operand of FB call operator '%s' is not a FB variable.", param_name);
+ STAGE3_ERROR(0, il_operator, il_operand, "Invalid FB call: operand is not a FB instance.");
return;
}
+
if (NULL == prev_il_instruction) {
STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name);
return;
}
+
/* Find the corresponding parameter in function declaration */
function_param_iterator_c fp_iterator(called_fb_declaration);
if (NULL == fp_iterator.search(param_name)) {
-/* TODO: must also check whther it is an IN parameter!! */
+ /* TODO: must also check whther it is an IN parameter!! */
+ /* NOTE: although all standard FBs have the implicit FB calls defined as input parameters
+ * (i.e., for all standard FBs, CLK, PT, IN, CU, CD, S1, R1, etc... is always an input parameter)
+ * if a non-standard (i.e. a FB not defined in the standard library) FB is being called, then
+ * this (CLK, PT, IN, CU, ...) parameter may just have been defined as OUT or INOUT,
+ * which will not work for an implicit FB call!
+ */
STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name);
return;
}
if (NULL == prev_il_instruction->datatype) {
- STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed, when invoking FB.", param_name);
+ STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name);
return;
}
-
+
+
+ /* NOTE: The error_level currently being used for errors in variables/constants etc... is rather high.
+ * However, in the case of an implicit FB call, if the datatype of the operand == NULL, this may be
+ * the __only__ indication of an error! So we test it here again, to make sure thtis error will really
+ * be printed out!
+ */
+ if (NULL == il_operand->datatype) {
+ /* Note: the case of (NULL == fb_declaration) was already caught above! */
+// if (NULL != fb_declaration) {
+ STAGE3_ERROR(0, il_operator, il_operator, "Invalid FB call: Datatype incompatibility between the FB's '%s' parameter and value being passed, or paramater '%s' is not a 'VAR_INPUT' parameter.", param_name, param_name);
+ return;
+// }
+ }
+//
return;
}
@@ -552,10 +580,8 @@
/* B 1.7 Configuration elements */
/********************************/
void *print_datatypes_error_c::visit(configuration_declaration_c *symbol) {
-#if 0
// TODO !!!
/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
-#endif
return NULL;
}
@@ -681,6 +707,8 @@
};
handle_function_invocation(symbol, fcall_param);
+ /* check the semantics of the CALC, CALCN operators! */
+ symbol->il_call_operator->accept(*this);
return NULL;
}
@@ -922,12 +950,19 @@
return NULL;
}
+
+void *print_datatypes_error_c::handle_conditional_flow_control_IL_instruction(symbol_c *symbol, const char *oper) {
+ if (NULL == symbol->datatype)
+ STAGE3_ERROR(0, symbol, symbol, "%s operator must be preceded by an IL instruction producing a BOOL value.", oper);
+ return NULL;
+}
+
void *print_datatypes_error_c::visit(CALC_operator_c *symbol) {
- return NULL;
+ return handle_conditional_flow_control_IL_instruction(symbol, "CALC");
}
void *print_datatypes_error_c::visit(CALCN_operator_c *symbol) {
- return NULL;
+ return handle_conditional_flow_control_IL_instruction(symbol, "CALCN");
}
void *print_datatypes_error_c::visit(RET_operator_c *symbol) {
@@ -935,11 +970,11 @@
}
void *print_datatypes_error_c::visit(RETC_operator_c *symbol) {
- return NULL;
+ return handle_conditional_flow_control_IL_instruction(symbol, "RETC");
}
void *print_datatypes_error_c::visit(RETCN_operator_c *symbol) {
- return NULL;
+ return handle_conditional_flow_control_IL_instruction(symbol, "RETCN");
}
void *print_datatypes_error_c::visit(JMP_operator_c *symbol) {
@@ -947,11 +982,11 @@
}
void *print_datatypes_error_c::visit(JMPC_operator_c *symbol) {
- return NULL;
+ return handle_conditional_flow_control_IL_instruction(symbol, "JMPC");
}
void *print_datatypes_error_c::visit(JMPCN_operator_c *symbol) {
- return NULL;
+ return handle_conditional_flow_control_IL_instruction(symbol, "JMPCN");
}
/* Symbol class handled together with function call checks */