# HG changeset patch # User Mario de Sousa # Date 1365014992 -3600 # Node ID 6679b6b212144eb13f6f3ea300991cf989a8aabb # Parent 970c582885bf43eb4c187876f4448ce2d5ef5991 Partial fix to VAR_EXTERN vs VAR_GLOBAL check. Now considers globals declared in resources too. TODO: recursively check FB declared in the program. diff -r 970c582885bf -r 6679b6b21214 absyntax_utils/search_var_instance_decl.cc --- a/absyntax_utils/search_var_instance_decl.cc Fri Feb 22 21:09:59 2013 +0000 +++ b/absyntax_utils/search_var_instance_decl.cc Wed Apr 03 19:49:52 2013 +0100 @@ -105,6 +105,7 @@ this->current_vartype = none_vt; this->current_option = none_opt; this->search_name = get_var_name_c::get_name(variable); + if (NULL == search_scope) return NULL; // NOTE: This is not an ERROR! declaration_check_c, for e.g., relies on this returning NULL! return (symbol_c *)search_scope->accept(*this); } @@ -112,6 +113,7 @@ this->current_vartype = none_vt; this->current_option = none_opt; this->search_name = get_var_name_c::get_name(variable); + if (NULL == search_scope) ERROR; search_scope->accept(*this); return this->current_vartype; } @@ -120,6 +122,7 @@ this->current_vartype = none_vt; this->current_option = none_opt; this->search_name = get_var_name_c::get_name(variable); + if (NULL == search_scope) ERROR; search_scope->accept(*this); return this->current_option; } diff -r 970c582885bf -r 6679b6b21214 stage3/declaration_check.cc --- a/stage3/declaration_check.cc Fri Feb 22 21:09:59 2013 +0000 +++ b/stage3/declaration_check.cc Wed Apr 03 19:49:52 2013 +0100 @@ -73,6 +73,7 @@ declaration_check_c::declaration_check_c(symbol_c *ignore) { current_display_error_level = 0; current_pou_decl = NULL; + current_resource_decl = NULL; error_count = 0; } @@ -85,36 +86,47 @@ } void declaration_check_c::check_global_decl(symbol_c *p_decl) { - symbol_c *var_name; - - search_var_instance_decl_c search_var_instance_glo_decl(current_pou_decl); - search_var_instance_decl_c search_var_instance_ext_decl(p_decl); - function_param_iterator_c fpi(p_decl); - while((var_name = fpi.next()) != NULL) { - if (fpi.param_direction() == function_param_iterator_c::direction_extref) { - /* found an external reference parameter. */ - symbol_c *glo_decl = search_var_instance_glo_decl.get_decl(var_name); - symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name); - if (glo_decl == NULL) { - STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external doesn't mach with any global var."); - continue; - } - if (search_var_instance_glo_decl.get_option(var_name) != search_var_instance_ext_decl.get_option(var_name)) - STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error an external redefinition option."); - - /* TODO: Check redefinition data type. - * We need a new class (like search_base_type class) to get type id by variable declaration. - * symbol_c *glo_type = ????; - * symbol_c *ext_type = fpi.param_type(); - */ - /* For the moment, we will just use search_base_type_c instead... */ - symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl); - symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl); - if (! get_datatype_info_c::is_type_equal(glo_type, ext_type)) - STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external redefinition data type."); + if (NULL == current_pou_decl) ERROR; + + search_var_instance_decl_c search_var_instance_pou_glo_decl(current_pou_decl); + search_var_instance_decl_c search_var_instance_res_glo_decl(current_resource_decl); + search_var_instance_decl_c search_var_instance_ext_decl(p_decl); + function_param_iterator_c fpi(p_decl); + + symbol_c *var_name; + while((var_name = fpi.next()) != NULL) { + if (fpi.param_direction() == function_param_iterator_c::direction_extref) { + /* found an external reference parameter. */ + symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name); + + // NOTE: Must check the POU first, and RESOURCE second! + symbol_c *glo_decl = search_var_instance_res_glo_decl.get_decl(var_name); + search_var_instance_decl_c *search_var_instance_glo_decl = &search_var_instance_res_glo_decl; + if (NULL == glo_decl) { + glo_decl = search_var_instance_pou_glo_decl.get_decl(var_name); + search_var_instance_glo_decl = &search_var_instance_pou_glo_decl; } - } - + + if (NULL == glo_decl) { + STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. The external variable does not match with any global variable."); + continue; + } + + if (search_var_instance_glo_decl->get_option(var_name) != search_var_instance_ext_decl.get_option(var_name)) + STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error. The external variable options do not match with thos of the global variable."); + + /* TODO: Check redefinition data type. + * We need a new class (like search_base_type class) to get type id by variable declaration. + * symbol_c *glo_type = ????; + * symbol_c *ext_type = fpi.param_type(); + */ + /* For the moment, we will just use search_base_type_c instead... */ + symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl); + symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl); + if (! get_datatype_info_c::is_type_equal(glo_type, ext_type)) + STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. Data type mismatch between external and global variable declarations."); + } + } } @@ -125,7 +137,10 @@ /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body) void *declaration_check_c::visit(function_block_declaration_c *symbol) { - current_pou_decl = symbol; + /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside FBs! + * current_pou_decl = symbol; + * current_resource_decl = NULL; + */ /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ if (NULL != symbol->var_declarations) symbol->var_declarations->accept(*this); @@ -138,7 +153,10 @@ /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body) void *declaration_check_c::visit(program_declaration_c *symbol) { - current_pou_decl = symbol; + /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside PROGRAMs! + * current_pou_decl = symbol; + * current_resource_decl = NULL; + */ /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ if (NULL != symbol->var_declarations) symbol->var_declarations->accept(*this); @@ -162,9 +180,27 @@ /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ if (NULL != symbol->resource_declarations) symbol->resource_declarations->accept(*this); - return NULL; -} - + current_pou_decl = NULL; + return NULL; +} + +/* +RESOURCE resource_name ON resource_type_name + optional_global_var_declarations + single_resource_declaration +END_RESOURCE +*/ +/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ +// SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, enumvalue_symtable_t enumvalue_symtable;) +void *declaration_check_c::visit(resource_declaration_c *symbol) { + current_resource_decl = symbol; + /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */ + symbol->resource_declaration->accept(*this); + current_resource_decl = NULL; + return NULL; +} + +/* PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */ void *declaration_check_c::visit(program_configuration_c *symbol) { symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name); if (p_decl == program_type_symtable.end_value()) diff -r 970c582885bf -r 6679b6b21214 stage3/declaration_check.hh --- a/stage3/declaration_check.hh Fri Feb 22 21:09:59 2013 +0000 +++ b/stage3/declaration_check.hh Wed Apr 03 19:49:52 2013 +0100 @@ -39,6 +39,7 @@ int error_count; int current_display_error_level; symbol_c *current_pou_decl; + symbol_c *current_resource_decl; public: declaration_check_c(symbol_c *ignore); @@ -61,5 +62,6 @@ /* B 1.7 Configuration elements */ /********************************/ void *visit(configuration_declaration_c *symbol); - void *visit(program_configuration_c *symbol); + void *visit(resource_declaration_c *symbol); + void *visit(program_configuration_c *symbol); };