From 589e0edf50a81794baf23ec521ecd98cd038e912 Mon Sep 17 00:00:00 2001 From: BenceJanosSzabo <bence.janos.szabo@ericsson.com> Date: Thu, 6 Jul 2017 16:00:12 +0200 Subject: [PATCH] Implemented mtc and system clauses in altsteps and functions (Bug 519281) Change-Id: I2dfa85d30b67a3d284464cbaabc9308cb308d5a4 Signed-off-by: BenceJanosSzabo <bence.janos.szabo@ericsson.com> --- compiler2/AST.cc | 10 ++ compiler2/AST.hh | 6 ++ compiler2/Setting.cc | 50 +++++++++ compiler2/Setting.hh | 12 +++ compiler2/Type.cc | 67 ++++++++++++ compiler2/Type.hh | 3 + compiler2/Type_chk.cc | 4 +- compiler2/ttcn3/AST_ttcn3.cc | 74 ++++++++++++- compiler2/ttcn3/AST_ttcn3.hh | 44 +++++++- compiler2/ttcn3/Statement.cc | 8 ++ compiler2/ttcn3/compiler.y | 46 ++++++-- .../Semantic_Analyser/Makefile.semantic | 2 +- .../MtcSystemClause_SE.ttcn | 102 ++++++++++++++++++ .../Semantic_Analyser/mtc_and_system_clause/t | 9 ++ 14 files changed, 420 insertions(+), 17 deletions(-) create mode 100644 function_test/Semantic_Analyser/mtc_and_system_clause/MtcSystemClause_SE.ttcn create mode 100755 function_test/Semantic_Analyser/mtc_and_system_clause/t diff --git a/compiler2/AST.cc b/compiler2/AST.cc index 88ffb738d..5fe91220a 100644 --- a/compiler2/AST.cc +++ b/compiler2/AST.cc @@ -1928,6 +1928,16 @@ namespace Common { return 0; } + Type *Assignment::get_MtcType() + { + return 0; + } + + Type *Assignment::get_SystemType() + { + return 0; + } + Type *Assignment::get_PortType() { return 0; diff --git a/compiler2/AST.hh b/compiler2/AST.hh index 9a5b303ff..0632d9935 100644 --- a/compiler2/AST.hh +++ b/compiler2/AST.hh @@ -589,6 +589,12 @@ namespace Common { /** Returns the component type referred by the 'runs on' clause of a * TTCN-3 definition */ virtual Type *get_RunsOnType(); + /** Returns the component type referred by the 'mtc' clause of a + * TTCN-3 definition */ + virtual Type *get_MtcType(); + /** Returns the component type referred by the 'system' clause of a + * TTCN-3 definition */ + virtual Type *get_SystemType(); /** Returns the port type referred by the 'port' clause of a * TTCN-3 function definition */ virtual Type *get_PortType(); diff --git a/compiler2/Setting.cc b/compiler2/Setting.cc index 3f4a4158e..7d8fcf422 100644 --- a/compiler2/Setting.cc +++ b/compiler2/Setting.cc @@ -692,6 +692,56 @@ namespace Common { refd_comptype->get_typename().c_str()); } } + + void Scope::chk_mtc_clause(Assignment *p_ass, const Location& p_loc, + const char *p_what, bool in_control_part) + { + // component type of the referred definition + Type *refd_comptype = p_ass->get_MtcType(); + // definitions without 'mtc' can be called from anywhere + if (!refd_comptype) return; + if (in_control_part) { + p_loc.error("Function with mtc or system clause is not allowed in control part."); + return; + } + Type *t_comptype = get_mtc_system_comptype(false); + if (t_comptype) { + if (!refd_comptype->is_compatible_component_by_port(t_comptype)) { + // the 'mtc' clause of the referred definition is not compatible + // with that of the current scope (i.e. the referring definition) + p_loc.error("Mtc clause mismatch: A definition that runs on " + "component type `%s' cannot %s %s, which mtc clause is `%s'", + t_comptype->get_typename().c_str(), p_what, + p_ass->get_description().c_str(), + refd_comptype->get_typename().c_str()); + } + } + } + + void Scope::chk_system_clause(Assignment *p_ass, const Location& p_loc, + const char *p_what, bool in_control_part) + { + // component type of the referred definition + Type *refd_comptype = p_ass->get_SystemType(); + // definitions without 'system' can be called from anywhere + if (!refd_comptype) return; + if (in_control_part) { + p_loc.error("Function with mtc or system clause is not allowed in control part."); + return; + } + Type *t_comptype = get_mtc_system_comptype(true); + if (t_comptype) { + if (!refd_comptype->is_compatible_component_by_port(t_comptype)) { + // the 'system' clause of the referred definition is not compatible + // with that of the current scope (i.e. the referring definition) + p_loc.error("System clause mismatch: A definition with system " + "component type `%s' cannot %s %s, which system clause is `%s'", + t_comptype->get_typename().c_str(), p_what, + p_ass->get_description().c_str(), + refd_comptype->get_typename().c_str()); + } + } + } // ================================= // ===== Reference diff --git a/compiler2/Setting.hh b/compiler2/Setting.hh index 11e8721f9..848b4fa5b 100644 --- a/compiler2/Setting.hh +++ b/compiler2/Setting.hh @@ -635,6 +635,18 @@ public: * \a p_what contains "call" or "activate". */ void chk_runs_on_clause(Type *p_fat, const Location& p_loc, const char *p_what); + /** Checks the 'mtc' clause of definition \a p_ass that it can + * be called from this scope unit. Parameters \a p_loc and \a + * p_what are used in error messages. \a p_what contains "call" or + * "activate". */ + void chk_mtc_clause(Assignment *p_ass, const Location& p_loc, + const char *p_what, bool in_control_part); + /** Checks the 'system' clause of definition \a p_ass that it can + * be called from this scope unit. Parameters \a p_loc and \a + * p_what are used in error messages. \a p_what contains "call" or + * "activate". */ + void chk_system_clause(Assignment *p_ass, const Location& p_loc, + const char *p_what, bool in_control_part); }; /** diff --git a/compiler2/Type.cc b/compiler2/Type.cc index 39f339c68..f170a3386 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -3695,6 +3695,73 @@ namespace Common { } } } + + + bool Type::is_compatible_component_by_port(Type *p_type) { + chk(); + p_type->chk(); + Type *t1 = get_type_refd_last(); + Type *t2 = p_type->get_type_refd_last(); + if (t1->typetype != T_COMPONENT || t2->typetype != T_COMPONENT) { + return false; + } + ComponentTypeBody* b1 = t1->get_CompBody(); + ComponentTypeBody* b2 = t2->get_CompBody(); + + // Does b2 contains every port with the same type and name as b1? + for (size_t i = 0; i < b1->get_nof_asss(); i++) { + Assignment * ass = b1->get_ass_byIndex(i); + if (ass->get_asstype() == Assignment::A_PORT) { + Type *port_type = ass->get_Type()->get_type_refd_last(); + const Identifier& id = ass->get_id(); + bool found = false; + for (size_t j = 0; j < b2->get_nof_asss(); j++) { + Assignment * ass2 = b2->get_ass_byIndex(j); + const Identifier& id2 = ass2->get_id(); + if (id == id2 && ass2->get_asstype() == Assignment::A_PORT) { + Type *port_type2 = ass2->get_Type()->get_type_refd_last(); + if (port_type != port_type2) { + return false; + } else { + found = true; + break; + } + } + } + if (!found) { + return false; + } + } + } + + // Does b1 contains every port with the same type and name as b2? + for (size_t i = 0; i < b2->get_nof_asss(); i++) { + Assignment * ass = b2->get_ass_byIndex(i); + if (ass->get_asstype() == Assignment::A_PORT) { + Type *port_type = ass->get_Type()->get_type_refd_last(); + const Identifier& id = ass->get_id(); + bool found = false; + for (size_t j = 0; j < b1->get_nof_asss(); j++) { + Assignment * ass2 = b1->get_ass_byIndex(j); + const Identifier& id2 = ass2->get_id(); + if (id == id2 && ass2->get_asstype() == Assignment::A_PORT) { + Type *port_type2 = ass2->get_Type()->get_type_refd_last(); + if (port_type != port_type2) { + return false; + } else { + found = true; + break; + } + } + } + if (!found) { + return false; + } + } + } + + return true; + } bool Type::is_compatible(Type *p_type, TypeCompatInfo *p_info, Location* p_loc, TypeChain *p_left_chain, TypeChain *p_right_chain, diff --git a/compiler2/Type.hh b/compiler2/Type.hh index e43dc4a8b..0b5bc3843 100644 --- a/compiler2/Type.hh +++ b/compiler2/Type.hh @@ -682,6 +682,9 @@ namespace Common { TypeChain *p_left_chain = NULL, TypeChain *p_right_chain = NULL, bool p_is_inline_template = false); + /** Check if the port definitions of the component types are the same + */ + bool is_compatible_component_by_port(Type *p_type); /** Check if the restrictions of a T_SEQOF/T_SETOF are "compatible" with * the given type \a p_type. Can be called only as a T_SEQOF/T_SETOF. * Currently, used for structured types only. \a p_type can be any kind diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index 21169edc8..d3c0e8aa4 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -5628,7 +5628,7 @@ void Type::chk_this_template_incorrect_field() { case T_SET_T: case T_OPENTYPE: for (size_t i = 0; i < t->get_nof_comps(); i++) { - Error_Context cntxt(t->get_comp_byIndex(i), "In field `%s'", t->get_comp_byIndex(i)->get_name().get_dispname().c_str()); + Error_Context cntxt2(t->get_comp_byIndex(i), "In field `%s'", t->get_comp_byIndex(i)->get_name().get_dispname().c_str()); t->get_comp_byIndex(i)->get_type()->chk_this_template_incorrect_field(); } break; @@ -5646,7 +5646,7 @@ void Type::chk_this_template_incorrect_field() { case Assignment::A_VAR_TEMPLATE: /**< template variable, dynamic template (TTCN-3) */ case Assignment::A_PORT: /**< port (TTCN-3) */ { - Error_Context cntxt(ass, "In field `%s'", ass->get_id().get_dispname().c_str()); + Error_Context cntxt2(ass, "In field `%s'", ass->get_id().get_dispname().c_str()); ass->get_Type()->chk_this_template_incorrect_field(); } default: diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index bde891ec0..8e727d3fd 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -6268,7 +6268,8 @@ namespace Ttcn { // ================================= Def_Function::Def_Function(Identifier *p_id, FormalParList *p_fpl, - Reference *p_runs_on_ref, Reference *p_port_ref, + Reference *p_runs_on_ref, Reference *p_mtc_ref, + Reference *p_system_ref, Reference *p_port_ref, Type *p_return_type, bool returns_template, template_restriction_t p_template_restriction, @@ -6276,6 +6277,8 @@ namespace Ttcn { : Def_Function_Base(false, p_id, p_fpl, p_return_type, returns_template, p_template_restriction), 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), port_ref(p_port_ref), port_type(0), block(p_block), is_startable(false), transparent(false) { @@ -6286,6 +6289,8 @@ namespace Ttcn { Def_Function::~Def_Function() { delete runs_on_ref; + delete mtc_ref; + delete system_ref; delete port_ref; delete block; } @@ -6299,6 +6304,8 @@ namespace Ttcn { { Def_Function_Base::set_fullname(p_fullname); if (runs_on_ref) runs_on_ref->set_fullname(p_fullname + ".<runs_on_type>"); + if (mtc_ref) mtc_ref->set_fullname(p_fullname + ".<mtc_type>"); + if (system_ref) system_ref->set_fullname(p_fullname + ".<system_type>"); if (port_ref) port_ref->set_fullname(p_fullname + ".<port_type>"); block->set_fullname(p_fullname + ".<statement_block>"); } @@ -6310,10 +6317,24 @@ namespace Ttcn { Def_Function_Base::set_my_scope(&bridgeScope); if (runs_on_ref) runs_on_ref->set_my_scope(&bridgeScope); + if (mtc_ref) mtc_ref->set_my_scope(&bridgeScope); + if (system_ref) system_ref->set_my_scope(&bridgeScope); if (port_ref) port_ref->set_my_scope(&bridgeScope); block->set_my_scope(fp_list); } + Type *Def_Function::get_MtcType() + { + if (!checked) chk(); + return mtc_type; + } + + Type *Def_Function::get_SystemType() + { + if (!checked) chk(); + return system_type; + } + Type *Def_Function::get_RunsOnType() { if (!checked) chk(); @@ -6362,6 +6383,17 @@ namespace Ttcn { } } + // checking the `mtc' clause + if (mtc_ref) { + Error_Context cntxt2(mtc_ref, "In `mtc' clause"); + mtc_type = mtc_ref->chk_comptype_ref(); + } + + // checking the `system' clause + if (system_ref) { + Error_Context cntxt2(system_ref, "In `system' clause"); + system_type = system_ref->chk_comptype_ref(); + } // checking the formal parameter list, the check must come before the // chk_prototype() function call. @@ -7584,10 +7616,12 @@ namespace Ttcn { // ================================= Def_Altstep::Def_Altstep(Identifier *p_id, FormalParList *p_fpl, - Reference *p_runs_on_ref, StatementBlock *p_sb, + Reference *p_runs_on_ref, Reference *p_mtc_ref, + Reference *p_system_ref, StatementBlock *p_sb, AltGuards *p_ags) : Definition(A_ALTSTEP, p_id), fp_list(p_fpl), runs_on_ref(p_runs_on_ref), - runs_on_type(0), sb(p_sb), ags(p_ags) + runs_on_type(0), mtc_ref(p_mtc_ref), mtc_type(0), + system_ref(p_system_ref), system_type(0), sb(p_sb), ags(p_ags) { if (!p_fpl || !p_sb || !p_ags) FATAL_ERROR("Def_Altstep::Def_Altstep()"); @@ -7601,6 +7635,8 @@ namespace Ttcn { { delete fp_list; delete runs_on_ref; + delete mtc_ref; + delete system_ref; delete sb; delete ags; } @@ -7615,6 +7651,8 @@ namespace Ttcn { Definition::set_fullname(p_fullname); fp_list->set_fullname(p_fullname + ".<formal_par_list>"); if (runs_on_ref) runs_on_ref->set_fullname(p_fullname + ".<runs_on_type>"); + if (mtc_ref) mtc_ref->set_fullname(p_fullname + ".<mtc_type>"); + if (system_ref) system_ref->set_fullname(p_fullname + ".<system_type>"); sb->set_fullname(p_fullname+".<block>"); ags->set_fullname(p_fullname + ".<guards>"); } @@ -7627,6 +7665,8 @@ namespace Ttcn { Definition::set_my_scope(&bridgeScope); // the scope of the parameter list is set during checking if (runs_on_ref) runs_on_ref->set_my_scope(&bridgeScope); + if (mtc_ref) mtc_ref->set_my_scope(&bridgeScope); + if (system_ref) system_ref->set_my_scope(&bridgeScope); sb->set_my_scope(fp_list); ags->set_my_scope(sb); } @@ -7636,6 +7676,18 @@ namespace Ttcn { if (!checked) chk(); return runs_on_type; } + + Type *Def_Altstep::get_MtcType() + { + if (!checked) chk(); + return mtc_type; + } + + Type *Def_Altstep::get_SystemType() + { + if (!checked) chk(); + return system_type; + } FormalParList *Def_Altstep::get_FormalParList() { @@ -7666,6 +7718,14 @@ namespace Ttcn { parlist_scope = runs_on_scope; } } + if (mtc_ref) { + Error_Context cntxt2(mtc_ref, "In `mtc' clause"); + mtc_type = mtc_ref->chk_comptype_ref(); + } + if (system_ref) { + Error_Context cntxt2(system_ref, "In `system' clause"); + system_type = system_ref->chk_comptype_ref(); + } fp_list->set_my_scope(parlist_scope); fp_list->chk(asstype); sb->chk(); @@ -7832,6 +7892,14 @@ namespace Ttcn { DEBUG(level + 1, "Runs on clause:"); runs_on_ref->dump(level + 2); } + if (mtc_ref) { + DEBUG(level + 1, "Mtc clause:"); + mtc_ref->dump(level + 2); + } + if (system_ref) { + DEBUG(level + 1, "System clause:"); + system_ref->dump(level + 2); + } /* DEBUG(level + 1, "Local definitions:"); sb->dump(level + 2); diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh index 85d246bfd..aeb433e38 100644 --- a/compiler2/ttcn3/AST_ttcn3.hh +++ b/compiler2/ttcn3/AST_ttcn3.hh @@ -1402,6 +1402,22 @@ namespace Ttcn { * It is NULL if the function has no 'runs on' clause or \a runs_on_ref is * erroneous. */ Type *runs_on_type; + /** The 'mtc' clause (i.e. a reference to a TTCN-3 component type) + * It is NULL if the function has no 'mtc' clause. */ + Reference *mtc_ref; + /** Points to the object describing the component type referred by + * 'mtc' clause. + * It is NULL if the function has no 'mtc' clause or \a mtc_ref is + * erroneous. */ + Type *mtc_type; + /** The 'system' clause (i.e. a reference to a TTCN-3 component type) + * It is NULL if the function has no 'system' clause. */ + Reference *system_ref; + /** Points to the object describing the component type referred by + * 'system' clause. + * It is NULL if the function has no 'system' clause or \a system_ref is + * erroneous. */ + Type *system_type; /** The 'port' clause (i.e. a reference to a TTCN-3 port type) * It is NULL if the function has no 'port' clause. */ Reference *port_ref; @@ -1433,6 +1449,8 @@ namespace Ttcn { * @param p_id function name * @param p_fpl formal parameter list * @param p_runs_on_ref "runs on", else NULL + * @param p_mtc_ref "mtc", else NULL + * @param p_system_ref "system", else NULL * @param p_port_ref "port", else NULL * @param p_return_type return type, may be NULL * @param returns_template true if the return value is a template @@ -1440,7 +1458,8 @@ namespace Ttcn { * @param p_block the body of the function */ Def_Function(Identifier *p_id, FormalParList *p_fpl, - Reference *p_runs_on_ref, Reference *p_port_ref, + Reference *p_runs_on_ref, Reference *p_mtc_ref, + Reference *p_system_ref, Reference *p_port_ref, Type *p_return_type, bool returns_template, template_restriction_t p_template_restriction, @@ -1450,6 +1469,8 @@ namespace Ttcn { virtual void set_fullname(const string& p_fullname); virtual void set_my_scope(Scope *p_scope); virtual Type *get_RunsOnType(); + virtual Type *get_MtcType(); + virtual Type *get_SystemType(); virtual Type *get_PortType(); /** Returns a scope that can access the definitions within component type * \a comptype and its parent is \a parent_scope.*/ @@ -1586,6 +1607,22 @@ namespace Ttcn { * It is NULL if the altstep has no 'runs on' clause or \a runs_on_ref is * erroneous. */ Type *runs_on_type; + /** The 'mtc' clause (i.e. a reference to a TTCN-3 component type) + * It is NULL if the altstep has no 'mtc' clause. */ + Reference *mtc_ref; + /** Points to the object describing the component type referred by + * 'mtc' clause. + * It is NULL if the altstep has no 'mtc' clause or \a mtc_ref is + * erroneous. */ + Type *mtc_type; + /** The 'system' clause (i.e. a reference to a TTCN-3 component type) + * It is NULL if the altstep has no 'system' clause. */ + Reference *system_ref; + /** Points to the object describing the component type referred by + * 'system' clause. + * It is NULL if the altstep has no 'system' clause or \a system_ref is + * erroneous. */ + Type *system_type; StatementBlock *sb; /**< contains the local definitions */ AltGuards *ags; @@ -1597,13 +1634,16 @@ namespace Ttcn { Def_Altstep& operator=(const Def_Altstep& p); public: Def_Altstep(Identifier *p_id, FormalParList *p_fpl, - Reference *p_runs_on_ref, StatementBlock *p_sb, + Reference *p_runs_on_ref, Reference *p_mtc_ref, + Reference *p_system_ref, StatementBlock *p_sb, AltGuards *p_ags); virtual ~Def_Altstep(); virtual Def_Altstep *clone() const; virtual void set_fullname(const string& p_fullname); virtual void set_my_scope(Scope *p_scope); virtual Type *get_RunsOnType(); + virtual Type *get_MtcType(); + virtual Type *get_SystemType(); virtual FormalParList *get_FormalParList(); /** Returns a scope that can access the definitions within component type * \a comptype and its parent is \a parent_scope.*/ diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc index 4e7448b4f..8c8115ab2 100644 --- a/compiler2/ttcn3/Statement.cc +++ b/compiler2/ttcn3/Statement.cc @@ -3125,6 +3125,11 @@ error: ref_pard->error("Function with `port' clause cannot be called directly."); } my_sb->chk_runs_on_clause(t_ass, *ref_pard, "call"); + + bool in_control_part = my_sb->get_my_def() == NULL; + my_sb->chk_mtc_clause(t_ass, *ref_pard, "call", in_control_part); + my_sb->chk_system_clause(t_ass, *ref_pard, "call", in_control_part); + if (t_ass->get_Type()) ref_pard->warning("The value returned by %s is not used", t_ass->get_description().c_str()); @@ -3375,6 +3380,9 @@ error: Error_Context cntxt(this, "In altstep instance"); Common::Assignment *t_ass = ref_pard->get_refd_assignment(); my_sb->chk_runs_on_clause(t_ass, *ref_pard, "call"); + bool in_control_part = my_sb->get_my_def() == NULL; + my_sb->chk_mtc_clause(t_ass, *ref_pard, "call", in_control_part); + my_sb->chk_system_clause(t_ass, *ref_pard, "call", in_control_part); } void Statement::chk_return() diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index 1c3973ee8..898064d0c 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -470,6 +470,11 @@ static const string anyname("anytype"); Ttcn::Reference *runsonref; Ttcn::Reference *systemref; } configspec; + + struct { + Ttcn::Reference *mtcref; + Ttcn::Reference *systemref; + } alt_tc_configspec; struct { Value *name; @@ -1023,6 +1028,7 @@ static const string anyname("anytype"); %type <reference> PortType optDerivedDef DerivedDef IndexSpec Signature VariableRef TimerRef Port PortOrAll ValueStoreSpec SenderSpec ComponentType optRunsOnSpec RunsOnSpec optSystemSpec optPortSpec + optMtcSpec %type <reference_or_any> PortOrAny TimerRefOrAny %type <valuerange> Range %type <type> NestedEnumDef NestedRecordDef NestedRecordOfDef NestedSetDef @@ -1089,6 +1095,7 @@ AllOrTypeListWithTo TypeListWithFrom TypeListWithTo %type <reforid> Reference %type <initial> Initial %type <configspec> ConfigSpec +%type <alt_tc_configspec> AltOrTcConfigSpec %type <createpar> optCreateParameter %type <applyop> ApplyOp %type <identifier_list> IdentifierList IdentifierListOrPredefType @@ -1442,6 +1449,7 @@ optExtendsDef optFromClause optFunctionActualParList optFunctionFormalParList +optMtcSpec optParDefaultValue optPortCallBody optReceiveParameter @@ -1745,6 +1753,12 @@ Initial } ConfigSpec +%destructor { + delete $$.mtcref; + delete $$.systemref; +} +AltOrTcConfigSpec + %destructor { delete $$.name; delete $$.loc; @@ -4175,11 +4189,11 @@ ValueofOp: // 162 FunctionDef: // 164 FunctionKeyword optDeterministicModifier IDentifier '(' optFunctionFormalParList ')' - optRunsOnSpec optPortSpec optReturnType optError StatementBlock + optRunsOnSpec AltOrTcConfigSpec optPortSpec optReturnType optError StatementBlock { $5->set_location(infile, @4, @6); - $$ = new Def_Function($3, $5, $7, $8, $9.type, $9.returns_template, - $9.template_restriction, $11); + $$ = new Def_Function($3, $5, $7, $8.mtcref, $8.systemref, $9, $10.type, $10.returns_template, + $10.template_restriction, $12); $$->set_location(infile, @$); } ; @@ -4664,12 +4678,26 @@ ConfigSpec: // 202 } ; +AltOrTcConfigSpec: + optMtcSpec optSystemSpec + { + $$.mtcref=$1; + $$.systemref=$2; + } +; + optSystemSpec: // [203] /* empty */ { $$ = 0; } | SystemKeyword ComponentType { $$ = $2; } | SystemKeyword error { $$ = 0; } ; +optMtcSpec: + /* empty */ { $$ = 0; } +| MTCKeyword ComponentType { $$ = $2; } +| MTCKeyword error { $$ = 0; } +; + TestcaseInstance: // 205 ExecuteKeyword '(' TestcaseRef '(' optTestcaseActualParList ')' optTestcaseTimerValue optError ')' @@ -4782,17 +4810,17 @@ TestcaseActualPar: AltstepDef: // 211 AltstepKeyword IDentifier '(' optAltstepFormalParList ')' optRunsOnSpec - optError '{' AltstepLocalDefList AltGuardList optError '}' + AltOrTcConfigSpec optError '{' AltstepLocalDefList AltGuardList optError '}' { StatementBlock *sb = new StatementBlock; - for (size_t i = 0; i < $9.nElements; i++) { - Statement *stmt = new Statement(Statement::S_DEF, $9.elements[i]); - stmt->set_location(*$9.elements[i]); + for (size_t i = 0; i < $10.nElements; i++) { + Statement *stmt = new Statement(Statement::S_DEF, $10.elements[i]); + stmt->set_location(*$10.elements[i]); sb->add_stmt(stmt); } - Free($9.elements); + Free($10.elements); $4->set_location(infile, @4); - $$ = new Def_Altstep($2, $4, $6, sb, $10); + $$ = new Def_Altstep($2, $4, $6, $7.mtcref, $7.systemref, sb, $11); $$->set_location(infile, @$); } ; diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic index dc3b085da..3a1908f6a 100644 --- a/function_test/Semantic_Analyser/Makefile.semantic +++ b/function_test/Semantic_Analyser/Makefile.semantic @@ -13,7 +13,7 @@ # ############################################################################## SADIRS := ver xer encode param template any_from pattern_ref float recof_index \ -port_translation +port_translation mtc_and_system_clause ifdef RT2 SADIRS += deprecated erroneous_attributes template_concat endif diff --git a/function_test/Semantic_Analyser/mtc_and_system_clause/MtcSystemClause_SE.ttcn b/function_test/Semantic_Analyser/mtc_and_system_clause/MtcSystemClause_SE.ttcn new file mode 100644 index 000000000..ddb37f5d1 --- /dev/null +++ b/function_test/Semantic_Analyser/mtc_and_system_clause/MtcSystemClause_SE.ttcn @@ -0,0 +1,102 @@ +/****************************************************************************** + * Copyright (c) 2000-2017 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Szabo, Bence Janos + * + ******************************************************************************/ + +module MtcSystemClause_SE { //^In TTCN-3 module// + + type port P1 message { + inout integer; + } with { + extension "internal"; + } + + type component Comp1 { + var charstring cs; + port P1 p1; + timer mytimer; + } + + type component Comp2 { + var integer i; + port P1 p2; /* Different name */ + timer mytimer; + } + + function diff_mtc() mtc Comp1 { + } + + function diff_system() system Comp1 { + } + + function diff_mtc_and_system() mtc Comp1 system Comp1 { + } + + altstep alt_diff_mtc() runs on Comp1 mtc Comp1 { + []mytimer.timeout{ + + } + } + + altstep alt_diff_system() runs on Comp1 system Comp1 { + []mytimer.timeout{ + + } + } + + altstep alt_diff_mtc_and_system() runs on Comp1 mtc Comp1 system Comp1 { + []mytimer.timeout{ + + } + } + + altstep alt_diff_mtc_bad() runs on Comp2 mtc Comp1 { + []mytimer.timeout{ + + } + } + + altstep alt_diff_system_bad() runs on Comp2 system Comp1 { + []mytimer.timeout{ + + } + } + + altstep alt_diff_mtc_and_system_bad() runs on Comp2 mtc Comp1 system Comp1 { + []mytimer.timeout{ + + } + } + + + + testcase tc_positive() runs on Comp1 system Comp1 { + diff_mtc(); + diff_system(); + diff_mtc_and_system(); + + alt_diff_mtc(); + alt_diff_system(); + alt_diff_mtc_and_system(); + } + + testcase tc_negative() runs on Comp2 system Comp2 { //^In testcase definition \`tc_negative\'\:// + diff_mtc(); //^In function instance\:// //^error\: Mtc clause mismatch\: A definition that runs on component type \`\@MtcSystemClause_SE\.Comp2\' cannot call function \`\@MtcSystemClause_SE\.diff_mtc\'\, which mtc clause is \`\@MtcSystemClause_SE\.Comp1\'// + diff_system(); //^In function instance\:// //^error\: System clause mismatch\: A definition with system component type \`\@MtcSystemClause_SE\.Comp2\' cannot call function \`\@MtcSystemClause_SE\.diff_system\'\, which system clause is \`\@MtcSystemClause_SE\.Comp1\'// + diff_mtc_and_system(); //^In function instance\:// //^error\: System clause mismatch\: A definition with system component type \`\@MtcSystemClause_SE\.Comp2\' cannot call function \`\@MtcSystemClause_SE\.diff_mtc_and_system\'\, which system clause is \`\@MtcSystemClause_SE\.Comp1\'// //^error\: Mtc clause mismatch\: A definition that runs on component type \`\@MtcSystemClause_SE\.Comp2\' cannot call function \`\@MtcSystemClause_SE\.diff_mtc_and_system\'\, which mtc clause is \`\@MtcSystemClause_SE\.Comp1\'// + + alt_diff_mtc_bad(); //^In altstep instance\:// //^error\: Mtc clause mismatch\: A definition that runs on component type \`\@MtcSystemClause_SE\.Comp2\' cannot call altstep \`\@MtcSystemClause_SE\.alt_diff_mtc_bad\'\, which mtc clause is \`\@MtcSystemClause_SE\.Comp1\'// + alt_diff_system_bad(); //^In altstep instance\:// //^error\: System clause mismatch\: A definition with system component type \`\@MtcSystemClause_SE\.Comp2\' cannot call altstep \`\@MtcSystemClause_SE\.alt_diff_system_bad\'\, which system clause is \`\@MtcSystemClause_SE\.Comp1\'// + alt_diff_mtc_and_system_bad(); //^In altstep instance\:// //^error\: System clause mismatch\: A definition with system component type \`\@MtcSystemClause_SE\.Comp2\' cannot call altstep \`\@MtcSystemClause_SE\.alt_diff_mtc_and_system_bad\'\, which system clause is \`\@MtcSystemClause_SE\.Comp1\'// //^error\: Mtc clause mismatch\: A definition that runs on component type \`\@MtcSystemClause_SE\.Comp2\' cannot call altstep \`\@MtcSystemClause_SE\.alt_diff_mtc_and_system_bad\'\, which mtc clause is \`\@MtcSystemClause_SE\.Comp1\'// + } + + + +} diff --git a/function_test/Semantic_Analyser/mtc_and_system_clause/t b/function_test/Semantic_Analyser/mtc_and_system_clause/t new file mode 100755 index 000000000..3a4b58ec1 --- /dev/null +++ b/function_test/Semantic_Analyser/mtc_and_system_clause/t @@ -0,0 +1,9 @@ +#!/usr/bin/perl +# note this is called through "perl -w" +use strict; + +my $self = $0; +$self =~ s!/t!!; + +exec('make check --no-print-directory -s -C ' . $self); + -- GitLab