stage3/declaration_check.cc
changeset 812 6679b6b21214
parent 718 a9f8cc778444
child 865 7365c3e5c9ae
equal deleted inserted replaced
811:970c582885bf 812:6679b6b21214
    71 
    71 
    72 
    72 
    73 declaration_check_c::declaration_check_c(symbol_c *ignore) {
    73 declaration_check_c::declaration_check_c(symbol_c *ignore) {
    74   current_display_error_level = 0;
    74   current_display_error_level = 0;
    75   current_pou_decl = NULL;
    75   current_pou_decl = NULL;
       
    76   current_resource_decl = NULL;
    76   error_count = 0;
    77   error_count = 0;
    77 }
    78 }
    78 
    79 
    79 declaration_check_c::~declaration_check_c(void) {
    80 declaration_check_c::~declaration_check_c(void) {
    80 
    81 
    83 int declaration_check_c::get_error_count() {
    84 int declaration_check_c::get_error_count() {
    84   return error_count;
    85   return error_count;
    85 }
    86 }
    86 
    87 
    87 void declaration_check_c::check_global_decl(symbol_c *p_decl) {
    88 void declaration_check_c::check_global_decl(symbol_c *p_decl) {
    88 	symbol_c *var_name;
    89   if (NULL == current_pou_decl) ERROR;
    89 
    90   
    90 	search_var_instance_decl_c search_var_instance_glo_decl(current_pou_decl);
    91   search_var_instance_decl_c search_var_instance_pou_glo_decl(current_pou_decl);
    91 	search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
    92   search_var_instance_decl_c search_var_instance_res_glo_decl(current_resource_decl);
    92 	function_param_iterator_c fpi(p_decl);
    93   search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
    93 	while((var_name = fpi.next()) != NULL) {
    94   function_param_iterator_c  fpi(p_decl);
    94       if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
    95   
    95      	 /* found an external reference parameter. */
    96   symbol_c *var_name;
    96      	symbol_c *glo_decl = search_var_instance_glo_decl.get_decl(var_name);
    97   while((var_name = fpi.next()) != NULL) {
    97         symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
    98     if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
    98     	if (glo_decl == NULL) {
    99       /* found an external reference parameter. */
    99     	  STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external doesn't mach with any global var.");
   100       symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
   100     	  continue;
   101       
   101     	}
   102       // NOTE: Must check the POU first, and RESOURCE second!
   102         if (search_var_instance_glo_decl.get_option(var_name) != search_var_instance_ext_decl.get_option(var_name))
   103       symbol_c                                       *glo_decl =  search_var_instance_res_glo_decl.get_decl(var_name);           
   103           STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error an external redefinition option.");
   104       search_var_instance_decl_c *search_var_instance_glo_decl = &search_var_instance_res_glo_decl;
   104 
   105       if (NULL == glo_decl) {
   105         /* TODO: Check redefinition data type.
   106         glo_decl                     =  search_var_instance_pou_glo_decl.get_decl(var_name);
   106          *       We need a new class (like search_base_type class) to get type id by variable declaration.
   107         search_var_instance_glo_decl = &search_var_instance_pou_glo_decl;
   107          *  symbol_c *glo_type = ????;
       
   108          *  symbol_c *ext_type = fpi.param_type();
       
   109 	 */
       
   110 	/* For the moment, we will just use search_base_type_c instead... */
       
   111         symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl);
       
   112         symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl);
       
   113         if (! get_datatype_info_c::is_type_equal(glo_type, ext_type))
       
   114           STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external redefinition data type.");
       
   115       }
   108       }
   116 	}
   109       
   117 
   110       if (NULL == glo_decl) {
       
   111         STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. The external variable does not match with any global variable.");
       
   112         continue;
       
   113       }
       
   114       
       
   115       if (search_var_instance_glo_decl->get_option(var_name) != search_var_instance_ext_decl.get_option(var_name))
       
   116         STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error.  The external variable options do not match with thos of the global variable.");
       
   117 
       
   118       /* TODO: Check redefinition data type.
       
   119        *       We need a new class (like search_base_type class) to get type id by variable declaration.
       
   120        *  symbol_c *glo_type = ????;
       
   121        *  symbol_c *ext_type = fpi.param_type();
       
   122        */
       
   123       /* For the moment, we will just use search_base_type_c instead... */
       
   124       symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl);
       
   125       symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl);
       
   126       if (! get_datatype_info_c::is_type_equal(glo_type, ext_type))
       
   127         STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error.  Data type mismatch between external and global variable declarations.");
       
   128     }
       
   129   }
   118 }
   130 }
   119 
   131 
   120 
   132 
   121 
   133 
   122 /*****************************/
   134 /*****************************/
   123 /* B 1.5.2 - Function Blocks */
   135 /* B 1.5.2 - Function Blocks */
   124 /*****************************/
   136 /*****************************/
   125 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
   137 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
   126 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
   138 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
   127 void *declaration_check_c::visit(function_block_declaration_c *symbol) {
   139 void *declaration_check_c::visit(function_block_declaration_c *symbol) {
   128   current_pou_decl = symbol;
   140   /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside FBs!
       
   141    * current_pou_decl = symbol;  
       
   142    * current_resource_decl = NULL;  
       
   143    */
   129   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
   144   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
   130   if (NULL != symbol->var_declarations)
   145   if (NULL != symbol->var_declarations)
   131     symbol->var_declarations->accept(*this);
   146     symbol->var_declarations->accept(*this);
   132   return NULL;
   147   return NULL;
   133 }
   148 }
   136 /* B 1.5.3 - Declaration & Initialisation */
   151 /* B 1.5.3 - Declaration & Initialisation */
   137 /******************************************/
   152 /******************************************/
   138 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
   153 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
   139 // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body)
   154 // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body)
   140 void *declaration_check_c::visit(program_declaration_c *symbol) {
   155 void *declaration_check_c::visit(program_declaration_c *symbol) {
   141   current_pou_decl = symbol;
   156   /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside PROGRAMs!
       
   157    * current_pou_decl = symbol;  
       
   158    * current_resource_decl = NULL;  
       
   159    */
   142   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
   160   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
   143   if (NULL != symbol->var_declarations)
   161   if (NULL != symbol->var_declarations)
   144     symbol->var_declarations->accept(*this);
   162     symbol->var_declarations->accept(*this);
   145   return NULL;
   163   return NULL;
   146 }
   164 }
   160 void *declaration_check_c::visit(configuration_declaration_c *symbol) {
   178 void *declaration_check_c::visit(configuration_declaration_c *symbol) {
   161   current_pou_decl = symbol;
   179   current_pou_decl = symbol;
   162   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
   180   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
   163   if (NULL != symbol->resource_declarations)
   181   if (NULL != symbol->resource_declarations)
   164     symbol->resource_declarations->accept(*this);
   182     symbol->resource_declarations->accept(*this);
   165   return NULL;
   183   current_pou_decl = NULL;
   166 }
   184   return NULL;
   167 
   185 }
       
   186 
       
   187 /*
       
   188 RESOURCE resource_name ON resource_type_name
       
   189    optional_global_var_declarations
       
   190    single_resource_declaration
       
   191 END_RESOURCE
       
   192 */
       
   193 /* 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 */
       
   194 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, enumvalue_symtable_t enumvalue_symtable;)
       
   195 void *declaration_check_c::visit(resource_declaration_c *symbol) {
       
   196   current_resource_decl = symbol;
       
   197   /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
       
   198   symbol->resource_declaration->accept(*this);
       
   199   current_resource_decl = NULL;  
       
   200   return NULL;
       
   201 }
       
   202 
       
   203 /*  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
   168 void *declaration_check_c::visit(program_configuration_c *symbol) {
   204 void *declaration_check_c::visit(program_configuration_c *symbol) {
   169   symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
   205   symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
   170   if (p_decl == program_type_symtable.end_value())
   206   if (p_decl == program_type_symtable.end_value())
   171     p_decl = function_block_type_symtable.find_value(symbol->program_type_name);
   207     p_decl = function_block_type_symtable.find_value(symbol->program_type_name);
   172   /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */
   208   /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */