Commit 78511aba authored by BenceJanosSzabo's avatar BenceJanosSzabo
Browse files

ischosen works as it is in the standard (Bug 518551)



Change-Id: Ie90baa2dc11b387f04b6999e56ef0593858432a2
Signed-off-by: default avatarBenceJanosSzabo <bence.janos.szabo@ericsson.com>
parent b8cf9f47
...@@ -46,7 +46,8 @@ enum namedbool { INCOMPLETE_NOT_ALLOWED = 0, INCOMPLETE_ALLOWED = 1, WARNING_FOR ...@@ -46,7 +46,8 @@ enum namedbool { INCOMPLETE_NOT_ALLOWED = 0, INCOMPLETE_ALLOWED = 1, WARNING_FOR
OMIT_NOT_ALLOWED = 0, OMIT_ALLOWED = 4, OMIT_NOT_ALLOWED = 0, OMIT_ALLOWED = 4,
ANY_OR_OMIT_NOT_ALLOWED = 0, ANY_OR_OMIT_ALLOWED = 5, ANY_OR_OMIT_NOT_ALLOWED = 0, ANY_OR_OMIT_ALLOWED = 5,
NOT_IMPLICIT_OMIT = 0, IMPLICIT_OMIT = 6, NOT_IMPLICIT_OMIT = 0, IMPLICIT_OMIT = 6,
NOT_STR_ELEM = 0, IS_STR_ELEM = 7 NOT_STR_ELEM = 0, IS_STR_ELEM = 7,
ISBOUND = 8, ISPRESENT = 9, ISCHOSEN = 10
}; };
namespace Asn { namespace Asn {
...@@ -1243,20 +1244,21 @@ namespace Common { ...@@ -1243,20 +1244,21 @@ namespace Common {
* Only used with new codec handling. */ * Only used with new codec handling. */
bool has_built_in_encoding(); bool has_built_in_encoding();
/** Generates type specific call for the reference used in isbound call /** Generates type specific call for the reference used in isbound/ispresent/ischosen call
* into argument \a expr. Argument \a subrefs holds the reference path * into argument \a expr. Argument \a subrefs holds the reference path
* that needs to be checked. Argument \a module is the actual module of * that needs to be checked. Argument \a module is the actual module of
* the reference and is used to gain access to temporal identifiers. * the reference and is used to gain access to temporal identifiers.
* Argument \a global_id is the name of the bool variable where the result * Argument \a global_id is the name of the bool variable where the result
* of the isbound check is calculated. Argument \a external_id is the name * of the isbound/ispresent/ischosen check is calculated. Argument \a external_id is the name
* of the assignment where the call chain starts. * of the assignment where the call chain starts.
* Argument \a is_template tells if the assignment is a template or not. * Argument \a is_template tells if the assignment is a template or not.
* Argument \a isbound tells if the function is isbound or ispresent. * Argument \a optype tells if the function is isbound or ispresent or ischosen.
* Argument \a field contains the inspected field of the union when the optype is ischosen.
*/ */
void generate_code_ispresentbound(expression_struct *expr, void generate_code_ispresentboundchosen(expression_struct *expr,
Ttcn::FieldOrArrayRefs *subrefs, Common::Module* module, Ttcn::FieldOrArrayRefs *subrefs, Common::Module* module,
const string& global_id, const string& external_id, const string& global_id, const string& external_id,
const bool is_template, const bool isbound); const bool is_template, const namedbool optype, const char* field);
/** Extension attribute for optimized code generation of structured types: /** Extension attribute for optimized code generation of structured types:
* with { extension "optimize:xxx" } * with { extension "optimize:xxx" }
......
...@@ -2668,10 +2668,10 @@ bool Type::ispresent_anyvalue_embedded_field(Type* t, ...@@ -2668,10 +2668,10 @@ bool Type::ispresent_anyvalue_embedded_field(Type* t,
return TRUE; return TRUE;
} }
void Type::generate_code_ispresentbound(expression_struct *expr, void Type::generate_code_ispresentboundchosen(expression_struct *expr,
Ttcn::FieldOrArrayRefs *subrefs, Common::Module* module, Ttcn::FieldOrArrayRefs *subrefs, Common::Module* module,
const string& global_id, const string& external_id, const bool is_template, const string& global_id, const string& external_id, const bool is_template,
const bool isbound) const namedbool optype, const char* field)
{ {
if (!subrefs) return; if (!subrefs) return;
...@@ -2690,8 +2690,10 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2690,8 +2690,10 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
if (is_template) { if (is_template) {
bool anyval_ret_val = TRUE; bool anyval_ret_val = TRUE;
if (!isbound) { if (optype == ISPRESENT) {
anyval_ret_val = ispresent_anyvalue_embedded_field(t, subrefs, i); anyval_ret_val = ispresent_anyvalue_embedded_field(t, subrefs, i);
} else if (optype == ISCHOSEN) {
anyval_ret_val = FALSE;
} }
expr->expr = mputprintf(expr->expr, "if(%s) {\n",global_id.c_str()); expr->expr = mputprintf(expr->expr, "if(%s) {\n",global_id.c_str());
expr->expr = mputprintf(expr->expr, expr->expr = mputprintf(expr->expr,
...@@ -2746,7 +2748,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2746,7 +2748,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
case T_ANYTYPE: case T_ANYTYPE:
break; break;
default: default:
FATAL_ERROR("Type::generate_code_isbound()"); FATAL_ERROR("Type::generate_code_ispresentboundchosen()");
} }
if (next_o) { if (next_o) {
...@@ -2775,7 +2777,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2775,7 +2777,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
"break;\n" "break;\n"
"default:\n", "default:\n",
tmp_id_str, global_id.c_str(),global_id.c_str(), tmp_id_str, global_id.c_str(),global_id.c_str(),
isbound ? "TRUE" : "FALSE"); optype == ISBOUND ? "TRUE" : "FALSE");
Free(tmp_generalid_str); Free(tmp_generalid_str);
tmp_generalid_str = mcopystr(tmp_id_str); tmp_generalid_str = mcopystr(tmp_id_str);
...@@ -2789,10 +2791,15 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2789,10 +2791,15 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
next_t->get_genname_value(module).c_str(), next_t->get_genname_value(module).c_str(),
is_template?"_template":"", tmp_id_str); is_template?"_template":"", tmp_id_str);
expr->expr = mputprintf(expr->expr, if (optype != ISCHOSEN) {
"%s = %s.%s(%s);\n", global_id.c_str(), expr->expr = mputprintf(expr->expr,
tmp_id2_str, isbound ? "is_bound" : "is_present", "%s = %s.%s(%s);\n", global_id.c_str(),
(!isbound && is_template && omit_in_value_list) ? "TRUE" : ""); tmp_id2_str, optype == ISBOUND ? "is_bound" : "is_present",
(optype != ISBOUND && is_template && omit_in_value_list) ? "TRUE" : "");
} else {
expr->expr = mputprintf(expr->expr,
"%s = %s.ischosen(%s);\n", global_id.c_str(), tmp_id2_str, field);
}
Free(tmp_generalid_str); Free(tmp_generalid_str);
tmp_generalid_str = mcopystr(tmp_id2_str); tmp_generalid_str = mcopystr(tmp_id2_str);
...@@ -2860,10 +2867,21 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2860,10 +2867,21 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
tmp_id2_str, tmp_id_str, tmp_id2_str, tmp_id_str,
t->typetype == T_ANYTYPE ? "AT_" : "", id.get_name().c_str()); t->typetype == T_ANYTYPE ? "AT_" : "", id.get_name().c_str());
expr->expr = mputprintf(expr->expr, if (optype != ISCHOSEN) {
"%s = %s.%s(%s);\n", global_id.c_str(), expr->expr = mputprintf(expr->expr,
tmp_id2_str, isbound||(i!=(nof_refs-1)) ? "is_bound" : "is_present", "%s = %s.%s(%s);\n", global_id.c_str(),
(!(isbound||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : ""); tmp_id2_str, optype == ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : "is_present",
(!(optype == ISBOUND||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
} else {
expr->expr = mputprintf(expr->expr,
"%s = %s.is_bound();\n", global_id.c_str(), tmp_id2_str);
if (i == nof_refs-1) {
expr->expr = mputprintf(expr->expr,
"if(%s) {\n"
"%s = %s.ischosen(%s);\n"
"}\n", global_id.c_str(), global_id.c_str(), tmp_id2_str, field);
}
}
Free(tmp_generalid_str); Free(tmp_generalid_str);
tmp_generalid_str = mcopystr(tmp_id2_str); tmp_generalid_str = mcopystr(tmp_id2_str);
} }
...@@ -2905,7 +2923,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2905,7 +2923,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
case T_GENERALIZEDTIME: case T_GENERALIZEDTIME:
case T_OBJECTDESCRIPTOR: case T_OBJECTDESCRIPTOR:
if (subrefs->refers_to_string_element()) { if (subrefs->refers_to_string_element()) {
FATAL_ERROR("Type::generate_code_isbound()"); FATAL_ERROR("Type::generate_code_ispresentboundchosen()");
} else { } else {
subrefs->set_string_element_ref(); subrefs->set_string_element_ref();
// string elements have the same type as the string itself // string elements have the same type as the string itself
...@@ -2914,7 +2932,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2914,7 +2932,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
break; break;
} }
default: default:
FATAL_ERROR("Type::generate_code_isbound()"); FATAL_ERROR("Type::generate_code_ispresentboundchosen()");
} }
next_t = embedded_type; next_t = embedded_type;
...@@ -2948,11 +2966,13 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2948,11 +2966,13 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
const char *tmp_id_str = tmp_id.c_str(); const char *tmp_id_str = tmp_id.c_str();
if (is_string_element) { if (is_string_element) {
expr->expr = mputprintf(expr->expr, if (optype != ISCHOSEN) {
"%s = %s[%s].%s(%s);\n", global_id.c_str(), expr->expr = mputprintf(expr->expr,
tmp_generalid_str, tmp_index_id_str, "%s = %s[%s].%s(%s);\n", global_id.c_str(),
isbound||(i!=(nof_refs-1)) ? "is_bound" : "is_present", tmp_generalid_str, tmp_index_id_str,
(!(isbound||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : ""); optype==ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : "is_present",
(!(optype==ISBOUND||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
}
} else { } else {
if (is_template) { if (is_template) {
expr->expr = mputprintf(expr->expr, expr->expr = mputprintf(expr->expr,
...@@ -2968,10 +2988,22 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2968,10 +2988,22 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
tmp_index_id_str); tmp_index_id_str);
} }
expr->expr = mputprintf(expr->expr, if (optype != ISCHOSEN) {
"%s = %s.%s(%s);\n", global_id.c_str(), tmp_id_str, expr->expr = mputprintf(expr->expr,
isbound||(i!=(nof_refs-1)) ? "is_bound" : "is_present", "%s = %s.%s(%s);\n", global_id.c_str(), tmp_id_str,
(!(isbound||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : ""); optype==ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : "is_present",
(!(optype==ISBOUND||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
} else {
expr->expr = mputprintf(expr->expr,
"%s = %s.is_bound();\n", global_id.c_str(),
tmp_id_str);
if (i == nof_refs-1) {
expr->expr = mputprintf(expr->expr,
"if(%s) {\n"
"%s = %s.ischosen(%s);\n"
"}\n", global_id.c_str(), global_id.c_str(), tmp_id_str, field);
}
}
} }
Free(tmp_generalid_str); Free(tmp_generalid_str);
...@@ -2981,7 +3013,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr, ...@@ -2981,7 +3013,7 @@ void Type::generate_code_ispresentbound(expression_struct *expr,
t = next_t; t = next_t;
break; } break; }
default: default:
FATAL_ERROR("Type::generate_code_isbound(): invalid reference type"); FATAL_ERROR("Type::generate_code_ispresentboundchosen(): invalid reference type");
} }
}//for }//for
......
...@@ -9370,7 +9370,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -9370,7 +9370,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
for valueof()... */ for valueof()... */
return true; return true;
case OPTYPE_ISCHOSEN_V: case OPTYPE_ISCHOSEN_V:
return u.expr.v1->is_unfoldable(refch, exp_val); return true;
case OPTYPE_LOG2STR: case OPTYPE_LOG2STR:
case OPTYPE_ANY2UNISTR: case OPTYPE_ANY2UNISTR:
case OPTYPE_TTCN2STRING: case OPTYPE_TTCN2STRING:
...@@ -12872,18 +12872,45 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -12872,18 +12872,45 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_ISCHOSEN: // r1 i2 case OPTYPE_ISCHOSEN: // r1 i2
FATAL_ERROR("Value::generate_code_expr_expr()"); FATAL_ERROR("Value::generate_code_expr_expr()");
break; break;
case OPTYPE_ISCHOSEN_V: // v1 i2 case OPTYPE_ISCHOSEN_V: { // v1 i2
u.expr.v1->generate_code_expr_mandatory(expr); char* field = mprintf("%s::ALT_%s",
expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)", u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(), u.expr.i2->get_name().c_str());
u.expr.i2->get_name().c_str()); if (u.expr.v1->get_valuetype() == Value::V_REFD) {
break; Ttcn::Reference* reference =
case OPTYPE_ISCHOSEN_T: // t1 i2 dynamic_cast<Ttcn::Reference*>(u.expr.v1->get_reference());
u.expr.t1->generate_code_expr(expr); if (reference) {
expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)", reference->generate_code_ispresentboundchosen(expr, false,
u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(), u.expr.v_optype, field);
u.expr.i2->get_name().c_str()); }
break; }
Free(field);
break; }
case OPTYPE_ISCHOSEN_T: { // t1 i2
char* field = mprintf("%s::ALT_%s",
u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
u.expr.i2->get_name().c_str());
Template::templatetype_t temp = u.expr.t1->get_templatetype();
if (temp == Template::SPECIFIC_VALUE) {
Value* specific_value = u.expr.t1->get_specific_value();
if (specific_value->get_valuetype() == Value::V_REFD) {
Ttcn::Reference* reference =
dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
if (reference) {
reference->generate_code_ispresentboundchosen(expr, false,
u.expr.v_optype, field);
}
}
} else if (temp == Template::TEMPLATE_REFD) {
Ttcn::Reference* reference =
dynamic_cast<Ttcn::Reference*>(u.expr.t1->get_reference());
if (reference) {
reference->generate_code_ispresentboundchosen(expr, true,
u.expr.v_optype, field);
}
}
Free(field);
break; }
case OPTYPE_ISPRESENT: case OPTYPE_ISPRESENT:
case OPTYPE_ISBOUND: { case OPTYPE_ISBOUND: {
Template::templatetype_t temp = u.expr.ti1->get_Template() Template::templatetype_t temp = u.expr.ti1->get_Template()
...@@ -12895,18 +12922,18 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -12895,18 +12922,18 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
Ttcn::Reference* reference = Ttcn::Reference* reference =
dynamic_cast<Ttcn::Reference*>(specific_value->get_reference()); dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
if (reference) { if (reference) {
reference->generate_code_ispresentbound(expr, false, reference->generate_code_ispresentboundchosen(expr, false,
u.expr.v_optype==OPTYPE_ISBOUND); u.expr.v_optype, NULL);
break; break;
} }
} }
} else if (temp == Template::TEMPLATE_REFD){ } else if (temp == Template::TEMPLATE_REFD) {
Ttcn::Reference* reference = Ttcn::Reference* reference =
dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template() dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
->get_reference()); ->get_reference());
if (reference) { if (reference) {
reference->generate_code_ispresentbound(expr, true, reference->generate_code_ispresentboundchosen(expr, true,
u.expr.v_optype==OPTYPE_ISBOUND); u.expr.v_optype, NULL);
break; break;
} }
} }
...@@ -14778,6 +14805,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -14778,6 +14805,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_DECODE: case OPTYPE_DECODE:
case OPTYPE_ISBOUND: case OPTYPE_ISBOUND:
case OPTYPE_ISPRESENT: case OPTYPE_ISPRESENT:
case OPTYPE_ISCHOSEN_T:
case OPTYPE_ISCHOSEN_V: // v1 i2
case OPTYPE_TTCN2STRING: case OPTYPE_TTCN2STRING:
case OPTYPE_ENCVALUE_UNICHAR: case OPTYPE_ENCVALUE_UNICHAR:
case OPTYPE_DECVALUE_UNICHAR: case OPTYPE_DECVALUE_UNICHAR:
...@@ -14826,13 +14855,10 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -14826,13 +14855,10 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_UNICHAR2CHAR: case OPTYPE_UNICHAR2CHAR:
case OPTYPE_ENUM2INT: case OPTYPE_ENUM2INT:
case OPTYPE_RNDWITHVAL: case OPTYPE_RNDWITHVAL:
case OPTYPE_ISCHOSEN_V: // v1 i2
case OPTYPE_GET_STRINGENCODING: case OPTYPE_GET_STRINGENCODING:
case OPTYPE_REMOVE_BOM: case OPTYPE_REMOVE_BOM:
case OPTYPE_DECODE_BASE64: case OPTYPE_DECODE_BASE64:
return u.expr.v1->has_single_expr(); return u.expr.v1->has_single_expr();
case OPTYPE_ISCHOSEN_T: // t1 i2
return u.expr.t1->has_single_expr();
case OPTYPE_ADD: // v1 v2 case OPTYPE_ADD: // v1 v2
case OPTYPE_SUBTRACT: case OPTYPE_SUBTRACT:
case OPTYPE_MULTIPLY: case OPTYPE_MULTIPLY:
......
...@@ -777,8 +777,8 @@ namespace Ttcn { ...@@ -777,8 +777,8 @@ namespace Ttcn {
} }
//FIXME quick hack //FIXME quick hack
void Reference::generate_code_ispresentbound(expression_struct_t *expr, void Reference::generate_code_ispresentboundchosen(expression_struct_t *expr,
bool is_template, const bool isbound) bool is_template, const Value::operationtype_t optype, const char* field)
{ {
ref_usage_found(); ref_usage_found();
Common::Assignment *ass = get_refd_assignment(); Common::Assignment *ass = get_refd_assignment();
...@@ -809,8 +809,18 @@ namespace Ttcn { ...@@ -809,8 +809,18 @@ namespace Ttcn {
isbound_expr.preamble = mputprintf(isbound_expr.preamble, isbound_expr.preamble = mputprintf(isbound_expr.preamble,
"boolean %s = %s.is_bound();\n", tmp_generalid_str, "boolean %s = %s.is_bound();\n", tmp_generalid_str,
ass_id_str); ass_id_str);
ass->get_Type()->generate_code_ispresentbound(&isbound_expr, &subrefs, my_scope->get_scope_mod_gen(), namedbool p_optype;
tmp_generalid, ass_id2, is_template, isbound); if (optype == Value::OPTYPE_ISBOUND) {
p_optype = ISBOUND;
} else if (optype == Value::OPTYPE_ISPRESENT) {
p_optype = ISPRESENT;
} else if (optype == Value::OPTYPE_ISCHOSEN_T || optype == Value::OPTYPE_ISCHOSEN_V) {
p_optype = ISCHOSEN;
} else {
FATAL_ERROR("AST_ttcn3.cc::generate_code_ispresentboundchosen()");
}
ass->get_Type()->generate_code_ispresentboundchosen(&isbound_expr, &subrefs, my_scope->get_scope_mod_gen(),
tmp_generalid, ass_id2, is_template, p_optype, field);
expr->preamble = mputstr(expr->preamble, isbound_expr.preamble); expr->preamble = mputstr(expr->preamble, isbound_expr.preamble);
expr->preamble = mputstr(expr->preamble, isbound_expr.expr); expr->preamble = mputstr(expr->preamble, isbound_expr.expr);
...@@ -818,9 +828,22 @@ namespace Ttcn { ...@@ -818,9 +828,22 @@ namespace Ttcn {
expr->expr = mputprintf(expr->expr, "%s", tmp_generalid_str); expr->expr = mputprintf(expr->expr, "%s", tmp_generalid_str);
} else { } else {
expr->expr = mputprintf(expr->expr, "%s.%s(%s)", ass_id_str, expr->expr = mputprintf(expr->expr, "%s.", ass_id_str);
isbound ? "is_bound":"is_present", switch (optype) {
(!isbound && is_template && omit_in_value_list) ? "TRUE" : ""); case Value::OPTYPE_ISBOUND:
expr->expr = mputstr(expr->expr, "is_bound()");
break;
case Value::OPTYPE_ISPRESENT:
expr->expr = mputprintf(expr->expr, "is_present(%s)",
is_template && omit_in_value_list ? "TRUE" : "");
break;
case Value::OPTYPE_ISCHOSEN_T:
case Value::OPTYPE_ISCHOSEN_V:
expr->expr = mputprintf(expr->expr, "ischosen(%s)", field);
break;
default:
FATAL_ERROR("AST_ttcn3.cc::generate_code_ispresentboundchosen()");
}
} }
} }
......
...@@ -348,8 +348,8 @@ namespace Ttcn { ...@@ -348,8 +348,8 @@ namespace Ttcn {
/** /**
* Generates code for checking if the reference * Generates code for checking if the reference
* and the referred objects are bound or not.*/ * and the referred objects are bound or not.*/
void generate_code_ispresentbound(expression_struct_t *expr, void generate_code_ispresentboundchosen(expression_struct_t *expr,
bool is_template, const bool isbound); bool is_template, const Value::operationtype_t optype, const char* field);
/** Lets the referenced assignment object know, that the reference is used /** Lets the referenced assignment object know, that the reference is used
* at least once (only relevant for formal parameters and external constants). */ * at least once (only relevant for formal parameters and external constants). */
void ref_usage_found(); void ref_usage_found();
......
...@@ -268,11 +268,8 @@ void defUnionClass(struct_def const *sdef, output_struct *output) ...@@ -268,11 +268,8 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
"{\n" "{\n"
"if (checked_selection == %s) TTCN_error(\"Internal error: Performing " "if (checked_selection == %s) TTCN_error(\"Internal error: Performing "
"ischosen() operation on an invalid field of union type %s.\");\n" "ischosen() operation on an invalid field of union type %s.\");\n"
"if (union_selection == %s) TTCN_error(\"Performing ischosen() operation "
"on an unbound value of union type %s.\");\n"
"return union_selection == checked_selection;\n" "return union_selection == checked_selection;\n"
"}\n\n", name, selection_type, unbound_value, dispname, unbound_value, "}\n\n", name, selection_type, unbound_value, dispname);
dispname);
/* is_bound function */ /* is_bound function */
def = mputstr (def, "boolean is_bound() const;\n"); def = mputstr (def, "boolean is_bound() const;\n");
...@@ -2809,31 +2806,18 @@ void defUnionTemplate(const struct_def *sdef, output_struct *output) ...@@ -2809,31 +2806,18 @@ void defUnionTemplate(const struct_def *sdef, output_struct *output)
"template of union type %s containing an empty list.\");\n" "template of union type %s containing an empty list.\");\n"
"boolean ret_val = " "boolean ret_val = "
"value_list.list_value[0].ischosen(checked_selection);\n" "value_list.list_value[0].ischosen(checked_selection);\n"
"boolean all_same = TRUE;\n" "for (unsigned int list_count = 1; ret_val == TRUE && list_count < value_list.n_values; "
"for (unsigned int list_count = 1; list_count < value_list.n_values; "
"list_count++) {\n" "list_count++) {\n"
"if (value_list.list_value[list_count].ischosen(checked_selection) != " "ret_val = value_list.list_value[list_count].ischosen(checked_selection);\n"
"ret_val) {\n"
"all_same = FALSE;\n"
"break;\n"
"}\n" "}\n"
"return ret_val;\n"
"}\n" "}\n"
"if (all_same) return ret_val;\n"
"}\n"
"case ANY_VALUE:\n"
"case ANY_OR_OMIT:\n"
"case OMIT_VALUE:\n"
"case COMPLEMENTED_LIST:\n"
"TTCN_error(\"Performing ischosen() operation on a template of union type "
"%s, which does not determine unambiguously the chosen field of the "
"matching values.\");\n"
"default:\n" "default:\n"
"TTCN_error(\"Performing ischosen() operation on an uninitialized " "return FALSE;\n"
"template of union type %s\");\n"
"}\n" "}\n"
"return FALSE;\n" "return FALSE;\n"
"}\n\n", name, selection_type, unbound_value, dispname, unbound_value, "}\n\n", name, selection_type, unbound_value, dispname, unbound_value,
dispname, dispname, dispname, dispname); dispname, dispname);
if (use_runtime_2) { if (use_runtime_2) {
def = mputstr(def, def = mputstr(def,
......
...@@ -939,7 +939,6 @@ const ASN_NULL& EXTERNAL_identification::fixed() const ...@@ -939,7 +939,6 @@ const ASN_NULL& EXTERNAL_identification::fixed() const
boolean EXTERNAL_identification::ischosen(union_selection_type checked_selection) const boolean EXTERNAL_identification::ischosen(union_selection_type checked_selection) const
{ {
if (checked_selection == UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type EXTERNAL.identification."); if (checked_selection == UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type EXTERNAL.identification.");
if (union_selection == UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an unbound value of union type EXTERNAL.identification.");
return union_selection == checked_selection; return union_selection == checked_selection;
} }
...@@ -1681,30 +1680,19 @@ boolean EXTERNAL_identification_template::ischosen(EXTERNAL_identification::unio ...@@ -1681,30 +1680,19 @@ boolean EXTERNAL_identification_template::ischosen(EXTERNAL_identification::unio
if (checked_selection == EXTERNAL_identification::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type EXTERNAL.identification."); if (checked_selection == EXTERNAL_identification::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type EXTERNAL.identification.");
switch (template_selection) { switch (template_selection) {
case SPECIFIC_VALUE: case SPECIFIC_VALUE:
if (single_value.union_selection == EXTERNAL_identification::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type EXTERNAL.identification.");
return single_value.union_selection == checked_selection; return single_value.union_selection == checked_selection;
case VALUE_LIST: case VALUE_LIST:
{ {
if (value_list.n_values < 1) if (value_list.n_values < 1)
TTCN_error("Internal error: Performing ischosen() operation on a template of union type EXTERNAL.identification containing an empty list."); TTCN_error("Internal error: Performing ischosen() operation on a template of union type EXTERNAL.identification containing an empty list.");
boolean ret_val = value_list.list_value[0].ischosen(checked_selection); boolean ret_val = value_list.list_value[0].ischosen(checked_selection);
boolean all_same = TRUE; for (unsigned int list_count = 1; ret_val == TRUE && list_count < value_list.n_values; list_count++) {
for (unsigned int list_count = 1; list_count < value_list.n_values; list_count++) { ret_val = value_list.list_value[list_count].ischosen(checked_selection);
if (value_list.list_value[list_count].ischosen(checked_selection) != ret_val) {
all_same = FALSE;
break;
}
} }
if (all_same) return ret_val; return ret_val;
} }
// FIXME really no break?
case ANY_VALUE:
case ANY_OR_OMIT:
case OMIT_VALUE:
case COMPLEMENTED_LIST:
TTCN_error("Performing ischosen() operation on a template of union type EXTERNAL.identification, which does not determine unambiguously the chosen field of the matching values.");
default: default:
TTCN_error("Performing ischosen() operation on an uninitialized template of union type EXTERNAL.identification"); return FALSE