# HG changeset patch # User mjsousa # Date 1405268720 -3600 # Node ID ef3347dbfa0c5fcd73278fbb8cf00092e5c168c5 # Parent a0518971127df8ea985ec7a055901289b5a8d972 Change REF() operator to return the correct REF_TO datatype datatype. diff -r a0518971127d -r ef3347dbfa0c stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Sun Jul 13 13:47:16 2014 +0100 +++ b/stage3/fill_candidate_datatypes.cc Sun Jul 13 17:25:20 2014 +0100 @@ -1861,10 +1861,30 @@ /***********************/ /* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ void *fill_candidate_datatypes_c::visit( ref_expression_c *symbol) { + /* We must first determine the datatype of the expression passe to the REF() operator, with no ambiguities! + * To do this, we could use the complete standard fill/narrow algorithm for determining the datatype + * of the expression. This is actually possible, as nothing stops us from directly calling the narrow_candidate_datatypes_c + * from this method inside fill_candidate_datatypes_c, to complete the fill/narrow algorithm on this + * expression only. + * However, for the moment we take a shortcut, and set the expression's "datatype" directly, even though this + * should really only be done in narrow_candidate_datatypes_c. This is possible because the expression should be + * an lvalue (assuming source code has no bugs), with only one candidate datatype. + * + * (We should really check whether the expression is an lvalue. For now, leave it for the future!) + * + * Note, however, that array variables are also lvalues, and they may containg complex + * expressions that include function calls in their indexes. These complex expressions must therefore still be + * analysed using the standard fill/narrow algorithm... + */ symbol->exp->accept(*this); - /* we should really check whether the expression is an lvalue. For now, leave it for the future! */ - /* For now, we handle references (i.e. pointers) as ULINT datatypes! */ - add_datatype_to_candidate_list(symbol, &get_datatype_info_c::ulint_type_name); + if (symbol->exp->candidate_datatypes.size() == 1) + symbol->exp->datatype = symbol->exp->candidate_datatypes[0]; + + /* Create a new object of ref_spec_c, as this is the class used as the canonical/base datatype of REF_TO types + * (see search_base_type_c ...) + */ + ref_spec_c *ref_spec = new ref_spec_c(symbol->exp->datatype); + add_datatype_to_candidate_list(symbol, ref_spec); return NULL; } diff -r a0518971127d -r ef3347dbfa0c stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Sun Jul 13 13:47:16 2014 +0100 +++ b/stage4/generate_c/generate_c_st.cc Sun Jul 13 17:25:20 2014 +0100 @@ -465,7 +465,6 @@ /***********************/ void *visit(ref_expression_c *symbol) { s4o.print("("); - s4o.print("(IEC_UDINT)"); if (this->is_variable_prefix_null()) { /* For code in FUNCTIONs */ s4o.print("&(");