Commit 173f32cd authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Implemented object-oriented features - stage 7 (bug 563718)



Change-Id: I8f4a57c7ff3f2d23d7b4226a3eba702eb2a150bf
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 22d79a78
......@@ -398,6 +398,15 @@ namespace Common {
u.expr.ti1 = p.u.expr.ti1->clone();
u.expr.v2 = p.u.expr.v2->clone();
break;
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
u.expr.type = p.u.expr.type->clone();
u.expr.r2 = p.u.expr.r2->clone();
break;
case OPTYPE_CLASS_CASTING_REF:
u.expr.r1 = p.u.expr.r1->clone();
u.expr.r2 = p.u.expr.r2->clone();
break;
default:
FATAL_ERROR("Value::Value()");
} // switch
......@@ -614,6 +623,14 @@ namespace Common {
u.expr.v2->chk_expr_immutability();
u.expr.ti1->chk_immutability();
break;
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
u.expr.r2->chk_immutability();
break;
case OPTYPE_CLASS_CASTING_REF:
u.expr.r1->chk_immutability();
u.expr.r2->chk_immutability();
break;
default:
FATAL_ERROR("Value::chk_expr_immutability()");
}
......@@ -869,6 +886,7 @@ namespace Common {
break;
case OPTYPE_UNDEF_RUNNING: // r1 [r2] b4
case OPTYPE_TMR_RUNNING: // r1 [r2] b4
case OPTYPE_CLASS_CASTING_REF:
delete u.expr.r1;
delete u.expr.r2;
break;
......@@ -991,6 +1009,11 @@ namespace Common {
case OPTYPE_ANY2UNISTR:
delete u.expr.logargs;
break;
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
delete u.expr.type;
delete u.expr.r2;
break;
default:
FATAL_ERROR("Value::clean_up_expr()");
} // switch
......@@ -1784,6 +1807,13 @@ namespace Common {
u.expr.v3=NULL;
u.expr.v4 = NULL;
break;
case OPTYPE_CLASS_CASTING_REF:
if (p_r1 == NULL || p_r2 == NULL) {
FATAL_ERROR("Value::Value()");
}
u.expr.r1 = p_r1;
u.expr.r2 = p_r2;
break;
default:
FATAL_ERROR("Value::Value()");
} // switch
......@@ -1873,6 +1903,26 @@ namespace Common {
FATAL_ERROR("Value::Value()");
} // switch
}
// type r2
Value::Value(operationtype_t p_optype, Type* p_type, Ttcn::Reference* p_r2)
: GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0), in_brackets(false)
{
u.expr.v_optype = p_optype;
u.expr.state = EXPR_NOT_CHECKED;
switch (p_optype) {
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
if (p_type == NULL || p_r2 == NULL) {
FATAL_ERROR("Value::Value()");
}
u.expr.type = p_type;
u.expr.r2 = p_r2;
break;
default:
FATAL_ERROR("Value::Value()");
} // switch
}
 
