-///////////////////////////////////////////////////////////////////////////////
-// 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"
#include "../../common/version_internal.h"
#include "../CodeGenHelper.hh"
#include "../../common/JSON_Tokenizer.hh"
+#include "../DebuggerStuff.hh"
#include <limits.h>
// implemented in coding_attrib_p.y
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
}
return true;
}
+
+ void Reference::ref_usage_found()
+ {
+ Common::Assignment *ass = get_refd_assignment();
+ if (!ass) FATAL_ERROR("Reference::ref_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 == NULL) {
+ FATAL_ERROR("Reference::ref_usage_found()");
+ }
+ fpar->set_usage_found();
+ break; }
+ case Common::Assignment::A_EXT_CONST: {
+ Def_ExtConst* def = dynamic_cast<Def_ExtConst*>(ass);
+ if (def == NULL) {
+ FATAL_ERROR("Reference::ref_usage_found()");
+ }
+ def->set_usage_found();
+ break; }
+ default:
+ break;
+ }
+ }
void Reference::generate_code(expression_struct_t *expr)
{
+ ref_usage_found();
Common::Assignment *ass = get_refd_assignment();
if (!ass) FATAL_ERROR("Reference::generate_code()");
if (parlist) {
generate_code(expr);
return;
}
-
+
+ ref_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)
{
+ ref_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)
{
+ ref_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" : "");
}
}
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: {
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());
}
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;
// 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) {
module_dispname);
target->functions.control = mputprintf(target->functions.control,
"TTCN_Runtime::begin_controlpart(\"%s\");\n", module_dispname);
+ if (debugger_active) {
+ target->functions.control = mputprintf(target->functions.control,
+ "charstring_list no_params = NULL_VALUE;\n"
+ "TTCN3_Debug_Function debug_scope(NULL, \"control\", \"%s\", no_params, no_params, NULL);\n"
+ "debug_scope.initial_snapshot();\n", module_dispname);
+ }
target->functions.control =
block->generate_code(target->functions.control);
target->functions.control = mputstr(target->functions.control,
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());
}
}
}
}
+
+ void Module::generate_debugger_init(output_struct* output)
+ {
+ static boolean first = TRUE;
+ // create the initializer function
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ "\n/* Initializing the TTCN-3 debugger */\n"
+ "void init_ttcn3_debugger()\n"
+ "{\n"
+ "%s", first ? " ttcn3_debugger.activate();\n" : "");
+ first = FALSE;
+
+ // initialize global scope and variables (including imported variables)
+ char* str_glob = generate_debugger_global_vars(NULL, this);
+ for (int i = 0; i < imp->get_imports_size(); ++i) {
+ str_glob = imp->get_impmod(i)->get_mod()->generate_debugger_global_vars(str_glob, this);
+ }
+ if (str_glob != NULL) {
+ // only add the global scope if it actually has variables
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ " /* global variables */\n"
+ " TTCN3_Debug_Scope* global_scope = ttcn3_debugger.add_global_scope(\"%s\");\n"
+ "%s",
+ get_modid().get_dispname().c_str(), str_glob);
+ Free(str_glob);
+ }
+
+ // initialize components' scopes and their variables
+ for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
+ Def_Type* def = dynamic_cast<Def_Type*>(asss->get_ass_byIndex(i));
+ if (def != NULL) {
+ Type* comp_type = def->get_Type();
+ if (comp_type->get_typetype() == Type::T_COMPONENT) {
+ char* str_comp = NULL;
+ ComponentTypeBody* comp_body = comp_type->get_CompBody();
+ for (size_t j = 0; j < comp_body->get_nof_asss(); ++j) {
+ str_comp = generate_code_debugger_add_var(str_comp, comp_body->get_ass_byIndex(j),
+ this, comp_type->get_dispname().c_str());
+ }
+ if (str_comp != NULL) {
+ // only add the component if it actually has variables
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ " /* variables of component %s */\n"
+ " TTCN3_Debug_Scope* %s_scope = ttcn3_debugger.add_component_scope(\"%s\");\n"
+ "%s"
+ , comp_type->get_dispname().c_str(), comp_type->get_dispname().c_str()
+ , comp_type->get_dispname().c_str(), str_comp);
+ Free(str_comp);
+ }
+ }
+ }
+ }
+
+ // close the initializer function
+ output->source.global_vars = mputstr(output->source.global_vars, "}\n");
+ }
+
+ char* Module::generate_debugger_global_vars(char* str, Common::Module* current_mod)
+ {
+ for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
+ Common::Assignment* ass = asss->get_ass_byIndex(i);
+ switch (ass->get_asstype()) {
+ case Common::Assignment::A_TEMPLATE:
+ if (ass->get_FormalParList() != NULL) {
+ // don't add parameterized templates, since they are functions in C++
+ break;
+ }
+ // else fall through
+ case Common::Assignment::A_CONST:
+ case Common::Assignment::A_MODULEPAR:
+ case Common::Assignment::A_MODULEPAR_TEMP:
+ str = generate_code_debugger_add_var(str, ass, current_mod, "global");
+ break;
+ case Common::Assignment::A_EXT_CONST: {
+ Def_ExtConst* def = dynamic_cast<Def_ExtConst*>(ass);
+ if (def == NULL) {
+ FATAL_ERROR("Module::generate_debugger_global_vars");
+ }
+ if (def->is_used()) {
+ str = generate_code_debugger_add_var(str, ass, current_mod, "global");
+ }
+ break; }
+ default:
+ break;
+ }
+ }
+ return str;
+ }
+
+ void Module::generate_debugger_functions(output_struct *output)
+ {
+ char* print_str = NULL;
+ char* overwrite_str = NULL;
+ for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
+ Def_Type* def = dynamic_cast<Def_Type*>(asss->get_ass_byIndex(i));
+ if (def != NULL) {
+ Type* t = def->get_Type();
+ if (!t->is_ref() && t->get_typetype() != Type::T_COMPONENT) {
+ // don't generate code for subtypes
+ if (t->get_typetype() != Type::T_SIGNATURE) {
+ print_str = mputprintf(print_str,
+ " %sif (!strcmp(p_var.type_name, \"%s\")) {\n"
+ " ((const %s*)ptr)->log();\n"
+ " }\n"
+ , (print_str != NULL) ? "else " : ""
+ , t->get_dispname().c_str(), t->get_genname_value(this).c_str());
+ if (t->get_typetype() != Type::T_PORT) {
+ overwrite_str = mputprintf(overwrite_str,
+ " %sif (!strcmp(p_var.type_name, \"%s\")) {\n"
+ " ((%s*)p_var.value)->set_param(p_new_value);\n"
+ " }\n"
+ , (overwrite_str != NULL) ? "else " : ""
+ , t->get_dispname().c_str(), t->get_genname_value(this).c_str());
+ }
+ }
+ if (t->get_typetype() != Type::T_PORT) {
+ print_str = mputprintf(print_str,
+ " %sif (!strcmp(p_var.type_name, \"%s template\")) {\n"
+ " ((const %s_template*)ptr)->log();\n"
+ " }\n"
+ , (print_str != NULL) ? "else " : ""
+ , t->get_dispname().c_str(), t->get_genname_value(this).c_str());
+ if (t->get_typetype() != Type::T_SIGNATURE) {
+ overwrite_str = mputprintf(overwrite_str,
+ " %sif (!strcmp(p_var.type_name, \"%s template\")) {\n"
+ " ((%s_template*)p_var.value)->set_param(p_new_value);\n"
+ " }\n"
+ , (overwrite_str != NULL) ? "else " : ""
+ , t->get_dispname().c_str(), t->get_genname_value(this).c_str());
+ }
+ }
+ }
+ }
+ }
+ if (print_str != NULL) {
+ // don't generate an empty printing function
+ output->header.class_defs = mputprintf(output->header.class_defs,
+ "/* Debugger printing and overwriting functions for types declared in this module */\n\n"
+ "extern CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var);\n",
+ get_modid().get_ttcnname().c_str());
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ "\n/* Debugger printing function for types declared in this module */\n"
+ "CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var)\n"
+ "{\n"
+ " const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;\n"
+ " TTCN_Logger::begin_event_log2str();\n"
+ "%s"
+ " else {\n"
+ " TTCN_Logger::log_event_str(\"<unrecognized value or template>\");\n"
+ " }\n"
+ " return TTCN_Logger::end_event_log2str();\n"
+ "}\n", get_modid().get_ttcnname().c_str(), print_str);
+ }
+ if (overwrite_str != NULL) {
+ // don't generate an empty overwriting function
+ output->header.class_defs = mputprintf(output->header.class_defs,
+ "extern boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value);\n",
+ get_modid().get_ttcnname().c_str());
+ output->source.global_vars = mputprintf(output->source.global_vars,
+ "\n/* Debugger overwriting function for types declared in this module */\n"
+ "boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value)\n"
+ "{\n"
+ "%s"
+ " else {\n"
+ " return FALSE;\n"
+ " }\n"
+ " return TRUE;\n"
+ "}\n", get_modid().get_ttcnname().c_str(), overwrite_str);
+ }
+ }
// =================================
// ===== Definition
// the value is assigned using subsequent statements
str = value->generate_code_init(str, genname_str);
}
+ if (debugger_active) {
+ str = generate_code_debugger_add_var(str, this);
+ }
return str;
}
if (!p_type) FATAL_ERROR("Ttcn::Def_ExtConst::Def_ExtConst()");
type = p_type;
type->set_ownertype(Type::OT_CONST_DEF, this);
+ usage_found = false;
}
Def_ExtConst::~Def_ExtConst()
"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
"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
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++) {
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 (debugger_active) {
+ function_body = generate_code_debugger_function_init(function_body, this);
+ }
if (base_template) {
// modified template
function_body = mputprintf(function_body, "%s ret_val(%s",
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();
+ 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,
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);
+ if (debugger_active) {
+ function_body = mputstr(function_body,
+ "ttcn3_debugger.set_return_value((TTCN_Logger::begin_event_log2str(), "
+ "ret_val.log(), TTCN_Logger::end_event_log2str()));\n");
+ }
+ 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);
str = Template::generate_restriction_check_code(str, genname_str,
template_restriction);
}
+ if (debugger_active) {
+ str = generate_code_debugger_add_var(str, this);
+ }
return str;
}
str = initial_value->generate_code_init(str, genname_str);
}
}
+ if (debugger_active) {
+ str = generate_code_debugger_add_var(str, this);
+ }
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);
&& gen_restriction_check)
str = Template::generate_restriction_check_code(str, genname_str,
template_restriction);
+ if (debugger_active) {
+ str = generate_code_debugger_add_var(str, this);
+ }
return str;
}
}
}
}
+ if (debugger_active) {
+ str = generate_code_debugger_add_var(str, this);
+ }
return str;
}
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);
+ if (debugger_active) {
+ body = generate_code_debugger_function_init(body, this);
+ }
+ 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
mputprintf(target->header.function_prototypes, "extern %s %s(%s);\n",
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);
+ 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?", ":"", formal_par_list, dispname_str);
+ 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");
"} 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(),
}
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) {
- if(encoding_type == Common::Type::CT_TEXT){ // the TEXT encoding support both octetstring ans charstring stream 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(output_type)) && (!stream_type2->is_identical(output_type)) ) {
- input_type->error("The output type of %s encoding should be `%s' or `%s' "
+ 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(),
- input_type->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)) {
- input_type->error("The output type of %s encoding should be `%s' "
+ 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(),
- input_type->get_typename().c_str());
+ output_type->get_typename().c_str());
}
}
}
error("Attribute `decode' cannot be used without `prototype'");
}
if (input_type) {
- if(encoding_type == Common::Type::CT_TEXT){ // the TEXT encoding support both octetstring ans charstring stream 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 encoding should be `%s' or `%s' "
+ 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(),
} 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 encoding should be `%s' "
+ 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)) {
- output_type->error("Output type `%s' does not support %s encoding",
- output_type->get_typename().c_str(),
- Type::get_encoding_name(encoding_type));
+ 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;
"TTCN_Logger::end_event();\n"
"}\n", result_name, function_name, result_name);
// returning the result stream if necessary
- if (prototype == PROTOTYPE_CONVERT) str = mputstr(str, "return ret_val;\n");
+ if (prototype == PROTOTYPE_CONVERT) {
+ if (debugger_active) {
+ str = mputstr(str,
+ "ttcn3_debugger.set_return_value((TTCN_Logger::begin_event_log2str(), "
+ "ret_val.log(), TTCN_Logger::end_event_log2str()));\n");
+ }
+ str = mputstr(str, "return ret_val;\n");
+ }
return str;
}
"}\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");
+ if (debugger_active) {
+ str = mputstr(str, "ttcn3_debugger.set_return_value(\"0\");\n");
+ }
+ str = mputstr(str,
+ "return 0;\n"
+ "} else {\n");
+ if (debugger_active) {
+ str = mputstr(str, "ttcn3_debugger.set_return_value(\"1\");\n");
+ }
+ str = mputstr(str,
+ "return 1;\n"
+ "}\n");
} else {
str = mputstr(str, "}\n");
- if (prototype == PROTOTYPE_CONVERT)
+ if (prototype == PROTOTYPE_CONVERT) {
+ if (debugger_active) {
+ str = mputstr(str,
+ "ttcn3_debugger.set_return_value((TTCN_Logger::begin_event_log2str(), "
+ "ret_val.log(), TTCN_Logger::end_event_log2str()));\n");
+ }
str = mputstr(str, "return ret_val;\n");
+ }
}
} else {
// result handling and debug printout for sliding decoders
"%s.log();\n"
"TTCN_Logger::end_event();\n"
"}\n"
- "return 0;\n"
+ "%sreturn 0;\n"
"case TTCN_EncDec::ET_INCOMPL_MSG:\n"
"case TTCN_EncDec::ET_LEN_ERR:\n"
- "return 2;\n"
+ "%sreturn 2;\n"
"default:\n"
- "return 1;\n"
- "}\n", first_par_name, function_name, first_par_name);
+ "%sreturn 1;\n"
+ "}\n", first_par_name, function_name, first_par_name,
+ debugger_active ? "ttcn3_debugger.set_return_value(\"0\");\n" : "",
+ debugger_active ? "ttcn3_debugger.set_return_value(\"2\");\n" : "",
+ debugger_active ? "ttcn3_debugger.set_return_value(\"1\");\n" : "");
}
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 =
"%s %s(%s)\n"
"{\n"
, return_type_str, genname_str, formal_par_list);
+ if (debugger_active) {
+ body = generate_code_debugger_function_init(body, this);
+ }
switch (function_type) {
case EXTFUNC_ENCODE:
body = generate_code_encode(body);
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);
+ if (debugger_active) {
+ body = generate_code_debugger_function_init(body, this);
+ }
+ 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);
"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 =
"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,
+ "}\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,
+ " : 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 =
target->header.function_prototypes =
mputprintf(target->header.function_prototypes,
"extern Default_Base *activate_%s(%s);\n", genname_str,
- formal_par_list);
+ 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,
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, "
+ 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);
+ if (debugger_active) {
+ body = generate_code_debugger_function_init(body, this);
+ }
body = mputprintf(body, "try {\n"
"TTCN_Runtime::begin_testcase(\"%s\", \"%s\", ",
my_scope->get_scope_mod()->get_modid().get_dispname().c_str(),
"} 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) {
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");
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);
}
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:
}
}
}
-
- 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 || debugger_active ||
+ (!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) {
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->ref_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->ref_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);
+ str = val->rearrange_init_code(str, usage_mod);
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()");
temp->dump(level + 1);
break;
case AP_REF:
- DEBUG(level, "actual parameter: referecne");
+ DEBUG(level, "actual parameter: reference");
ref->dump(level + 1);
break;
case AP_DEFAULT:
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;
}