# HG changeset patch # User Mario de Sousa # Date 1491394910 -3600 # Node ID 34b733cb66416ade8272c8a4463377b232666f39 # Parent 292b7dcf14f6743d1bcd225aff8b9766483abebe Do datatype checking of initial values for structures and FBs, and print error messages when compiling erroneuos source code. diff -r 292b7dcf14f6 -r 34b733cb6641 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Apr 04 17:21:42 2017 +0100 +++ b/stage3/fill_candidate_datatypes.cc Wed Apr 05 13:21:50 2017 +0100 @@ -1176,21 +1176,28 @@ iterator_visitor_c::visit(symbol); // call visit(structure_element_initialization_c *) on all elements for (unsigned int i = 0; i < symbol->parent->candidate_datatypes.size(); i++) { // size() should always be 1 here -> a single structure or FB type! - // assume symbol->parent is a FB type + // assume symbol->parent->candidate_datatypes[i] is a FB type search_varfb_instance_type_c search_varfb_instance_type(symbol->parent->candidate_datatypes[i]); + // assume symbol->parent->candidate_datatypes[i] is a STRUCT data type + structure_element_declaration_list_c *struct_decl = dynamic_cast(symbol->parent->candidate_datatypes[i]); // flag indicating all struct_elem->structure_element_name are structure elements found in the symbol->parent->candidate_datatypes[i] datatype int flag_all_elem_ok = 1; // assume all found for (int k = 0; k < symbol->n; k++) { - // assume symbol->parent->candidate_datatypes[i] is a FB type... - structure_element_initialization_c *struct_elem = (structure_element_initialization_c *)symbol->get_element(k); - symbol_c *type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name); - if (!get_datatype_info_c::is_type_valid(type)) { - // either get_datatype_info_c::is_type_valid(type) is not a FB type, or the element is not declared in that FB - // Lets try a struct type!! - // TODO... + structure_element_initialization_c *struct_elem = dynamic_cast(symbol->get_element(k)); + if (struct_elem == NULL) ERROR; + + // assume symbol->parent is a FB type... + symbol_c *type = NULL; + if (struct_decl != NULL) { + // search in the struct!! + type = search_base_type_c::get_basetype_decl(struct_decl->find_element(struct_elem->structure_element_name)); + } else { + // parent is a FB type. Lets search there!! + type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name); } if (!get_datatype_info_c::is_ANY_ELEMENTARY(type) && get_datatype_info_c::is_type_valid(type)) { - add_datatype_to_candidate_list(struct_elem, type); // for non-elementary datatypes, we must use a top->down algorithm!! + // for non-elementary datatypes, we must use a top->down algorithm!! + add_datatype_to_candidate_list(struct_elem, type); struct_elem->accept(*this); } if (search_in_candidate_datatype_list(type, struct_elem->candidate_datatypes) < 0) { diff -r 292b7dcf14f6 -r 34b733cb6641 stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Tue Apr 04 17:21:42 2017 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Wed Apr 05 13:21:50 2017 +0100 @@ -673,20 +673,36 @@ /* structure_element_initialization_list ',' structure_element_initialization */ // SYM_LIST(structure_element_initialization_list_c) void *narrow_candidate_datatypes_c::visit(structure_element_initialization_list_c *symbol) { - if (get_datatype_info_c::is_type_valid(symbol->datatype)) { - /* Note that in principle structure_element_initialization_list_c will have at most 1 candidate_datatype - * (the FB or structure in the type specification). However, our algorithm is more generic and will - * assume that more than 1 candidate_datatype is possible. In this case we need to iterate and check each - * candidate_datatype whether it is feasible, as they may all be feasible but not for the same ... - */ - // assume symbol->datatype is a FB type - search_varfb_instance_type_c search_varfb_instance_type(symbol->datatype); + symbol_c *type = NULL; + + // first try to narrow with the correct type, if valid. + if (!get_datatype_info_c::is_type_valid(type)) type = symbol->datatype; + // to reduce number of error messages, we try to narrow with parent's spec_init->datatype + if (!get_datatype_info_c::is_type_valid(type)) type = symbol->parent->datatype; + + if (get_datatype_info_c::is_type_valid(type)) { + // We need to iterate and determine the required datatype of each structure element + // assume type is a FB type + search_varfb_instance_type_c search_varfb_instance_type(type); + // assume type is a STRUCT type + structure_element_declaration_list_c *struct_decl = dynamic_cast(type); for (int k = 0; k < symbol->n; k++) { structure_element_initialization_c *struct_elem = (structure_element_initialization_c *)symbol->get_element(k); - symbol_c *type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name); + symbol_c *type = NULL; + if (struct_decl == NULL) { + // type is not a struct. Must be a FB. + type = search_varfb_instance_type.get_basetype_decl(struct_elem->structure_element_name); + } else { + // type is a struct. + type = search_base_type_c::get_basetype_decl(struct_decl->find_element(struct_elem->structure_element_name)); + } set_datatype(type, struct_elem); struct_elem->accept(*this); - if (struct_elem->datatype == NULL) ERROR; // should never occur. Already checked in fill_candidate_datatypes_c + /* We do best effort narrowing, even in the presence of errors, to reduce number of error messages + * so the following two assertions are not always met. + */ + // if (!get_datatype_info_c::is_type_valid(type)) ERROR; + // if (struct_elem->datatype == NULL) ERROR; // should never occur. Already checked in fill_candidate_datatypes_c } } return NULL; @@ -694,7 +710,7 @@ /* structure_element_name ASSIGN value */ // SYM_REF2(structure_element_initialization_c, structure_element_name, value) -void *narrow_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) {set_datatype(symbol->datatype, symbol->value); return NULL;} +void *narrow_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) {set_datatype(symbol->datatype, symbol->value); symbol->value->accept(*this); return NULL;} /* string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */ // SYM_REF4(string_type_declaration_c, string_type_name, elementary_string_type_name, string_type_declaration_size, string_type_declaration_init/* may be == NULL! */) diff -r 292b7dcf14f6 -r 34b733cb6641 stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Tue Apr 04 17:21:42 2017 +0100 +++ b/stage3/print_datatypes_error.cc Wed Apr 05 13:21:50 2017 +0100 @@ -545,6 +545,16 @@ } + +void *print_datatypes_error_c::visit(structure_element_initialization_c *symbol) { + symbol->value->accept(*this); + if (!get_datatype_info_c::is_type_valid(symbol->datatype)) + STAGE3_ERROR(0, symbol, symbol, "Initialization element identifier (%s) is not declared in referenced structure/FB scope, or is set to value of incompatible datatype.", + symbol->structure_element_name->token->value); + return NULL; +} + + /*********************/ /* B 1.4 - Variables */ /*********************/ diff -r 292b7dcf14f6 -r 34b733cb6641 stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Tue Apr 04 17:21:42 2017 +0100 +++ b/stage3/print_datatypes_error.hh Wed Apr 05 13:21:50 2017 +0100 @@ -161,6 +161,8 @@ void *visit(simple_spec_init_c *symbol); // void *visit(data_type_declaration_c *symbol); /* use base iterator_c method! */ void *visit(enumerated_value_c *symbol); +// void *visit(structure_element_initialization_list_c *symbol); + void *visit(structure_element_initialization_c *symbol); /*********************/ /* B 1.4 - Variables */