-///////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2000-2014 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
-///////////////////////////////////////////////////////////////////////////////
+/******************************************************************************
+ * Copyright (c) 2000-2016 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:
+ * Baji, Laszlo
+ * Balasko, Jeno
+ * Baranyi, Botond
+ * Beres, Szabolcs
+ * Delic, Adam
+ * Kovacs, Ferenc
+ * Raduly, Csaba
+ * Szabados, Kristof
+ * Szalai, Gabor
+ * Zalanyi, Balazs Andor
+ * Pandi, Krisztian
+ *
+ ******************************************************************************/
#include "../../common/dbgnew.hh"
#include "AST_ttcn3.hh"
#include "../Identifier.hh"
str += "<unknown sub-reference>";
}
}
+
+ void FieldOrArrayRef::set_field_name_to_lowercase()
+ {
+ if (ref_type != FIELD_REF) FATAL_ERROR("FieldOrArrayRef::set_field_name_to_lowercase()");
+ string new_name = u.id->get_name();
+ if (isupper(new_name[0])) {
+ new_name[0] = tolower(new_name[0]);
+ if (new_name[new_name.size() - 1] == '_') {
+ // an underscore is inserted at the end of the field name if it's
+ // a basic type's name (since it would conflict with the class generated
+ // for that type)
+ // remove the underscore, it won't conflict with anything if its name
+ // starts with a lowercase letter
+ new_name.replace(new_name.size() - 1, 1, "");
+ }
+ delete u.id;
+ u.id = new Identifier(Identifier::ID_NAME, new_name);
+ }
+ }
// =================================
// ===== FieldOrArrayRefs
Node::set_fullname(p_fullname);
for (size_t i = 0; i < refs.size(); i++)
refs[i]->set_fullname(p_fullname +
- ".<sub_reference" + Int2string(i + 1) + ">");
+ ".<sub_reference" + Int2string(i + 1) + ">");
}
void FieldOrArrayRefs::set_my_scope(Scope *p_scope)
for (size_t i = 0; i < refs.size(); i++) {
FieldOrArrayRef *ref = refs[i];
if (ref->get_type() == FieldOrArrayRef::ARRAY_REF) {
- Value *v = ref->get_val();
- v->set_lowerid_to_ref();
- if (v->is_unfoldable()) return true;
+ Value *v = ref->get_val();
+ v->set_lowerid_to_ref();
+ if (v->is_unfoldable()) return true;
}
}
return false;
expr->expr = mputprintf(expr->expr, ".%s%s()",
((type!=0 && type->get_typetype()==Type::T_ANYTYPE) ? "AT_" : ""),
id.get_name().c_str());
- if (type) {
- CompField *cf = type->get_comp_byName(id);
- // If the field is optional, the return type of the accessor is an
- // OPTIONAL<T>. Write a call to OPTIONAL<T>::operator(),
- // which "reaches into" the OPTIONAL to get the contained type T.
- // Don't do this at the end of the reference chain.
- // Accessor methods for a foo_template return a bar_template
- // and OPTIONAL<> is not involved, hence no "()".
- if (!is_template && i < n_refs - 1 && cf->get_is_optional())
- expr->expr = mputstr(expr->expr, "()");
+ if (type) {
+ CompField *cf = type->get_comp_byName(id);
+ // If the field is optional, the return type of the accessor is an
+ // OPTIONAL<T>. Write a call to OPTIONAL<T>::operator(),
+ // which "reaches into" the OPTIONAL to get the contained type T.
+ // Don't do this at the end of the reference chain.
+ // Accessor methods for a foo_template return a bar_template
+ // and OPTIONAL<> is not involved, hence no "()".
+ if (!is_template && i < n_refs - 1 && cf->get_is_optional())
+ expr->expr = mputstr(expr->expr, "()");
// Follow the field type.
- type = cf->get_type();
- }
+ type = cf->get_type();
+ }
} else {
// Generate code for array reference.
expr->expr = mputc(expr->expr, '[');
- ref->get_val()->generate_code_expr(expr);
+ ref->get_val()->generate_code_expr(expr);
expr->expr = mputc(expr->expr, ']');
- if (type) {
+ if (type) {
// Follow the embedded type.
- switch (type->get_typetype()) {
- case Type::T_SEQOF:
- case Type::T_SETOF:
- case Type::T_ARRAY:
- type = type->get_ofType();
- break;
- default:
- // The index points to a string element.
- // There are no further sub-references.
- type = 0;
- } // switch
- } // if (type)
+ switch (type->get_typetype()) {
+ case Type::T_SEQOF:
+ case Type::T_SETOF:
+ case Type::T_ARRAY:
+ type = type->get_ofType();
+ break;
+ default:
+ // The index points to a string element.
+ // There are no further sub-references.
+ type = 0;
+ } // switch
+ } // if (type)
} // if (ref->get_type)
} // next reference
}
}
/* Called by:
- * Common::PortTypeBody::PortTypeBody
- * Common::Type::Type
- * Common::TypeMappingTarget::TypeMappingTarget
- * Common::PatternString::ps_elem_t::chk_ref */
+ * Common::PortTypeBody::PortTypeBody
+ * Common::Type::Type
+ * Common::TypeMappingTarget::TypeMappingTarget
+ * Common::PatternString::ps_elem_t::chk_ref */
Reference *Reference::clone() const
{
return new Reference(*this);
string ret_val;
if (id) {
if (modid) {
- ret_val += modid->get_dispname();
- ret_val += '.';
+ ret_val += modid->get_dispname();
+ ret_val += '.';
}
ret_val += id->get_dispname();
subrefs.append_stringRepr(ret_val);
parlist->set_my_scope(my_scope);
} else {
error("Reference to parameterized definition `%s' without "
- "actual parameter list", ass->get_id().get_dispname().c_str());
+ "actual parameter list", ass->get_id().get_dispname().c_str());
}
}
}
break;
default:
error("Reference to a variable or value parameter was "
- "expected instead of %s", t_ass->get_description().c_str());
+ "expected instead of %s", t_ass->get_description().c_str());
return 0;
}
FieldOrArrayRefs *t_subrefs = get_subrefs();
Type::EXPECTED_DYNAMIC_VALUE);
if (ret_val && t_subrefs && t_subrefs->refers_to_string_element()) {
error("Reference to a string element of type `%s' cannot be used in "
- "this context", ret_val->get_typename().c_str());
+ "this context", ret_val->get_typename().c_str());
}
return ret_val;
}
if (ass) {
if (ass->get_asstype() == Common::Assignment::A_TYPE) {
Type *t = ass->get_Type()->get_type_refd_last();
- switch (t->get_typetype()) {
- case Type::T_ERROR:
- // remain silent
- break;
- case Type::T_COMPONENT:
- return t;
- default:
- error("Reference `%s' does not refer to a component type",
- get_dispname().c_str());
- }
+ switch (t->get_typetype()) {
+ case Type::T_ERROR:
+ // remain silent
+ break;
+ case Type::T_COMPONENT:
+ return t;
+ default:
+ error("Reference `%s' does not refer to a component type",
+ get_dispname().c_str());
+ }
} else {
- error("Reference `%s' does not refer to a type",
- get_dispname().c_str());
+ error("Reference `%s' does not refer to a type",
+ get_dispname().c_str());
}
}
return 0;
}
return true;
}
+
+ void Reference::refd_param_usage_found()
+ {
+ Common::Assignment *ass = get_refd_assignment();
+ if (!ass) FATAL_ERROR("Reference::refd_param_usage_found()");
+ switch (ass->get_asstype()) {
+ case Common::Assignment::A_PAR_VAL_OUT:
+ case Common::Assignment::A_PAR_TEMPL_OUT:
+ case Common::Assignment::A_PAR_VAL:
+ case Common::Assignment::A_PAR_VAL_IN:
+ case Common::Assignment::A_PAR_VAL_INOUT:
+ case Common::Assignment::A_PAR_TEMPL_IN:
+ case Common::Assignment::A_PAR_TEMPL_INOUT:
+ case Common::Assignment::A_PAR_PORT:
+ case Common::Assignment::A_PAR_TIMER: {
+ FormalPar *fpar = dynamic_cast<FormalPar*>(ass);
+ if (!fpar) FATAL_ERROR("Reference::refd_param_usage_found()");
+ fpar->set_usage_found();
+ break; }
+ default:
+ break;
+ }
+ }
void Reference::generate_code(expression_struct_t *expr)
{
+ refd_param_usage_found();
Common::Assignment *ass = get_refd_assignment();
if (!ass) FATAL_ERROR("Reference::generate_code()");
if (parlist) {
generate_code(expr);
return;
}
-
+
+ refd_param_usage_found();
Common::Assignment *ass = get_refd_assignment();
if (!ass) FATAL_ERROR("Reference::generate_code_const_ref()");
void Reference::generate_code_portref(expression_struct_t *expr,
Scope *p_scope)
{
+ refd_param_usage_found();
Common::Assignment *ass = get_refd_assignment();
if (!ass) FATAL_ERROR("Reference::generate_code_portref()");
expr->expr = mputstr(expr->expr,
void Reference::generate_code_ispresentbound(expression_struct_t *expr,
bool is_template, const bool isbound)
{
+ refd_param_usage_found();
Common::Assignment *ass = get_refd_assignment();
const string& ass_id = ass->get_genname_from_scope(my_scope);
const char *ass_id_str = ass_id.c_str();
expr->expr = mputprintf(expr->expr, "%s", tmp_generalid_str);
} else {
- expr->expr = mputprintf(expr->expr, "%s.%s()", ass_id_str, isbound ? "is_bound":"is_present");
+ expr->expr = mputprintf(expr->expr, "%s.%s(%s)", ass_id_str,
+ isbound ? "is_bound":"is_present",
+ (!isbound && is_template && omit_in_value_list) ? "TRUE" : "");
}
}
FieldOrArrayRef *second_ref = subrefs.get_ref(1);
if (second_ref->get_type() == FieldOrArrayRef::FIELD_REF) {
// the reference begins with <id>.<id> (most complicated case)
- // there are 3 possible situations:
- // 1. first_id points to a local definition (this has the priority)
- // modid: 0, id: first_id
- // 2. first_id points to an imported module (trivial case)
- // modid: first_id, id: second_id
- // 3. none of the above (first_id might be an imported symbol)
- // modid: 0, id: first_id
- // Note: Rule 1 has the priority because it can be overridden using
- // the notation <id>.objid { ... }.<id> (modid and id are set in the
- // constructor), but there is no work-around in the reverse way.
- if (!my_scope->has_ass_withId(*first_id)
- && my_scope->is_valid_moduleid(*first_id)) {
- // rule 1 is not fulfilled, but rule 2 is fulfilled
- second_id = second_ref->get_id();
- }
+ // there are 3 possible situations:
+ // 1. first_id points to a local definition (this has the priority)
+ // modid: 0, id: first_id
+ // 2. first_id points to an imported module (trivial case)
+ // modid: first_id, id: second_id
+ // 3. none of the above (first_id might be an imported symbol)
+ // modid: 0, id: first_id
+ // Note: Rule 1 has the priority because it can be overridden using
+ // the notation <id>.objid { ... }.<id> (modid and id are set in the
+ // constructor), but there is no work-around in the reverse way.
+ if (!my_scope->has_ass_withId(*first_id)
+ && my_scope->is_valid_moduleid(*first_id)) {
+ // rule 1 is not fulfilled, but rule 2 is fulfilled
+ second_id = second_ref->get_id();
+ }
} // else: the reference begins with <id>[<arrayref>] -> there is no modid
} // else: the reference consists of a single <id> -> there is no modid
if (second_id) {
if (params_checked) {
// used after semantic analysis
for (size_t i = 0; i < parlist.get_nof_pars(); i++) {
- if (i > 0) ret_val += ", ";
- parlist.get_par(i)->append_stringRepr(ret_val);
+ if (i > 0) ret_val += ", ";
+ parlist.get_par(i)->append_stringRepr(ret_val);
}
} else {
// used before semantic analysis
for (size_t i = 0; i < params->get_nof_tis(); i++) {
- if (i > 0) ret_val += ", ";
- params->get_ti_byIndex(i)->append_stringRepr(ret_val);
+ if (i > 0) ret_val += ", ";
+ params->get_ti_byIndex(i)->append_stringRepr(ret_val);
}
}
ret_val += ')';
params_checked = true;
FormalParList *fplist = ass->get_FormalParList();
if (fplist) {
- Error_Context cntxt(params, "In actual parameter list of %s",
- ass->get_description().c_str());
- is_erroneous = fplist->fold_named_and_chk(params, &parlist);
- parlist.set_fullname(get_fullname());
- parlist.set_my_scope(my_scope);
- // the parsed parameter list is no longer needed
- delete params;
- params = 0;
+ Error_Context cntxt(params, "In actual parameter list of %s",
+ ass->get_description().c_str());
+ is_erroneous = fplist->fold_named_and_chk(params, &parlist);
+ parlist.set_fullname(get_fullname());
+ parlist.set_my_scope(my_scope);
+ // the parsed parameter list is no longer needed
+ delete params;
+ params = 0;
} else {
params->error("The referenced %s cannot have actual parameters",
- ass->get_description().c_str());
+ ass->get_description().c_str());
}
}
return ass;
if (!t_ass) return false;
if (t_ass->get_asstype() != Common::Assignment::A_ALTSTEP) {
error("Reference to an altstep was expected in the argument instead of "
- "%s", t_ass->get_description().c_str());
+ "%s", t_ass->get_description().c_str());
return false;
}
my_scope->chk_runs_on_clause(t_ass, *this, "activate");
bool is_template;
switch (ass->get_asstype()) {
+ case Common::Assignment::A_TEMPLATE:
+ if (NULL == ass->get_FormalParList()) {
+ // not a parameterized template
+ is_template = true;
+ break;
+ }
+ // else fall through
case Common::Assignment::A_CONST:
case Common::Assignment::A_EXT_CONST:
case Common::Assignment::A_ALTSTEP:
case Common::Assignment::A_TESTCASE:
case Common::Assignment::A_FUNCTION:
case Common::Assignment::A_EXT_FUNCTION:
+ case Common::Assignment::A_FUNCTION_RVAL:
+ case Common::Assignment::A_EXT_FUNCTION_RVAL:
+ case Common::Assignment::A_FUNCTION_RTEMP:
+ case Common::Assignment::A_EXT_FUNCTION_RTEMP:
generate_code(expr);
return;
case Common::Assignment::A_MODULEPAR:
case Common::Assignment::A_VAR:
- case Common::Assignment::A_FUNCTION_RVAL:
- case Common::Assignment::A_EXT_FUNCTION_RVAL:
case Common::Assignment::A_PAR_VAL_IN:
case Common::Assignment::A_PAR_VAL_OUT:
case Common::Assignment::A_PAR_VAL_INOUT: {
is_template = false;
break; }
case Common::Assignment::A_MODULEPAR_TEMP:
- case Common::Assignment::A_TEMPLATE:
case Common::Assignment::A_VAR_TEMPLATE:
- case Common::Assignment::A_FUNCTION_RTEMP:
- case Common::Assignment::A_EXT_FUNCTION_RTEMP:
case Common::Assignment::A_PAR_TEMPL_IN:
case Common::Assignment::A_PAR_TEMPL_OUT:
case Common::Assignment::A_PAR_TEMPL_INOUT: {
const Identifier& id = comp_def->get_id();
if (parent_scope->has_ass_withId(id)) {
comp_def->warning("Imported component element definition `%s' hides a "
- "definition at module scope", comp_def->get_fullname().c_str());
- Reference ref(0, id.clone());
- Common::Assignment *hidden_ass = parent_scope->get_ass_bySRef(&ref);
- hidden_ass->warning("Hidden definition `%s' is here",
- hidden_ass->get_fullname().c_str());
+ "definition at module scope", comp_def->get_fullname().c_str());
+ Reference ref(0, id.clone());
+ Common::Assignment *hidden_ass = parent_scope->get_ass_bySRef(&ref);
+ hidden_ass->warning("Hidden definition `%s' is here",
+ hidden_ass->get_fullname().c_str());
}
}
result = NULL;
} else {
loc->error(
- "It is not possible to resolve the reference unambigously"
+ "It is not possible to resolve the reference unambiguously"
", as it can be resolved to `%s' and to `%s'",
result->get_fullname().c_str(), t_ass->get_fullname().c_str());
}
duplicate_underscores ? module_name : modid->get_ttcnname().c_str());
target->functions.pre_init = mputprintf(target->functions.pre_init,
- "%s%s.pre_init_module();\n", module_name,
+ "%s%s.pre_init_module();\n", module_name,
"::module_object");
if (mod->get_moduletype() == Common::Module::MOD_TTCN) {
target->functions.post_init = mputprintf(target->functions.post_init,
- "%s%s.post_init_module();\n", module_name,
+ "%s%s.post_init_module();\n", module_name,
"::module_object");
}
if (w_attrib_path) {
MultiWithAttrib *attrib = w_attrib_path->get_with_attr();
if (attrib) {
- DEBUG(level + 1, "Attributes:");
- attrib->dump(level + 2);
+ DEBUG(level + 1, "Attributes:");
+ attrib->dump(level + 2);
}
}
}
result = NULL;
} else {
loc->error(
- "It is not possible to resolve the reference unambigously"
+ "It is not possible to resolve the reference unambiguously"
", as it can be resolved to `%s' and to `%s'",
result->get_fullname().c_str(), ass->get_fullname().c_str());
}
void Imports::generate_code(output_struct *target)
{
- bool base_lib_needed = true;
+ target->header.includes = mputstr(target->header.includes,
+ "#include <TTCN3.hh>\n");
for (size_t i = 0; i < impmods_v.size(); i++) {
ImpMod *im = impmods_v[i];
Common::Module *m = im->get_mod();
- // do not include the header file of the base library if a real
- // (not circular) imported module is found
- if (base_lib_needed && !m->is_visible(my_mod)) base_lib_needed = false;
// inclusion of m's header file can be eliminated if we find another
// imported module that imports m
bool covered = false;
for (size_t j = 0; j < impmods_v.size(); j++) {
- // skip over the same import definition
- if (j == i) continue;
- ImpMod *im2 = impmods_v[j];
- Common::Module *m2 = im2->get_mod();
- // a module that is equivalent to the current module due to
- // circular imports cannot be used to cover anything
- if (m2->is_visible(my_mod)) continue;
- if (m2->is_visible(m) && !m->is_visible(m2)) {
- // m2 covers m (i.e. m is visible from m2)
- // and they are not in the same import loop
- covered = true;
- break;
- }
+ // skip over the same import definition
+ if (j == i) continue;
+ ImpMod *im2 = impmods_v[j];
+ Common::Module *m2 = im2->get_mod();
+ // a module that is equivalent to the current module due to
+ // circular imports cannot be used to cover anything
+ if (m2->is_visible(my_mod)) continue;
+ if (m2->is_visible(m) && !m->is_visible(m2)) {
+ // m2 covers m (i.e. m is visible from m2)
+ // and they are not in the same import loop
+ covered = true;
+ break;
+ }
}
// do not generate the #include if a covering module is found
if (!covered) im->generate_code(target);
}
- if (base_lib_needed) {
- // if no real import was found the base library definitions has to be
- // #include'd
- target->header.includes = mputstr(target->header.includes,
- "#include <TTCN3.hh>\n");
- }
}
void Imports::generate_code(CodeGenHelper& cgh) {
ass->error("Duplicate definition with name `%s'", dispname_str);
ass_m[name]->note("Previous definition of `%s' is here", dispname_str);
} else {
- ass_m.add(name, ass);
- if (parent_scope->is_valid_moduleid(id)) {
- ass->warning("Definition with name `%s' hides a module identifier",
- id.get_dispname().c_str());
- }
+ ass_m.add(name, ass);
+ if (parent_scope->is_valid_moduleid(id)) {
+ ass->warning("Definition with name `%s' hides a module identifier",
+ id.get_dispname().c_str());
+ }
}
}
checked = true;
const Identifier& id = def->get_id();
const string& name = id.get_name();
if (ass_m.has_key(name)) {
- const char *dispname_str = id.get_dispname().c_str();
- def->error("Duplicate definition with name `%s'", dispname_str);
- ass_m[name]->note("Previous definition of `%s' is here", dispname_str);
+ const char *dispname_str = id.get_dispname().c_str();
+ def->error("Duplicate definition with name `%s'", dispname_str);
+ ass_m[name]->note("Previous definition of `%s' is here", dispname_str);
} else {
- ass_m.add(name, def);
- if (parent_scope) {
- if (parent_scope->has_ass_withId(id)) {
- const char *dispname_str = id.get_dispname().c_str();
- def->error("Definition with identifier `%s' is not unique in the "
- "scope hierarchy", dispname_str);
- Reference ref(0, id.clone());
- Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref);
- if (!ass) FATAL_ERROR("OtherDefinitions::chk_for()");
- ass->note("Previous definition with identifier `%s' in higher "
- "scope unit is here", dispname_str);
- } else if (parent_scope->is_valid_moduleid(id)) {
- def->warning("Definition with name `%s' hides a module identifier",
- id.get_dispname().c_str());
- }
- }
+ ass_m.add(name, def);
+ if (parent_scope) {
+ if (parent_scope->has_ass_withId(id)) {
+ const char *dispname_str = id.get_dispname().c_str();
+ def->error("Definition with identifier `%s' is not unique in the "
+ "scope hierarchy", dispname_str);
+ Reference ref(0, id.clone());
+ Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref);
+ if (!ass) FATAL_ERROR("OtherDefinitions::chk_for()");
+ ass->note("Previous definition with identifier `%s' in higher "
+ "scope unit is here", dispname_str);
+ } else if (parent_scope->is_valid_moduleid(id)) {
+ def->warning("Definition with name `%s' hides a module identifier",
+ id.get_dispname().c_str());
+ }
+ }
}
def->chk();
}
const string& group_name = group_id.get_name();
if (ass_m.has_key(group_name)) {
group->error("Group name `%s' clashes with a definition",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
ass_m[group_name]->note("Definition of `%s' is here",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
}
if (group_m.has_key(group_name)) {
group->error("Duplicate group with name `%s'",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
group_m[group_name]->note("Group `%s' is already defined here",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
} else group_m.add(group_name, group);
}
checked = true;
if (w_attrib_path) {
MultiWithAttrib *attrib = w_attrib_path->get_with_attr();
if (attrib) {
- DEBUG(level + 1, "Group Attributes:");
- attrib->dump(level + 2);
+ DEBUG(level + 1, "Group Attributes:");
+ attrib->dump(level + 2);
}
}
}
if (w_attrib_path) {
MultiWithAttrib *attrib = w_attrib_path->get_with_attr();
if (attrib) {
- DEBUG(level + 1, "Attributes:");
- attrib->dump(level + 2);
+ DEBUG(level + 1, "Attributes:");
+ attrib->dump(level + 2);
}
}
}
result_ass = t_ass;
} else if(result_ass != t_ass) {
p_ref->error(
- "It is not possible to resolve the reference unambigously"
+ "It is not possible to resolve the reference unambiguously"
", as it can be resolved to `%s' and to `%s'",
result_ass->get_fullname().c_str(), t_ass->get_fullname().c_str());
}
t_result = t_ass;
} else if(t_result != t_ass) {
p_ref->error(
- "It is not possible to resolve the reference unambigously"
+ "It is not possible to resolve the reference unambiguously"
", as it can be resolved to `%s' and to `%s'",
t_result->get_fullname().c_str(), t_ass->get_fullname().c_str());
}
if(ass_m.has_key(group_name))
{
group->error("Group name `%s' clashes with a definition",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
ass_m[group_name]->note("Definition of `%s' is here",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
}
if(group_m.has_key(group_name))
{
group->error("Duplicate group with name `%s'",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
group_m[group_name]->note("Group `%s' is already defined here",
- group_id.get_dispname().c_str());
+ group_id.get_dispname().c_str());
}else{
group_m.add(group_name,group_v[i]);
}
if (w_attrib_path) {
MultiWithAttrib *attrib = w_attrib_path->get_with_attr();
if (attrib) {
- DEBUG(level, "Module Attributes:");
- attrib->dump(level + 1);
+ DEBUG(level, "Module Attributes:");
+ attrib->dump(level + 1);
}
}
}
if (w_attrib_path) {
MultiWithAttrib *attrib = w_attrib_path->get_with_attr();
if (attrib) {
- DEBUG(level + 1, "Definition Attributes:");
- attrib->dump(level + 2);
+ DEBUG(level + 1, "Definition Attributes:");
+ attrib->dump(level + 2);
}
}
if (erroneous_attrs) erroneous_attrs->dump(level+1);
if (p_def->get_asstype() != A_CONST) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a constant, but the definition "
- "inherited from component type `%s' is a %s", dispname_str,
+ "inherited from component type `%s' is a %s", dispname_str,
p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname());
p_def->note("The inherited definition of `%s' is here", dispname_str);
return false;
if (!type->is_identical(p_def_const->type)) {
const char *dispname_str = id->get_dispname().c_str();
type->error("Local constant `%s' has type `%s', but the constant "
- "inherited from component type `%s' has type `%s'", dispname_str,
- type->get_typename().c_str(),
+ "inherited from component type `%s' has type `%s'", dispname_str,
+ type->get_typename().c_str(),
p_def_const->get_my_scope()->get_fullname().c_str(),
- p_def_const->type->get_typename().c_str());
+ p_def_const->type->get_typename().c_str());
p_def_const->note("The inherited constant `%s' is here", dispname_str);
return false;
} else if (!(*value == *p_def_const->value)) {
const char *dispname_str = id->get_dispname().c_str();
value->error("Local constant `%s' and the constant inherited from "
- "component type `%s' have different values", dispname_str,
+ "component type `%s' have different values", dispname_str,
p_def_const->get_my_scope()->get_fullname().c_str());
p_def_const->note("The inherited constant `%s' is here", dispname_str);
return false;
map<Type*,void> type_chain;
map<Type::typetype_t, void> not_allowed;
not_allowed.add(Type::T_PORT, 0);
- not_allowed.add(Type::T_COMPONENT, 0);
- not_allowed.add(Type::T_DEFAULT, 0);
Type *t = type->get_type_refd_last();
// if the type is valid the original will be returned
Type::typetype_t tt = t->search_for_not_allowed_type(type_chain, not_allowed);
error("Type of module parameter cannot be signature `%s'",
t->get_fullname().c_str());
break;
- case Type::T_COMPONENT:
- error("Type of module parameter cannot be or embed component `%s'",
- t->get_fullname().c_str());
- break;
- case Type::T_DEFAULT:
- error("Type of module parameter cannot be or embed default `%s'",
- t->get_fullname().c_str());
- break;
case Type::T_FUNCTION:
case Type::T_ALTSTEP:
case Type::T_TESTCASE:
"modulepar_%s.set_param(param);\n"
"return TRUE;\n"
"} else ", dispname, name);
+ target->functions.get_param = mputprintf(target->functions.get_param,
+ "if (!strcmp(par_name, \"%s\")) {\n"
+ "return modulepar_%s.get_param(param_name);\n"
+ "} else ", dispname, name);
if (target->functions.log_param) {
// this is not the first modulepar
target->functions.log_param = mputprintf(target->functions.log_param,
- "TTCN_Logger::log_event_str(\", %s := \");\n", dispname);
+ "TTCN_Logger::log_event_str(\", %s := \");\n", dispname);
} else {
// this is the first modulepar
target->functions.log_param = mputprintf(target->functions.log_param,
- "TTCN_Logger::log_event_str(\"%s := \");\n", dispname);
+ "TTCN_Logger::log_event_str(\"%s := \");\n", dispname);
}
target->functions.log_param = mputprintf(target->functions.log_param,
"%s.log();\n", name);
"modulepar_%s.set_param(param);\n"
"return TRUE;\n"
"} else ", dispname, name);
+ target->functions.get_param = mputprintf(target->functions.get_param,
+ "if (!strcmp(par_name, \"%s\")) {\n"
+ "return modulepar_%s.get_param(param_name);\n"
+ "} else ", dispname, name);
if (target->functions.log_param) {
// this is not the first modulepar
target->functions.log_param = mputprintf(target->functions.log_param,
- "TTCN_Logger::log_event_str(\", %s := \");\n", dispname);
+ "TTCN_Logger::log_event_str(\", %s := \");\n", dispname);
} else {
// this is the first modulepar
target->functions.log_param = mputprintf(target->functions.log_param,
- "TTCN_Logger::log_event_str(\"%s := \");\n", dispname);
+ "TTCN_Logger::log_event_str(\"%s := \");\n", dispname);
}
target->functions.log_param = mputprintf(target->functions.log_param,
"%s.log();\n", name);
Error_Context ec(this, "While checking template restriction `%s'",
Template::get_restriction_name(template_restriction));
gen_restriction_check =
- body->chk_restriction("template definition", template_restriction);
+ body->chk_restriction("template definition", template_restriction, body);
if (fp_list && template_restriction!=TR_PRESENT) {
size_t nof_fps = fp_list->get_nof_fps();
for (size_t i=0; i<nof_fps; i++) {
{
if (iter->recurs_deriv_checked) break;
else if (refch.add(iter->get_fullname()))
- iter->recurs_deriv_checked = true;
- else break;
+ iter->recurs_deriv_checked = true;
+ else break;
}
}
recurs_deriv_checked = true;
const char *template_dispname = id->get_dispname().c_str();
const string& type_genname = type->get_genname_template(my_scope);
const char *type_genname_str = type_genname.c_str();
- char *formal_par_list = fp_list->generate_code(memptystr());
- fp_list->generate_code_defval(target);
- target->header.function_prototypes =
- mputprintf(target->header.function_prototypes,
- "extern %s %s(%s);\n",
- type_genname_str, template_name, formal_par_list);
- char *function_body = mprintf("%s %s(%s)\n"
- "{\n", type_genname_str, template_name, formal_par_list);
- function_body = create_location_object(function_body, "TEMPLATE",
+
+ // assemble the function body first (this also determines which parameters
+ // are never used)
+ size_t nof_base_pars = 0;
+ char* function_body = create_location_object(memptystr(), "TEMPLATE",
template_dispname);
if (base_template) {
// modified template
function_body = mputprintf(function_body, "%s ret_val(%s",
- type_genname_str,
- base_template->get_genname_from_scope(my_scope).c_str());
- if (base_template->fp_list) {
- // the base template is also parameterized
- function_body = mputc(function_body, '(');
- size_t nof_base_pars = base_template->fp_list->get_nof_fps();
- for (size_t i = 0; i < nof_base_pars; i++) {
- if (i > 0) function_body = mputstr(function_body, ", ");
- function_body = mputstr(function_body,
- fp_list->get_fp_byIndex(i)->get_id().get_name().c_str());
- }
- function_body = mputc(function_body, ')');
- }
- function_body = mputstr(function_body, ");\n");
+ type_genname_str,
+ base_template->get_genname_from_scope(my_scope).c_str());
+ if (base_template->fp_list) {
+ // the base template is also parameterized
+ function_body = mputc(function_body, '(');
+ nof_base_pars = base_template->fp_list->get_nof_fps();
+ for (size_t i = 0; i < nof_base_pars; i++) {
+ if (i > 0) function_body = mputstr(function_body, ", ");
+ function_body = mputstr(function_body,
+ fp_list->get_fp_byIndex(i)->get_id().get_name().c_str());
+ }
+ function_body = mputc(function_body, ')');
+ }
+ function_body = mputstr(function_body, ");\n");
} else {
// simple template
function_body = mputprintf(function_body, "%s ret_val;\n",
- type_genname_str);
+ type_genname_str);
}
if (erroneous_attrs && erroneous_attrs->get_err_descr()) {
function_body = erroneous_attrs->get_err_descr()->
if (template_restriction!=TR_NONE && gen_restriction_check)
function_body = Template::generate_restriction_check_code(function_body,
"ret_val", template_restriction);
- function_body = mputstr(function_body, "return ret_val;\n"
- "}\n\n");
- target->source.function_bodies =
- mputstr(target->source.function_bodies, function_body);
+ function_body = mputstr(function_body, "return ret_val;\n");
+ // if the template modifies a parameterized template, then the inherited
+ // formal parameters must always be displayed, otherwise generate a smart
+ // formal parameter list (where the names of unused parameters are omitted)
+ char *formal_par_list = fp_list->generate_code(memptystr(), nof_base_pars);
+ fp_list->generate_code_defval(target);
+
+ target->header.function_prototypes =
+ mputprintf(target->header.function_prototypes,
+ "extern %s %s(%s);\n",
+ type_genname_str, template_name, formal_par_list);
+ target->source.function_bodies = mputprintf(target->source.function_bodies,
+ "%s %s(%s)\n"
+ "{\n"
+ "%s"
+ "}\n\n", type_genname_str, template_name, formal_par_list, function_body);
Free(formal_par_list);
Free(function_body);
} else {
// the object is initialized by the constructor
str = mputprintf(str, "%s %s(%s);\n", type_genname_str,
genname_str, body->get_single_expr(false).c_str());
+ // make sure the template's code is not generated twice (TR: HU56425)
+ body->set_code_generated();
} else {
// the default constructor is used
str = mputprintf(str, "%s %s;\n", type_genname_str, genname_str);
if (fp_list) {
const char *dispname_str = id->get_dispname().c_str();
NOTSUPP("Code generation for parameterized local template `%s'",
- dispname_str);
+ dispname_str);
def = mputprintf(def, "/* NOT SUPPORTED: template %s */\n", dispname_str);
init = mputprintf(init, "/* NOT SUPPORTED: template %s */\n",
- dispname_str);
+ dispname_str);
} else {
// non-parameterized template
// use the default constructor for initialization
def = mputprintf(def, "%s %s;\n",
- type->get_genname_template(my_scope).c_str(), genname_str);
+ type->get_genname_template(my_scope).c_str(), genname_str);
if (base_template) {
- // copy the base template with an assignment
- init = mputprintf(init, "%s = %s;\n", genname_str,
- base_template->get_genname_from_scope(my_scope).c_str());
+ // copy the base template with an assignment
+ init = mputprintf(init, "%s = %s;\n", genname_str,
+ base_template->get_genname_from_scope(my_scope).c_str());
}
// finally assign the body
init = body->generate_code_init(init, genname_str);
if (p_def->get_asstype() != A_VAR) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a variable, but the definition "
- "inherited from component type `%s' is a %s", dispname_str,
+ "inherited from component type `%s' is a %s", dispname_str,
p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname());
p_def->note("The inherited definition of `%s' is here", dispname_str);
return false;
if (!type->is_identical(p_def_var->type)) {
const char *dispname_str = id->get_dispname().c_str();
type->error("Local variable `%s' has type `%s', but the variable "
- "inherited from component type `%s' has type `%s'", dispname_str,
- type->get_typename().c_str(),
+ "inherited from component type `%s' has type `%s'", dispname_str,
+ type->get_typename().c_str(),
p_def_var->get_my_scope()->get_fullname().c_str(),
- p_def_var->type->get_typename().c_str());
+ p_def_var->type->get_typename().c_str());
p_def_var->note("The inherited variable `%s' is here", dispname_str);
return false;
}
if (initial_value) {
if (p_def_var->initial_value) {
if (!initial_value->is_unfoldable() &&
- !p_def_var->initial_value->is_unfoldable() &&
- !(*initial_value == *p_def_var->initial_value)) {
- const char *dispname_str = id->get_dispname().c_str();
- initial_value->warning("Local variable `%s' and the variable "
- "inherited from component type `%s' have different initial values",
- dispname_str, p_def_var->get_my_scope()->get_fullname().c_str());
- p_def_var->note("The inherited variable `%s' is here", dispname_str);
- }
+ !p_def_var->initial_value->is_unfoldable() &&
+ !(*initial_value == *p_def_var->initial_value)) {
+ const char *dispname_str = id->get_dispname().c_str();
+ initial_value->warning("Local variable `%s' and the variable "
+ "inherited from component type `%s' have different initial values",
+ dispname_str, p_def_var->get_my_scope()->get_fullname().c_str());
+ p_def_var->note("The inherited variable `%s' is here", dispname_str);
+ }
} else {
- const char *dispname_str = id->get_dispname().c_str();
- initial_value->warning("Local variable `%s' has initial value, but "
- "the variable inherited from component type `%s' does not",
- dispname_str, p_def_var->get_my_scope()->get_fullname().c_str());
- p_def_var->note("The inherited variable `%s' is here", dispname_str);
+ const char *dispname_str = id->get_dispname().c_str();
+ initial_value->warning("Local variable `%s' has initial value, but "
+ "the variable inherited from component type `%s' does not",
+ dispname_str, p_def_var->get_my_scope()->get_fullname().c_str());
+ p_def_var->note("The inherited variable `%s' is here", dispname_str);
}
} else if (p_def_var->initial_value) {
const char *dispname_str = id->get_dispname().c_str();
warning("Local variable `%s' does not have initial value, but the "
- "variable inherited from component type `%s' has", dispname_str,
- p_def_var->get_my_scope()->get_fullname().c_str());
+ "variable inherited from component type `%s' has", dispname_str,
+ p_def_var->get_my_scope()->get_fullname().c_str());
p_def_var->note("The inherited variable `%s' is here", dispname_str);
}
return true;
// the initial value can be represented by a single C++ expression
// the object is initialized by the constructor
str = mputprintf(str, "%s %s(%s);\n",
- type->get_genname_value(my_scope).c_str(), genname_str,
- initial_value->get_single_expr().c_str());
+ type->get_genname_value(my_scope).c_str(), genname_str,
+ initial_value->get_single_expr().c_str());
} else {
// use the default constructor
str = mputprintf(str, "%s %s;\n",
- type->get_genname_value(my_scope).c_str(), genname_str);
+ type->get_genname_value(my_scope).c_str(), genname_str);
if (initial_value) {
- // the initial value is assigned using subsequent statements
- str = initial_value->generate_code_init(str, genname_str);
+ // the initial value is assigned using subsequent statements
+ str = initial_value->generate_code_init(str, genname_str);
}
}
return str;
{
if (initial_value) {
str = initial_value->generate_code_init(str,
- base_defn->get_genname_from_scope(my_scope).c_str());
+ base_defn->get_genname_from_scope(my_scope).c_str());
}
return str;
}
OMIT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, IMPLICIT_OMIT, 0);
gen_restriction_check =
initial_value->chk_restriction("template variable definition",
- template_restriction);
+ template_restriction, initial_value);
if (!semantic_check_only) {
initial_value->set_genname_recursive(get_genname());
initial_value->set_code_section(GovernedSimple::CS_INLINE);
if (p_def->get_asstype() != A_VAR_TEMPLATE) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a template variable, but the definition "
- "inherited from component type `%s' is a %s", dispname_str,
+ "inherited from component type `%s' is a %s", dispname_str,
p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname());
p_def->note("The inherited definition of `%s' is here", dispname_str);
return false;
if (!type->is_identical(p_def_var_template->type)) {
const char *dispname_str = id->get_dispname().c_str();
type->error("Local template variable `%s' has type `%s', but the "
- "template variable inherited from component type `%s' has type `%s'",
- dispname_str, type->get_typename().c_str(),
+ "template variable inherited from component type `%s' has type `%s'",
+ dispname_str, type->get_typename().c_str(),
p_def_var_template->get_my_scope()->get_fullname().c_str(),
- p_def_var_template->type->get_typename().c_str());
+ p_def_var_template->type->get_typename().c_str());
p_def_var_template->note("The inherited template variable `%s' is here",
- dispname_str);
+ dispname_str);
return false;
}
if (initial_value) {
if (!p_def_var_template->initial_value) {
- const char *dispname_str = id->get_dispname().c_str();
- initial_value->warning("Local template variable `%s' has initial "
- "value, but the template variable inherited from component type "
- "`%s' does not", dispname_str,
- p_def_var_template->get_my_scope()->get_fullname().c_str());
- p_def_var_template->note("The inherited template variable `%s' is here",
- dispname_str);
+ const char *dispname_str = id->get_dispname().c_str();
+ initial_value->warning("Local template variable `%s' has initial "
+ "value, but the template variable inherited from component type "
+ "`%s' does not", dispname_str,
+ p_def_var_template->get_my_scope()->get_fullname().c_str());
+ p_def_var_template->note("The inherited template variable `%s' is here",
+ dispname_str);
}
} else if (p_def_var_template->initial_value) {
const char *dispname_str = id->get_dispname().c_str();
warning("Local template variable `%s' does not have initial value, but "
- "the template variable inherited from component type `%s' has",
- dispname_str,
- p_def_var_template->get_my_scope()->get_fullname().c_str());
+ "the template variable inherited from component type `%s' has",
+ dispname_str,
+ p_def_var_template->get_my_scope()->get_fullname().c_str());
p_def_var_template->note("The inherited template variable `%s' is here",
- dispname_str);
+ dispname_str);
}
return true;
}
{
if (initial_value) {
str = initial_value->generate_code_init(str,
- base_defn->get_genname_from_scope(my_scope).c_str());
+ base_defn->get_genname_from_scope(my_scope).c_str());
if (template_restriction != TR_NONE && gen_restriction_check)
str = Template::generate_restriction_check_code(str,
base_defn->get_genname_from_scope(my_scope).c_str(),
if (p_def->get_asstype() != A_TIMER) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a timer, but the definition inherited "
- "from component type `%s' is a %s", dispname_str,
+ "from component type `%s' is a %s", dispname_str,
p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname());
p_def->note("The inherited definition of `%s' is here", dispname_str);
return false;
if (dimensions) {
if (p_def_timer->dimensions) {
if (!dimensions->is_identical(p_def_timer->dimensions)) {
- const char *dispname_str = id->get_dispname().c_str();
- error("Local timer `%s' and the timer inherited from component type "
- "`%s' have different array dimensions", dispname_str,
+ const char *dispname_str = id->get_dispname().c_str();
+ error("Local timer `%s' and the timer inherited from component type "
+ "`%s' have different array dimensions", dispname_str,
p_def_timer->get_my_scope()->get_fullname().c_str());
- p_def_timer->note("The inherited timer `%s' is here", dispname_str);
- return false;
- }
+ p_def_timer->note("The inherited timer `%s' is here", dispname_str);
+ return false;
+ }
} else {
- const char *dispname_str = id->get_dispname().c_str();
- error("Local definition `%s' is a timer array, but the definition "
- "inherited from component type `%s' is a single timer", dispname_str,
+ const char *dispname_str = id->get_dispname().c_str();
+ error("Local definition `%s' is a timer array, but the definition "
+ "inherited from component type `%s' is a single timer", dispname_str,
p_def_timer->get_my_scope()->get_fullname().c_str());
- p_def_timer->note("The inherited timer `%s' is here", dispname_str);
- return false;
+ p_def_timer->note("The inherited timer `%s' is here", dispname_str);
+ return false;
}
} else if (p_def_timer->dimensions) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a single timer, but the definition "
- "inherited from component type `%s' is a timer array", dispname_str,
+ "inherited from component type `%s' is a timer array", dispname_str,
p_def_timer->get_my_scope()->get_fullname().c_str());
p_def_timer->note("The inherited timer `%s' is here", dispname_str);
return false;
if (default_duration) {
if (p_def_timer->default_duration) {
if (!default_duration->is_unfoldable() &&
- !p_def_timer->default_duration->is_unfoldable() &&
- !(*default_duration == *p_def_timer->default_duration)) {
- const char *dispname_str = id->get_dispname().c_str();
- default_duration->warning("Local timer `%s' and the timer inherited "
- "from component type `%s' have different default durations",
- dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str());
- p_def_timer->note("The inherited timer `%s' is here", dispname_str);
- }
+ !p_def_timer->default_duration->is_unfoldable() &&
+ !(*default_duration == *p_def_timer->default_duration)) {
+ const char *dispname_str = id->get_dispname().c_str();
+ default_duration->warning("Local timer `%s' and the timer inherited "
+ "from component type `%s' have different default durations",
+ dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str());
+ p_def_timer->note("The inherited timer `%s' is here", dispname_str);
+ }
} else {
- const char *dispname_str = id->get_dispname().c_str();
- default_duration->error("Local timer `%s' has default duration, but "
- "the timer inherited from component type `%s' does not", dispname_str,
+ const char *dispname_str = id->get_dispname().c_str();
+ default_duration->error("Local timer `%s' has default duration, but "
+ "the timer inherited from component type `%s' does not", dispname_str,
p_def_timer->get_my_scope()->get_fullname().c_str());
- p_def_timer->note("The inherited timer `%s' is here", dispname_str);
- return false;
+ p_def_timer->note("The inherited timer `%s' is here", dispname_str);
+ return false;
}
} else if (p_def_timer->default_duration) {
const char *dispname_str = id->get_dispname().c_str();
error("Local timer `%s' does not have default duration, but the timer "
- "inherited from component type `%s' has", dispname_str,
- p_def_timer->get_my_scope()->get_fullname().c_str());
+ "inherited from component type `%s' has", dispname_str,
+ p_def_timer->get_my_scope()->get_fullname().c_str());
p_def_timer->note("The inherited timer `%s' is here", dispname_str);
return false;
}
const string& array_type = dimensions->get_timer_type();
const char *array_type_str = array_type.c_str();
target->header.global_vars = mputprintf(target->header.global_vars,
- "extern %s %s;\n", array_type_str, genname_str);
+ "extern %s %s;\n", array_type_str, genname_str);
target->source.global_vars = mputprintf(target->source.global_vars,
- "%s %s;\n", array_type_str, genname_str);
+ "%s %s;\n", array_type_str, genname_str);
target->functions.pre_init = mputstr(target->functions.pre_init, "{\n"
- "static const char * const timer_name = \"");
+ "static const char * const timer_name = \"");
target->functions.pre_init = mputstr(target->functions.pre_init,
- dispname.c_str());
+ dispname.c_str());
target->functions.pre_init = mputprintf(target->functions.pre_init,
- "\";\n"
+ "\";\n"
"%s.set_name(timer_name);\n"
- "}\n", genname_str);
+ "}\n", genname_str);
if (default_duration) target->functions.post_init =
- generate_code_array_duration(target->functions.post_init, genname_str,
- default_duration);
+ generate_code_array_duration(target->functions.post_init, genname_str,
+ default_duration);
} else {
// single timer
target->header.global_vars = mputprintf(target->header.global_vars,
- "extern TIMER %s;\n", genname_str);
+ "extern TIMER %s;\n", genname_str);
if (default_duration) {
- // has default duration
- Value *v = default_duration->get_value_refd_last();
- if (v->get_valuetype() == Value::V_REAL) {
- // duration is known at compilation time -> set in the constructor
- target->source.global_vars = mputprintf(target->source.global_vars,
- "TIMER %s(\"%s\", %s);\n", genname_str, dispname.c_str(),
- v->get_single_expr().c_str());
- } else {
- // duration is known only at runtime -> set in post_init
- target->source.global_vars = mputprintf(target->source.global_vars,
- "TIMER %s(\"%s\");\n", genname_str, dispname.c_str());
- expression_struct expr;
- Code::init_expr(&expr);
- expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
- genname_str);
- default_duration->generate_code_expr(&expr);
- expr.expr = mputc(expr.expr, ')');
- target->functions.post_init =
- Code::merge_free_expr(target->functions.post_init, &expr);
- }
+ // has default duration
+ Value *v = default_duration->get_value_refd_last();
+ if (v->get_valuetype() == Value::V_REAL) {
+ // duration is known at compilation time -> set in the constructor
+ target->source.global_vars = mputprintf(target->source.global_vars,
+ "TIMER %s(\"%s\", %s);\n", genname_str, dispname.c_str(),
+ v->get_single_expr().c_str());
+ } else {
+ // duration is known only at runtime -> set in post_init
+ target->source.global_vars = mputprintf(target->source.global_vars,
+ "TIMER %s(\"%s\");\n", genname_str, dispname.c_str());
+ expression_struct expr;
+ Code::init_expr(&expr);
+ expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
+ genname_str);
+ default_duration->generate_code_expr(&expr);
+ expr.expr = mputc(expr.expr, ')');
+ target->functions.post_init =
+ Code::merge_free_expr(target->functions.post_init, &expr);
+ }
} else {
- // does not have default duration
- target->source.global_vars = mputprintf(target->source.global_vars,
- "TIMER %s(\"%s\");\n", genname_str, dispname.c_str());
+ // does not have default duration
+ target->source.global_vars = mputprintf(target->source.global_vars,
+ "TIMER %s(\"%s\");\n", genname_str, dispname.c_str());
}
}
}
const char *array_type_str = array_type.c_str();
str = mputprintf(str, "%s %s;\n", array_type_str, genname_str);
str = mputstr(str, "{\n"
- "static const char * const timer_name = \"");
+ "static const char * const timer_name = \"");
str = mputstr(str, dispname.c_str());
str = mputprintf(str, "\";\n"
"%s.set_name(timer_name);\n"
- "}\n", genname_str);
+ "}\n", genname_str);
if (default_duration) str = generate_code_array_duration(str,
- genname_str, default_duration);
+ genname_str, default_duration);
} else {
// single timer
if (default_duration && default_duration->has_single_expr()) {
- // the default duration can be passed to the constructor
- str = mputprintf(str, "TIMER %s(\"%s\", %s);\n", genname_str,
- dispname.c_str(), default_duration->get_single_expr().c_str());
+ // the default duration can be passed to the constructor
+ str = mputprintf(str, "TIMER %s(\"%s\", %s);\n", genname_str,
+ dispname.c_str(), default_duration->get_single_expr().c_str());
} else {
- // only the name is passed to the constructor
- str = mputprintf(str, "TIMER %s(\"%s\");\n", genname_str,
- dispname.c_str());
- if (default_duration) {
- // the default duration is set explicitly
- expression_struct expr;
- Code::init_expr(&expr);
- expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
- genname_str);
- default_duration->generate_code_expr(&expr);
- expr.expr = mputc(expr.expr, ')');
- str = Code::merge_free_expr(str, &expr);
- }
+ // only the name is passed to the constructor
+ str = mputprintf(str, "TIMER %s(\"%s\");\n", genname_str,
+ dispname.c_str());
+ if (default_duration) {
+ // the default duration is set explicitly
+ expression_struct expr;
+ Code::init_expr(&expr);
+ expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
+ genname_str);
+ default_duration->generate_code_expr(&expr);
+ expr.expr = mputc(expr.expr, ')');
+ str = Code::merge_free_expr(str, &expr);
+ }
}
}
return str;
const char *array_type_str = array_type.c_str();
def = mputprintf(def, "%s %s;\n", array_type_str, genname_str);
def = mputstr(def, "{\n"
- "static const char * const timer_names[] = { ");
+ "static const char * const timer_names[] = { ");
def = dimensions->generate_element_names(def, dispname);
def = mputprintf(def, " };\n"
"%s.set_name(%lu, timer_names);\n"
- "}\n", genname_str, (unsigned long) dimensions->get_array_size());
+ "}\n", genname_str, (unsigned long) dimensions->get_array_size());
if (default_duration) init = generate_code_array_duration(init,
- genname_str, default_duration);
+ genname_str, default_duration);
} else {
// single timer
if (default_duration) {
- // has default duration
- Value *v = default_duration->get_value_refd_last();
- if (v->get_valuetype() == Value::V_REAL) {
- // duration is known at compilation time -> set in the constructor
- def = mputprintf(def, "TIMER %s(\"%s\", %s);\n", genname_str,
- dispname.c_str(), v->get_single_expr().c_str());
- } else {
- // duration is known only at runtime -> set when control reaches the
- // timer definition
- def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str,
- dispname.c_str());
+ // has default duration
+ Value *v = default_duration->get_value_refd_last();
+ if (v->get_valuetype() == Value::V_REAL) {
+ // duration is known at compilation time -> set in the constructor
+ def = mputprintf(def, "TIMER %s(\"%s\", %s);\n", genname_str,
+ dispname.c_str(), v->get_single_expr().c_str());
+ } else {
+ // duration is known only at runtime -> set when control reaches the
+ // timer definition
+ def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str,
+ dispname.c_str());
expression_struct expr;
Code::init_expr(&expr);
- expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
- genname_str);
- default_duration->generate_code_expr(&expr);
- expr.expr = mputc(expr.expr, ')');
- init = Code::merge_free_expr(init, &expr);
- }
+ expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
+ genname_str);
+ default_duration->generate_code_expr(&expr);
+ expr.expr = mputc(expr.expr, ')');
+ init = Code::merge_free_expr(init, &expr);
+ }
} else {
- // does not have default duration
- def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str,
- dispname.c_str());
+ // does not have default duration
+ def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str,
+ dispname.c_str());
}
}
}
if (default_duration) {
Def_Timer *base_timer_defn = dynamic_cast<Def_Timer*>(base_defn);
if (!base_timer_defn || !base_timer_defn->default_duration)
- FATAL_ERROR("Def_Timer::generate_code_init_comp()");
+ FATAL_ERROR("Def_Timer::generate_code_init_comp()");
// initializer is not needed if the default durations are the same
// constants in both timers
if (default_duration->is_unfoldable() ||
- base_timer_defn->default_duration->is_unfoldable() ||
- !(*default_duration == *base_timer_defn->default_duration)) {
- if (dimensions) {
- str = generate_code_array_duration(str,
- base_timer_defn->get_genname_from_scope(my_scope).c_str(),
- default_duration);
- } else {
- expression_struct expr;
- Code::init_expr(&expr);
- expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
- base_timer_defn->get_genname_from_scope(my_scope).c_str());
- default_duration->generate_code_expr(&expr);
- expr.expr = mputc(expr.expr, ')');
- str = Code::merge_free_expr(str, &expr);
- }
+ base_timer_defn->default_duration->is_unfoldable() ||
+ !(*default_duration == *base_timer_defn->default_duration)) {
+ if (dimensions) {
+ str = generate_code_array_duration(str,
+ base_timer_defn->get_genname_from_scope(my_scope).c_str(),
+ default_duration);
+ } else {
+ expression_struct expr;
+ Code::init_expr(&expr);
+ expr.expr = mputprintf(expr.expr, "%s.set_default_duration(",
+ base_timer_defn->get_genname_from_scope(my_scope).c_str());
+ default_duration->generate_code_expr(&expr);
+ expr.expr = mputc(expr.expr, ')');
+ str = Code::merge_free_expr(str, &expr);
+ }
}
}
return str;
if (ass) {
if (ass->get_asstype() == A_TYPE) {
Type *t = ass->get_Type()->get_type_refd_last();
- if (t->get_typetype() == Type::T_PORT) port_type = t;
- else type_ref->error("Type reference `%s' does not refer to a "
- "port type", type_ref->get_dispname().c_str());
+ if (t->get_typetype() == Type::T_PORT) port_type = t;
+ else type_ref->error("Type reference `%s' does not refer to a "
+ "port type", type_ref->get_dispname().c_str());
} else type_ref->error("Reference `%s' does not refer to a "
"type", type_ref->get_dispname().c_str());
}
if (p_def->get_asstype() != A_PORT) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a port, but the definition inherited "
- "from component type `%s' is a %s", dispname_str,
+ "from component type `%s' is a %s", dispname_str,
p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname());
p_def->note("The inherited definition of `%s' is here", dispname_str);
return false;
Def_Port *p_def_port = dynamic_cast<Def_Port*>(p_def);
if (!p_def_port) FATAL_ERROR("Def_Port::chk_identical()");
if (port_type && p_def_port->port_type &&
- port_type != p_def_port->port_type) {
+ port_type != p_def_port->port_type) {
const char *dispname_str = id->get_dispname().c_str();
type_ref->error("Local port `%s' has type `%s', but the port inherited "
- "from component type `%s' has type `%s'", dispname_str,
- port_type->get_typename().c_str(),
+ "from component type `%s' has type `%s'", dispname_str,
+ port_type->get_typename().c_str(),
p_def_port->get_my_scope()->get_fullname().c_str(),
- p_def_port->port_type->get_typename().c_str());
+ p_def_port->port_type->get_typename().c_str());
p_def_port->note("The inherited port `%s' is here", dispname_str);
return false;
}
if (dimensions) {
if (p_def_port->dimensions) {
if (!dimensions->is_identical(p_def_port->dimensions)) {
- const char *dispname_str = id->get_dispname().c_str();
- error("Local port `%s' and the port inherited from component type "
- "`%s' have different array dimensions", dispname_str,
+ const char *dispname_str = id->get_dispname().c_str();
+ error("Local port `%s' and the port inherited from component type "
+ "`%s' have different array dimensions", dispname_str,
p_def_port->get_my_scope()->get_fullname().c_str());
- p_def_port->note("The inherited port `%s' is here", dispname_str);
- return false;
- }
+ p_def_port->note("The inherited port `%s' is here", dispname_str);
+ return false;
+ }
} else {
- const char *dispname_str = id->get_dispname().c_str();
- error("Local definition `%s' is a port array, but the definition "
- "inherited from component type `%s' is a single port", dispname_str,
+ const char *dispname_str = id->get_dispname().c_str();
+ error("Local definition `%s' is a port array, but the definition "
+ "inherited from component type `%s' is a single port", dispname_str,
p_def_port->get_my_scope()->get_fullname().c_str());
- p_def_port->note("The inherited port `%s' is here", dispname_str);
- return false;
+ p_def_port->note("The inherited port `%s' is here", dispname_str);
+ return false;
}
} else if (p_def_port->dimensions) {
const char *dispname_str = id->get_dispname().c_str();
error("Local definition `%s' is a single port, but the definition "
- "inherited from component type `%s' is a port array", dispname_str,
+ "inherited from component type `%s' is a port array", dispname_str,
p_def_port->get_my_scope()->get_fullname().c_str());
p_def_port->note("The inherited port `%s' is here", dispname_str);
return false;
const string& array_type = dimensions->get_port_type(type_genname);
const char *array_type_str = array_type.c_str();
target->header.global_vars = mputprintf(target->header.global_vars,
- "extern %s %s;\n", array_type_str, genname_str);
+ "extern %s %s;\n", array_type_str, genname_str);
target->source.global_vars = mputprintf(target->source.global_vars,
- "%s %s;\n", array_type_str, genname_str);
+ "%s %s;\n", array_type_str, genname_str);
target->functions.pre_init = mputstr(target->functions.pre_init, "{\n"
- "static const char * const port_name = \"");
+ "static const char * const port_name = \"");
target->functions.pre_init = mputstr(target->functions.pre_init,
- dispname.c_str());
+ dispname.c_str());
target->functions.pre_init = mputprintf(target->functions.pre_init,
- "\";\n"
+ "\";\n"
"%s.set_name(port_name);\n"
- "}\n", genname_str);
+ "}\n", genname_str);
} else {
// single port
const char *type_genname_str = type_genname.c_str();
target->header.global_vars = mputprintf(target->header.global_vars,
- "extern %s %s;\n", type_genname_str, genname_str);
+ "extern %s %s;\n", type_genname_str, genname_str);
target->source.global_vars = mputprintf(target->source.global_vars,
- "%s %s(\"%s\");\n", type_genname_str, genname_str, dispname.c_str());
+ "%s %s(\"%s\");\n", type_genname_str, genname_str, dispname.c_str());
}
target->functions.init_comp = mputprintf(target->functions.init_comp,
"%s.activate_port();\n", genname_str);
{
if (is_external) {
if (has_return_type) {
- if (returns_template) return A_EXT_FUNCTION_RTEMP;
- else return A_EXT_FUNCTION_RVAL;
+ if (returns_template) return A_EXT_FUNCTION_RTEMP;
+ else return A_EXT_FUNCTION_RVAL;
} else {
- if (returns_template)
- FATAL_ERROR("Def_Function_Base::determine_asstype()");
- return A_EXT_FUNCTION;
+ if (returns_template)
+ FATAL_ERROR("Def_Function_Base::determine_asstype()");
+ return A_EXT_FUNCTION;
}
} else { // not an external function
if (has_return_type) {
- if (returns_template) return A_FUNCTION_RTEMP;
- else return A_FUNCTION_RVAL;
+ if (returns_template) return A_FUNCTION_RTEMP;
+ else return A_FUNCTION_RVAL;
} else {
- if (returns_template)
- FATAL_ERROR("Def_Function_Base::determine_asstype()");
- return A_FUNCTION;
+ if (returns_template)
+ FATAL_ERROR("Def_Function_Base::determine_asstype()");
+ return A_FUNCTION;
}
}
}
FormalParList *p_fpl, Type *p_return_type, bool returns_template,
template_restriction_t p_template_restriction)
: 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),
+ 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)
{
if (!p_fpl) FATAL_ERROR("Def_Function_Base::Def_Function_Base()");
// checking the formal parameter list
if (prototype == PROTOTYPE_CONVERT) {
if (fp_list->get_nof_fps() == 1) {
- FormalPar *par = fp_list->get_fp_byIndex(0);
- if (par->get_asstype() == A_PAR_VAL_IN) {
- input_type = par->get_Type();
- } else {
- par->error("The parameter must be an `in' value parameter for "
- "attribute `prototype(%s)' instead of %s", get_prototype_name(),
- par->get_assname());
- }
+ FormalPar *par = fp_list->get_fp_byIndex(0);
+ if (par->get_asstype() == A_PAR_VAL_IN) {
+ input_type = par->get_Type();
+ } else {
+ par->error("The parameter must be an `in' value parameter for "
+ "attribute `prototype(%s)' instead of %s", get_prototype_name(),
+ par->get_assname());
+ }
} else {
- fp_list->error("The function must have one parameter instead of %lu "
- "for attribute `prototype(%s)'", (unsigned long) fp_list->get_nof_fps(),
- get_prototype_name());
+ fp_list->error("The function must have one parameter instead of %lu "
+ "for attribute `prototype(%s)'", (unsigned long) fp_list->get_nof_fps(),
+ get_prototype_name());
}
} else { // not PROTOTYPE_CONVERT
if (fp_list->get_nof_fps() == 2) {
- FormalPar *first_par = fp_list->get_fp_byIndex(0);
- if (prototype == PROTOTYPE_SLIDING) {
- if (first_par->get_asstype() == A_PAR_VAL_INOUT) {
- Type *first_par_type = first_par->get_Type();
- switch (first_par_type->get_type_refd_last()
- ->get_typetype_ttcn3()) {
- case Type::T_ERROR:
- case Type::T_OSTR:
- case Type::T_CSTR:
- case Type::T_BSTR:
- input_type = first_par_type;
- break;
- default:
- first_par_type->error("The type of the first parameter must be "
- "`octetstring' or `charstring' or `bitstring' for attribute "
- "`prototype(%s)' instead of `%s'", get_prototype_name(),
- first_par_type->get_typename().c_str());
- }
- } else {
- first_par->error("The first parameter must be an `inout' value "
- "parameter for attribute `prototype(%s)' instead of %s",
- get_prototype_name(), first_par->get_assname());
- }
- } else {
- if (first_par->get_asstype() == A_PAR_VAL_IN) {
- input_type = first_par->get_Type();
- } else {
- first_par->error("The first parameter must be an `in' value "
- "parameter for attribute `prototype(%s)' instead of %s",
- get_prototype_name(), first_par->get_assname());
- }
- }
- FormalPar *second_par = fp_list->get_fp_byIndex(1);
- if (second_par->get_asstype() == A_PAR_VAL_OUT) {
- output_type = second_par->get_Type();
- } else {
- second_par->error("The second parameter must be an `out' value "
- "parameter for attribute `prototype(%s)' instead of %s",
- get_prototype_name(), second_par->get_assname());
- }
+ FormalPar *first_par = fp_list->get_fp_byIndex(0);
+ if (prototype == PROTOTYPE_SLIDING) {
+ if (first_par->get_asstype() == A_PAR_VAL_INOUT) {
+ Type *first_par_type = first_par->get_Type();
+ switch (first_par_type->get_type_refd_last()
+ ->get_typetype_ttcn3()) {
+ case Type::T_ERROR:
+ case Type::T_OSTR:
+ case Type::T_CSTR:
+ case Type::T_BSTR:
+ input_type = first_par_type;
+ break;
+ default:
+ first_par_type->error("The type of the first parameter must be "
+ "`octetstring' or `charstring' or `bitstring' for attribute "
+ "`prototype(%s)' instead of `%s'", get_prototype_name(),
+ first_par_type->get_typename().c_str());
+ }
+ } else {
+ first_par->error("The first parameter must be an `inout' value "
+ "parameter for attribute `prototype(%s)' instead of %s",
+ get_prototype_name(), first_par->get_assname());
+ }
+ } else {
+ if (first_par->get_asstype() == A_PAR_VAL_IN) {
+ input_type = first_par->get_Type();
+ } else {
+ first_par->error("The first parameter must be an `in' value "
+ "parameter for attribute `prototype(%s)' instead of %s",
+ get_prototype_name(), first_par->get_assname());
+ }
+ }
+ FormalPar *second_par = fp_list->get_fp_byIndex(1);
+ if (second_par->get_asstype() == A_PAR_VAL_OUT) {
+ output_type = second_par->get_Type();
+ } else {
+ second_par->error("The second parameter must be an `out' value "
+ "parameter for attribute `prototype(%s)' instead of %s",
+ get_prototype_name(), second_par->get_assname());
+ }
} else {
- fp_list->error("The function must have two parameters for attribute "
- "`prototype(%s)' instead of %lu", get_prototype_name(),
- (unsigned long) fp_list->get_nof_fps());
+ fp_list->error("The function must have two parameters for attribute "
+ "`prototype(%s)' instead of %lu", get_prototype_name(),
+ (unsigned long) fp_list->get_nof_fps());
}
}
// checking the return type
if (prototype == PROTOTYPE_FAST) {
if (return_type) {
- return_type->error("The function cannot have return type for "
- "attribute `prototype(%s)'", get_prototype_name());
+ return_type->error("The function cannot have return type for "
+ "attribute `prototype(%s)'", get_prototype_name());
}
} else {
if (return_type) {
- if (asstype == A_FUNCTION_RTEMP || asstype == A_EXT_FUNCTION_RTEMP)
- return_type->error("The function must return a value instead of a "
- "template for attribute `prototype(%s)'", get_prototype_name());
- if (prototype == PROTOTYPE_CONVERT) {
- output_type = return_type;
- } else {
- switch (return_type->get_type_refd_last()->get_typetype_ttcn3()) {
- case Type::T_ERROR:
- case Type::T_INT:
- break;
- default:
- return_type->error("The return type of the function must be "
- "`integer' instead of `%s' for attribute `prototype(%s)'",
- return_type->get_typename().c_str(), get_prototype_name());
- }
- }
+ if (asstype == A_FUNCTION_RTEMP || asstype == A_EXT_FUNCTION_RTEMP)
+ return_type->error("The function must return a value instead of a "
+ "template for attribute `prototype(%s)'", get_prototype_name());
+ if (prototype == PROTOTYPE_CONVERT) {
+ output_type = return_type;
+ } else {
+ switch (return_type->get_type_refd_last()->get_typetype_ttcn3()) {
+ case Type::T_ERROR:
+ case Type::T_INT:
+ break;
+ default:
+ return_type->error("The return type of the function must be "
+ "`integer' instead of `%s' for attribute `prototype(%s)'",
+ return_type->get_typename().c_str(), get_prototype_name());
+ }
+ }
} else {
- error("The function must have return type for attribute "
- "`prototype(%s)'", get_prototype_name());
+ error("The function must have return type for attribute "
+ "`prototype(%s)'", get_prototype_name());
}
}
// checking the 'runs on' clause
if (get_RunsOnType()) {
error("The function cannot have `runs on' clause for attribute "
- "`prototype(%s)'", get_prototype_name());
+ "`prototype(%s)'", get_prototype_name());
}
}
StatementBlock *p_block)
: 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), block(p_block),
- is_startable(false), transparent(false)
+ runs_on_ref(p_runs_on_ref), runs_on_type(0), block(p_block),
+ is_startable(false), transparent(false)
{
if (!p_block) FATAL_ERROR("Def_Function::Def_Function()");
block->set_my_def(this);
is_startable = runs_on_ref != 0;
if (is_startable && !fp_list->get_startability()) is_startable = false;
if (is_startable && return_type && return_type->is_component_internal())
- is_startable = false;
+ is_startable = false;
// checking of statement block
block->chk();
if (return_type) {
switch (block->has_return()) {
case StatementBlock::RS_NO:
error("The function has return type, but it does not have any return "
- "statement");
+ "statement");
break;
case StatementBlock::RS_MAYBE:
- error("The function has return type, but control might leave it "
- "without reaching a return statement");
+ error("The function has return type, but control might leave it "
+ "without reaching a return statement");
default:
- break;
+ break;
}
}
if (!semantic_check_only) {
FATAL_ERROR("Def_Function::generate_code()");
}
const char *return_type_str = return_type_name.c_str();
+
+ // assemble the function body first (this also determines which parameters
+ // are never used)
+ char* body = create_location_object(memptystr(), "FUNCTION", dispname_str);
+ if (!enable_set_bound_out_param)
+ body = fp_list->generate_code_set_unbound(body); // conform the standard out parameter is unbound
+ body = fp_list->generate_shadow_objects(body);
+ body = block->generate_code(body);
+ // smart formal parameter list (names of unused parameters are omitted)
char *formal_par_list = fp_list->generate_code(memptystr());
fp_list->generate_code_defval(target);
// function prototype
target->header.function_prototypes =
mputprintf(target->header.function_prototypes, "extern %s %s(%s);\n",
- return_type_str, genname_str, formal_par_list);
+ return_type_str, genname_str, formal_par_list);
- // function body
- char *body = mprintf("%s %s(%s)\n"
- "{\n", return_type_str, genname_str, formal_par_list);
- body = create_location_object(body, "FUNCTION", dispname_str);
- if (!enable_set_bound_out_param)
- body = fp_list->generate_code_set_unbound(body); // conform the standard out parameter is unbound
- body = fp_list->generate_shadow_objects(body);
- body = block->generate_code(body);
- body = mputstr(body, "}\n\n");
- target->source.function_bodies = mputstr(target->source.function_bodies,
- body);
+ // function body
+ target->source.function_bodies = mputprintf(target->source.function_bodies,
+ "%s %s(%s)\n"
+ "{\n"
+ "%s"
+ "}\n\n", return_type_str, genname_str, formal_par_list, body);
+ Free(formal_par_list);
Free(body);
if (is_startable) {
size_t nof_fps = fp_list->get_nof_fps();
+ // use the full list of formal parameters here (since they are all logged)
+ char *full_formal_par_list = fp_list->generate_code(memptystr(), nof_fps);
// starter function (stub)
- // function prototype
- target->header.function_prototypes =
- mputprintf(target->header.function_prototypes,
- "extern void start_%s(const COMPONENT& component_reference%s%s);\n",
- genname_str, nof_fps>0?", ":"", formal_par_list);
- // function body
- body = mprintf("void start_%s(const COMPONENT& component_reference%s"
- "%s)\n"
- "{\n"
- "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n"
- "TTCN_Logger::log_event_str(\"Starting function %s(\");\n",
- genname_str, nof_fps>0?", ":"", formal_par_list, dispname_str);
- for (size_t i = 0; i < nof_fps; i++) {
- if (i > 0) body = mputstr(body,
+ // function prototype
+ target->header.function_prototypes =
+ mputprintf(target->header.function_prototypes,
+ "extern void start_%s(const COMPONENT& component_reference%s%s);\n",
+ genname_str, nof_fps>0?", ":"", full_formal_par_list);
+ // function body
+ body = mprintf("void start_%s(const COMPONENT& component_reference%s"
+ "%s)\n"
+ "{\n"
+ "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n"
+ "TTCN_Logger::log_event_str(\"Starting function %s(\");\n",
+ genname_str, nof_fps>0?", ":"", full_formal_par_list, dispname_str);
+ for (size_t i = 0; i < nof_fps; i++) {
+ if (i > 0) body = mputstr(body,
"TTCN_Logger::log_event_str(\", \");\n");
- body = mputprintf(body, "%s.log();\n",
- fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
- }
- body = mputprintf(body,
- "TTCN_Logger::log_event_str(\") on component \");\n"
- "component_reference.log();\n"
- "TTCN_Logger::log_char('.');\n"
- "TTCN_Logger::end_event();\n"
- "Text_Buf text_buf;\n"
- "TTCN_Runtime::prepare_start_component(component_reference, "
- "\"%s\", \"%s\", text_buf);\n",
- my_scope->get_scope_mod()->get_modid().get_dispname().c_str(),
- dispname_str);
- for (size_t i = 0; i < nof_fps; i++) {
- body = mputprintf(body, "%s.encode_text(text_buf);\n",
- fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
- }
- body = mputstr(body, "TTCN_Runtime::send_start_component(text_buf);\n"
- "}\n\n");
- target->source.function_bodies = mputstr(target->source.function_bodies,
- body);
- Free(body);
+ body = mputprintf(body, "%s.log();\n",
+ fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
+ }
+ body = mputprintf(body,
+ "TTCN_Logger::log_event_str(\") on component \");\n"
+ "component_reference.log();\n"
+ "TTCN_Logger::log_char('.');\n"
+ "TTCN_Logger::end_event();\n"
+ "Text_Buf text_buf;\n"
+ "TTCN_Runtime::prepare_start_component(component_reference, "
+ "\"%s\", \"%s\", text_buf);\n",
+ my_scope->get_scope_mod()->get_modid().get_dispname().c_str(),
+ dispname_str);
+ for (size_t i = 0; i < nof_fps; i++) {
+ body = mputprintf(body, "%s.encode_text(text_buf);\n",
+ fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
+ }
+ body = mputstr(body, "TTCN_Runtime::send_start_component(text_buf);\n"
+ "}\n\n");
+ target->source.function_bodies = mputstr(target->source.function_bodies,
+ body);
+ Free(body);
// an entry in start_ptc_function
body = mprintf("if (!strcmp(function_name, \"%s\")) {\n",
- dispname_str);
+ dispname_str);
if (nof_fps > 0) {
- body = fp_list->generate_code_object(body, "", ' ');
- for (size_t i = 0; i < nof_fps; i++) {
- body = mputprintf(body, "%s.decode_text(function_arguments);\n",
- fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
- }
- body = mputprintf(body,
- "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n"
- "TTCN_Logger::log_event_str(\"Starting function %s(\");\n",
- dispname_str);
- for (size_t i = 0; i < nof_fps; i++) {
- if (i > 0) body = mputstr(body,
+ body = fp_list->generate_code_object(body, "", ' ');
+ for (size_t i = 0; i < nof_fps; i++) {
+ body = mputprintf(body, "%s.decode_text(function_arguments);\n",
+ fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
+ }
+ body = mputprintf(body,
+ "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n"
+ "TTCN_Logger::log_event_str(\"Starting function %s(\");\n",
+ dispname_str);
+ for (size_t i = 0; i < nof_fps; i++) {
+ if (i > 0) body = mputstr(body,
"TTCN_Logger::log_event_str(\", \");\n");
- body = mputprintf(body, "%s.log();\n",
- fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
- }
- body = mputstr(body, "TTCN_Logger::log_event_str(\").\");\n"
- "TTCN_Logger::end_event();\n");
+ body = mputprintf(body, "%s.log();\n",
+ fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str());
+ }
+ body = mputstr(body, "TTCN_Logger::log_event_str(\").\");\n"
+ "TTCN_Logger::end_event();\n");
} else {
- body = mputprintf(body,
- "TTCN_Logger::log_str(TTCN_Logger::PARALLEL_PTC, \"Starting function "
+ body = mputprintf(body,
+ "TTCN_Logger::log_str(TTCN_Logger::PARALLEL_PTC, \"Starting function "
"%s().\");\n", dispname_str);
}
body = mputstr(body,
- "TTCN_Runtime::function_started(function_arguments);\n");
+ "TTCN_Runtime::function_started(function_arguments);\n");
char *actual_par_list =
- fp_list->generate_code_actual_parlist(memptystr(), "");
+ fp_list->generate_code_actual_parlist(memptystr(), "");
bool return_value_kept = false;
if (asstype == A_FUNCTION_RVAL) {
- // the return value is kept only if the function returns a value
- // (rather than a template) and the return type has the "done"
- // extension attribute
- for (Type *t = return_type; ; t = t->get_type_refd()) {
- if (t->has_done_attribute()) {
- return_value_kept = true;
- break;
- } else if (!t->is_ref()) break;
- }
+ // the return value is kept only if the function returns a value
+ // (rather than a template) and the return type has the "done"
+ // extension attribute
+ for (Type *t = return_type; ; t = t->get_type_refd()) {
+ if (t->has_done_attribute()) {
+ return_value_kept = true;
+ break;
+ } else if (!t->is_ref()) break;
+ }
}
if (return_value_kept) {
- const string& return_type_dispname = return_type->get_typename();
- const char *return_type_dispname_str = return_type_dispname.c_str();
- body = mputprintf(body, "%s ret_val(%s(%s));\n"
- "TTCN_Logger::begin_event(TTCN_PARALLEL);\n"
- "TTCN_Logger::log_event_str(\"Function %s returned %s : \");\n"
- "ret_val.log();\n"
- "Text_Buf text_buf;\n"
- "TTCN_Runtime::prepare_function_finished(\"%s\", text_buf);\n"
- "ret_val.encode_text(text_buf);\n"
- "TTCN_Runtime::send_function_finished(text_buf);\n",
- return_type_str, genname_str, actual_par_list, dispname_str,
- return_type_dispname_str, return_type_dispname_str);
+ const string& return_type_dispname = return_type->get_typename();
+ const char *return_type_dispname_str = return_type_dispname.c_str();
+ body = mputprintf(body, "%s ret_val(%s(%s));\n"
+ "TTCN_Logger::begin_event(TTCN_PARALLEL);\n"
+ "TTCN_Logger::log_event_str(\"Function %s returned %s : \");\n"
+ "ret_val.log();\n"
+ "Text_Buf text_buf;\n"
+ "TTCN_Runtime::prepare_function_finished(\"%s\", text_buf);\n"
+ "ret_val.encode_text(text_buf);\n"
+ "TTCN_Runtime::send_function_finished(text_buf);\n",
+ return_type_str, genname_str, actual_par_list, dispname_str,
+ return_type_dispname_str, return_type_dispname_str);
} else {
- body = mputprintf(body, "%s(%s);\n"
- "TTCN_Runtime::function_finished(\"%s\");\n",
- genname_str, actual_par_list, dispname_str);
+ body = mputprintf(body, "%s(%s);\n"
+ "TTCN_Runtime::function_finished(\"%s\");\n",
+ genname_str, actual_par_list, dispname_str);
}
Free(actual_par_list);
body = mputstr(body, "return TRUE;\n"
- "} else ");
+ "} else ");
target->functions.start = mputstr(target->functions.start, body);
Free(body);
+ Free(full_formal_par_list);
}
- Free(formal_par_list);
target->functions.pre_init = mputprintf(target->functions.pre_init,
"%s.add_function(\"%s\", (genericfunc_t)&%s, ", get_module_object_name(),
switch (function_type) {
case EXTFUNC_MANUAL:
if (eb_list) {
- eb_list->error("Attribute `errorbehavior' can only be used together "
- "with `encode' or `decode'");
- eb_list->chk();
+ eb_list->error("Attribute `errorbehavior' can only be used together "
+ "with `encode' or `decode'");
+ eb_list->chk();
}
break;
case EXTFUNC_ENCODE:
switch (prototype) {
case PROTOTYPE_NONE:
- error("Attribute `encode' cannot be used without `prototype'");
- break;
+ error("Attribute `encode' cannot be used without `prototype'");
+ break;
case PROTOTYPE_BACKTRACK:
case PROTOTYPE_SLIDING:
- error("Attribute `encode' cannot be used with `prototype(%s)'",
- get_prototype_name());
+ error("Attribute `encode' cannot be used with `prototype(%s)'",
+ get_prototype_name());
default: /* CONVERT and FAST allowed */
break;
}
if (input_type) {
- if (!input_type->has_encoding(encoding_type)) {
- input_type->error("Input type `%s' does not support %s encoding",
- input_type->get_typename().c_str(),
- Type::get_encoding_name(encoding_type));
+ if (!input_type->has_encoding(encoding_type, encoding_options)) {
+ if (Common::Type::CT_CUSTOM == encoding_type) {
+ input_type->error("Input type `%s' does not support custom encoding '%s'",
+ input_type->get_typename().c_str(), encoding_options->c_str());
+ }
+ else {
+ input_type->error("Input type `%s' does not support %s encoding",
+ input_type->get_typename().c_str(),
+ Type::get_encoding_name(encoding_type));
+ }
}
- if (Common::Type::CT_XER == encoding_type
- && input_type->get_type_refd_last()->is_untagged()) {
- // "untagged" on the (toplevel) input type will have no effect.
- warning("UNTAGGED encoding attribute is ignored on top-level type");
+ else {
+ if (Common::Type::CT_XER == encoding_type
+ && input_type->get_type_refd_last()->is_untagged()) {
+ // "untagged" on the (toplevel) input type will have no effect.
+ warning("UNTAGGED encoding attribute is ignored on top-level type");
+ }
+ if (Common::Type::CT_CUSTOM == encoding_type) {
+ if (PROTOTYPE_CONVERT != prototype) {
+ error("Only `prototype(convert)' is allowed for custom encoding functions");
+ }
+ else {
+ // let the input type know that this is its encoding function
+ input_type->get_type_refd()->set_coding_function(true,
+ get_genname_from_scope(input_type->get_type_refd()->get_my_scope()));
+ // treat this as a manual external function during code generation
+ function_type = EXTFUNC_MANUAL;
+ }
+ }
}
}
if (output_type) {
- Type *stream_type = Type::get_stream_type(encoding_type);
- if (!stream_type->is_identical(output_type)) {
- output_type->error("The output type of %s encoding should be `%s' "
- "instead of `%s'", Type::get_encoding_name(encoding_type),
- stream_type->get_typename().c_str(),
- output_type->get_typename().c_str());
- }
+ if(encoding_type == Common::Type::CT_TEXT) { // TEXT encoding supports both octetstring and charstring stream types
+ Type *stream_type = Type::get_stream_type(encoding_type,0);
+ Type *stream_type2 = Type::get_stream_type(encoding_type,1);
+ if ( (!stream_type->is_identical(output_type)) && (!stream_type2->is_identical(output_type)) ) {
+ output_type->error("The output type of %s encoding should be `%s' or `%s' "
+ "instead of `%s'", Type::get_encoding_name(encoding_type),
+ stream_type->get_typename().c_str(),
+ stream_type2->get_typename().c_str(),
+ output_type->get_typename().c_str());
+ }
+ } else {
+ Type *stream_type = Type::get_stream_type(encoding_type);
+ if (!stream_type->is_identical(output_type)) {
+ output_type->error("The output type of %s encoding should be `%s' "
+ "instead of `%s'", Type::get_encoding_name(encoding_type),
+ stream_type->get_typename().c_str(),
+ output_type->get_typename().c_str());
+ }
+ }
}
if (eb_list) eb_list->chk();
chk_allowed_encode();
break;
case EXTFUNC_DECODE:
if (prototype == PROTOTYPE_NONE) {
- error("Attribute `decode' cannot be used without `prototype'");
+ error("Attribute `decode' cannot be used without `prototype'");
}
if (input_type) {
- Type *stream_type = Type::get_stream_type(encoding_type);
- if (!stream_type->is_identical(input_type)) {
- input_type->error("The input type of %s encoding should be `%s' "
- "instead of `%s'", Type::get_encoding_name(encoding_type),
- stream_type->get_typename().c_str(),
- input_type->get_typename().c_str());
- }
- }
- if (output_type && !output_type->has_encoding(encoding_type)) {
- output_type->error("Output type `%s' does not support %s encoding",
- output_type->get_typename().c_str(),
- Type::get_encoding_name(encoding_type));
+ if(encoding_type == Common::Type::CT_TEXT) { // TEXT encoding supports both octetstring and charstring stream types
+ Type *stream_type = Type::get_stream_type(encoding_type,0);
+ Type *stream_type2 = Type::get_stream_type(encoding_type,1);
+ if ( (!stream_type->is_identical(input_type)) && (!stream_type2->is_identical(input_type)) ) {
+ input_type->error("The input type of %s decoding should be `%s' or `%s' "
+ "instead of `%s'", Type::get_encoding_name(encoding_type),
+ stream_type->get_typename().c_str(),
+ stream_type2->get_typename().c_str(),
+ input_type->get_typename().c_str());
+ }
+ } else {
+ Type *stream_type = Type::get_stream_type(encoding_type);
+ if (!stream_type->is_identical(input_type)) {
+ input_type->error("The input type of %s decoding should be `%s' "
+ "instead of `%s'", Type::get_encoding_name(encoding_type),
+ stream_type->get_typename().c_str(),
+ input_type->get_typename().c_str());
+ }
+ }
+
+ }
+ if (output_type && !output_type->has_encoding(encoding_type, encoding_options)) {
+ if (Common::Type::CT_CUSTOM == encoding_type) {
+ output_type->error("Output type `%s' does not support custom encoding '%s'",
+ output_type->get_typename().c_str(), encoding_options->c_str());
+ }
+ else {
+ output_type->error("Output type `%s' does not support %s encoding",
+ output_type->get_typename().c_str(),
+ Type::get_encoding_name(encoding_type));
+ }
+ }
+ else {
+ if (Common::Type::CT_CUSTOM == encoding_type) {
+ if (PROTOTYPE_SLIDING != prototype) {
+ error("Only `prototype(sliding)' is allowed for custom decoding functions");
+ }
+ else if (output_type) {
+ // let the output type know that this is its decoding function
+ output_type->get_type_refd()->set_coding_function(false,
+ get_genname_from_scope(output_type->get_type_refd()->get_my_scope()));
+ // treat this as a manual external function during code generation
+ function_type = EXTFUNC_MANUAL;
+ }
+ }
}
if (eb_list) eb_list->chk();
chk_allowed_encode();
case Type::CT_JSON:
if (enable_json()) return;
break;
+ case Type::CT_CUSTOM:
+ return; // cannot be disabled
default:
FATAL_ERROR("Def_ExtFunction::chk_allowed_encode");
break;
Error_Context cntxt2(return_type, "In return type");
return_type->chk();
return_type->chk_as_return_type(asstype == A_EXT_FUNCTION_RVAL,
- "external function");
+ "external function");
}
if (!semantic_check_only) fp_list->set_genname(get_genname());
if (w_attrib_path) {
result_name = "ret_val";
// creating a local variable for the result stream
str = mputprintf(str, "%s ret_val;\n",
- output_type->get_genname_value(my_scope).c_str());
+ output_type->get_genname_value(my_scope).c_str());
break;
case PROTOTYPE_FAST:
result_name = fp_list->get_fp_byIndex(1)->get_id().get_name().c_str();
// setting error behavior
if (eb_list) str = eb_list->generate_code(str);
else if (prototype == PROTOTYPE_BACKTRACK || prototype == PROTOTYPE_SLIDING) {
- str = mputstr(str, "TTCN_EncDec::set_error_behavior("
+ str = mputstr(str, "TTCN_EncDec::set_error_behavior("
"TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n");
} else str = mputstr(str, "TTCN_EncDec::set_error_behavior("
"TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);\n");
if (prototype == PROTOTYPE_CONVERT) {
// creating a local variable for the result
str = mputprintf(str, "%s ret_val;\n",
- output_type->get_genname_value(my_scope).c_str());
+ output_type->get_genname_value(my_scope).c_str());
result_name = "ret_val";
} else {
result_name = fp_list->get_fp_byIndex(1)->get_id().get_name().c_str();
if (prototype != PROTOTYPE_SLIDING) {
// checking for remaining data in the buffer if decoding was successful
str = mputprintf(str, "if (TTCN_EncDec::get_last_error_type() == "
- "TTCN_EncDec::ET_NONE) {\n"
- "if (ttcn_buffer.get_pos() < ttcn_buffer.get_len()-1 && "
- "TTCN_Logger::log_this_event(TTCN_WARNING)) {\n"
- "ttcn_buffer.cut();\n"
- "%s remaining_stream;\n"
- "ttcn_buffer.get_string(remaining_stream);\n"
- "TTCN_Logger::begin_event(TTCN_WARNING);\n"
- "TTCN_Logger::log_event_str(\"%s(): Warning: Data remained at the end "
- "of the stream after successful decoding: \");\n"
- "remaining_stream.log();\n"
- "TTCN_Logger::end_event();\n"
- "}\n", input_type->get_genname_value(my_scope).c_str(), function_name);
+ "TTCN_EncDec::ET_NONE) {\n"
+ "if (ttcn_buffer.get_pos() < ttcn_buffer.get_len()-1 && "
+ "TTCN_Logger::log_this_event(TTCN_WARNING)) {\n"
+ "ttcn_buffer.cut();\n"
+ "%s remaining_stream;\n"
+ "ttcn_buffer.get_string(remaining_stream);\n"
+ "TTCN_Logger::begin_event(TTCN_WARNING);\n"
+ "TTCN_Logger::log_event_str(\"%s(): Warning: Data remained at the end "
+ "of the stream after successful decoding: \");\n"
+ "remaining_stream.log();\n"
+ "TTCN_Logger::end_event();\n"
+ "}\n", input_type->get_genname_value(my_scope).c_str(), function_name);
// closing the block and returning the appropriate result or status code
if (prototype == PROTOTYPE_BACKTRACK) {
- str = mputstr(str, "return 0;\n"
- "} else return 1;\n");
+ str = mputstr(str, "return 0;\n"
+ "} else return 1;\n");
} else {
- str = mputstr(str, "}\n");
- if (prototype == PROTOTYPE_CONVERT)
+ str = mputstr(str, "}\n");
+ if (prototype == PROTOTYPE_CONVERT)
str = mputstr(str, "return ret_val;\n");
}
} else {
// result handling and debug printout for sliding decoders
str = mputprintf(str, "switch (TTCN_EncDec::get_last_error_type()) {\n"
- "case TTCN_EncDec::ET_NONE:\n"
- // TTCN_Buffer::get_string will call OCTETSTRING::clean_up()
- "ttcn_buffer.cut();\n"
- "ttcn_buffer.get_string(%s);\n"
- "if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {\n"
- "TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);\n"
- "TTCN_Logger::log_event_str(\"%s(): Stream after decoding: \");\n"
- "%s.log();\n"
- "TTCN_Logger::end_event();\n"
- "}\n"
- "return 0;\n"
+ "case TTCN_EncDec::ET_NONE:\n"
+ // TTCN_Buffer::get_string will call OCTETSTRING::clean_up()
+ "ttcn_buffer.cut();\n"
+ "ttcn_buffer.get_string(%s);\n"
+ "if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {\n"
+ "TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);\n"
+ "TTCN_Logger::log_event_str(\"%s(): Stream after decoding: \");\n"
+ "%s.log();\n"
+ "TTCN_Logger::end_event();\n"
+ "}\n"
+ "return 0;\n"
"case TTCN_EncDec::ET_INCOMPL_MSG:\n"
- "case TTCN_EncDec::ET_LEN_ERR:\n"
- "return 2;\n"
- "default:\n"
- "return 1;\n"
- "}\n", first_par_name, function_name, first_par_name);
+ "case TTCN_EncDec::ET_LEN_ERR:\n"
+ "return 2;\n"
+ "default:\n"
+ "return 1;\n"
+ "}\n", first_par_name, function_name, first_par_name);
}
return str;
}
FATAL_ERROR("Def_ExtFunction::generate_code()");
}
const char *return_type_str = return_type_name.c_str();
- char *formal_par_list = fp_list->generate_code(memptystr());
+ char *formal_par_list = fp_list->generate_code(memptystr(), fp_list->get_nof_fps());
fp_list->generate_code_defval(target);
// function prototype
target->header.function_prototypes =
mputprintf(target->header.function_prototypes, "extern %s %s(%s);\n",
- return_type_str, genname_str, formal_par_list);
+ return_type_str, genname_str, formal_par_list);
if (function_type != EXTFUNC_MANUAL) {
// function body written by the compiler
, __FUNCTION__, __LINE__);
#endif
body = mputprintf(body,
- "%s %s(%s)\n"
- "{\n"
- , return_type_str, genname_str, formal_par_list);
+ "%s %s(%s)\n"
+ "{\n"
+ , return_type_str, genname_str, formal_par_list);
switch (function_type) {
case EXTFUNC_ENCODE:
body = generate_code_encode(body);
- break;
+ break;
case EXTFUNC_DECODE:
body = generate_code_decode(body);
- break;
+ break;
default:
FATAL_ERROR("Def_ExtFunction::generate_code()");
}
body = mputstr(body, "}\n\n");
target->source.function_bodies = mputstr(target->source.function_bodies,
- body);
+ body);
Free(body);
}
DEBUG(level + 1, "Prototype: %s", get_prototype_name());
if (function_type != EXTFUNC_MANUAL) {
DEBUG(level + 1, "Automatically generated: %s",
- function_type == EXTFUNC_ENCODE ? "encoder" : "decoder");
+ function_type == EXTFUNC_ENCODE ? "encoder" : "decoder");
DEBUG(level + 2, "Encoding type: %s",
- Type::get_encoding_name(encoding_type));
+ Type::get_encoding_name(encoding_type));
if (encoding_options)
- DEBUG(level + 2, "Encoding options: %s", encoding_options->c_str());
+ DEBUG(level + 2, "Encoding options: %s", encoding_options->c_str());
}
if (eb_list) eb_list->dump(level + 1);
}
const string& t_genname = get_genname();
const char *genname_str = t_genname.c_str();
const char *dispname_str = id->get_dispname().c_str();
+
+ // function for altstep instance:
+ // assemble the function body first (this also determines which parameters
+ // are never used)
+ char* body = create_location_object(memptystr(), "ALTSTEP", dispname_str);
+ body = fp_list->generate_shadow_objects(body);
+ body = sb->generate_code(body);
+ body = ags->generate_code_altstep(body);
+ // generate a smart formal parameter list (omits unused parameter names)
char *formal_par_list = fp_list->generate_code(memptystr());
fp_list->generate_code_defval(target);
// function for altstep instance: prototype
target->header.function_prototypes =
mputprintf(target->header.function_prototypes,
- "extern alt_status %s_instance(%s);\n", genname_str, formal_par_list);
+ "extern alt_status %s_instance(%s);\n", genname_str, formal_par_list);
// function for altstep instance: body
- char *str = mprintf("alt_status %s_instance(%s)\n"
- "{\n", genname_str, formal_par_list);
- str = create_location_object(str, "ALTSTEP", dispname_str);
- str = fp_list->generate_shadow_objects(str);
- str = sb->generate_code(str);
- str = ags->generate_code_altstep(str);
- str = mputstr(str, "}\n\n");
- target->source.function_bodies = mputstr(target->source.function_bodies,
- str);
- Free(str);
+ target->source.function_bodies = mputprintf(target->source.function_bodies,
+ "alt_status %s_instance(%s)\n"
+ "{\n"
+ "%s"
+ "}\n\n", genname_str, formal_par_list, body);
+ Free(formal_par_list);
+ Free(body);
char *actual_par_list =
fp_list->generate_code_actual_parlist(memptystr(), "");
+
+ // use a full formal parameter list for the rest of the functions
+ char *full_formal_par_list = fp_list->generate_code(memptystr(),
+ fp_list->get_nof_fps());
// wrapper function for stand-alone instantiation: prototype
target->header.function_prototypes =
mputprintf(target->header.function_prototypes,
- "extern void %s(%s);\n", genname_str, formal_par_list);
+ "extern void %s(%s);\n", genname_str, full_formal_par_list);
// wrapper function for stand-alone instantiation: body
target->source.function_bodies =
mputprintf(target->source.function_bodies, "void %s(%s)\n"
- "{\n"
- "altstep_begin:\n"
- "boolean block_flag = FALSE;\n"
- "alt_status altstep_flag = ALT_UNCHECKED, "
- "default_flag = ALT_UNCHECKED;\n"
- "for ( ; ; ) {\n"
- "TTCN_Snapshot::take_new(block_flag);\n"
- "if (altstep_flag != ALT_NO) {\n"
- "altstep_flag = %s_instance(%s);\n"
- "if (altstep_flag == ALT_YES || altstep_flag == ALT_BREAK) return;\n"
- "else if (altstep_flag == ALT_REPEAT) goto altstep_begin;\n"
- "}\n"
- "if (default_flag != ALT_NO) {\n"
- "default_flag = TTCN_Default::try_altsteps();\n"
- "if (default_flag == ALT_YES || default_flag == ALT_BREAK) return;\n"
- "else if (default_flag == ALT_REPEAT) goto altstep_begin;\n"
- "}\n"
- "if (altstep_flag == ALT_NO && default_flag == ALT_NO) "
- "TTCN_error(\"None of the branches can be chosen in altstep %s.\");\n"
- "else block_flag = TRUE;\n"
- "}\n"
- "}\n\n", genname_str, formal_par_list, genname_str, actual_par_list,
- dispname_str);
+ "{\n"
+ "altstep_begin:\n"
+ "boolean block_flag = FALSE;\n"
+ "alt_status altstep_flag = ALT_UNCHECKED, "
+ "default_flag = ALT_UNCHECKED;\n"
+ "for ( ; ; ) {\n"
+ "TTCN_Snapshot::take_new(block_flag);\n"
+ "if (altstep_flag != ALT_NO) {\n"
+ "altstep_flag = %s_instance(%s);\n"
+ "if (altstep_flag == ALT_YES || altstep_flag == ALT_BREAK) return;\n"
+ "else if (altstep_flag == ALT_REPEAT) goto altstep_begin;\n"
+ "}\n"
+ "if (default_flag != ALT_NO) {\n"
+ "default_flag = TTCN_Default::try_altsteps();\n"
+ "if (default_flag == ALT_YES || default_flag == ALT_BREAK) return;\n"
+ "else if (default_flag == ALT_REPEAT) goto altstep_begin;\n"
+ "}\n"
+ "if (altstep_flag == ALT_NO && default_flag == ALT_NO) "
+ "TTCN_error(\"None of the branches can be chosen in altstep %s.\");\n"
+ "else block_flag = TRUE;\n"
+ "}\n"
+ "}\n\n", genname_str, full_formal_par_list, genname_str, actual_par_list,
+ dispname_str);
// class for keeping the altstep in the default context
// the class is for internal use, we do not need to publish it in the
// header file
- str = mprintf("class %s_Default : public Default_Base {\n", genname_str);
+ char* str = mprintf("class %s_Default : public Default_Base {\n", genname_str);
str = fp_list->generate_code_object(str, "par_");
str = mputprintf(str, "public:\n"
"%s_Default(%s);\n"
"alt_status call_altstep();\n"
- "};\n\n", genname_str, formal_par_list);
+ "};\n\n", genname_str, full_formal_par_list);
target->source.class_defs = mputstr(target->source.class_defs, str);
Free(str);
// member functions of the class
str = mprintf("%s_Default::%s_Default(%s)\n"
- " : Default_Base(\"%s\")", genname_str, genname_str, formal_par_list,
- dispname_str);
+ " : Default_Base(\"%s\")", genname_str, genname_str, full_formal_par_list,
+ dispname_str);
for (size_t i = 0; i < fp_list->get_nof_fps(); i++) {
const char *fp_name_str =
- fp_list->get_fp_byIndex(i)->get_id().get_name().c_str();
+ fp_list->get_fp_byIndex(i)->get_id().get_name().c_str();
str = mputprintf(str, ", par_%s(%s)", fp_name_str, fp_name_str);
}
str = mputstr(str, "\n{\n}\n\n");
// function for default activation: prototype
target->header.function_prototypes =
mputprintf(target->header.function_prototypes,
- "extern Default_Base *activate_%s(%s);\n", genname_str,
- formal_par_list);
+ "extern Default_Base *activate_%s(%s);\n", genname_str,
+ full_formal_par_list);
// function for default activation: body
str = mprintf("Default_Base *activate_%s(%s)\n"
- "{\n", genname_str, formal_par_list);
+ "{\n", genname_str, full_formal_par_list);
str = mputprintf(str, "return new %s_Default(%s);\n"
"}\n\n", genname_str, actual_par_list);
target->source.function_bodies = mputstr(target->source.function_bodies,
str);
Free(str);
- Free(formal_par_list);
+ Free(full_formal_par_list);
Free(actual_par_list);
target->functions.pre_init = mputprintf(target->functions.pre_init,
"%s.add_altstep(\"%s\", (genericfunc_t)&%s_instance, (genericfunc_t )&activate_%s, "
- "(genericfunc_t )&%s);\n", get_module_object_name(), dispname_str, genname_str,
+ "(genericfunc_t )&%s);\n", get_module_object_name(), dispname_str, genname_str,
genname_str, genname_str);
}
const string& t_genname = get_genname();
const char *genname_str = t_genname.c_str();
const char *dispname_str = id->get_dispname().c_str();
- // formal parameter list
- char *formal_par_list = fp_list->generate_code(memptystr());
- fp_list->generate_code_defval(target);
- if (fp_list->get_nof_fps() > 0)
- formal_par_list = mputstr(formal_par_list, ", ");
- formal_par_list = mputstr(formal_par_list,
- "boolean has_timer, double timer_value");
-
- // function prototype
- target->header.function_prototypes =
- mputprintf(target->header.function_prototypes,
- "extern verdicttype testcase_%s(%s);\n", genname_str, formal_par_list);
-
- // function body
- char *body = mprintf("verdicttype testcase_%s(%s)\n"
- "{\n", genname_str, formal_par_list);
- Free(formal_par_list);
+
+ // assemble the function body first (this also determines which parameters
+ // are never used)
+
// Checking whether the testcase was invoked from another one.
// At this point the location information should refer to the execute()
// statement rather than this testcase.
- body = mputstr(body, "TTCN_Runtime::check_begin_testcase(has_timer, "
- "timer_value);\n");
+ char* body = mputstr(memptystr(), "TTCN_Runtime::check_begin_testcase(has_timer, "
+ "timer_value);\n");
body = create_location_object(body, "TESTCASE", dispname_str);
body = fp_list->generate_shadow_objects(body);
body = mputprintf(body, "try {\n"
"} catch (const TC_End& tc_end) {\n"
"TTCN_Logger::log_str(TTCN_FUNCTION, \"Test case %s was stopped.\");\n"
"}\n", dispname_str);
- body = mputstr(body, "return TTCN_Runtime::end_testcase();\n"
- "}\n\n");
- target->source.function_bodies = mputstr(target->source.function_bodies,
- body);
+ body = mputstr(body, "return TTCN_Runtime::end_testcase();\n");
+
+ // smart formal parameter list (names of unused parameters are omitted)
+ char *formal_par_list = fp_list->generate_code(memptystr());
+ fp_list->generate_code_defval(target);
+ if (fp_list->get_nof_fps() > 0)
+ formal_par_list = mputstr(formal_par_list, ", ");
+ formal_par_list = mputstr(formal_par_list,
+ "boolean has_timer, double timer_value");
+
+ // function prototype
+ target->header.function_prototypes =
+ mputprintf(target->header.function_prototypes,
+ "extern verdicttype testcase_%s(%s);\n", genname_str, formal_par_list);
+
+ // function body
+ target->source.function_bodies = mputprintf(target->source.function_bodies,
+ "verdicttype testcase_%s(%s)\n"
+ "{\n"
+ "%s"
+ "}\n\n", genname_str, formal_par_list, body);
+ Free(formal_par_list);
Free(body);
if (fp_list->get_nof_fps() == 0) {
// adding to the list of startable testcases
target->functions.pre_init = mputprintf(target->functions.pre_init,
- "%s.add_testcase_nonpard(\"%s\", testcase_%s);\n",
- get_module_object_name(), dispname_str, genname_str);
+ "%s.add_testcase_nonpard(\"%s\", testcase_%s);\n",
+ get_module_object_name(), dispname_str, genname_str);
} else {
target->functions.pre_init = mputprintf(target->functions.pre_init,
"%s.add_testcase_pard(\"%s\", (genericfunc_t)&testcase_%s);\n",
TemplateInstance *p_defval, bool p_lazy_eval)
: Definition(p_asstype, p_name), type(p_type), my_parlist(0),
used_as_lvalue(false), template_restriction(TR_NONE),
- lazy_eval(p_lazy_eval)
+ lazy_eval(p_lazy_eval), defval_generated(false), usage_found(false)
{
switch (p_asstype) {
case A_PAR_VAL:
Identifier* p_name, TemplateInstance *p_defval, bool p_lazy_eval)
: Definition(p_asstype, p_name), type(p_type), my_parlist(0),
used_as_lvalue(false), template_restriction(p_template_restriction),
- lazy_eval(p_lazy_eval)
+ lazy_eval(p_lazy_eval), defval_generated(false), usage_found(false)
{
switch (p_asstype) {
case A_PAR_TEMPL_IN:
FormalPar::FormalPar(asstype_t p_asstype, Identifier* p_name,
TemplateInstance *p_defval)
: Definition(p_asstype, p_name), type(0), my_parlist(0),
- used_as_lvalue(false), template_restriction(TR_NONE), lazy_eval(false)
+ used_as_lvalue(false), template_restriction(TR_NONE), lazy_eval(false),
+ defval_generated(false), usage_found(false)
{
if (p_asstype != A_PAR_TIMER)
FATAL_ERROR("Ttcn::FormalPar::FormalPar(): invalid parameter type");
switch (t->get_typetype()) {
case Type::T_PORT:
switch (asstype) {
- case A_PAR_VAL:
- case A_PAR_VAL_INOUT:
- asstype = A_PAR_PORT;
- break;
- default:
- error("Port type `%s' cannot be used as %s",
- t->get_fullname().c_str(), get_assname());
- }
- break;
+ case A_PAR_VAL:
+ case A_PAR_VAL_INOUT:
+ asstype = A_PAR_PORT;
+ break;
+ default:
+ error("Port type `%s' cannot be used as %s",
+ t->get_fullname().c_str(), get_assname());
+ }
+ break;
case Type::T_SIGNATURE:
switch (asstype) {
- case A_PAR_TEMPL_IN:
- case A_PAR_TEMPL_OUT:
- case A_PAR_TEMPL_INOUT:
- break;
- default:
- error("Signature `%s' cannot be used as %s",
- t->get_fullname().c_str(), get_assname());
- }
- break;
+ case A_PAR_TEMPL_IN:
+ case A_PAR_TEMPL_OUT:
+ case A_PAR_TEMPL_INOUT:
+ break;
+ default:
+ error("Signature `%s' cannot be used as %s",
+ t->get_fullname().c_str(), get_assname());
+ }
+ break;
default:
switch (asstype) {
- case A_PAR_PORT:
- case A_PAR_TIMER:
- FATAL_ERROR("FormalPar::chk()");
- case A_PAR_VAL:
- asstype = A_PAR_VAL_IN;
- default:
+ case A_PAR_PORT:
+ case A_PAR_TIMER:
+ FATAL_ERROR("FormalPar::chk()");
+ case A_PAR_VAL:
+ asstype = A_PAR_VAL_IN;
+ default:
break;
- }
+ }
}
} else if (asstype != A_PAR_TIMER) FATAL_ERROR("FormalPar::chk()");
defval.ap = chk_actual_par(default_value, Type::EXPECTED_STATIC_VALUE);
delete default_value;
if (!semantic_check_only)
- defval.ap->set_code_section(GovernedSimple::CS_POST_INIT);
+ defval.ap->set_code_section(GovernedSimple::CS_POST_INIT);
}
}
return new ActualPar(v);
} else {
actual_par->error("A specific value without matching symbols "
- "was expected for a %s", get_assname());
+ "was expected for a %s", get_assname());
return new ActualPar();
}
}
if (template_restriction!=TR_NONE) {
bool needs_runtime_check =
ret_val->get_TemplateInstance()->chk_restriction(
- "template formal parameter", template_restriction);
+ "template formal parameter", template_restriction,
+ ret_val->get_TemplateInstance());
if (needs_runtime_check)
ret_val->set_gen_restriction_check(template_restriction);
}
Type *ap_type = actual_par->get_Type();
if (ap_type) {
ap_type->warning("Explicit type specification is useless for an %s",
- get_assname());
+ get_assname());
actual_par->chk_Type(type);
}
Ref_base *derived_ref = actual_par->get_DerivedRef();
if (derived_ref) {
derived_ref->error("An in-line modified template cannot be used as %s",
- get_assname());
+ get_assname());
actual_par->chk_DerivedRef(type);
}
// needed for the error messages
Ref_base *ref = ap_template->get_Ref();
Common::Assignment *ass = ref->get_refd_assignment();
if (!ass) {
- delete ref;
- return new ActualPar();
+ delete ref;
+ return new ActualPar();
}
bool asstype_correct = false;
switch (ass->get_asstype()) {
case A_PAR_VAL_IN:
- ass->use_as_lvalue(*ref);
- if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) {
- ass->warning("Passing an `in' parameter as another function's `out' parameter");
- }
- // no break
+ ass->use_as_lvalue(*ref);
+ if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) {
+ ass->warning("Passing an `in' parameter as another function's `out' parameter");
+ }
+ // no break
case A_VAR:
case A_PAR_VAL_OUT:
case A_PAR_VAL_INOUT:
if (!is_template) asstype_correct = true;
- break;
+ break;
case A_PAR_TEMPL_IN:
- ass->use_as_lvalue(*ref);
- if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) {
- ass->warning("Passing an `in' parameter as another function's `out' parameter");
- }
- // no break
+ ass->use_as_lvalue(*ref);
+ if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) {
+ ass->warning("Passing an `in' parameter as another function's `out' parameter");
+ }
+ // no break
case A_VAR_TEMPLATE:
case A_PAR_TEMPL_OUT:
case A_PAR_TEMPL_INOUT:
if (is_template) asstype_correct = true;
- break;
+ break;
default:
- break;
+ break;
}
if (asstype_correct) {
- FieldOrArrayRefs *t_subrefs = ref->get_subrefs();
- Type *ref_type = ass->get_Type()->get_field_type(t_subrefs, exp_val);
- if (ref_type) {
- if (!type->is_identical(ref_type)) {
- ref->error("Type mismatch: Reference to a %s of type "
- "`%s' was expected instead of `%s'", expected_string,
- type->get_typename().c_str(), ref_type->get_typename().c_str());
- } else if (type->get_sub_type() && ref_type->get_sub_type() &&
+ FieldOrArrayRefs *t_subrefs = ref->get_subrefs();
+ Type *ref_type = ass->get_Type()->get_field_type(t_subrefs, exp_val);
+ if (ref_type) {
+ if (!type->is_identical(ref_type)) {
+ ref->error("Type mismatch: Reference to a %s of type "
+ "`%s' was expected instead of `%s'", expected_string,
+ type->get_typename().c_str(), ref_type->get_typename().c_str());
+ } else if (type->get_sub_type() && ref_type->get_sub_type() &&
(type->get_sub_type()->get_subtypetype()==ref_type->get_sub_type()->get_subtypetype()) &&
(!type->get_sub_type()->is_compatible(ref_type->get_sub_type()))) {
ref->error("Subtype mismatch: subtype %s has no common value with subtype %s",
type->get_sub_type()->to_string().c_str(),
ref_type->get_sub_type()->to_string().c_str());
}
- if (t_subrefs && t_subrefs->refers_to_string_element()) {
- ref->error("Reference to a string element of type `%s' cannot be "
- "used in this context", ref_type->get_typename().c_str());
- }
- }
+ if (t_subrefs && t_subrefs->refers_to_string_element()) {
+ ref->error("Reference to a string element of type `%s' cannot be "
+ "used in this context", ref_type->get_typename().c_str());
+ }
+ }
} else {
ref->error("Reference to a %s was expected for an %s instead of %s",
- expected_string, get_assname(), ass->get_description().c_str());
+ expected_string, get_assname(), ass->get_description().c_str());
}
ActualPar* ret_val_ap = new ActualPar(ref);
// restriction checking if this is a reference to a template variable
case A_PAR_TEMPL_OUT:
case A_PAR_TEMPL_INOUT: {
FormalPar* fp = dynamic_cast<FormalPar*>(ass);
- if (!fp) FATAL_ERROR("Template::chk_restriction_refd()");
+ if (!fp) FATAL_ERROR("FormalPar::chk_actual_par_by_ref()");
refd_tr = fp->get_template_restriction();
} break;
default:
Ref_base *ref = ap_template->get_Ref();
Common::Assignment *ass = ref->get_refd_assignment();
if (!ass) {
- delete ref;
- return new ActualPar();
+ delete ref;
+ return new ActualPar();
}
switch (ass->get_asstype()) {
case A_TIMER: {
ArrayDimensions *dims = ass->get_Dimensions();
- if (dims) dims->chk_indices(ref, "timer", false, exp_val);
- else if (ref->get_subrefs()) ref->error("Reference to single %s "
- "cannot have field or array sub-references",
- ass->get_description().c_str());
- break; }
+ if (dims) dims->chk_indices(ref, "timer", false, exp_val);
+ else if (ref->get_subrefs()) ref->error("Reference to single %s "
+ "cannot have field or array sub-references",
+ ass->get_description().c_str());
+ break; }
case A_PAR_TIMER:
if (ref->get_subrefs()) ref->error("Reference to %s cannot have "
- "field or array sub-references", ass->get_description().c_str());
- break;
+ "field or array sub-references", ass->get_description().c_str());
+ break;
default:
ref->error("Reference to a timer or timer parameter was expected for "
- "a timer parameter instead of %s", ass->get_description().c_str());
+ "a timer parameter instead of %s", ass->get_description().c_str());
}
return new ActualPar(ref);
} else {
Ref_base *ref = ap_template->get_Ref();
Common::Assignment *ass = ref->get_refd_assignment();
if (!ass) {
- delete ref;
- return new ActualPar();
+ delete ref;
+ return new ActualPar();
}
bool asstype_correct = false;
switch (ass->get_asstype()) {
case A_PORT: {
ArrayDimensions *dims = ass->get_Dimensions();
- if (dims) dims->chk_indices(ref, "port", false, exp_val);
- else if (ref->get_subrefs()) ref->error("Reference to single %s "
- "cannot have field or array sub-references",
- ass->get_description().c_str());
+ if (dims) dims->chk_indices(ref, "port", false, exp_val);
+ else if (ref->get_subrefs()) ref->error("Reference to single %s "
+ "cannot have field or array sub-references",
+ ass->get_description().c_str());
asstype_correct = true;
- break; }
+ break; }
case A_PAR_PORT:
if (ref->get_subrefs()) ref->error("Reference to %s cannot have "
- "field or array sub-references", ass->get_description().c_str());
+ "field or array sub-references", ass->get_description().c_str());
asstype_correct = true;
- break;
+ break;
default:
ref->error("Reference to a port or port parameter was expected for a "
- "port parameter instead of %s", ass->get_description().c_str());
+ "port parameter instead of %s", ass->get_description().c_str());
}
if (asstype_correct) {
- Type *ref_type = ass->get_Type();
- if (ref_type && !type->is_identical(ref_type))
- ref->error("Type mismatch: Reference to a port or port parameter "
- "of type `%s' was expected instead of `%s'",
- type->get_typename().c_str(), ref_type->get_typename().c_str());
+ Type *ref_type = ass->get_Type();
+ if (ref_type && !type->is_identical(ref_type))
+ ref->error("Type mismatch: Reference to a port or port parameter "
+ "of type `%s' was expected instead of `%s'",
+ type->get_typename().c_str(), ref_type->get_typename().c_str());
}
return new ActualPar(ref);
} else {
Definition *my_def = my_parlist->get_my_def();
if (!my_def) FATAL_ERROR("FormalPar::use_as_lvalue()");
if (my_def->get_asstype() == A_TEMPLATE)
- p_loc.error("Parameter `%s' of the template cannot be passed further "
- "as `out' or `inout' parameter", id->get_dispname().c_str());
+ p_loc.error("Parameter `%s' of the template cannot be passed further "
+ "as `out' or `inout' parameter", id->get_dispname().c_str());
else {
- // update the genname so that all references in the generated code
- // will point to the shadow object
+ // update the genname so that all references in the generated code
+ // will point to the shadow object
if (!lazy_eval) {
- set_genname(id->get_name() + "_shadow");
+ set_genname(id->get_name() + "_shadow");
}
- used_as_lvalue = true;
+ used_as_lvalue = true;
}
}
}
-
- void FormalPar::generate_code_defval(output_struct *target, bool)
+
+ char* FormalPar::generate_code_defval(char* str)
{
- if (!defval.ap) return;
+ if (!defval.ap || defval_generated) return str;
+ defval_generated = true;
switch (defval.ap->get_selection()) {
case ActualPar::AP_VALUE: {
Value *val = defval.ap->get_Value();
- const_def cdef;
- Code::init_cdef(&cdef);
- type->generate_code_object(&cdef, val);
- Code::merge_cdef(target, &cdef);
- Code::free_cdef(&cdef);
if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
- target->functions.post_init = TypeConv::gen_conv_code_refd(target->
- functions.post_init, val->get_lhs_name().c_str(), val);
+ str = TypeConv::gen_conv_code_refd(str, val->get_lhs_name().c_str(), val);
} else {
- target->functions.post_init = val->generate_code_init(
- target->functions.post_init, val->get_lhs_name().c_str());
+ str = val->generate_code_init(str, val->get_lhs_name().c_str());
}
break; }
case ActualPar::AP_TEMPLATE: {
TemplateInstance *ti = defval.ap->get_TemplateInstance();
Template *temp = ti->get_Template();
- const_def cdef;
- Code::init_cdef(&cdef);
- type->generate_code_object(&cdef, temp);
- Code::merge_cdef(target, &cdef);
- Code::free_cdef(&cdef);
Ref_base *dref = ti->get_DerivedRef();
if (dref) {
expression_struct expr;
expr.expr = mputprintf(expr.expr, "%s = ",
temp->get_lhs_name().c_str());
dref->generate_code(&expr);
- target->functions.post_init =
- Code::merge_free_expr(target->functions.post_init, &expr, false);
+ str = Code::merge_free_expr(str, &expr, false);
}
if (use_runtime_2 && TypeConv::needs_conv_refd(temp)) {
- target->functions.post_init = TypeConv::gen_conv_code_refd(target->
- functions.post_init, temp->get_lhs_name().c_str(), temp);
+ str = TypeConv::gen_conv_code_refd(str, temp->get_lhs_name().c_str(), temp);
} else {
- target->functions.post_init =
- temp->generate_code_init(target->functions.post_init,
- temp->get_lhs_name().c_str());
+ str = temp->generate_code_init(str, temp->get_lhs_name().c_str());
}
if (defval.ap->get_gen_restriction_check() != TR_NONE) {
- target->functions.post_init =
- Template::generate_restriction_check_code(
- target->functions.post_init, temp->get_lhs_name().c_str(),
- defval.ap->get_gen_restriction_check());
+ str = Template::generate_restriction_check_code(str,
+ temp->get_lhs_name().c_str(), defval.ap->get_gen_restriction_check());
}
break; }
case ActualPar::AP_REF:
default:
FATAL_ERROR("FormalPar::generate_code()");
}
+ return str;
}
- char *FormalPar::generate_code_fpar(char *str)
+ void FormalPar::generate_code_defval(output_struct *target, bool)
{
- const char *name_str = id->get_name().c_str();
+ if (!defval.ap) return;
+ switch (defval.ap->get_selection()) {
+ case ActualPar::AP_VALUE: {
+ Value *val = defval.ap->get_Value();
+ const_def cdef;
+ Code::init_cdef(&cdef);
+ type->generate_code_object(&cdef, val);
+ Code::merge_cdef(target, &cdef);
+ Code::free_cdef(&cdef);
+ break; }
+ case ActualPar::AP_TEMPLATE: {
+ TemplateInstance *ti = defval.ap->get_TemplateInstance();
+ Template *temp = ti->get_Template();
+ const_def cdef;
+ Code::init_cdef(&cdef);
+ type->generate_code_object(&cdef, temp);
+ Code::merge_cdef(target, &cdef);
+ Code::free_cdef(&cdef);
+ break; }
+ case ActualPar::AP_REF:
+ break;
+ default:
+ FATAL_ERROR("FormalPar::generate_code()");
+ }
+ target->functions.post_init = generate_code_defval(target->functions.post_init);
+ }
+
+ char *FormalPar::generate_code_fpar(char *str, bool display_unused /* = false */)
+ {
+ // the name of the parameter should not be displayed if the parameter is not
+ // used (to avoid a compiler warning)
+ bool display_name = (usage_found || display_unused || (!enable_set_bound_out_param &&
+ (asstype == A_PAR_VAL_OUT || asstype == A_PAR_TEMPL_OUT)));
+ const char *name_str = display_name ? id->get_name().c_str() : "";
switch (asstype) {
case A_PAR_VAL_IN:
if (lazy_eval) {
case A_PAR_VAL_INOUT:
case A_PAR_PORT:
str = mputprintf(str, "%s& %s", type->get_genname_value(my_scope).c_str(),
- name_str);
+ name_str);
break;
case A_PAR_TEMPL_IN:
if (lazy_eval) {
case A_PAR_TEMPL_OUT:
case A_PAR_TEMPL_INOUT:
str = mputprintf(str, "%s& %s",
- type->get_genname_template(my_scope).c_str(), name_str);
+ type->get_genname_template(my_scope).c_str(), name_str);
break;
case A_PAR_TIMER:
str = mputprintf(str, "TIMER& %s", name_str);
case A_PAR_VAL_INOUT:
case A_PAR_PORT:
str = mputprintf(str, "%s%c %s%s;\n",
- type->get_genname_value(my_scope).c_str(), refch, p_prefix, name_str);
+ type->get_genname_value(my_scope).c_str(), refch, p_prefix, name_str);
break;
case A_PAR_TEMPL_IN:
if (lazy_eval) {
case A_PAR_TEMPL_OUT:
case A_PAR_TEMPL_INOUT:
str = mputprintf(str, "%s%c %s%s;\n",
- type->get_genname_template(my_scope).c_str(), refch, p_prefix, name_str);
+ type->get_genname_template(my_scope).c_str(), refch, p_prefix, name_str);
break;
case A_PAR_TIMER:
str = mputprintf(str, "TIMER& %s%s;\n", p_prefix, name_str);
const char *name_str = id->get_name().c_str();
switch (asstype) {
case A_PAR_VAL_IN:
- str = mputprintf(str, "%s %s(%s);\n",
- type->get_genname_value(my_scope).c_str(), genname_str, name_str);
- break;
+ str = mputprintf(str, "%s %s(%s);\n",
+ type->get_genname_value(my_scope).c_str(), genname_str, name_str);
+ break;
case A_PAR_TEMPL_IN:
- str = mputprintf(str, "%s %s(%s);\n",
- type->get_genname_template(my_scope).c_str(), genname_str, name_str);
- break;
+ str = mputprintf(str, "%s %s(%s);\n",
+ type->get_genname_template(my_scope).c_str(), genname_str, name_str);
+ break;
default:
- FATAL_ERROR("FormalPar::generate_shadow_object()");
+ FATAL_ERROR("FormalPar::generate_shadow_object()");
}
}
return str;
FormalPar *par = pars_v[i];
const string& par_name = par->get_id().get_name();
if (par->get_asstype() != Definition::A_PAR_TIMER)
- par->get_Type()->set_genname(p_prefix, par_name);
+ par->get_Type()->set_genname(p_prefix, par_name);
if (par->has_defval()) {
- string embedded_genname(p_prefix);
- embedded_genname += '_';
- embedded_genname += par_name;
- embedded_genname += "_defval";
+ string embedded_genname(p_prefix);
+ embedded_genname += '_';
+ embedded_genname += par_name;
+ embedded_genname += "_defval";
ActualPar *defval = par->get_defval();
switch (defval->get_selection()) {
case ActualPar::AP_ERROR:
case ActualPar::AP_REF:
break;
case ActualPar::AP_VALUE: {
- Value *v = defval->get_Value();
+ Value *v = defval->get_Value();
v->set_genname_prefix("const_");
- v->set_genname_recursive(embedded_genname);
+ v->set_genname_recursive(embedded_genname);
break; }
case ActualPar::AP_TEMPLATE: {
- Template *t = defval->get_TemplateInstance()->get_Template();
- t->set_genname_prefix("template_");
- t->set_genname_recursive(embedded_genname);
- break; }
+ Template *t = defval->get_TemplateInstance()->get_Template();
+ t->set_genname_prefix("template_");
+ t->set_genname_recursive(embedded_genname);
+ break; }
default:
FATAL_ERROR("FormalParList::set_genname()");
}
const string& name = id.get_name();
const char *dispname = id.get_dispname().c_str();
if (pars_m.has_key(name)) {
- par->error("Duplicate parameter with name `%s'", dispname);
- pars_m[name]->note("Previous definition of `%s' is here", dispname);
+ par->error("Duplicate parameter with name `%s'", dispname);
+ pars_m[name]->note("Previous definition of `%s' is here", dispname);
} else {
- pars_m.add(name, par);
- if (parent_scope && parent_scope->has_ass_withId(id)) {
- par->error("Parameter name `%s' is not unique in the scope "
- "hierarchy", dispname);
- Reference ref(0, id.clone());
- Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref);
- if (!ass) FATAL_ERROR("FormalParList::chk()");
- ass->note("Symbol `%s' is already defined here in a higher scope "
- "unit", dispname);
- }
+ pars_m.add(name, par);
+ if (parent_scope && parent_scope->has_ass_withId(id)) {
+ par->error("Parameter name `%s' is not unique in the scope "
+ "hierarchy", dispname);
+ Reference ref(0, id.clone());
+ Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref);
+ if (!ass) FATAL_ERROR("FormalParList::chk()");
+ ass->note("Symbol `%s' is already defined here in a higher scope "
+ "unit", dispname);
+ }
}
Error_Context cntxt2(par, "In parameter `%s'", dispname);
par->chk();
switch (deftype) {
case Definition::A_TEMPLATE:
switch (par->get_asstype()) {
- case Definition::A_PAR_VAL_IN:
- case Definition::A_PAR_TEMPL_IN:
- // these are allowed
+ case Definition::A_PAR_VAL_IN:
+ case Definition::A_PAR_TEMPL_IN:
+ // these are allowed
break;
- default:
+ default:
par->error("A template cannot have %s", par->get_assname());
- }
- break;
+ }
+ break;
case Definition::A_TESTCASE:
switch (par->get_asstype()) {
- case Definition::A_PAR_TIMER:
- case Definition::A_PAR_PORT:
- // these are forbidden
+ case Definition::A_PAR_TIMER:
+ case Definition::A_PAR_PORT:
+ // these are forbidden
par->error("A testcase cannot have %s", par->get_assname());
- default:
+ default:
break;
- }
+ }
default:
// everything is allowed for functions and altsteps
break;
break;
default:
par->error("%s `%s' cannot be started on a parallel test component "
- "because it has %s", p_what, p_name, par->get_description().c_str());
+ "because it has %s", p_what, p_name, par->get_description().c_str());
}
}
}
// check for the number of parameters
if (nof_type_pars != nof_function_pars) {
p_fp_list->error("Too %s parameters: %lu was expected instead of %lu",
- nof_type_pars < nof_function_pars ? "many" : "few",
- (unsigned long) nof_type_pars, (unsigned long) nof_function_pars);
+ nof_type_pars < nof_function_pars ? "many" : "few",
+ (unsigned long) nof_type_pars, (unsigned long) nof_function_pars);
}
size_t upper_limit =
nof_type_pars < nof_function_pars ? nof_type_pars : nof_function_pars;
// check for parameter kind equivalence
// (in, out or inout / value or template)
if (type_par_asstype != function_par_asstype) {
- function_par->error("The kind of the parameter is not the same as in "
- "type `%s': %s was expected instead of %s", where,
- type_par->get_assname(), function_par->get_assname());
+ function_par->error("The kind of the parameter is not the same as in "
+ "type `%s': %s was expected instead of %s", where,
+ type_par->get_assname(), function_par->get_assname());
}
// check for type equivalence
if (type_par_asstype != FormalPar::A_PAR_TIMER &&
- function_par_asstype != FormalPar::A_PAR_TIMER) {
- Type *type_par_type = type_par->get_Type();
- Type *function_par_type = function_par->get_Type();
- if (!type_par_type->is_identical(function_par_type)) {
- function_par_type->error("The type of the parameter is not the same "
- "as in type `%s': `%s' was expected instead of `%s'", where,
- type_par_type->get_typename().c_str(),
- function_par_type->get_typename().c_str());
- } else if (type_par_type->get_sub_type() && function_par_type->get_sub_type() &&
+ function_par_asstype != FormalPar::A_PAR_TIMER) {
+ Type *type_par_type = type_par->get_Type();
+ Type *function_par_type = function_par->get_Type();
+ if (!type_par_type->is_identical(function_par_type)) {
+ function_par_type->error("The type of the parameter is not the same "
+ "as in type `%s': `%s' was expected instead of `%s'", where,
+ type_par_type->get_typename().c_str(),
+ function_par_type->get_typename().c_str());
+ } else if (type_par_type->get_sub_type() && function_par_type->get_sub_type() &&
(type_par_type->get_sub_type()->get_subtypetype()==function_par_type->get_sub_type()->get_subtypetype()) &&
(!type_par_type->get_sub_type()->is_compatible(function_par_type->get_sub_type()))) {
// TODO: maybe equivalence should be checked, or maybe that is too strict
function_par->error("The template restriction of the parameter is "
"not the same as in type `%s': %s restriction was expected instead "
"of %s restriction", where,
- type_par->get_template_restriction()==TR_NONE ? "no" :
+ type_par->get_template_restriction()==TR_NONE ? "no" :
Template::get_restriction_name(type_par->get_template_restriction()),
function_par->get_template_restriction()==TR_NONE ? "no" :
Template::get_restriction_name(function_par->
const Identifier& type_par_id = type_par->get_id();
const Identifier& function_par_id = function_par->get_id();
if (type_par_id != function_par_id) {
- function_par->warning("The name of the parameter is not the same "
- "as in type `%s': `%s' was expected instead of `%s'", where,
- type_par_id.get_dispname().c_str(),
- function_par_id.get_dispname().c_str());
+ function_par->warning("The name of the parameter is not the same "
+ "as in type `%s': `%s' was expected instead of `%s'", where,
+ type_par_id.get_dispname().c_str(),
+ function_par_id.get_dispname().c_str());
}
}
}
// We are now responsible for np.
if (has_fp_withName(*np->get_name())) {
- // there is a formal parameter with that name
- FormalPar *fp = get_fp_byName(*np->get_name());
- const size_t is_at = *formalpar_map[fp]; // the index of the formal par
- if (is_at >= num_actual) {
- // There is no actual par in the unnamed part.
- // Create one from the named param.
-
- // First, pad the gap with '-'
- for (; num_actual < is_at; ++num_actual) {
- Template *not_used;
- if (pars_v[num_actual]->has_defval()) {
- not_used = new Template(Template::TEMPLATE_NOTUSED);
- }
- else { // cannot use '-' if no default value
- not_used = new Template(Template::TEMPLATE_ERROR);
- }
- TemplateInstance *new_ti = new TemplateInstance(0, 0, not_used);
- // Conjure a location info at the beginning of the unnamed part
- // (that is, the beginning of the actual parameter list)
- new_ti->set_location(p_paps->get_tis()->get_filename(),
- p_paps->get_tis()->get_first_line(),
- p_paps->get_tis()->get_first_column(), 0, 0);
- p_paps->get_tis()->add_ti(new_ti);
- }
- TemplateInstance * namedti = np->extract_ti();
- p_paps->get_tis()->add_ti(namedti);
- ++num_actual;
- } else {
- // There is already an actual par at that position, fetch it
- TemplateInstance * ti = p_paps->get_tis()->get_ti_byIndex(is_at);
- Template::templatetype_t tt = ti->get_Template()->get_templatetype();
-
- if (is_at >= num_unnamed && !ti->get_Type() && !ti->get_DerivedRef()
- && (tt == Template::TEMPLATE_NOTUSED || tt == Template::TEMPLATE_ERROR)) {
- // NotUsed in the named part => padding
- np->error("Named parameter `%s' out of order",
- np->get_name()->get_dispname().c_str());
- } else {
- // attempt to override an original unnamed param with a named one
- np->error("Formal parameter `%s' assigned more than once",
- np->get_name()->get_dispname().c_str());
- }
- }
+ // there is a formal parameter with that name
+ FormalPar *fp = get_fp_byName(*np->get_name());
+ const size_t is_at = *formalpar_map[fp]; // the index of the formal par
+ if (is_at >= num_actual) {
+ // There is no actual par in the unnamed part.
+ // Create one from the named param.
+
+ // First, pad the gap with '-'
+ for (; num_actual < is_at; ++num_actual) {
+ Template *not_used;
+ if (pars_v[num_actual]->has_defval()) {
+ not_used = new Template(Template::TEMPLATE_NOTUSED);
+ }
+ else { // cannot use '-' if no default value
+ not_used = new Template(Template::TEMPLATE_ERROR);
+ }
+ TemplateInstance *new_ti = new TemplateInstance(0, 0, not_used);
+ // Conjure a location info at the beginning of the unnamed part
+ // (that is, the beginning of the actual parameter list)
+ new_ti->set_location(p_paps->get_tis()->get_filename(),
+ p_paps->get_tis()->get_first_line(),
+ p_paps->get_tis()->get_first_column(), 0, 0);
+ p_paps->get_tis()->add_ti(new_ti);
+ }
+ TemplateInstance * namedti = np->extract_ti();
+ p_paps->get_tis()->add_ti(namedti);
+ ++num_actual;
+ } else {
+ // There is already an actual par at that position, fetch it
+ TemplateInstance * ti = p_paps->get_tis()->get_ti_byIndex(is_at);
+ Template::templatetype_t tt = ti->get_Template()->get_templatetype();
+
+ if (is_at >= num_unnamed && !ti->get_Type() && !ti->get_DerivedRef()
+ && (tt == Template::TEMPLATE_NOTUSED || tt == Template::TEMPLATE_ERROR)) {
+ // NotUsed in the named part => padding
+ np->error("Named parameter `%s' out of order",
+ np->get_name()->get_dispname().c_str());
+ } else {
+ // attempt to override an original unnamed param with a named one
+ np->error("Formal parameter `%s' assigned more than once",
+ np->get_name()->get_dispname().c_str());
+ }
+ }
}
else { // no formal parameter with that name
- char * nam = 0;
- switch (my_def->get_asstype()) {
- case Common::Assignment::A_TYPE: {
- Type *t = my_def->get_Type();
-
- switch (t ? t->get_typetype() : 0) {
- case Type::T_FUNCTION:
- nam = mcopystr("Function reference");
- break;
- case Type::T_ALTSTEP:
- nam = mcopystr("Altstep reference");
- break;
- case Type::T_TESTCASE:
- nam = mcopystr("Testcase reference");
- break;
- default:
- FATAL_ERROR("FormalParList::chk_actual_parlist() "
- "Unexpected type %s", t->get_typename().c_str());
- } // switch(typetype)
- break; }
- default:
- nam = mcopystr(my_def->get_assname());
- break;
- } // switch(asstype)
-
- *nam &= ~('a'-'A'); // Make the first letter uppercase
- p_paps->get_tis()->error("%s `%s' has no formal parameter `%s'",
- nam,
- my_def->get_fullname().c_str(),
- np->get_name()->get_dispname().c_str());
- Free(nam);
+ char * nam = 0;
+ switch (my_def->get_asstype()) {
+ case Common::Assignment::A_TYPE: {
+ Type *t = my_def->get_Type();
+
+ switch (t ? t->get_typetype() : 0) {
+ case Type::T_FUNCTION:
+ nam = mcopystr("Function reference");
+ break;
+ case Type::T_ALTSTEP:
+ nam = mcopystr("Altstep reference");
+ break;
+ case Type::T_TESTCASE:
+ nam = mcopystr("Testcase reference");
+ break;
+ default:
+ FATAL_ERROR("FormalParList::chk_actual_parlist() "
+ "Unexpected type %s", t->get_typename().c_str());
+ } // switch(typetype)
+ break; }
+ default:
+ nam = mcopystr(my_def->get_assname());
+ break;
+ } // switch(asstype)
+
+ *nam &= ~('a'-'A'); // Make the first letter uppercase
+ p_paps->get_tis()->error("%s `%s' has no formal parameter `%s'",
+ nam,
+ my_def->get_fullname().c_str(),
+ np->get_name()->get_dispname().c_str());
+ Free(nam);
}
delete np;
}
// the formal parameter for the current actual parameter
FormalPar *fp = pars_v[i];
Error_Context cntxt(ti, "In parameter #%lu for `%s'",
- (unsigned long) (i + 1), fp->get_id().get_dispname().c_str());
+ (unsigned long) (i + 1), fp->get_id().get_dispname().c_str());
if (!ti->get_Type() && !ti->get_DerivedRef() && ti->get_Template()
- ->get_templatetype() == Template::TEMPLATE_NOTUSED) {
- if (fp->has_defval()) {
- ActualPar *defval = fp->get_defval();
- p_aplist->add(new ActualPar(defval));
- if (defval->is_erroneous()) error_flag = true;
- } else {
- ti->error("Not used symbol (`-') cannot be used for parameter "
- "that does not have default value");
- p_aplist->add(new ActualPar());
- error_flag = true;
- }
+ ->get_templatetype() == Template::TEMPLATE_NOTUSED) {
+ if (fp->has_defval()) {
+ ActualPar *defval = fp->get_defval();
+ p_aplist->add(new ActualPar(defval));
+ if (defval->is_erroneous()) error_flag = true;
+ } else {
+ ti->error("Not used symbol (`-') cannot be used for parameter "
+ "that does not have default value");
+ p_aplist->add(new ActualPar());
+ error_flag = true;
+ }
} else if (!ti->get_Type() && !ti->get_DerivedRef() && ti->get_Template()
- ->get_templatetype() == Template::TEMPLATE_ERROR) {
- ti->error("Parameter not specified");
+ ->get_templatetype() == Template::TEMPLATE_ERROR) {
+ ti->error("Parameter not specified");
} else {
ActualPar *ap = fp->chk_actual_par(ti, Type::EXPECTED_DYNAMIC_VALUE);
p_aplist->add(ap);
for (size_t i = upper_limit; i < formal_pars; i++) {
FormalPar *fp = pars_v[i];
if (fp->has_defval()) {
- ActualPar *defval = fp->get_defval();
+ ActualPar *defval = fp->get_defval();
p_aplist->add(new ActualPar(defval));
if (defval->is_erroneous()) error_flag = true;
} else {
case Common::Assignment::A_VAR:
case Common::Assignment::A_VAR_TEMPLATE:
case Common::Assignment::A_TIMER:
- // it is not allowed to pass references of local variables or timers
- if (t_par_ass->is_local()) {
- t_ref->error("Parameter #%lu of %s refers to %s, which is a local "
- "definition within a statement block and may have shorter "
- "lifespan than the activated default. Only references to "
- "variables and timers defined in the component type can be passed "
- "to activated defaults", (unsigned long) (i + 1), p_description,
- t_par_ass->get_description().c_str());
- ret_val = false;
- }
- break;
+ // it is not allowed to pass references of local variables or timers
+ if (t_par_ass->is_local()) {
+ t_ref->error("Parameter #%lu of %s refers to %s, which is a local "
+ "definition within a statement block and may have shorter "
+ "lifespan than the activated default. Only references to "
+ "variables and timers defined in the component type can be passed "
+ "to activated defaults", (unsigned long) (i + 1), p_description,
+ t_par_ass->get_description().c_str());
+ ret_val = false;
+ }
+ break;
case Common::Assignment::A_PAR_VAL_IN:
case Common::Assignment::A_PAR_VAL_OUT:
case Common::Assignment::A_PAR_VAL_INOUT:
case Common::Assignment::A_PAR_TEMPL_OUT:
case Common::Assignment::A_PAR_TEMPL_INOUT:
case Common::Assignment::A_PAR_TIMER: {
- // it is not allowed to pass references pointing to formal parameters
- // except for activate() statements within testcases
- // note: all defaults are deactivated at the end of the testcase
- FormalPar *t_refd_fp = dynamic_cast<FormalPar*>(t_par_ass);
- if (!t_refd_fp) FATAL_ERROR("FormalParList::chk_activate_argument()");
- FormalParList *t_fpl = t_refd_fp->get_my_parlist();
- if (!t_fpl || !t_fpl->my_def)
- FATAL_ERROR("FormalParList::chk_activate_argument()");
- if (t_fpl->my_def->get_asstype() != Common::Assignment::A_TESTCASE) {
+ // it is not allowed to pass references pointing to formal parameters
+ // except for activate() statements within testcases
+ // note: all defaults are deactivated at the end of the testcase
+ FormalPar *t_refd_fp = dynamic_cast<FormalPar*>(t_par_ass);
+ if (!t_refd_fp) FATAL_ERROR("FormalParList::chk_activate_argument()");
+ FormalParList *t_fpl = t_refd_fp->get_my_parlist();
+ if (!t_fpl || !t_fpl->my_def)
+ FATAL_ERROR("FormalParList::chk_activate_argument()");
+ if (t_fpl->my_def->get_asstype() != Common::Assignment::A_TESTCASE) {
t_ref->error("Parameter #%lu of %s refers to %s, which may have "
- "shorter lifespan than the activated default. Only references to "
- "variables and timers defined in the component type can be passed "
- "to activated defaults", (unsigned long) (i + 1), p_description,
- t_par_ass->get_description().c_str());
+ "shorter lifespan than the activated default. Only references to "
+ "variables and timers defined in the component type can be passed "
+ "to activated defaults", (unsigned long) (i + 1), p_description,
+ t_par_ass->get_description().c_str());
ret_val = false;
- } }
+ } }
default:
- break;
+ break;
}
}
return ret_val;
}
- char *FormalParList::generate_code(char *str)
+ char *FormalParList::generate_code(char *str, size_t display_unused /* = 0 */)
{
for (size_t i = 0; i < pars_v.size(); i++) {
if (i > 0) str = mputstr(str, ", ");
- str = pars_v[i]->generate_code_fpar(str);
+ str = pars_v[i]->generate_code_fpar(str, i < display_unused);
+ }
+ return str;
+ }
+
+ char* FormalParList::generate_code_defval(char* str)
+ {
+ for (size_t i = 0; i < pars_v.size(); i++) {
+ str = pars_v[i]->generate_code_defval(str);
}
return str;
}
void FormalParList::generate_code_defval(output_struct *target)
{
- for (size_t i = 0; i < pars_v.size(); i++)
+ for (size_t i = 0; i < pars_v.size(); i++) {
pars_v[i]->generate_code_defval(target);
+ }
}
char *FormalParList::generate_code_actual_parlist(char *str,
LazyParamData::init(used_as_lvalue);
LazyParamData::generate_code(expr, val, my_scope);
LazyParamData::clean();
+ if (val->get_valuetype() == Value::V_REFD) {
+ // check if the reference is a parameter, mark it as used if it is
+ Reference* ref = dynamic_cast<Reference*>(val->get_reference());
+ if (ref != NULL) {
+ ref->refd_param_usage_found();
+ }
+ }
} else {
if (copy_needed) expr->expr = mputprintf(expr->expr, "%s(",
val->get_my_governor()->get_genname_value(my_scope).c_str());
LazyParamData::init(used_as_lvalue);
LazyParamData::generate_code(expr, temp, gen_restriction_check, my_scope);
LazyParamData::clean();
+ if (temp->get_DerivedRef() != NULL ||
+ temp->get_Template()->get_templatetype() == Template::TEMPLATE_REFD) {
+ // check if the reference is a parameter, mark it as used if it is
+ Reference* ref = dynamic_cast<Reference*>(temp->get_DerivedRef() != NULL ?
+ temp->get_DerivedRef() : temp->get_Template()->get_reference());
+ if (ref != NULL) {
+ ref->refd_param_usage_found();
+ }
+ }
} else {
if (copy_needed)
expr->expr = mputprintf(expr->expr, "%s(", temp->get_Template()
}
}
- char *ActualPar::rearrange_init_code(char *str, bool is_local)
+ char *ActualPar::rearrange_init_code(char *str, Common::Module* usage_mod)
{
switch (selection) {
case AP_VALUE:
str = val->rearrange_init_code(str);
break;
case AP_TEMPLATE:
- str = temp->rearrange_init_code(str);
+ str = temp->rearrange_init_code(str, usage_mod);
case AP_REF:
break;
case AP_DEFAULT:
- if (is_local) str = act->rearrange_init_code_defval(str);
+ str = act->rearrange_init_code_defval(str, usage_mod);
break;
default:
FATAL_ERROR("ActualPar::rearrange_init_code()");
return str;
}
- char *ActualPar::rearrange_init_code_defval(char *str)
+ char *ActualPar::rearrange_init_code_defval(char *str, Common::Module* usage_mod)
{
switch (selection) {
case AP_VALUE:
- str = val->generate_code_init(str, val->get_lhs_name().c_str());
+ if (val->get_my_scope()->get_scope_mod_gen() == usage_mod) {
+ str = val->generate_code_init(str, val->get_lhs_name().c_str());
+ }
break;
case AP_TEMPLATE: {
- str = temp->rearrange_init_code(str);
- Ref_base *dref = temp->get_DerivedRef();
+ str = temp->rearrange_init_code(str, usage_mod);
Template *t = temp->get_Template();
- if (dref) {
- expression_struct expr;
- Code::init_expr(&expr);
- expr.expr = mputprintf(expr.expr, "%s = ", t->get_lhs_name().c_str());
- dref->generate_code(&expr);
- str = Code::merge_free_expr(str, &expr, false);
+ if (t->get_my_scope()->get_scope_mod_gen() == usage_mod) {
+ Ref_base *dref = temp->get_DerivedRef();
+ if (dref) {
+ expression_struct expr;
+ Code::init_expr(&expr);
+ expr.expr = mputprintf(expr.expr, "%s = ", t->get_lhs_name().c_str());
+ dref->generate_code(&expr);
+ str = Code::merge_free_expr(str, &expr, false);
+ }
+ str = t->generate_code_init(str, t->get_lhs_name().c_str());
}
- str = t->generate_code_init(str, t->get_lhs_name().c_str());
break; }
default:
FATAL_ERROR("ActualPar::rearrange_init_code_defval()");
size_t nof_pars = params.size();
for(size_t i = 0; i < nof_pars; i++)
params[i]->set_fullname(p_fullname +
- ".<parameter" + Int2string(i + 1) + ">");
+ ".<parameter" + Int2string(i + 1) + ">");
}
void ActualParList::set_my_scope(Scope *p_scope)
for (size_t i = 0; i < nof_pars; i++) {
ActualPar *par = params[i];
if (par->get_selection() == ActualPar::AP_DEFAULT)
- par = par->get_ActualPar();
+ par = par->get_ActualPar();
if (par->get_selection() == ActualPar::AP_REF) {
- Common::Assignment *ass = par->get_Ref()->get_refd_assignment();
- switch (ass->get_asstype()) {
- case Common::Assignment::A_VAR:
- case Common::Assignment::A_PAR_VAL_IN:
- case Common::Assignment::A_PAR_VAL_OUT:
- case Common::Assignment::A_PAR_VAL_INOUT:
- if (!value_refs.has_key(ass)) value_refs.add(ass, 0);
- break;
- case Common::Assignment::A_VAR_TEMPLATE:
- case Common::Assignment::A_PAR_TEMPL_IN:
- case Common::Assignment::A_PAR_TEMPL_OUT:
- case Common::Assignment::A_PAR_TEMPL_INOUT:
- if (!template_refs.has_key(ass)) template_refs.add(ass, 0);
- default:
- break;
- }
+ Common::Assignment *ass = par->get_Ref()->get_refd_assignment();
+ switch (ass->get_asstype()) {
+ case Common::Assignment::A_VAR:
+ case Common::Assignment::A_PAR_VAL_IN:
+ case Common::Assignment::A_PAR_VAL_OUT:
+ case Common::Assignment::A_PAR_VAL_INOUT:
+ if (!value_refs.has_key(ass)) value_refs.add(ass, 0);
+ break;
+ case Common::Assignment::A_VAR_TEMPLATE:
+ case Common::Assignment::A_PAR_TEMPL_IN:
+ case Common::Assignment::A_PAR_TEMPL_OUT:
+ case Common::Assignment::A_PAR_TEMPL_INOUT:
+ if (!template_refs.has_key(ass)) template_refs.add(ass, 0);
+ default:
+ break;
+ }
}
}
// walk through the parameter list and generate the code
// the copy constructor call is not needed if the parameter is copied
// into a shadow object in the body of the called function
if (!p_fpl || !p_fpl->get_fp_byIndex(i)->get_used_as_lvalue()) {
- switch (par->get_selection()) {
- case ActualPar::AP_VALUE: {
- Value *v = par->get_Value();
- if (v->get_valuetype() == Value::V_REFD) {
- Common::Assignment *t_ass =
- v->get_reference()->get_refd_assignment();
- if (value_refs.has_key(t_ass)) {
- // a reference to the same variable is also passed to the called
- // definition
- copy_needed = true;
- } else if (p_comptype || p_compself) {
- // the called definition has a 'runs on' clause so it can access
- // component variables
- switch (t_ass->get_asstype()) {
- case Common::Assignment::A_PAR_VAL_OUT:
- case Common::Assignment::A_PAR_VAL_INOUT:
- // the parameter may be an alias of a component variable
- copy_needed = true;
- break;
- case Common::Assignment::A_VAR:
- // copy is needed if t_ass is a component variable that is
- // visible by the called definition
- if (!t_ass->is_local()) copy_needed = true;
- /** \todo component type compatibility: check whether t_ass is
- * visible from p_comptype (otherwise copy is not needed) */
- default:
- break;
- }
- }
- }
- break; }
- case ActualPar::AP_TEMPLATE: {
- TemplateInstance *ti = par->get_TemplateInstance();
- if (!ti->get_DerivedRef()) {
- Template *t = ti->get_Template();
- if (t->get_templatetype() == Template::TEMPLATE_REFD) {
- Common::Assignment *t_ass =
- t->get_reference()->get_refd_assignment();
- if (template_refs.has_key(t_ass)) {
- // a reference to the same variable is also passed to the called
- // definition
- copy_needed = true;
- } else if (p_comptype || p_compself) {
- // the called definition has a 'runs on' clause so it can access
- // component variables
- switch (t_ass->get_asstype()) {
- case Common::Assignment::A_PAR_TEMPL_OUT:
- case Common::Assignment::A_PAR_TEMPL_INOUT:
- // the parameter may be an alias of a component variable
- copy_needed = true;
- break;
- case Common::Assignment::A_VAR_TEMPLATE:
- // copy is needed if t_ass is a component variable that is
- // visible by the called definition
- if (!t_ass->is_local()) copy_needed = true;
- /** \todo component type compatibility: check whether t_ass is
- * visible from p_comptype (otherwise copy is not needed) */
- default:
- break;
- }
- }
- }
- } }
- default:
- break;
- }
+ switch (par->get_selection()) {
+ case ActualPar::AP_VALUE: {
+ Value *v = par->get_Value();
+ if (v->get_valuetype() == Value::V_REFD) {
+ Common::Assignment *t_ass =
+ v->get_reference()->get_refd_assignment();
+ if (value_refs.has_key(t_ass)) {
+ // a reference to the same variable is also passed to the called
+ // definition
+ copy_needed = true;
+ } else if (p_comptype || p_compself) {
+ // the called definition has a 'runs on' clause so it can access
+ // component variables
+ switch (t_ass->get_asstype()) {
+ case Common::Assignment::A_PAR_VAL_OUT:
+ case Common::Assignment::A_PAR_VAL_INOUT:
+ // the parameter may be an alias of a component variable
+ copy_needed = true;
+ break;
+ case Common::Assignment::A_VAR:
+ // copy is needed if t_ass is a component variable that is
+ // visible by the called definition
+ if (!t_ass->is_local()) copy_needed = true;
+ /** \todo component type compatibility: check whether t_ass is
+ * visible from p_comptype (otherwise copy is not needed) */
+ default:
+ break;
+ }
+ }
+ }
+ break; }
+ case ActualPar::AP_TEMPLATE: {
+ TemplateInstance *ti = par->get_TemplateInstance();
+ if (!ti->get_DerivedRef()) {
+ Template *t = ti->get_Template();
+ if (t->get_templatetype() == Template::TEMPLATE_REFD) {
+ Common::Assignment *t_ass =
+ t->get_reference()->get_refd_assignment();
+ if (template_refs.has_key(t_ass)) {
+ // a reference to the same variable is also passed to the called
+ // definition
+ copy_needed = true;
+ } else if (p_comptype || p_compself) {
+ // the called definition has a 'runs on' clause so it can access
+ // component variables
+ switch (t_ass->get_asstype()) {
+ case Common::Assignment::A_PAR_TEMPL_OUT:
+ case Common::Assignment::A_PAR_TEMPL_INOUT:
+ // the parameter may be an alias of a component variable
+ copy_needed = true;
+ break;
+ case Common::Assignment::A_VAR_TEMPLATE:
+ // copy is needed if t_ass is a component variable that is
+ // visible by the called definition
+ if (!t_ass->is_local()) copy_needed = true;
+ /** \todo component type compatibility: check whether t_ass is
+ * visible from p_comptype (otherwise copy is not needed) */
+ default:
+ break;
+ }
+ }
+ }
+ } }
+ default:
+ break;
+ }
}
if (use_runtime_2 && ActualPar::AP_REF == par->get_selection()) {
}
// let the array object know that the index is referenced before
// calling the function, and let it know that it's now longer
- // referenced after the function call
+ // referenced after the function call (this is done with the help
+ // of the RefdIndexHandler's constructor and destructor)
+ string tmp_id = ref->get_my_scope()->get_scope_mod_gen()->get_temporary_id();
expr->preamble = mputprintf(expr->preamble,
- "%s.add_refd_index(%s);\n",
- array_expr.expr, index_expr.expr);
- expr->postamble = mputprintf(expr->postamble,
- "%s.remove_refd_index(%s);\n",
- array_expr.expr, index_expr.expr);
+ "RefdIndexHandler %s(&%s, %s);\n",
+ tmp_id.c_str(), array_expr.expr, index_expr.expr);
// insert any postambles the array object or the index might have
if (array_expr.postamble != NULL) {
expr->preamble = mputstr(expr->preamble, array_expr.postamble);
template_refs.clear();
}
- char *ActualParList::rearrange_init_code(char *str, bool is_local)
+ char *ActualParList::rearrange_init_code(char *str, Common::Module* usage_mod)
{
for (size_t i = 0; i < params.size(); i++)
- str = params[i]->rearrange_init_code(str, is_local);
+ str = params[i]->rearrange_init_code(str, usage_mod);
return str;
}