Value::~Value()
{
......@@ -2257,6 +2307,15 @@ namespace Common {
u.expr.r2->set_fullname(p_fullname+".redirindex");
}
break;
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
u.expr.type->set_fullname(p_fullname + ".<classtype>");
u.expr.r2->set_fullname(p_fullname + ".<operand>");
break;
case OPTYPE_CLASS_CASTING_REF:
u.expr.r1->set_fullname(p_fullname + ".<operand2>");
u.expr.r2->set_fullname(p_fullname + ".<operand1>");
break;
default:
FATAL_ERROR("Value::set_fullname_expr()");
} // switch
......@@ -2515,6 +2574,15 @@ namespace Common {
case OPTYPE_ANY2UNISTR:
u.expr.logargs->set_my_scope(p_scope);
break;
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
u.expr.type->set_my_scope(p_scope);
u.expr.r2->set_my_scope(p_scope);
break;
case OPTYPE_CLASS_CASTING_REF:
u.expr.r1->set_my_scope(p_scope);
u.expr.r2->set_my_scope(p_scope);
break;
default:
FATAL_ERROR("Value::set_my_scope_expr()");
} // switch
......@@ -2906,6 +2974,13 @@ namespace Common {
case OPTYPE_ANY2UNISTR:
u.expr.logargs->set_code_section(p_code_section);
break;
case OPTYPE_CLASS_CASTING_REF:
u.expr.r1->set_code_section(p_code_section);
// no break
case OPTYPE_CLASS_CASTING:
case OPTYPE_OF_CLASS:
u.expr.r2->set_code_section(p_code_section);
break;
default:
FATAL_ERROR("Value::set_code_section()");
} // switch
......@@ -3653,6 +3728,7 @@ namespace Common {
case OPTYPE_CHECKSTATE_ANY:
case OPTYPE_CHECKSTATE_ALL:
case OPTYPE_ISTEMPLATEKIND:
case OPTYPE_OF_CLASS:
return Type::T_BOOL;
case OPTYPE_GETVERDICT:
return Type::T_VERDICT;
......@@ -3935,6 +4011,9 @@ namespace Common {
return Type::T_OSTR;
case OPTYPE_DECOMP:
return Type::T_OID;
case OPTYPE_CLASS_CASTING:
case OPTYPE_CLASS_CASTING_REF:
return Type::T_CLASS;
default:
FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
// to avoid warning
......@@ -4116,6 +4195,11 @@ namespace Common {
case OPTYPE_GET_PORT_REF:
chk_expr_operands(NULL, exp_val); // calculate the port type
return u.expr.type;
case OPTYPE_CLASS_CASTING_REF:
chk_expr_operands(NULL, exp_val);
// no break
case OPTYPE_CLASS_CASTING:
return u.expr.type;
default:
break;
}
......@@ -4411,6 +4495,11 @@ namespace Common {
return "@profiler.running";
case OPTYPE_GET_PORT_REF:
return "port.getref()";
case OPTYPE_OF_CLASS:
return "of";
case OPTYPE_CLASS_CASTING:
case OPTYPE_CLASS_CASTING_REF:
return "=>";
default:
FATAL_ERROR("Value::get_opname()");
} // switch
......@@ -8347,6 +8436,69 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
if (!governor) return;
chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
} break;
case OPTYPE_CLASS_CASTING_REF:
{
Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
Type* type = u.expr.r1->chk_variable_ref();
type = (type == NULL) ? new Type(Type::T_ERROR) : type->clone();
type->set_my_scope(my_scope);
type->set_fullname(get_fullname() + ".<classtype>");
type->set_location(*u.expr.r1);
delete u.expr.r1;
u.expr.type = type;
u.expr.v_optype = OPTYPE_CLASS_CASTING;
}
// no break
case OPTYPE_CLASS_CASTING:
case OPTYPE_OF_CLASS: {
bool erroneous = false;
Type* ref_type_last = NULL;
{
Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
Type* ref_type = u.expr.r2->chk_variable_ref();
if (ref_type != NULL) {
ref_type_last = ref_type->get_type_refd_last();
if (ref_type_last->get_typetype() != Type::T_CLASS) {
u.expr.r2->error("Reference to a class object was expected");
erroneous = true;
}
}
else {
erroneous = true;
}
}
{
Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
u.expr.type->chk();
Type* type_last = u.expr.type->get_type_refd_last();
if (type_last->get_typetype() != Type::T_CLASS) {
if (type_last->get_typetype() != Type::T_ERROR) {
u.expr.type->error("Class type was expected");
}
erroneous = true;
}
else if (u.expr.v_optype == OPTYPE_CLASS_CASTING) {
Ttcn::ClassTypeBody* new_class = type_last->get_class_type_body();
if (new_class->is_abstract()) {
u.expr.type->error("Cannot cast to abstract class type `%s'",
u.expr.type->get_typename().c_str());
}
if (!erroneous) {
Ttcn::ClassTypeBody* old_class = ref_type_last->get_class_type_body();
if (!new_class->is_parent_class(old_class) &&
!old_class->is_parent_class(new_class)) {
u.expr.type->error("Cannot cast an object of class type `%s' "
"to class type `%s'",
ref_type_last->get_typename().c_str(),
u.expr.type->get_typename().c_str());
}
}
}
}
if (erroneous) {
set_valuetype(V_ERROR);
}
break; }
default:
FATAL_ERROR("chk_expr_operands()");
} // switch optype
......@@ -9293,6 +9445,25 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
delete v1;
}
break;
case OPTYPE_OF_CLASS:
if (!is_unfoldable()) {
clean_up();
valuetype = V_BOOL;
u.val_bool = false;
}
break;
case OPTYPE_CLASS_CASTING:
if (!is_unfoldable()) {
Type* type = u.expr.type;
Reference* ref = u.expr.r2;
valuetype = V_REFD;
u.ref.ref = ref;
u.ref.refd_last = this;
set_my_governor(type->get_type_refd_last());
delete type;
}
break;
case OPTYPE_CLASS_CASTING_REF:
case OPTYPE_UNDEF_RUNNING:
default:
FATAL_ERROR("Value::evaluate_value()");
......@@ -9904,6 +10075,19 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_ANY2UNISTR:
case OPTYPE_TTCN2STRING:
return true;
case OPTYPE_OF_CLASS: {
// class of object reference
Ttcn::ClassTypeBody* ref_class = u.expr.r2->chk_variable_ref()->
get_type_refd_last()->get_class_type_body();
// expected class
Ttcn::ClassTypeBody* exp_class = u.expr.type->get_type_refd_last()->
get_class_type_body();
// the result is always false if the classes are not related to each other,
// otherwise a runtime check is required
return ref_class->is_parent_class(exp_class) ||
exp_class->is_parent_class(ref_class); }
case OPTYPE_CLASS_CASTING:
return !u.expr.type->is_identical(u.expr.r2->chk_variable_ref());
default:
FATAL_ERROR("Value::is_unfoldable()");
} // switch
......@@ -11661,9 +11845,15 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
// TODO t_list2
break;
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING: {
Common::Assignment *ass = u.expr.r2->get_refd_assignment();
self_ref |= (ass == lhs);
break; }
 
