# HG changeset patch # User Mario de Sousa # Date 1491253600 -3600 # Node ID e8563dcaefca47ff6699896d10e080c682c7e7bd # Parent bf39078476e493a75c6c8ed5f1c8ef9926af900b Start implementation of datatype checking of initial values for structures and FBs. diff -r bf39078476e4 -r e8563dcaefca stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Mon Apr 03 18:30:50 2017 +0100 +++ b/stage3/fill_candidate_datatypes.cc Mon Apr 03 22:06:40 2017 +0100 @@ -958,7 +958,15 @@ type_spec->accept(*this); // use bottom->up algorithm!! - if (NULL != init_value) init_value->accept(*this); + /* NOTE: In special cases we will run a modified bottom->up algorithm, i.e. with a top->down indication of + * tentative candidate_datatypes... + * (e.g. structure_element_initialization_list_c). The tentative candidate_datatypes (a list of + * candidate_datatypes to consider while running the bottom->up algorithm) will actually be the + * datatypes in symbol->parent->candidate_datatpes + * This implies that we can only run this bottom->up algorithm on the initial values _after_ + * having set the symbol->candidate_datatpes of the type specification (i.e. the symbol parameter) + */ + if (NULL != init_value) init_value->accept(*this); /* NOTE: Even if the constant and the type are of incompatible data types, we let the * ***_spec_init_c object inherit the data type of the type declaration (simple_specification) * This will let us produce more informative error messages when checking data type compatibility @@ -1163,9 +1171,51 @@ /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ // SYM_LIST(structure_element_initialization_list_c) +void *fill_candidate_datatypes_c::visit(structure_element_initialization_list_c *symbol) { + // use bottom->up algorithm -> first let all elements determine their candidate_datatypes + 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 + search_varfb_instance_type_c search_varfb_instance_type(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->elements[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... + } + 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!! + struct_elem->accept(*this); + } + if (search_in_candidate_datatype_list(type, struct_elem->candidate_datatypes) < 0) { + flag_all_elem_ok = 0; // the necessary datatype for structure init element is not a candidate_datatype of that element + } + } + if (flag_all_elem_ok) { + add_datatype_to_candidate_list(symbol, symbol->parent->candidate_datatypes[i]); + fprintf(stderr, "ADDED DATAYPE type--->\n"); + debug_c::print(symbol); + } + } + return NULL; +} + /* structure_element_name ASSIGN value */ // SYM_REF2(structure_element_initialization_c, structure_element_name, value) +void *fill_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) { + symbol->value->accept(*this); + symbol->candidate_datatypes = symbol->value->candidate_datatypes; + // Note that candidate_datatypes of symbol->structure_element_name are left empty! + 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 bf39078476e4 -r e8563dcaefca stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Mon Apr 03 18:30:50 2017 +0100 +++ b/stage3/fill_candidate_datatypes.hh Mon Apr 03 22:06:40 2017 +0100 @@ -211,8 +211,8 @@ void *visit(initialized_structure_c *symbol); // void *visit(structure_element_declaration_list_c *symbol); // void *visit(structure_element_declaration_c *symbol); -// void *visit(structure_element_initialization_list_c *symbol); -// void *visit(structure_element_initialization_c *symbol); + void *visit(structure_element_initialization_list_c *symbol); + void *visit(structure_element_initialization_c *symbol); // void *visit(string_type_declaration_c *symbol); void *visit(fb_spec_init_c *symbol); diff -r bf39078476e4 -r e8563dcaefca stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Mon Apr 03 18:30:50 2017 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Mon Apr 03 22:06:40 2017 +0100 @@ -672,11 +672,29 @@ /* structure_initialization: '(' structure_element_initialization_list ')' */ /* structure_element_initialization_list ',' structure_element_initialization */ // SYM_LIST(structure_element_initialization_list_c) -// Not needed ??? +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); + for (int k = 0; k < symbol->n; k++) { + structure_element_initialization_c *struct_elem = (structure_element_initialization_c *)symbol->elements[k]; + symbol_c *type = search_varfb_instance_type.get_basetype_decl(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 + } + } + return NULL; +} /* structure_element_name ASSIGN value */ // SYM_REF2(structure_element_initialization_c, structure_element_name, value) -// Not needed ??? +void *narrow_candidate_datatypes_c::visit(structure_element_initialization_c *symbol) {set_datatype(symbol->datatype, symbol->value); 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 bf39078476e4 -r e8563dcaefca stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Mon Apr 03 18:30:50 2017 +0100 +++ b/stage3/narrow_candidate_datatypes.hh Mon Apr 03 22:06:40 2017 +0100 @@ -185,8 +185,8 @@ void *visit(initialized_structure_c *symbol); // void *visit(structure_element_declaration_list_c *symbol); // void *visit(structure_element_declaration_c *symbol); -// void *visit(structure_element_initialization_list_c *symbol); -// void *visit(structure_element_initialization_c *symbol); + void *visit(structure_element_initialization_list_c *symbol); + void *visit(structure_element_initialization_c *symbol); // void *visit(string_type_declaration_c *symbol); void *visit(fb_spec_init_c *symbol);