Commit 64c877b2 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

OOP: classes embedded in structures - part 2 (issue #601)


Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 516715d2
...@@ -4309,6 +4309,11 @@ namespace Ttcn { ...@@ -4309,6 +4309,11 @@ namespace Ttcn {
t->get_typename().c_str()); t->get_typename().c_str());
break; break;
default: default:
if (t->contains_class()) {
error("Constant cannot be defined for type `%s', which contains a class",
t->get_typename().c_str());
break;
}
if (value != NULL) { if (value != NULL) {
value_under_check = true; value_under_check = true;
namedbool class_member_init = my_scope->is_class_scope() ? namedbool class_member_init = my_scope->is_class_scope() ?
...@@ -4641,10 +4646,6 @@ namespace Ttcn { ...@@ -4641,10 +4646,6 @@ namespace Ttcn {
error("Type of module parameter cannot be signature `%s'", error("Type of module parameter cannot be signature `%s'",
t->get_fullname().c_str()); t->get_fullname().c_str());
break; break;
case Type::T_CLASS:
error("Type of module parameter cannot be or embed class type `%s'",
t->get_typename().c_str());
break;
case Type::T_FUNCTION: case Type::T_FUNCTION:
case Type::T_ALTSTEP: case Type::T_ALTSTEP:
case Type::T_TESTCASE: case Type::T_TESTCASE:
...@@ -4657,6 +4658,10 @@ namespace Ttcn { ...@@ -4657,6 +4658,10 @@ namespace Ttcn {
#if defined(MINGW) #if defined(MINGW)
checked = true; checked = true;
#else #else
if (t->contains_class()) {
error("Type of module parameter cannot be or embed a class type");
break;
}
if (def_value) { if (def_value) {
Error_Context cntxt2(def_value, "In default value"); Error_Context cntxt2(def_value, "In default value");
def_value->set_my_governor(type); def_value->set_my_governor(type);
...@@ -4821,11 +4826,11 @@ namespace Ttcn { ...@@ -4821,11 +4826,11 @@ namespace Ttcn {
" `%s' which has runs on self clause", t->get_fullname().c_str()); " `%s' which has runs on self clause", t->get_fullname().c_str());
} }
break; break;
case Type::T_CLASS:
error("Type of template module parameter cannot be class type `%s'",
t->get_typename().c_str());
break;
default: default:
if (t->contains_class()) {
error("Type of template module parameter cannot be or embed a class type");
break;
}
if (IMPLICIT_OMIT == has_implicit_omit_attr()) { if (IMPLICIT_OMIT == has_implicit_omit_attr()) {
error("Implicit omit not supported for template module parameters"); error("Implicit omit not supported for template module parameters");
} }
...@@ -5063,6 +5068,10 @@ namespace Ttcn { ...@@ -5063,6 +5068,10 @@ namespace Ttcn {
error("Template cannot be defined for class type `%s'", error("Template cannot be defined for class type `%s'",
t->get_typename().c_str()); t->get_typename().c_str());
} }
else if (t->contains_class()) {
error("Template cannot be defined for type `%s', which contains a class",
t->get_typename().c_str());
}
type->chk_this_template_incorrect_field(); type->chk_this_template_incorrect_field();
chk_modified(); chk_modified();
chk_recursive_derivation(); chk_recursive_derivation();
...@@ -5950,6 +5959,10 @@ namespace Ttcn { ...@@ -5950,6 +5959,10 @@ namespace Ttcn {
error("Template variable cannot be defined for class type `%s'", error("Template variable cannot be defined for class type `%s'",
t->get_typename().c_str()); t->get_typename().c_str());
} }
else if (t->contains_class()) {
error("Template variable cannot be defined for type `%s', which contains a class",
t->get_typename().c_str());
}
if (initial_value) { if (initial_value) {
initial_value->set_my_governor(type); initial_value->set_my_governor(type);
...@@ -9300,7 +9313,7 @@ namespace Ttcn { ...@@ -9300,7 +9313,7 @@ namespace Ttcn {
LazyFuzzyParamData::clean(); LazyFuzzyParamData::clean();
} }
else { else {
if (use_runtime_2 && fp->get_defpar_wrapper() == Common::Type::NO_DEFPAR_WRAPPER) { if (use_runtime_2 && !fp->has_defpar_wrapper()) {
string tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id(); string tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id();
expr.preamble = mputprintf(expr.preamble, "%s %s;\n", expr.preamble = mputprintf(expr.preamble, "%s %s;\n",
fp->get_Type()->get_genname_template(my_scope).c_str(), tmp_id.c_str()); fp->get_Type()->get_genname_template(my_scope).c_str(), tmp_id.c_str());
...@@ -9775,7 +9788,7 @@ namespace Ttcn { ...@@ -9775,7 +9788,7 @@ namespace Ttcn {
my_parlist->get_my_def()->get_asstype() == Definition::A_ALTSTEP) || my_parlist->get_my_def()->get_asstype() == Definition::A_ALTSTEP) ||
// always shadow 'in' parameters of class type (to avoid having to deal // always shadow 'in' parameters of class type (to avoid having to deal
// with constant OBJECT_REFs at runtime) // with constant OBJECT_REFs at runtime)
(type != NULL && type->get_type_refd_last()->get_typetype() == Type::T_CLASS))) { (type != NULL && type->contains_class()))) {
use_as_lvalue(*this); use_as_lvalue(*this);
} }
break; break;
...@@ -10397,7 +10410,7 @@ namespace Ttcn { ...@@ -10397,7 +10410,7 @@ namespace Ttcn {
else { else {
// update the genname so that all references in the generated code // update the genname so that all references in the generated code
// will point to the shadow object // will point to the shadow object
if (eval == NORMAL_EVAL && get_defpar_wrapper() == Common::Type::NO_DEFPAR_WRAPPER) { if (eval == NORMAL_EVAL && !has_defpar_wrapper()) {
set_genname(id->get_name() + "_shadow"); set_genname(id->get_name() + "_shadow");
} }
used_as_lvalue = true; used_as_lvalue = true;
...@@ -10432,7 +10445,7 @@ namespace Ttcn { ...@@ -10432,7 +10445,7 @@ namespace Ttcn {
return str; return str;
} }
Common::Type::defpar_wapper_t FormalPar::get_defpar_wrapper() const bool FormalPar::has_defpar_wrapper() const
{ {
Definition* def = my_parlist->get_my_def(); Definition* def = my_parlist->get_my_def();
if (defval.ap != NULL && def != NULL && if (defval.ap != NULL && def != NULL &&
...@@ -10440,27 +10453,20 @@ namespace Ttcn { ...@@ -10440,27 +10453,20 @@ namespace Ttcn {
switch (asstype) { switch (asstype) {
case A_PAR_VAL_IN: case A_PAR_VAL_IN:
case A_PAR_TEMPL_IN: case A_PAR_TEMPL_IN:
return Common::Type::DEFPAR_IN_WRAPPER; return true;
case A_PAR_VAL_OUT:
case A_PAR_VAL_INOUT:
case A_PAR_TEMPL_OUT:
case A_PAR_TEMPL_INOUT:
case A_PAR_TIMER:
case A_PAR_PORT:
return Common::Type::DEFPAR_OUT_WRAPPER;
default: default:
FATAL_ERROR("FormalPar::get_defpar_wrapper"); break;
} }
} }
return Common::Type::NO_DEFPAR_WRAPPER; return false;
} }
char* FormalPar::generate_code_defval(char* str) char* FormalPar::generate_code_defval(char* str)
{ {
if (!defval.ap || defval_generated) return str; if (!defval.ap || defval_generated) return str;
defval_generated = true; defval_generated = true;
Common::Type::defpar_wapper_t defpar_wrapper = get_defpar_wrapper(); bool defpar_wrapper = has_defpar_wrapper();
if (!usage_found && defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER) { if (!usage_found && defpar_wrapper) {
return str; return str;
} }
switch (defval.ap->get_selection()) { switch (defval.ap->get_selection()) {
...@@ -10468,7 +10474,7 @@ namespace Ttcn { ...@@ -10468,7 +10474,7 @@ namespace Ttcn {
Value *val = defval.ap->get_Value(); Value *val = defval.ap->get_Value();
str = val->update_location_object(str); str = val->update_location_object(str);
string tmp_id; string tmp_id;
if (defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER) { if (defpar_wrapper) {
tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id(); tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id();
str = mputprintf(str, str = mputprintf(str,
"%s %s;\n", "%s %s;\n",
...@@ -10476,22 +10482,22 @@ namespace Ttcn { ...@@ -10476,22 +10482,22 @@ namespace Ttcn {
val->set_gen_class_defpar_prefix(); val->set_gen_class_defpar_prefix();
} }
if (use_runtime_2 && TypeConv::needs_conv_refd(val)) { if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
str = TypeConv::gen_conv_code_refd(str, defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER ? str = TypeConv::gen_conv_code_refd(str, defpar_wrapper ?
tmp_id.c_str() : val->get_lhs_name().c_str(), val); tmp_id.c_str() : val->get_lhs_name().c_str(), val);
} else { } else {
str = val->generate_code_init(str, defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER ? str = val->generate_code_init(str, defpar_wrapper ?
tmp_id.c_str() : val->get_lhs_name().c_str()); tmp_id.c_str() : val->get_lhs_name().c_str());
} }
if (defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER) { if (defpar_wrapper) {
str = mputprintf(str, "def_val = %s;\n", tmp_id.c_str()); str = mputprintf(str, "def_val = %s;\n", tmp_id.c_str());
} }
break; } break; }
case ActualPar::AP_TEMPLATE: { case ActualPar::AP_TEMPLATE: {
if (!use_runtime_2 || defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER) { if (!use_runtime_2 || defpar_wrapper) {
TemplateInstance *ti = defval.ap->get_TemplateInstance(); TemplateInstance *ti = defval.ap->get_TemplateInstance();
str = ti->get_Template()->update_location_object(str); str = ti->get_Template()->update_location_object(str);
string tmp_id; string tmp_id;
if (defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER) { if (defpar_wrapper) {
tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id(); tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id();
str = mputprintf(str, str = mputprintf(str,
"%s %s;\n", "%s %s;\n",
...@@ -10499,10 +10505,10 @@ namespace Ttcn { ...@@ -10499,10 +10505,10 @@ namespace Ttcn {
ti->set_gen_class_defpar_prefix(); ti->set_gen_class_defpar_prefix();
} }
str = generate_code_defval_template(str, ti, str = generate_code_defval_template(str, ti,
defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER ? defpar_wrapper ?
tmp_id : ti->get_Template()->get_lhs_name(), tmp_id : ti->get_Template()->get_lhs_name(),
defval.ap->get_gen_restriction_check()); defval.ap->get_gen_restriction_check());
if (defpar_wrapper != Common::Type::NO_DEFPAR_WRAPPER) { if (defpar_wrapper) {
str = mputprintf(str, "def_val = %s;\n", tmp_id.c_str()); str = mputprintf(str, "def_val = %s;\n", tmp_id.c_str());
} }
} }
...@@ -10518,12 +10524,11 @@ namespace Ttcn { ...@@ -10518,12 +10524,11 @@ namespace Ttcn {
char* FormalPar::generate_code_defpar_init(char* str) char* FormalPar::generate_code_defpar_init(char* str)
{ {
if (defval.ap == NULL || !usage_found) return str; if (defval.ap == NULL || !usage_found) return str;
Common::Type::defpar_wapper_t defpar_wrapper = get_defpar_wrapper();
switch (defval.ap->get_selection()) { switch (defval.ap->get_selection()) {
case ActualPar::AP_VALUE: case ActualPar::AP_VALUE:
str = mputprintf(str, str = mputprintf(str,
"%s%s%s %s = %s_defpar(this);\n", "%s%s%s %s = %s_defpar(this);\n",
(defpar_wrapper == Common::Type::DEFPAR_IN_WRAPPER && !used_as_lvalue) ? "const " : "", !used_as_lvalue ? "const " : "",
type->get_genname_value(my_scope).c_str(), !used_as_lvalue ? "&" : "", type->get_genname_value(my_scope).c_str(), !used_as_lvalue ? "&" : "",
id->get_name().c_str(), id->get_name().c_str()); id->get_name().c_str(), id->get_name().c_str());
// this code also works if the parameter is used as lvalue, no need for shadow objects // this code also works if the parameter is used as lvalue, no need for shadow objects
...@@ -10532,7 +10537,7 @@ namespace Ttcn { ...@@ -10532,7 +10537,7 @@ namespace Ttcn {
case ActualPar::AP_TEMPLATE: case ActualPar::AP_TEMPLATE:
str = mputprintf(str, str = mputprintf(str,
"%s%s%s %s = %s_defpar(this);\n", "%s%s%s %s = %s_defpar(this);\n",
(defpar_wrapper == Common::Type::DEFPAR_IN_WRAPPER && !used_as_lvalue) ? "const " : "", !used_as_lvalue ? "const " : "",
type->get_genname_template(my_scope).c_str(), !used_as_lvalue ? "&" : "", type->get_genname_template(my_scope).c_str(), !used_as_lvalue ? "&" : "",
id->get_name().c_str(), id->get_name().c_str()); id->get_name().c_str(), id->get_name().c_str());
// this code also works if the parameter is used as lvalue, no need for shadow objects // this code also works if the parameter is used as lvalue, no need for shadow objects
...@@ -10551,7 +10556,7 @@ namespace Ttcn { ...@@ -10551,7 +10556,7 @@ namespace Ttcn {
if (!defval.ap) return; if (!defval.ap) return;
Definition* def = my_parlist->get_my_def(); Definition* def = my_parlist->get_my_def();
Scope* scope = def != NULL ? def->get_my_scope() : NULL; Scope* scope = def != NULL ? def->get_my_scope() : NULL;
bool defpar_wrapper = get_defpar_wrapper() != Common::Type::NO_DEFPAR_WRAPPER; bool defpar_wrapper = has_defpar_wrapper();
switch (defval.ap->get_selection()) { switch (defval.ap->get_selection()) {
case ActualPar::AP_VALUE: { case ActualPar::AP_VALUE: {
Value *val = defval.ap->get_Value(); Value *val = defval.ap->get_Value();
...@@ -10563,7 +10568,7 @@ namespace Ttcn { ...@@ -10563,7 +10568,7 @@ namespace Ttcn {
Code::free_cdef(&cdef); Code::free_cdef(&cdef);
break; } break; }
case ActualPar::AP_TEMPLATE: { case ActualPar::AP_TEMPLATE: {
if (use_runtime_2 && defpar_wrapper == Common::Type::NO_DEFPAR_WRAPPER) { if (use_runtime_2 && !defpar_wrapper) {
break; break;
} }
TemplateInstance *ti = defval.ap->get_TemplateInstance(); TemplateInstance *ti = defval.ap->get_TemplateInstance();
...@@ -10589,7 +10594,7 @@ namespace Ttcn { ...@@ -10589,7 +10594,7 @@ namespace Ttcn {
{ {
Definition* def = my_parlist->get_my_def(); Definition* def = my_parlist->get_my_def();
Scope* scope = def != NULL ? def->get_my_scope() : NULL; Scope* scope = def != NULL ? def->get_my_scope() : NULL;
bool defpar_wrapper = get_defpar_wrapper() != Common::Type::NO_DEFPAR_WRAPPER; bool defpar_wrapper = has_defpar_wrapper();
// the name of the parameter should not be displayed if the parameter is not // the name of the parameter should not be displayed if the parameter is not
// used (to avoid a compiler warning) // used (to avoid a compiler warning)
bool display_name = (usage_found || display_unused || debugger_active || bool display_name = (usage_found || display_unused || debugger_active ||
...@@ -11029,7 +11034,7 @@ namespace Ttcn { ...@@ -11029,7 +11034,7 @@ namespace Ttcn {
case Common::Assignment::A_PAR_TEMPL_OUT: case Common::Assignment::A_PAR_TEMPL_OUT:
if (is_startable && if (is_startable &&
(par->get_Type()->is_component_internal() || (par->get_Type()->is_component_internal() ||
(par->get_Type()->get_type_refd_last()->get_typetype() == Common::Type::T_CLASS))) { (par->get_Type()->contains_class()))) {
is_startable = false; is_startable = false;
} }
break; break;
...@@ -11081,9 +11086,9 @@ namespace Ttcn { ...@@ -11081,9 +11086,9 @@ namespace Ttcn {
Free(err_str); Free(err_str);
} }
if (!is_startable && if (!is_startable &&
par->get_Type()->get_type_refd_last()->get_typetype() == Common::Type::T_CLASS) { par->get_Type()->contains_class()) {
caller_location->error("%s `%s' cannot be started on a parallel test component " caller_location->error("%s `%s' cannot be started on a parallel test component "
"because parameter `%s' is of a class type", "because the type of parameter `%s' is or embeds a class type",
p_what, p_name, par->get_id().get_dispname().c_str()); p_what, p_name, par->get_id().get_dispname().c_str());
} }
break; break;
...@@ -11919,8 +11924,7 @@ namespace Ttcn { ...@@ -11919,8 +11924,7 @@ namespace Ttcn {
} }
} }
if (val_expr.postamble == NULL) { if (val_expr.postamble == NULL) {
if (formal_par != NULL && if (formal_par != NULL && formal_par->has_defpar_wrapper()) {
formal_par->get_defpar_wrapper() != Common::Type::NO_DEFPAR_WRAPPER) {
expr_expr = mputprintf(expr_expr, "%s(%s)", expr_expr = mputprintf(expr_expr, "%s(%s)",
val->get_my_governor()->get_genname_value(my_scope).c_str(), val_expr.expr); val->get_my_governor()->get_genname_value(my_scope).c_str(), val_expr.expr);
} }
...@@ -12136,8 +12140,7 @@ namespace Ttcn { ...@@ -12136,8 +12140,7 @@ namespace Ttcn {
LazyFuzzyParamData::generate_code_ap_default_ti(expr, act->temp, my_scope, LazyFuzzyParamData::generate_code_ap_default_ti(expr, act->temp, my_scope,
param_eval == LAZY_EVAL); param_eval == LAZY_EVAL);
} }
else if (use_runtime_2 && (formal_par == NULL || else if (use_runtime_2 && (formal_par == NULL || !formal_par->has_defpar_wrapper())) {
formal_par->get_defpar_wrapper() == Common::Type::NO_DEFPAR_WRAPPER)) {
// use the actual parameter's scope, not the formal parameter's // use the actual parameter's scope, not the formal parameter's
act->temp->set_my_scope(my_scope); act->temp->set_my_scope(my_scope);
Template* temp_ = act->temp->get_Template(); Template* temp_ = act->temp->get_Template();
......
...@@ -1983,7 +1983,7 @@ namespace Ttcn { ...@@ -1983,7 +1983,7 @@ namespace Ttcn {
/** Returns whether a wrapper class is used for the formal parameter in the /** Returns whether a wrapper class is used for the formal parameter in the
* generated code. * generated code.
* (Wrappers are used for class function parameters with default values.) */ * (Wrappers are used for class function parameters with default values.) */
Common::Type::defpar_wapper_t get_defpar_wrapper() const; bool has_defpar_wrapper() const;
}; };
/** Class to represent a list of formal parameters. Owned by a /** Class to represent a list of formal parameters. Owned by a
......
...@@ -3365,9 +3365,12 @@ namespace Ttcn { ...@@ -3365,9 +3365,12 @@ namespace Ttcn {
case Definition::A_PAR_VAL_OUT: case Definition::A_PAR_VAL_OUT:
case Definition::A_PAR_VAL_INOUT: case Definition::A_PAR_VAL_INOUT:
case Definition::A_PAR_TEMPL_OUT: case Definition::A_PAR_TEMPL_OUT:
case Definition::A_PAR_TEMPL_INOUT: case Definition::A_PAR_TEMPL_INOUT: {
// valid assignment types Common::Type* ref_type = refd_ass->get_Type()->get_type_refd_last();
break; if (ref_type->contains_class()) {
convert_op.ref->error("The type of the second parameter cannot be or embed a class type");
}
break; }
default: default:
convert_op.ref->error("Reference to '%s' cannot be used as the second parameter", refd_ass->get_assname()); convert_op.ref->error("Reference to '%s' cannot be used as the second parameter", refd_ass->get_assname());
goto error; goto error;
......
...@@ -1353,6 +1353,10 @@ namespace Ttcn { ...@@ -1353,6 +1353,10 @@ namespace Ttcn {
t->error("Data type `%s' cannot be %s on a procedure based port", t->error("Data type `%s' cannot be %s on a procedure based port",
t_last->get_typename().c_str(), err_msg); t_last->get_typename().c_str(), err_msg);
} }
if (t->contains_class()) {
t->error("Type `%s' is not a data type, since it is or contains a class, and cannot be "
"sent or received through a port", t->get_typename().c_str());
}
if (is_in) { if (is_in) {
if (in_msgs && in_msgs->has_type(t_last)) { if (in_msgs && in_msgs->has_type(t_last)) {
const string& type_name = t_last->get_typename(); const string& type_name = t_last->get_typename();
...@@ -4231,19 +4235,19 @@ namespace Ttcn { ...@@ -4231,19 +4235,19 @@ namespace Ttcn {
par_type->get_genname_value(this); par_type->get_genname_value(this);
local_struct->header.class_defs = mputprintf(local_struct->header.class_defs, local_struct->header.class_defs = mputprintf(local_struct->header.class_defs,
"class %s : public DEFPAR_%s_WRAPPER<%s> {\n" // 1 "class %s : public DEFPAR_WRAPPER<%s> {\n" // 1
"public:\n" "public:\n"
"%s(): DEFPAR_%s_WRAPPER<%s>() { }\n" // 2 "%s(): DEFPAR_WRAPPER<%s>() { }\n" // 2
"%s(%s%s& par): DEFPAR_%s_WRAPPER<%s>(par) { }\n" // 3 "%s(const %s& par): DEFPAR_WRAPPER<%s>(par) { }\n" // 3
"%s(const %s& par): DEFPAR_%s_WRAPPER<%s>(par) { }\n" // 4 "%s(const %s& par): DEFPAR_WRAPPER<%s>(par) { }\n" // 4
"%s%s& operator()(%s* p_class);\n" // 5 "const %s& operator()(%s* p_class);\n" // 5
"};\n\n", defpar_list.get_nth_elem(i), in_par ? "IN" : "OUT", par_type_str.c_str(), // 1 "};\n\n", defpar_list.get_nth_elem(i), par_type_str.c_str(), // 1
defpar_list.get_nth_elem(i), in_par ? "IN" : "OUT", par_type_str.c_str(), // 2 defpar_list.get_nth_elem(i), par_type_str.c_str(), // 2
defpar_list.get_nth_elem(i), in_par ? "const " : "", par_type_str.c_str(), // 3 defpar_list.get_nth_elem(i), par_type_str.c_str(), // 3
in_par ? "IN" : "OUT", par_type_str.c_str(), // 3 par_type_str.c_str(), // 3
defpar_list.get_nth_elem(i), defpar_list.get_nth_elem(i), // 4 defpar_list.get_nth_elem(i), defpar_list.get_nth_elem(i), // 4
in_par ? "IN" : "OUT", par_type_str.c_str(), // 4 par_type_str.c_str(), // 4
in_par ? "const " : "", par_type_str.c_str(), class_id->get_name().c_str()); // 5 par_type_str.c_str(), class_id->get_name().c_str()); // 5
local_struct->source.methods = mputprintf(local_struct->source.methods, local_struct->source.methods = mputprintf(local_struct->source.methods,
"%s%s& %s::operator()(%s* p_class)\n" "%s%s& %s::operator()(%s* p_class)\n"
......
...@@ -411,27 +411,15 @@ public: ...@@ -411,27 +411,15 @@ public:
#endif // C++11 #endif // C++11
template<typename T> template<typename T>
class DEFPAR_IN_WRAPPER { class DEFPAR_WRAPPER {
protected: protected:
boolean def_; boolean def_;
T def_val; T def_val;
const T& act_val; const T& act_val;
public: public:
DEFPAR_IN_WRAPPER(): def_(TRUE), def_val(), act_val(def_val) { } DEFPAR_WRAPPER(): def_(TRUE), def_val(), act_val(def_val) { }
DEFPAR_IN_WRAPPER(const T& par): def_(FALSE), def_val(), act_val(par) { } DEFPAR_WRAPPER(const T& par): def_(FALSE), def_val(), act_val(par) { }
DEFPAR_IN_WRAPPER(const DEFPAR_IN_WRAPPER& par): def_(par.def_), def_val(), act_val(def_ ? def_val : par.act_val) { } DEFPAR_WRAPPER(const DEFPAR_WRAPPER& par): def_(par.def_), def_val(), act_val(def_ ? def_val : par.act_val) { }
};
template<typename T>
class DEFPAR_OUT_WRAPPER {
protected:
boolean def_;
T dummy;
T& act_val;
public:
DEFPAR_OUT_WRAPPER(): def_(TRUE), dummy(), act_val(dummy) { }
DEFPAR_OUT_WRAPPER(T& par): def_(FALSE), dummy(), act_val(par) { }
DEFPAR_OUT_WRAPPER(const DEFPAR_OUT_WRAPPER& par): def_(par.def_), dummy(), act_val(par.act_val) { }
}; };
#endif /* OOP_HH */ #endif /* OOP_HH */
......
...@@ -138,10 +138,10 @@ type class C9 extends C8 { } //^In type definition// //^In superclass or supertr ...@@ -138,10 +138,10 @@ type class C9 extends C8 { } //^In type definition// //^In superclass or supertr
external const C0 ec_c0; //^In external constant definition// //External constant cannot be defined for class type `@oop_SE.C0'// external const C0 ec_c0; //^In external constant definition// //External constant cannot be defined for class type `@oop_SE.C0'//
external const object ec_obj; //^In external constant definition// //External constant cannot be defined for class type `object'// external const object ec_obj; //^In external constant definition// //External constant cannot be defined for class type `object'//
modulepar C0 mp_c0; //^In module parameter definition// //Type of module parameter cannot be or embed class type `@oop_SE.C0'// modulepar C0 mp_c0; //^In module parameter definition// //Type of module parameter cannot be or embed a class type//
modulepar object mp_obj; //^In module parameter definition// //Type of module parameter cannot be or embed class type `object'// modulepar object mp_obj; //^In module parameter definition// //Type of module parameter cannot be or embed a class type//
modulepar template C0 mpt_c0; //^In template module parameter definition// //Type of template module parameter cannot be class type `@oop_SE.C0'// modulepar template C0 mpt_c0; //^In template module parameter definition// //Type of template module parameter cannot be or embed a class type//
modulepar template object mpt_obj; //^In template module parameter definition// //Type of template module parameter cannot be class type `object'// modulepar template object mpt_obj; //^In template module parameter definition// //Type of template module parameter cannot be or embed a class type//
function f_defs() { //^In function definition// function f_defs() { //^In function definition//
const C0 c_c0 := null; //^In constant definition// //Constant cannot be defined for class type `@oop_SE.C0'// const C0 c_c0 := null; //^In constant definition// //Constant cannot be defined for class type `@oop_SE.C0'//
...@@ -160,6 +160,11 @@ type record RecClass { ...@@ -160,6 +160,11 @@ type record RecClass {
object y object y
} }
type record RecClassOpt {
C0 x optional,
object y optional
}
type set SetClass { type set SetClass {
C0 x, C0 x,
object y object y
...@@ -175,14 +180,71 @@ type union UniClass { ...@@ -175,14 +180,71 @@ type union UniClass {
C0 x, C0 x,
object y object y
} }
const RecClassOpt v_rec_opt := { } with { optional "implicit omit" }; //^In constant definition// //Constant cannot be defined for type `@oop_SE.RecClassOpt', which contains a class//
modulepar RecOfObject mp_recof; //^In module parameter definition// //Type of module parameter cannot be or embed a class type//
modulepar template SetOfObject mpt_setof; //^In template module parameter definition// //Type of template module parameter cannot be or embed a class type//
type port ClassPort message { //^In type definition//
inout C0, //^In `inout' list// //Type `@oop_SE.C0' is not a data type, since it is or contains a class, and cannot be sent or received through a port//
RecOfClass //Type `@oop_SE.RecOfClass' is not a data type, since it is or contains a class, and cannot be sent or received through a port//
}
with { extension "internal" };
type component CT_w_port {
port ClassPort pt;
}
function f_embedded_types() { //^In function definition//