case NUMBER_OF_OPTYPES: // can never happen
case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
case OPTYPE_CLASS_CASTING_REF:
FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
break;
} // switch u.expr.v_optype
......@@ -12301,6 +12491,15 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
return string("@profiler.running");
case OPTYPE_GET_PORT_REF:
return string("port.getref()");
case OPTYPE_OF_CLASS:
return u.expr.r2->get_dispname() + string(" of ") +
u.expr.type->get_typename();
case OPTYPE_CLASS_CASTING:
return u.expr.r2->get_dispname() + string(" => ") +
u.expr.type->get_typename();
case OPTYPE_CLASS_CASTING_REF:
return u.expr.r2->get_dispname() + string(" => (") +
u.expr.r1->get_dispname() + string(")");
default:
return string("<unsupported optype>");
} // switch u.expr.v_optype
......@@ -13919,6 +14118,41 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
u.expr.type->get_typename().c_str());
expr->expr = mputprintf(expr->expr, "(*%s)", tmp_id.c_str());
break; }
case OPTYPE_OF_CLASS: {
Ttcn::ClassTypeBody* exp_class = u.expr.type->get_type_refd_last()->
get_class_type_body();
expression_struct_t ref_expr;
Code::init_expr(&ref_expr);
u.expr.r2->generate_code(&ref_expr);
if (ref_expr.preamble != NULL) {
expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
}
expr->expr = mputprintf(expr->expr,
"%s != NULL_VALUE && dynamic_cast<%s*>(*%s) != NULL",
ref_expr.expr, exp_class->is_built_in() ? "OBJECT" :
u.expr.type->get_type_refd_last()->get_genname_own(my_scope).c_str(),
ref_expr.expr);
if (ref_expr.postamble != NULL) {
expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
}
Code::free_expr(&ref_expr);
break; }
case OPTYPE_CLASS_CASTING: {
expression_struct_t ref_expr;
Code::init_expr(&ref_expr);
u.expr.r2->generate_code(&ref_expr);
if (ref_expr.preamble != NULL) {
expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
}
expr->expr = mputprintf(expr->expr,
"%s.cast_to<%s>()",
ref_expr.expr,
u.expr.type->get_type_refd_last()->get_genname_own(my_scope).c_str());
if (ref_expr.postamble != NULL) {
expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
}
Code::free_expr(&ref_expr);
break; }
default:
FATAL_ERROR("Value::generate_code_expr_expr()");
}
......@@ -15770,6 +16004,9 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
(!u.expr.v3 || u.expr.v3->has_single_expr());
case OPTYPE_OF_CLASS:
case OPTYPE_CLASS_CASTING:
return u.expr.r2->has_single_expr();
default:
FATAL_ERROR("Value::has_single_expr_expr()");
} // switch
......
......@@ -279,11 +279,15 @@ namespace Common {
OPTYPE_CBOR2JSON, // v1
OPTYPE_JSON2CBOR, // v1
OPTYPE_BSON2JSON, // v1
OPTYPE_JSON2BSON, // v1
OPTYPE_JSON2BSON, // v1 120
OPTYPE_GET_PORT_REF, // -
OPTYPE_OF_CLASS, // type r2
OPTYPE_CLASS_CASTING, // type r2
OPTYPE_CLASS_CASTING_REF, // r1 r2
NUMBER_OF_OPTYPES // must be last 122
NUMBER_OF_OPTYPES // must be last 125
};
enum macrotype_t {
......@@ -474,7 +478,7 @@ namespace Common {
Value(valuetype_t p_vt, Reference *p_ref);
Value(valuetype_t p_vt, Block *p_block);
Value(valuetype_t p_vt, verdict_t p_verdict);
/** Constructor used by decode */
/** Constructor used by V_EXPR "r1 r2": DECODE, OPTYPE_CLASS_CASTING_REF */
Value(operationtype_t p_optype, Ttcn::Reference *p_r1, Ttcn::Reference *p_r2);
/** Constructor used by decvalue_unichar*/
Value(operationtype_t p_optype, Ttcn::Reference *p_r1, Ttcn::Reference *p_r2, Value *p_v3);
......@@ -486,6 +490,8 @@ namespace Common {
Value* p_v3, Value* p_v4, Value* p_v5);
/** Constructor used by V_ANY_VALUE and V_ANY_OR_OMIT */
Value(valuetype_t p_vt, Ttcn::LengthRestriction* p_len_res);
/** Constructor used by V_EXPR "type r2": OF_CLASS, OPTYPE_CLASS_CASTING */
Value(operationtype_t p_optype, Type* p_type, Ttcn::Reference* p_r2);
virtual ~Value();
virtual Value* clone() const;
valuetype_t get_valuetype() const {return valuetype;}
......
......@@ -6428,7 +6428,8 @@ namespace Ttcn {
}
Def_Function_Base::Def_Function_Base(const Def_Function_Base& p)
: Definition(p), prototype(PROTOTYPE_NONE), input_type(0), output_type(0)
: Definition(p), prototype(PROTOTYPE_NONE), input_type(0), output_type(0),
final(p.final)
{
fp_list = p.fp_list->clone();
fp_list->set_my_def(this);
......@@ -6438,11 +6439,11 @@ namespace Ttcn {
Def_Function_Base::Def_Function_Base(bool is_external, Identifier *p_id,
FormalParList *p_fpl, Type *p_return_type, bool returns_template,
template_restriction_t p_template_restriction)
template_restriction_t p_template_restriction, bool p_final)
: Definition(determine_asstype(is_external, p_return_type != 0,
returns_template), p_id), fp_list(p_fpl), return_type(p_return_type),
prototype(PROTOTYPE_NONE), input_type(0), output_type(0),
template_restriction(p_template_restriction)
template_restriction(p_template_restriction), final(p_final)
{
if (!p_fpl) FATAL_ERROR("Def_Function_Base::Def_Function_Base()");
fp_list->set_my_def(this);
......@@ -6662,9 +6663,9 @@ namespace Ttcn {
Type *p_return_type,
bool returns_template,
template_restriction_t p_template_restriction,
StatementBlock *p_block)
bool p_final, StatementBlock *p_block)
: Def_Function_Base(false, p_id, p_fpl, p_return_type, returns_template,
p_template_restriction),
p_template_restriction, p_final),
runs_on_ref(p_runs_on_ref), runs_on_type(0),
mtc_ref(p_mtc_ref), mtc_type(0),
system_ref(p_system_ref), system_type(0),
......
......@@ -1356,6 +1356,7 @@ namespace Ttcn {
Type *output_type;
/** optional template restriction on return template value */
template_restriction_t template_restriction;
bool final;
static asstype_t determine_asstype(bool is_external, bool has_return_type,
bool returns_template);
......@@ -1376,7 +1377,7 @@ namespace Ttcn {
*/
Def_Function_Base(bool is_external, Identifier *p_id,
FormalParList *p_fpl, Type *p_return_type, bool returns_template,
template_restriction_t p_template_restriction);
template_restriction_t p_template_restriction, bool p_final);
virtual ~Def_Function_Base();
virtual void set_fullname(const string& p_fullname);
virtual void set_my_scope(Scope *p_scope);
......@@ -1393,6 +1394,7 @@ namespace Ttcn {
bool is_identical(Def_Function_Base* p_other);
template_restriction_t get_template_restriction()
{ return template_restriction; }
virtual bool is_final() const { return final; }
/** Checks and returns whether the function is startable.
* Reports the appropriate error message(s) if not. */
//bool chk_startable(Location* caller_location);
......@@ -1471,10 +1473,9 @@ namespace Ttcn {
Def_Function(bool p_deterministic, Identifier *p_id, FormalParList *p_fpl,
Reference *p_runs_on_ref, Reference *p_mtc_ref,
Reference *p_system_ref, Reference *p_port_ref,
Type *p_return_type,
bool returns_template,
Type *p_return_type, bool returns_template,
template_restriction_t p_template_restriction,
StatementBlock *p_block);
bool p_final, StatementBlock *p_block);
virtual ~Def_Function();
virtual Def_Function *clone() const;
virtual void set_fullname(const string& p_fullname);
......@@ -1570,9 +1571,9 @@ namespace Ttcn {
*/
Def_ExtFunction(bool p_deterministic, Identifier *p_id, FormalParList *p_fpl,
Type *p_return_type, bool returns_template,
template_restriction_t p_template_restriction, bool p_ext_keyword)
template_restriction_t p_template_restriction, bool p_final, bool p_ext_keyword)
: Def_Function_Base(true, p_id, p_fpl, p_return_type, returns_template,
p_template_restriction),
p_template_restriction, p_final),
function_type(EXTFUNC_MANUAL), encoding_type(Type::CT_UNDEF),
encoding_options(0), eb_list(0), printing(0),
deterministic(p_deterministic), ext_keyword(p_ext_keyword) { }
......@@ -1617,7 +1618,7 @@ namespace Ttcn {
Type* p_return_type, bool returns_template,
template_restriction_t p_template_restriction)
: Def_Function_Base(false, p_id, p_fpl, p_return_type, returns_template,
p_template_restriction) { }
p_template_restriction, false) { }
virtual ~Def_AbsFunction();
virtual Definition* clone() const;
virtual void chk();
......
......@@ -550,6 +550,10 @@ namespace Ttcn {
delete select_union.expr;
delete select_union.sus;
break;
case S_SELECT_CLASS:
delete select_class.ref;
delete select_class.sccs;
break;
case S_FOR:
if(loop.for_stmt.varinst)
delete loop.for_stmt.init_varinst;
......@@ -964,7 +968,7 @@ namespace Ttcn {
} // switch statementtype
}
Statement::Statement(statementtype_t p_st, Value *p_expr, SelectUnions *p_sus)
Statement::Statement(statementtype_t p_st, Value *p_expr, SelectUnions *p_sus)
: statementtype(p_st), my_sb(0)
{
switch(statementtype) {
......@@ -978,6 +982,22 @@ namespace Ttcn {
FATAL_ERROR("Statement::Statement()");
} // switch statementtype
}
Statement::Statement(statementtype_t p_st, Reference *p_ref, SelectClassCases *p_sccs)
: statementtype(p_st), my_sb(0)
{
switch(statementtype) {
case S_SELECT_CLASS:
if (p_ref == NULL || p_sccs == NULL) {
FATAL_ERROR("Statement::Statement()");
}
select_class.ref = p_ref;
select_class.sccs = p_sccs;
break;
default:
FATAL_ERROR("Statement::Statement()");
} // switch statementtype
}
Statement::Statement(statementtype_t p_st, Definitions *p_defs,
Assignment *p_ass, Value *p_final,
......@@ -1598,6 +1618,7 @@ namespace Ttcn {
case S_IF: return "if";
case S_SELECT: return "select-case";
case S_SELECTUNION: return "select-union";
case S_SELECT_CLASS: return "select-class";
case S_FOR: return "for";
case S_WHILE: return "while";
case S_DOWHILE: return "do-while";
......@@ -1777,6 +1798,10 @@ namespace Ttcn {
select_union.expr->set_my_scope(p_scope);
select_union.sus->set_my_scope(p_scope);
break;
case S_SELECT_CLASS:
select_class.ref->set_my_scope(p_scope);
select_class.sccs->set_my_scope(p_scope);
break;
case S_FOR:
if (loop.for_stmt.varinst) {
loop.for_stmt.init_varinst->set_parent_scope(p_scope);
......@@ -2086,6 +2111,10 @@ namespace Ttcn {
select_union.expr->set_fullname(p_fullname+".expr");
select_union.sus->set_fullname(p_fullname+".sus");
break;
case S_SELECT_CLASS:
select_class.ref->set_fullname(p_fullname+".ref");
select_class.sccs->set_fullname(p_fullname+".sccs");
break;
case S_FOR:
if(loop.for_stmt.varinst)
loop.for_stmt.init_varinst->set_fullname(p_fullname+".init");
......@@ -2380,6 +2409,9 @@ namespace Ttcn {
case S_SELECTUNION:
select_union.sus->set_my_sb(p_sb, p_index);
break;
case S_SELECT_CLASS:
select_class.sccs->set_my_sb(p_sb, p_index);
break;
case S_FOR:
case S_WHILE:
case S_DOWHILE:
......@@ -2413,6 +2445,9 @@ namespace Ttcn {
case S_SELECTUNION:
select_union.sus->set_my_def(p_def);
break;
case S_SELECT_CLASS:
select_class.sccs->set_my_def(p_def);
break;
case S_FOR:
case S_WHILE:
case S_DOWHILE:
......@@ -2446,6 +2481,9 @@ namespace Ttcn {
case S_SELECTUNION:
select_union.sus->set_my_ags(p_ags);
break;
case S_SELECT_CLASS:
select_class.sccs->set_my_ags(p_ags);
break;
case S_FOR:
case S_WHILE:
case S_DOWHILE:
......@@ -2476,6 +2514,9 @@ namespace Ttcn {
case S_SELECTUNION:
select_union.sus->set_my_laic_stmt(p_ags, p_loop_stmt);
break;
case S_SELECT_CLASS:
select_class.sccs->set_my_laic_stmt(p_ags, p_loop_stmt);
break;
case S_ALT:
case S_INTERLEAVE:
if (p_loop_stmt)
......@@ -2548,6 +2589,8 @@ namespace Ttcn {
return select.scs->has_return();
case S_SELECTUNION:
return select_union.sus->has_return();
case S_SELECT_CLASS:
return select_class.sccs->has_return();
case S_FOR:
case S_WHILE:
if (loop.block->has_return() == StatementBlock::RS_NO)
......@@ -2672,6 +2715,8 @@ namespace Ttcn {
return select.scs->has_receiving_stmt();
case S_SELECTUNION:
return select_union.sus->has_receiving_stmt();
case S_SELECT_CLASS:
return select_class.sccs->has_receiving_stmt();
case S_FOR:
case S_WHILE:
case S_DOWHILE:
......@@ -2763,6 +2808,9 @@ namespace Ttcn {
case S_SELECTUNION:
chk_select_union();
break;
case S_SELECT_CLASS:
chk_select_class();
break;
case S_FOR:
chk_for();
break;
......@@ -2989,6 +3037,9 @@ namespace Ttcn {
case S_SELECTUNION:
select_union.sus->chk_allowed_interleave();
break;
case S_SELECT_CLASS:
select_class.sccs->chk_allowed_interleave();
break;
case S_FOR:
case S_WHILE: