Commit 083dc876 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

OOP: implemented the 'raise' statement and 'catch'/'finally' blocks (Bug 568899)


Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
Change-Id: Id98b9cd7eb7f0a1cd842405f07f8feb75a42d277
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 4a191f2c
...@@ -1828,6 +1828,8 @@ namespace Common { ...@@ -1828,6 +1828,8 @@ namespace Common {
return "template"; return "template";
case A_VAR: case A_VAR:
return "variable"; return "variable";
case A_EXCEPTION:
return "exception";
case A_VAR_TEMPLATE: case A_VAR_TEMPLATE:
return "template variable"; return "template variable";
case A_TIMER: case A_TIMER:
...@@ -1884,6 +1886,7 @@ namespace Common { ...@@ -1884,6 +1886,7 @@ namespace Common {
case A_PAR_TEMPL_INOUT: case A_PAR_TEMPL_INOUT:
case A_PAR_TIMER: case A_PAR_TIMER:
case A_PAR_PORT: case A_PAR_PORT:
case A_EXCEPTION:
// parameter is identified using its id // parameter is identified using its id
ret_val += id->get_dispname(); ret_val += id->get_dispname();
break; break;
......
...@@ -515,6 +515,7 @@ namespace Common { ...@@ -515,6 +515,7 @@ namespace Common {
A_MODULEPAR_TEMP, /**< template module parameter */ A_MODULEPAR_TEMP, /**< template module parameter */
A_TEMPLATE, /**< template (TTCN-3) */ A_TEMPLATE, /**< template (TTCN-3) */
A_VAR, /**< variable (TTCN-3) */ A_VAR, /**< variable (TTCN-3) */
A_EXCEPTION, /**< exception (at the beginning of a catch block) (TTCN-3) */
A_VAR_TEMPLATE, /**< template variable, dynamic template (TTCN-3) */ A_VAR_TEMPLATE, /**< template variable, dynamic template (TTCN-3) */
A_TIMER, /**< timer (TTCN-3) */ A_TIMER, /**< timer (TTCN-3) */
A_PORT, /**< port (TTCN-3) */ A_PORT, /**< port (TTCN-3) */
......
...@@ -7965,6 +7965,25 @@ namespace Common { ...@@ -7965,6 +7965,25 @@ namespace Common {
} }
} }
} }
string Type::get_exception_name()
{
switch (ownertype) {
case OT_TYPE_ASS:
case OT_TYPE_DEF:
case OT_ARRAY:
case OT_COMP_FIELD:
case OT_RECORD_OF:
return get_genname_own();
default:
if (is_ref()) {
return get_type_refd()->get_exception_name();
}
else {
return get_typename();
}
}
}
string Type::get_genname_typename(Scope *p_scope) string Type::get_genname_typename(Scope *p_scope)
{ {
......
...@@ -1368,6 +1368,7 @@ namespace Common { ...@@ -1368,6 +1368,7 @@ namespace Common {
string get_genname_typedescriptor(Scope *p_scope); string get_genname_typedescriptor(Scope *p_scope);
string get_genname_coder(Scope* p_scope); string get_genname_coder(Scope* p_scope);
string get_genname_default_coding(Scope* p_scope); string get_genname_default_coding(Scope* p_scope);
string get_exception_name();
private: private:
/** Returns the name prefix of type descriptors, etc. that belong to the /** Returns the name prefix of type descriptors, etc. that belong to the
* equivalent C++ class referenced from the module of scope \a p_scope. * equivalent C++ class referenced from the module of scope \a p_scope.
......
...@@ -4233,6 +4233,7 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v ...@@ -4233,6 +4233,7 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v
} }
// else fall through // else fall through
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL: case Assignment::A_PAR_VAL:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
...@@ -6515,6 +6516,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed, ...@@ -6515,6 +6516,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
switch (ass->get_asstype()) { switch (ass->get_asstype()) {
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_INOUT: case Assignment::A_PAR_VAL_INOUT:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
......
...@@ -4168,6 +4168,7 @@ namespace Common { ...@@ -4168,6 +4168,7 @@ namespace Common {
case Assignment::A_MODULEPAR_TEMP: case Assignment::A_MODULEPAR_TEMP:
case Assignment::A_TEMPLATE: case Assignment::A_TEMPLATE:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_VAR_TEMPLATE: case Assignment::A_VAR_TEMPLATE:
case Assignment::A_FUNCTION_RVAL: case Assignment::A_FUNCTION_RVAL:
case Assignment::A_FUNCTION_RTEMP: case Assignment::A_FUNCTION_RTEMP:
...@@ -4570,6 +4571,7 @@ namespace Common { ...@@ -4570,6 +4571,7 @@ namespace Common {
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
case Assignment::A_PAR_VAL_INOUT: case Assignment::A_PAR_VAL_INOUT:
...@@ -5069,6 +5071,7 @@ namespace Common { ...@@ -5069,6 +5071,7 @@ namespace Common {
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_FUNCTION_RVAL: case Assignment::A_FUNCTION_RVAL:
case Assignment::A_EXT_FUNCTION_RVAL: case Assignment::A_EXT_FUNCTION_RVAL:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
...@@ -5276,6 +5279,7 @@ namespace Common { ...@@ -5276,6 +5279,7 @@ namespace Common {
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_FUNCTION_RVAL: case Assignment::A_FUNCTION_RVAL:
case Assignment::A_EXT_FUNCTION_RVAL: case Assignment::A_EXT_FUNCTION_RVAL:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
...@@ -6683,6 +6687,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -6683,6 +6687,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
goto error; goto error;
break; break;
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
case Assignment::A_PAR_VAL_INOUT: case Assignment::A_PAR_VAL_INOUT:
break; break;
...@@ -6752,6 +6757,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -6752,6 +6757,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
// Extra check for HM59355. // Extra check for HM59355.
switch (t_ass->get_asstype()) { switch (t_ass->get_asstype()) {
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
case Assignment::A_PAR_VAL_INOUT: case Assignment::A_PAR_VAL_INOUT:
...@@ -7043,6 +7049,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -7043,6 +7049,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
} }
break; break;
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
case Assignment::A_PAR_VAL_INOUT: case Assignment::A_PAR_VAL_INOUT:
...@@ -10322,6 +10329,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -10322,6 +10329,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_FUNCTION_RVAL: case Assignment::A_FUNCTION_RVAL:
case Assignment::A_EXT_FUNCTION_RVAL: case Assignment::A_EXT_FUNCTION_RVAL:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
...@@ -12007,6 +12015,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -12007,6 +12015,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
case Assignment::A_PAR_VAL_INOUT: { case Assignment::A_PAR_VAL_INOUT: {
...@@ -15177,6 +15186,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -15177,6 +15186,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_FUNCTION_RVAL: case Assignment::A_FUNCTION_RVAL:
case Assignment::A_EXT_FUNCTION_RVAL: case Assignment::A_EXT_FUNCTION_RVAL:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
...@@ -16778,6 +16788,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -16778,6 +16788,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case Assignment::A_EXT_CONST: case Assignment::A_EXT_CONST:
case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR:
case Assignment::A_VAR: case Assignment::A_VAR:
case Assignment::A_EXCEPTION:
case Assignment::A_PAR_VAL_IN: case Assignment::A_PAR_VAL_IN:
case Assignment::A_PAR_VAL_OUT: case Assignment::A_PAR_VAL_OUT:
case Assignment::A_PAR_VAL_INOUT: case Assignment::A_PAR_VAL_INOUT:
......
...@@ -398,6 +398,7 @@ namespace Ttcn { ...@@ -398,6 +398,7 @@ namespace Ttcn {
case Common::Assignment::A_EXT_CONST: // a Def_ExtConst case Common::Assignment::A_EXT_CONST: // a Def_ExtConst
case Common::Assignment::A_MODULEPAR: // a Def_Modulepar case Common::Assignment::A_MODULEPAR: // a Def_Modulepar
case Common::Assignment::A_VAR: // a Def_Var case Common::Assignment::A_VAR: // a Def_Var
case Common::Assignment::A_EXCEPTION: // a Def_Exception
case Common::Assignment::A_FUNCTION_RVAL: // a Def_Function case Common::Assignment::A_FUNCTION_RVAL: // a Def_Function
case Common::Assignment::A_EXT_FUNCTION_RVAL: // a Def_ExtFunction case Common::Assignment::A_EXT_FUNCTION_RVAL: // a Def_ExtFunction
case Common::Assignment::A_PAR_VAL_IN: // a FormalPar case Common::Assignment::A_PAR_VAL_IN: // a FormalPar
...@@ -673,6 +674,7 @@ namespace Ttcn { ...@@ -673,6 +674,7 @@ namespace Ttcn {
case Common::Assignment::A_MODULEPAR: /**< module parameter (TTCN-3) */ case Common::Assignment::A_MODULEPAR: /**< module parameter (TTCN-3) */
case Common::Assignment::A_MODULEPAR_TEMP: /**< template module parameter */ case Common::Assignment::A_MODULEPAR_TEMP: /**< template module parameter */
case Common::Assignment::A_VAR: /**< variable (TTCN-3) */ case Common::Assignment::A_VAR: /**< variable (TTCN-3) */
case Common::Assignment::A_EXCEPTION: /**< exception (TTCN-3) */
case Common::Assignment::A_VAR_TEMPLATE: /**< template variable: dynamic template (TTCN-3) */ case Common::Assignment::A_VAR_TEMPLATE: /**< template variable: dynamic template (TTCN-3) */
case Common::Assignment::A_TIMER: /**< timer (TTCN-3) */ case Common::Assignment::A_TIMER: /**< timer (TTCN-3) */
case Common::Assignment::A_PORT: /**< port (TTCN-3) */ case Common::Assignment::A_PORT: /**< port (TTCN-3) */
...@@ -914,6 +916,7 @@ namespace Ttcn { ...@@ -914,6 +916,7 @@ namespace Ttcn {
if (ass != NULL && subrefs.get_nof_refs() != 0) { if (ass != NULL && subrefs.get_nof_refs() != 0) {
switch (ass->get_asstype()) { switch (ass->get_asstype()) {
case Common::Assignment::A_VAR: case Common::Assignment::A_VAR:
case Common::Assignment::A_EXCEPTION:
case Common::Assignment::A_PAR_VAL: case Common::Assignment::A_PAR_VAL:
case Common::Assignment::A_PAR_VAL_IN: case Common::Assignment::A_PAR_VAL_IN:
case Common::Assignment::A_PAR_VAL_INOUT: case Common::Assignment::A_PAR_VAL_INOUT:
...@@ -981,6 +984,7 @@ namespace Ttcn { ...@@ -981,6 +984,7 @@ namespace Ttcn {
t_ass->use_as_lvalue(*this); t_ass->use_as_lvalue(*this);
// no break // no break
case Common::Assignment::A_VAR: case Common::Assignment::A_VAR:
case Common::Assignment::A_EXCEPTION:
case Common::Assignment::A_PAR_VAL_OUT: case Common::Assignment::A_PAR_VAL_OUT:
case Common::Assignment::A_PAR_VAL_INOUT: case Common::Assignment::A_PAR_VAL_INOUT:
if (has_parameters()) { if (has_parameters()) {
...@@ -1186,6 +1190,7 @@ namespace Ttcn { ...@@ -1186,6 +1190,7 @@ namespace Ttcn {
base_type->get_genname_own(my_scope).c_str()); base_type->get_genname_own(my_scope).c_str());
} }
string const_prefix; // empty by default string const_prefix; // empty by default
string exception_postfix; // also empty by default
if (gen_const_prefix) { if (gen_const_prefix) {
if (ass->get_asstype() == Common::Assignment::A_CONST) { if (ass->get_asstype() == Common::Assignment::A_CONST) {
const_prefix = "const_"; const_prefix = "const_";
...@@ -1194,6 +1199,9 @@ namespace Ttcn { ...@@ -1194,6 +1199,9 @@ namespace Ttcn {
const_prefix = "template_"; const_prefix = "template_";
} }
} }
if (ass->get_asstype() == Common::Assignment::A_EXCEPTION) {
exception_postfix = "()";
}
if (parlist != NULL) { if (parlist != NULL) {
expr->expr = mputprintf(expr->expr, "%s(", expr->expr = mputprintf(expr->expr, "%s(",
ass->get_genname_from_scope(my_scope).c_str()); ass->get_genname_from_scope(my_scope).c_str());
...@@ -1204,7 +1212,7 @@ namespace Ttcn { ...@@ -1204,7 +1212,7 @@ namespace Ttcn {
expr->expr = mputstr(expr->expr, expr->expr = mputstr(expr->expr,
LazyFuzzyParamData::in_lazy_or_fuzzy() ? LazyFuzzyParamData::in_lazy_or_fuzzy() ?
LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() : LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() :
(const_prefix + ass->get_genname_from_scope(my_scope)).c_str()); (const_prefix + ass->get_genname_from_scope(my_scope) + exception_postfix).c_str());
} }
if (subrefs.get_nof_refs() > 0) subrefs.generate_code(expr, ass, my_scope); if (subrefs.get_nof_refs() > 0) subrefs.generate_code(expr, ass, my_scope);
} }
...@@ -1225,6 +1233,7 @@ namespace Ttcn { ...@@ -1225,6 +1233,7 @@ namespace Ttcn {
switch (ass->get_asstype()) { switch (ass->get_asstype()) {
case Common::Assignment::A_MODULEPAR: case Common::Assignment::A_MODULEPAR:
case Common::Assignment::A_VAR: case Common::Assignment::A_VAR:
case Common::Assignment::A_EXCEPTION:
case Common::Assignment::A_PAR_VAL: case Common::Assignment::A_PAR_VAL:
case Common::Assignment::A_PAR_VAL_IN: case Common::Assignment::A_PAR_VAL_IN:
case Common::Assignment::A_PAR_VAL_OUT: case Common::Assignment::A_PAR_VAL_OUT:
...@@ -1270,6 +1279,10 @@ namespace Ttcn { ...@@ -1270,6 +1279,10 @@ namespace Ttcn {
refd_gov->get_genname_value(get_my_scope()).c_str()); refd_gov->get_genname_value(get_my_scope()).c_str());
} }
} }
string exception_postfix;
if (ass->get_asstype() == Common::Assignment::A_EXCEPTION) {
exception_postfix = "()";
}
if (parlist != NULL) { if (parlist != NULL) {
// reference without parameters to a template that has only default formal parameters. // reference without parameters to a template that has only default formal parameters.
// if @lazy: nothing to do, it's a C++ function call just like in case of Ref_pard::generate_code() // if @lazy: nothing to do, it's a C++ function call just like in case of Ref_pard::generate_code()
...@@ -1282,7 +1295,7 @@ namespace Ttcn { ...@@ -1282,7 +1295,7 @@ namespace Ttcn {
this_expr.expr = mputstr(this_expr.expr, this_expr.expr = mputstr(this_expr.expr,
LazyFuzzyParamData::in_lazy_or_fuzzy() ? LazyFuzzyParamData::in_lazy_or_fuzzy() ?
LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() : LazyFuzzyParamData::add_ref_genname(ass, my_scope).c_str() :
ass->get_genname_from_scope(my_scope).c_str()); (ass->get_genname_from_scope(my_scope) + exception_postfix).c_str());
} }
if (refd_gov->get_type_refd_last()->get_typetype() != Common::Type::T_CLASS) { if (refd_gov->get_type_refd_last()->get_typetype() != Common::Type::T_CLASS) {
this_expr.expr = mputstr(this_expr.expr, ")"); this_expr.expr = mputstr(this_expr.expr, ")");
...@@ -5490,6 +5503,21 @@ namespace Ttcn { ...@@ -5490,6 +5503,21 @@ namespace Ttcn {
if (initial_value) initial_value->dump(level + 1); if (initial_value) initial_value->dump(level + 1);
} }
// =================================
// ===== Def_Exception
// =================================
Def_Exception::Def_Exception(Identifier* p_id, Type* p_type): Def_Var(p_id, p_type, NULL)
{
asstype = Common::Assignment::A_EXCEPTION;
}
char* Def_Exception::generate_code_str(char *str)
{
return mputprintf(str, "EXCEPTION<%s>& %s = static_cast<EXCEPTION<%s>&>(exc_base);\n",
type->get_genname_value(my_scope).c_str(), id->get_name().c_str(), type->get_genname_value(my_scope).c_str());
}
// ================================= // =================================
// ===== Def_Var_Template // ===== Def_Var_Template
// ================================= // =================================
...@@ -8425,9 +8453,7 @@ namespace Ttcn { ...@@ -8425,9 +8453,7 @@ namespace Ttcn {
body = generate_code_debugger_function_init(body, this); body = generate_code_debugger_function_init(body, this);
} }
body = sb->generate_code(body, target->header.global_vars, body = sb->generate_code(body, target->header.global_vars,
target->source.global_vars); target->source.global_vars, ags);
body = ags->generate_code_altstep(body, target->header.global_vars,
target->source.global_vars);
// generate a smart formal parameter list (omits unused parameter names) // generate a smart formal parameter list (omits unused parameter names)
char *formal_par_list = fp_list->generate_code(memptystr()); char *formal_par_list = fp_list->generate_code(memptystr());
fp_list->generate_code_defval(target); fp_list->generate_code_defval(target);
...@@ -8708,7 +8734,9 @@ namespace Ttcn { ...@@ -8708,7 +8734,9 @@ namespace Ttcn {
body = generate_code_debugger_function_init(body, this); body = generate_code_debugger_function_init(body, this);
} }
body = mputprintf(body, "try {\n" body = mputprintf(body, "try {\n"
"%s"
"TTCN_Runtime::begin_testcase(\"%s\", \"%s\", ", "TTCN_Runtime::begin_testcase(\"%s\", \"%s\", ",
oop_features ? "try {\n" : "",
my_scope->get_scope_mod()->get_modid().get_dispname().c_str(), my_scope->get_scope_mod()->get_modid().get_dispname().c_str(),
dispname_str); dispname_str);
ComponentTypeBody *runs_on_body = runs_on_type->get_CompBody(); ComponentTypeBody *runs_on_body = runs_on_type->get_CompBody();
...@@ -8721,10 +8749,14 @@ namespace Ttcn { ...@@ -8721,10 +8749,14 @@ namespace Ttcn {
body = block->generate_code(body, target->header.global_vars, body = block->generate_code(body, target->header.global_vars,
target->source.global_vars); target->source.global_vars);
body = mputprintf(body, body = mputprintf(body,
"%s"
"} catch (const TC_Error& tc_error) {\n" "} catch (const TC_Error& tc_error) {\n"
"} catch (const TC_End& tc_end) {\n" "} catch (const TC_End& tc_end) {\n"
"TTCN_Logger::log_str(TTCN_FUNCTION, \"Test case %s was stopped.\");\n" "TTCN_Logger::log_str(TTCN_FUNCTION, \"Test case %s was stopped.\");\n"
"}\n", dispname_str); "}\n",
oop_features ? "} catch (const EXCEPTION_BASE& exc) {\n"
"TTCN_error(\"Unhandled exception: %s\", (const char*) exc.get_log());\n"
"}\n" : "", dispname_str);
body = mputstr(body, "return TTCN_Runtime::end_testcase();\n"); body = mputstr(body, "return TTCN_Runtime::end_testcase();\n");
// smart formal parameter list (names of unused parameters are omitted) // smart formal parameter list (names of unused parameters are omitted)
...@@ -9595,6 +9627,7 @@ namespace Ttcn { ...@@ -9595,6 +9627,7 @@ namespace Ttcn {
} }
// no break // no break
case A_VAR: case A_VAR:
case A_EXCEPTION:
case A_PAR_VAL_OUT: case A_PAR_VAL_OUT:
case A_PAR_VAL_INOUT: case A_PAR_VAL_INOUT:
if (!is_template) asstype_correct = true; if (!is_template) asstype_correct = true;
...@@ -10709,6 +10742,7 @@ namespace Ttcn { ...@@ -10709,6 +10742,7 @@ namespace Ttcn {
if(!t_par_ass) FATAL_ERROR("FormalParList::chk_activate_argument()"); if(!t_par_ass) FATAL_ERROR("FormalParList::chk_activate_argument()");
switch (t_par_ass->get_asstype()) { switch (t_par_ass->get_asstype()) {
case Common::Assignment::A_VAR: case Common::Assignment::A_VAR:
case Common::Assignment::A_EXCEPTION: // TODO: can exceptions be of 'default' type?
case Common::Assignment::A_VAR_TEMPLATE: case Common::Assignment::A_VAR_TEMPLATE:
case Common::Assignment::A_TIMER: case Common::Assignment::A_TIMER:
// it is not allowed to pass references of local variables or timers // it is not allowed to pass references of local variables or timers
...@@ -11562,6 +11596,7 @@ namespace Ttcn { ...@@ -11562,6 +11596,7 @@ namespace Ttcn {
Common::Assignment *ass = par->get_Ref()->get_refd_assignment(); Common::Assignment *ass = par->get_Ref()->get_refd_assignment();
switch (ass->get_asstype()) { switch (ass->get_asstype()) {
case Common::Assignment::A_VAR: case Common::Assignment::A_VAR:
case Common::Assignment::A_EXCEPTION:
case Common::Assignment::A_PAR_VAL_IN: case Common::Assignment::A_PAR_VAL_IN:
case Common::Assignment::A_PAR_VAL_OUT: case Common::Assignment::A_PAR_VAL_OUT:
case Common::Assignment::A_PAR_VAL_INOUT: case Common::Assignment::A_PAR_VAL_INOUT:
......
...@@ -1166,11 +1166,13 @@ namespace Ttcn { ...@@ -1166,11 +1166,13 @@ namespace Ttcn {
* Def_Var class represents a variable definition. * Def_Var class represents a variable definition.
*/ */
class Def_Var : public Definition { class Def_Var : public Definition {
private: protected:
Type *type; Type *type;
private:
/** the initial value: optional and maybe incomplete */ /** the initial value: optional and maybe incomplete */
Value *initial_value; Value *initial_value;
/// Copy constructor disabled /// Copy constructor disabled
Def_Var(const Def_Var& p); Def_Var(const Def_Var& p);
/// %Assignment disabled /// %Assignment disabled
...@@ -1191,6 +1193,18 @@ namespace Ttcn { ...@@ -1191,6 +1193,18 @@ namespace Ttcn {
virtual char *generate_code_init_comp(char *str, Definition *base_defn); virtual char *generate_code_init_comp(char *str, Definition *base_defn);
virtual void dump_internal(unsigned level) const; virtual void dump_internal(unsigned level) const;
}; };
class Def_Exception : public Def_Var {
private:
/// Copy constructor disabled
Def_Exception(const Def_Exception& p);
/// %Assignment disabled
Def_Exception& operator=(const Def_Exception& p);
public:
Def_Exception(Identifier* p_id, Type* p_type);
virtual char* generate_code_str(char *str);
};
/** /**
* Def_Var_Template class represents a template variable (dynamic template) * Def_Var_Template class represents a template variable (dynamic template)
......
...@@ -675,6 +675,7 @@ namespace Ttcn { ...@@ -675,6 +675,7 @@ namespace Ttcn {
} }
} else if ((assign->get_asstype() == Common::Assignment::A_MODULEPAR } else if ((assign->get_asstype() == Common::Assignment::A_MODULEPAR
|| assign->get_asstype() == Common::Assignment::A_VAR || assign->get_asstype() == Common::Assignment::A_VAR
|| assign->get_asstype() == Common::Assignment::A_EXCEPTION
|| assign->get_asstype() == Common::Assignment::A_PAR_VAL || assign->get_asstype() == Common::Assignment::A_PAR_VAL
|| assign->get_asstype() == Common::Assignment::A_PAR_VAL_IN || assign->get_asstype() == Common::Assignment::A_PAR_VAL_IN
|| assign->get_asstype() == Common::Assignment::A_PAR_VAL_OUT || assign->get_asstype() == Common::Assignment::A_PAR_VAL_OUT
......
...@@ -43,7 +43,8 @@ namespace Ttcn { ...@@ -43,7 +43,8 @@ namespace Ttcn {
// ================================= // =================================
StatementBlock::StatementBlock() StatementBlock::StatementBlock()
: Scope(), checked(false), labels_checked(false), my_sb(0), my_def(0), exception_handling(EH_NONE) : Scope(), checked(false), labels_checked(false), my_sb(0), my_def(0), exception_handling(EH_NONE),
finally_block(NULL)
{ {
} }
...@@ -54,6 +55,11 @@ namespace Ttcn { ...@@ -54,6 +55,11 @@ namespace Ttcn {
stmts.clear(); stmts.clear();
defs.clear(); defs.clear();
labels.clear(); labels.clear();
for (size_t i = 0; i < catch_blocks.size(); ++i) {
delete catch_blocks[i];
}
catch_blocks.clear();
delete finally_block;
} }
StatementBlock *StatementBlock::clone() const StatementBlock *StatementBlock::clone() const
...@@ -89,6 +95,12 @@ namespace Ttcn { ...@@ -89,6 +95,12 @@ namespace Ttcn {
set_parent_scope(p_scope); set_parent_scope(p_scope);
for(size_t i=0; i<stmts.size(); i++) for(size_t i=0; i<stmts.size(); i++)
stmts[i]->set_my_scope(this); stmts[i]->set_my_scope(this);
for (size_t i = 0; i < catch_blocks.size(); ++i) {
catch_blocks[i]->set_parent_scope(p_scope);
}
if (finally_block != NULL) {
finally_block->set_parent_scope(p_scope);
}
} }
void StatementBlock::set_fullname(const string& p_fullname) void StatementBlock::set_fullname(const string& p_fullname)
...@@ -96,6 +108,12 @@ namespace Ttcn { ...@@ -96,6 +108,12 @@ namespace Ttcn {
Node::set_fullname(p_fullname); Node::set_fullname(p_fullname);
for(size_t i=0; i<stmts.size(); i++) for(size_t i=0; i<stmts.size(); i++)
stmts[i]->set_fullname(p_fullname+".stmt_"+Int2string(i+1)); stmts[i]->set_fullname(p_fullname+".stmt_"+Int2string(i+1));
for (size_t i = 0; i < catch_blocks.size(); ++i) {
catch_blocks[i]->set_fullname(p_fullname + ".catch_block_" + Int2string(i + 1));
}
if (finally_block != NULL) {
finally_block->set_fullname(p_fullname + ".finally_block");
}