Commit b674ff14 authored by Aron Simon's avatar Aron Simon
Browse files

feat(compiler2): 16.1.4 Invoking function from specific places



Change-Id: I26881e00cffd8d87d6e74c64dee6c17a99f998e0
Signed-off-by: default avatarAron Simon <aron.simon@sigmatechnology.se>
parent d6a11d06
......@@ -30,6 +30,7 @@
******************************************************************************/
#include "../common/dbgnew.hh"
#include "Value.hh"
#include "AST.hh"
#include "Identifier.hh"
#include "Valuestuff.hh"
#include "PredefFunc.hh"
......@@ -410,6 +411,285 @@ namespace Common {
} // switch
}
 
void Value::chk_expr_immutability() {
switch (valuetype) {
case V_REFD: {/**< referenced */
int asstype = get_reference()->get_refd_assignment()->get_asstype();
switch (asstype) {
case Assignment::A_TYPE: /**< type */
case Assignment::A_CONST: /**< value (const) */
case Assignment::A_UNDEF: /**< undefined/undecided (ASN.1) */
case Assignment::A_ERROR: /**< erroneous; the kind cannot be deduced (ASN.1) */
case Assignment::A_OC: /**< information object class (ASN.1) */
case Assignment::A_OBJECT: /**< information object (ASN.1) */
case Assignment::A_OS: /**< information object set (ASN.1) */
case Assignment::A_VS: /**< value set (ASN.1) */
case Assignment::A_EXT_CONST: /**< external constant (TTCN-3) */
case Assignment::A_MODULEPAR: /**< module parameter (TTCN-3) */
case Assignment::A_MODULEPAR_TEMP: /**< template module parameter */
case Assignment::A_VAR: /**< variable (TTCN-3) */
case Assignment::A_VAR_TEMPLATE: /**< template variable: dynamic template (TTCN-3) */
case Assignment::A_TIMER: /**< timer (TTCN-3) */
case Assignment::A_PORT: /**< port (TTCN-3) */
case Assignment::A_ALTSTEP: /**< altstep (TTCN-3) */
case Assignment::A_TESTCASE: /**< testcase Assignment::(TTCN-3) */
case Assignment::A_PAR_TIMER: /**< formal parameter (timer) (TTCN-3) */
case Assignment::A_PAR_PORT: /**< formal parameter (port) (TTCN-3) */
break;
case Assignment::A_TEMPLATE:
if(get_reference()->get_parlist())
get_reference()->get_parlist()->chk_immutability();
break;
case Assignment::A_FUNCTION: /**< function without return type (TTCN-3) */
case Assignment::A_FUNCTION_RVAL: /**< function that returns a value (TTCN-3) */
case Assignment::A_FUNCTION_RTEMP: /**< function that returns a template (TTCN-3) */
case Assignment::A_EXT_FUNCTION: /**< external function without return type (TTCN-3) */
case Assignment::A_EXT_FUNCTION_RVAL: /**< ext. func that returns a value (TTCN-3) */
case Assignment::A_EXT_FUNCTION_RTEMP: /**< ext. func that returns a template (TTCN-3) */
warning("Function invocation '%s' may change the actual snapshot.",
get_reference()->get_dispname().c_str());
break;
case Assignment::A_PAR_VAL: /**< formal parameter (value) (TTCN-3) */
case Assignment::A_PAR_VAL_IN: /**< formal parameter (in value) (TTCN-3) */
case Assignment::A_PAR_VAL_OUT: /**< formal parameter (out value) (TTCN-3) */
// TODO: @fuzzy INOUT parameter is not valid
case Assignment::A_PAR_VAL_INOUT: /**< formal parameter (inout value) (TTCN-3) */
case Assignment::A_PAR_TEMPL_IN: /**< formal parameter ([in] template) (TTCN-3) */
case Assignment::A_PAR_TEMPL_OUT: /**< formal parameter (out template) (TTCN-3) */
case Assignment::A_PAR_TEMPL_INOUT:/**< formal parameter (inout template) (TTCN-3) */
if (get_reference()->get_refd_assignment()->get_eval_type() == FUZZY_EVAL)
warning("Fuzzy parameter '%s' may change (during) the actual snapshot.",
get_reference()->get_dispname().c_str());
break;
default:
FATAL_ERROR("Value::chk_expr_immutability()");
}
break;}
case V_EXPR: /**< expressions */
switch (u.expr.v_optype) {
case OPTYPE_TESTCASENAME: // -
break;
case OPTYPE_RND: // -
case OPTYPE_RNDWITHVAL: /** \todo -> SEED */ // v1
warning("Random number generation 'rnd()' change the actual snapshot.");
break;
case OPTYPE_UNARYPLUS: // v1
case OPTYPE_UNARYMINUS: // v1
case OPTYPE_NOT: // v1
case OPTYPE_NOT4B: // v1
case OPTYPE_BIT2HEX: // v1 6
case OPTYPE_BIT2INT: // v1
case OPTYPE_BIT2OCT: // v1
case OPTYPE_BIT2STR: // v1
case OPTYPE_CHAR2INT: // v1 10
case OPTYPE_CHAR2OCT: // v1
case OPTYPE_FLOAT2INT: // v1
case OPTYPE_FLOAT2STR: // v1
case OPTYPE_HEX2BIT: // v1
case OPTYPE_HEX2INT: // v1
case OPTYPE_HEX2OCT: // v1
case OPTYPE_HEX2STR: // v1
case OPTYPE_INT2CHAR: // v1
case OPTYPE_INT2FLOAT: // v1
case OPTYPE_INT2STR: // v1 20
case OPTYPE_INT2UNICHAR: // v1
case OPTYPE_OCT2BIT: // v1
case OPTYPE_OCT2CHAR: // v1
case OPTYPE_OCT2HEX: // v1
case OPTYPE_OCT2INT: // v1
case OPTYPE_OCT2STR: // v1
case OPTYPE_STR2BIT: // v1
case OPTYPE_STR2FLOAT: // v1
case OPTYPE_STR2HEX: // v1
case OPTYPE_STR2INT: // v1 30
case OPTYPE_STR2OCT: // v1
case OPTYPE_UNICHAR2INT: // v1
case OPTYPE_UNICHAR2CHAR: // v1
case OPTYPE_ENUM2INT: // v1
case OPTYPE_REMOVE_BOM: //v1
case OPTYPE_GET_STRINGENCODING: //v1
case OPTYPE_DECODE_BASE64: //v1
case OPTYPE_CBOR2JSON: // v1
case OPTYPE_JSON2CBOR: // v1
case OPTYPE_BSON2JSON: // v1
case OPTYPE_JSON2BSON: // v1
u.expr.v1->chk_expr_immutability();
break;
case OPTYPE_UNICHAR2OCT: // v1 [v2]
case OPTYPE_OCT2UNICHAR: // v1 [v2]
case OPTYPE_ENCODE_BASE64: //v1 [v2]
u.expr.v1->chk_expr_immutability();
if (u.expr.v2) u.expr.v2->chk_expr_immutability();
break;
case OPTYPE_ADD: // v1 v2
case OPTYPE_SUBTRACT: // v1 v2
case OPTYPE_MULTIPLY: // v1 v2
case OPTYPE_DIVIDE: // v1 v2 40
case OPTYPE_MOD: // v1 v2
case OPTYPE_REM: // v1 v2
case OPTYPE_CONCAT: // v1 v2
case OPTYPE_EQ: // v1 v2 ==
case OPTYPE_LT: // v1 v2 <
case OPTYPE_GT: // v1 v2 >
case OPTYPE_NE: // v1 v2 !=
case OPTYPE_GE: // v1 v2 >=
case OPTYPE_LE: // v1 v2 <=
case OPTYPE_AND: // v1 v2 50
case OPTYPE_OR: // v1 v2
case OPTYPE_XOR: // v1 v2
case OPTYPE_AND4B: // v1 v2
case OPTYPE_OR4B: // v1 v2
case OPTYPE_XOR4B: // v1 v2
case OPTYPE_SHL: // v1 v2
case OPTYPE_SHR: // v1 v2
case OPTYPE_ROTL: // v1 v2
case OPTYPE_ROTR: // v1 v2
case OPTYPE_INT2BIT: // v1 v2 60
case OPTYPE_INT2HEX: // v1 v2
case OPTYPE_INT2OCT: // v1 v2
u.expr.v1->chk_expr_immutability();
u.expr.v2->chk_expr_immutability();
break;
case OPTYPE_ENCODE: // ti1 [v2] [v3] 35
case OPTYPE_DECODE: // r1 r2 [v3] [v4]
// not yet done.
break;
case OPTYPE_SUBSTR:
u.expr.ti1->chk_immutability();
u.expr.v2->chk_expr_immutability();
u.expr.v3->chk_expr_immutability();
break;
case OPTYPE_REGEXP:
u.expr.ti1->chk_immutability();
u.expr.t2->chk_immutability();
u.expr.v3->chk_expr_immutability();
break;
case OPTYPE_DECOMP: // not implemented (reference guide)
u.expr.v1->chk_expr_immutability();
u.expr.v2->chk_expr_immutability();
u.expr.v3->chk_expr_immutability();
break;
case OPTYPE_REPLACE: // ti1 v2 v3 ti4
u.expr.ti1->chk_immutability();
u.expr.v2->chk_expr_immutability();
u.expr.v3->chk_expr_immutability();
u.expr.ti4->chk_immutability();
break;
case OPTYPE_ISVALUE: // ti1 68
case OPTYPE_ISBOUND: // ti1
case OPTYPE_ISPRESENT: // ti1
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_TTCN2STRING: // ti1
u.expr.ti1->chk_immutability();
break;
case OPTYPE_ISCHOSEN: // r1 i2
break;
case OPTYPE_ISCHOSEN_V: // v1 i2
u.expr.v1->chk_expr_immutability();
break;
case OPTYPE_ISCHOSEN_T: // t1 i2
u.expr.t1->chk_immutability();
break;
case OPTYPE_MATCH: // v1 t2
u.expr.v1->chk_expr_immutability();
u.expr.t2->chk_immutability();
break;
case OPTYPE_UNDEF_RUNNING:
case OPTYPE_COMP_NULL:
case OPTYPE_COMP_MTC:
case OPTYPE_COMP_SYSTEM:
case OPTYPE_COMP_SELF:
case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
break;
case OPTYPE_COMP_RUNNING: // v1 [r2] b4
case OPTYPE_COMP_RUNNING_ANY: // -
case OPTYPE_COMP_RUNNING_ALL: // -
case OPTYPE_COMP_ALIVE: // v1
case OPTYPE_COMP_ALIVE_ANY: // -
case OPTYPE_COMP_ALIVE_ALL: // -
warning("State of component(s) may change during the actual snapshot.");
break;
case OPTYPE_TMR_READ: // r1 90
case OPTYPE_TMR_RUNNING: // r1 [r2] b4
case OPTYPE_TMR_RUNNING_ANY: // -
warning("State of timer(s) may change during the actual snapshot.");
break;
case OPTYPE_GETVERDICT: // -
case OPTYPE_ACTIVATE: // r1
case OPTYPE_ACTIVATE_REFD: //v1 t_list2
case OPTYPE_EXECUTE: // r1 [v2]
case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
case OPTYPE_LOG2STR: // logargs
case OPTYPE_PROF_RUNNING: // - 99
case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2] [v3] [v4]
case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3] [v4] [v5]
case OPTYPE_GET_PORT_REF: // -optypes
case OPTYPE_ANY2UNISTR: // logarg: length = 1
break;
case OPTYPE_CHECKSTATE_ANY: // [r1] v2: port or any
case OPTYPE_CHECKSTATE_ALL: // [r1] v2: port or all
u.expr.v2->chk_expr_immutability();
break;
case OPTYPE_HOSTID: // [v1]
if (u.expr.v1) u.expr.v1->chk_expr_immutability();
break;
case OPTYPE_ISTEMPLATEKIND: // ti1 v2
u.expr.v2->chk_expr_immutability();
u.expr.ti1->chk_immutability();
break;
default:
FATAL_ERROR("Value::chk_expr_immutability()");
}
break;
case V_ERROR: /**< erroneous */
case V_UNDEF_LOWERID: /**< undefined loweridentifier */
case V_NULL: /**< NULL (for ASN.1 NULL type: also in TTCN-3) */
case V_BOOL: /**< boolean */
case V_NAMEDINT: /**< integer / named number */
case V_NAMEDBITS: /**< named bits (identifiers) */
case V_INT: /**< integer */
case V_REAL: /**< real/float */
case V_ENUM: /**< enumerated */
case V_BSTR: /**< bitstring */
case V_HSTR: /**< hexstring */
case V_OSTR: /**< octetstring */
case V_CSTR: /**< charstring */
case V_USTR: /**< universal charstring */
case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
case V_OID: /**< object identifier */
case V_ROID: /**< relative object identifier */
case V_CHOICE: /**< choice; set directly by the ASN.1 parser */
case V_SEQOF: /**< sequence (record) of */
case V_SETOF: /**< set of */
case V_ARRAY: /**< array */
case V_SEQ: /**< sequence (record) */
// TODO test?
case V_SET: /**< set */
case V_OPENTYPE: /**< open type */
case V_UNDEF_BLOCK: /**< undefined {block} */
case V_OMIT: /**< special value for optional values */
case V_VERDICT: /**< verdict */
case V_TTCN3_NULL: /**< TTCN-3 null (for component or default references) */
case V_DEFAULT_NULL: /**< null default reference */
case V_FAT_NULL: /**< null for function: altstep and testcase */
case V_MACRO: /**< macros (%%something) */
case V_NOTUSED: /**< not used symbol ('-') */
case V_FUNCTION: /**< function */
case V_ALTSTEP: /**< altstep */
case V_TESTCASE: /**< testcase */
case V_INVOKE: /**< invoke operation */
case V_REFER: /**< refer(function) */
case V_ANY_VALUE: /**< any value (?) - used by template concatenation */
case V_ANY_OR_OMIT: /**< any or omit (*) - used by template concatenation */
break;
default:
FATAL_ERROR("Value::chk_expr_immutability()");
} // switch
}
void Value::clean_up()
{
switch (valuetype) {
......
......@@ -741,6 +741,8 @@ namespace Common {
/** Checks that the value (expression) evals to a default value */
inline void chk_expr_default(Type::expected_value_t exp_val)
{ chk_expr_type(Type::T_DEFAULT, "default", exp_val); }
void chk_expr_immutability();
/** Checks that the value is (or evaluates to) a valid universal charstring
* encoding format. */
......
......@@ -10614,6 +10614,38 @@ namespace Ttcn {
params[i]->chk_recursions(refch);
}
void ActualParList::chk_immutability() {
size_t num = this->get_nof_pars();
for (size_t i = 0; i < num; ++i) {
const Ttcn::ActualPar *ap = this->get_par(i);
deeper:
switch (ap->get_selection()) {
case ActualPar::AP_ERROR:
break;
case ActualPar::AP_VALUE: ///< "in" value parameter
ap->get_Value()->chk_expr_immutability();
break;
case ActualPar::AP_TEMPLATE: ///< "in" template parameter
ap->get_TemplateInstance()->chk_immutability();
break;
case ActualPar::AP_REF: ///< out/inout value or template parameter
// TODO: test!
if(ap->get_Value())
ap->get_Value()->chk_expr_immutability();
if(ap->get_TemplateInstance())
ap->get_TemplateInstance()->chk_immutability();
break;
case ActualPar::AP_DEFAULT: { ///< created from the default value of a formal parameter
// TODO: test!
ap = ap->get_ActualPar();
goto deeper;
break;
}
// no default
} // switch actual par selection
} // next
}
void ActualParList::generate_code_noalias(expression_struct *expr, FormalParList *p_fpl)
{
size_t nof_pars = params.size();
......
......@@ -164,6 +164,8 @@ namespace Ttcn {
/** Checks the embedded recursions within the values and template
* instances of actual parameters. */
void chk_recursions(ReferenceChain& refch);
void chk_immutability();
/** Generates the C++ equivalent of the actual parameter list without
* considering any aliasing between variables and 'in' parameters. */
void generate_code_noalias(expression_struct *expr, FormalParList *p_fpl);
......
......@@ -4089,6 +4089,11 @@ error:
chk_index_redirect(port_op.r.redirect.index,
t_ass != NULL ? t_ass->get_Dimensions() : NULL, port_op.anyfrom, "port");
}
// checking deterministic
if (port_op.r.rcvpar) {
port_op.r.rcvpar->chk_immutability();
}
}
void Statement::chk_getcall()
......@@ -12749,6 +12754,7 @@ error:
if (expr) {
Error_Context cntxt(expr, "In guard expression");
expr->chk_expr_bool(Type::EXPECTED_DYNAMIC_VALUE);
expr->chk_expr_immutability();
}
{
Error_Context cntxt(stmt, "In guard operation");
......@@ -12760,6 +12766,7 @@ error:
if (expr) {
Error_Context cntxt(expr, "In guard expression");
expr->chk_expr_bool(Type::EXPECTED_DYNAMIC_VALUE);
expr->chk_expr_immutability();
}
{
Error_Context cntxt(ref, "In guard statement");
......@@ -12779,6 +12786,7 @@ error:
if (expr) {
Error_Context cntxt(expr, "In guard expression");
expr->chk_expr_bool(Type::EXPECTED_DYNAMIC_VALUE);
expr->chk_expr_immutability();
}
{
if (!invoke.t_list) return; //already_checked
......
......@@ -2474,6 +2474,94 @@ end:
}
}
void Template::chk_immutability()
{
switch (templatetype) {
case TEMPLATE_ERROR: /**< erroneous template */
case TEMPLATE_NOTUSED: /**< not used symbol (-) */
case OMIT_VALUE: /**< omit */
case ANY_VALUE: /**< any value (?) */
case ANY_OR_OMIT: /**< any or omit (*) */
case TEMPLATE_INVOKE: /** template returning invoke */
case BSTR_PATTERN: /**< bitstring pattern */
case HSTR_PATTERN: /**< hexstring pattern */
case OSTR_PATTERN: /**< octetstring pattern */
case CSTR_PATTERN: /**< character string pattern */
case USTR_PATTERN: /**< universal charstring pattern */
break;
case ALL_FROM:
u.all_from->chk_immutability();
break;
case SPECIFIC_VALUE:
u.specific_value->chk_expr_immutability();
break;
case TEMPLATE_REFD: {
Ttcn::ActualParList *aplist = get_reference()->get_parlist();
if (aplist) {
aplist->chk_immutability();
}
if (get_template_refd_last()->templatetype == TEMPLATE_REFD)
{
Assignment *formal_param_ass = get_template_refd_last()->get_reference()->get_refd_assignment();
if (formal_param_ass->get_asstype() >= Assignment::A_PAR_VAL)
if (formal_param_ass->get_asstype() <= Assignment::A_PAR_TEMPL_INOUT)
if (formal_param_ass->get_eval_type() != NORMAL_EVAL)
warning("Fuzzy parameter '%s' may change (during) the actual snapshot.",
get_reference()->get_dispname().c_str());
}
if(aplist && get_template_refd_last()->templatetype == TEMPLATE_REFD)
warning("Function invocation '%s' may change the actual snapshot.",
get_reference()->get_dispname().c_str());
break;
}
case NAMED_TEMPLATE_LIST: {
size_t nnt = get_nof_comps();
for (size_t i = 0; i < nnt; ++i)
{
Ttcn::NamedTemplate *nt = get_namedtemp_byIndex(i);
nt->get_template()->chk_immutability();
}
break;
}
case INDEXED_TEMPLATE_LIST: {
size_t nnt = get_nof_comps();
for (size_t i = 0; i < nnt; ++i)
{
Ttcn::IndexedTemplate *it = get_indexedtemp_byIndex(i);
it->get_index().get_val()->chk_expr_immutability();
it->get_template()->chk_immutability();
}
break;
}
case TEMPLATE_LIST: /**< value list notation */
case SUPERSET_MATCH: /**< superset match */
case SUBSET_MATCH: /**< subset match */
case PERMUTATION_MATCH: /**< permutation match */
case COMPLEMENTED_LIST: /**< complemented list match */
case VALUE_LIST: {
size_t num = get_nof_comps();
for (size_t i = 0; i < num; ++i) {
get_temp_byIndex(i)->chk_immutability();
}
break;
}
case VALUE_RANGE:
get_value_range()->get_min_v()->chk_expr_immutability();
get_value_range()->get_max_v()->chk_expr_immutability();
break;
case DECODE_MATCH: /**< decoded content match */
get_decode_target()->get_Template()->chk_immutability();
break;
case TEMPLATE_CONCAT:
u.concat.op1->chk_immutability();
u.concat.op2->chk_immutability();
break;
default:
FATAL_ERROR("Template::chk_immutability()");
}
}
Templates *Template::harbinger(Template *t, bool from_permutation, bool killer)
{
Templates *new_templates = new Templates;
......@@ -5676,6 +5764,57 @@ compile_time:
return needs_runtime_check;
}
void TemplateInstance::chk_immutability() const {
if (derived_reference) {
int asstype = ((Reference*)derived_reference)->get_refd_assignment()->get_asstype();
switch (asstype) {
case Assignment::A_TYPE: /**< type */
case Assignment::A_CONST: /**< value (const) */
case Assignment::A_UNDEF: /**< undefined/undecided (ASN.1) */
case Assignment::A_ERROR: /**< erroneous; the kind cannot be deduced (ASN.1) */
case Assignment::A_OC: /**< information object class (ASN.1) */
case Assignment::A_OBJECT: /**< information object (ASN.1) */
case Assignment::A_OS: /**< information object set (ASN.1) */
case Assignment::A_VS: /**< value set (ASN.1) */
case Assignment::A_EXT_CONST: /**< external constant (TTCN-3) */
case Assignment::A_MODULEPAR: /**< module parameter (TTCN-3) */
case Assignment::A_MODULEPAR_TEMP: /**< template module parameter */
case Assignment::A_VAR: /**< variable (TTCN-3) */
case Assignment::A_VAR_TEMPLATE: /**< template variable: dynamic template (TTCN-3) */
case Assignment::A_TIMER: /**< timer (TTCN-3) */
case Assignment::A_PORT: /**< port (TTCN-3) */
case Assignment::A_ALTSTEP: /**< altstep (TTCN-3) */
case Assignment::A_TESTCASE: /**< testcase Assignment::(TTCN-3) */
case Assignment::A_PAR_TIMER: /**< formal parameter (timer) (TTCN-3) */
case Assignment::A_PAR_PORT: /**< formal parameter (port) (TTCN-3) */
case Assignment::A_FUNCTION: /**< function without return type (TTCN-3) */
case Assignment::A_FUNCTION_RVAL: /**< function that returns a value (TTCN-3) */
case Assignment::A_FUNCTION_RTEMP: /**< function that returns a template (TTCN-3) */
case Assignment::A_EXT_FUNCTION: /**< external function without return type (TTCN-3) */
case Assignment::A_EXT_FUNCTION_RVAL: /**< ext. func that returns a value (TTCN-3) */
case Assignment::A_EXT_FUNCTION_RTEMP: /**< ext. func that returns a template (TTCN-3) */
break;
case Assignment::A_TEMPLATE: /**< template (TTCN-3) */
((Reference*)derived_reference)->get_parlist()->chk_immutability();
break;
case Assignment::A_PAR_VAL: /**< formal parameter (value) (TTCN-3) */
case Assignment::A_PAR_VAL_IN: /**< formal parameter (in value) (TTCN-3) */
case Assignment::A_PAR_VAL_OUT: /**< formal parameter (out value) (TTCN-3) */
case Assignment::A_PAR_VAL_INOUT: /**< formal parameter (inout value) (TTCN-3) */
case Assignment::A_PAR_TEMPL_IN: /**< formal parameter ([in] template) (TTCN-3) */
case Assignment::A_PAR_TEMPL_OUT: /**< formal parameter (out template) (TTCN-3) */
case Assignment::A_PAR_TEMPL_INOUT:/**< formal parameter (inout template) (TTCN-3) */
if (((Reference*)derived_reference)->get_refd_assignment()->get_eval_type() == FUZZY_EVAL)
warning("Fuzzy parameter '%s' may change (during) the actual snapshot.",
((Reference*)derived_reference)->get_dispname().c_str());
break;
default:
FATAL_ERROR("Value::chk_expr_immutability()");
}
}
template_body->chk_immutability();
}
bool TemplateInstance::has_single_expr()
{
if (derived_reference) return false;
......
......@@ -363,6 +363,8 @@ namespace Ttcn {
void chk_invoke();
void chk_concat_double_length_res();
void chk_immutability();
/** Copy template elements from the "all from" into the template.
*
* @param from_permutation \a true if the "all from" occurs inside
......@@ -593,6 +595,8 @@ namespace Ttcn {
bool chk_restriction(const char* definition_name,
template_restriction_t template_restriction, const Location* usage_loc);
void chk_immutability() const ;
/** Returns whether the template instance can be represented by an in-line
* C++ expression. */
bool has_single_expr();
......
/******************************************************************************
* Copyright (c) 2000-2018 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* Aron Simon
*
******************************************************************************/
module InvokingFunctionFromSpecificPlaces_SW { //^In TTCN-3 module//
modulepar boolean mp := true;
type component MTC { port P p }
type component PTC { }
type record R { integer field, boolean field2 optional }
type record SR { R field }
type union U {integer i1, integer i2}
template U TU := { i1 := 1 }
type port P message { inout R, SR, RoI, SoI }
template R T := {field := fi(), field2 := omit}
template R PT (boolean field_param) := {field := fi(), field2 := field_param}
template R PTD (boolean field_param := false) := {field := fi(), field2 := field_param}
template SR ST := {field := T}
template SR PST (template R field_param) := { field := field_param}
type record of integer RoI;
template RoI roi := {1,2,3,(4..6)}
template RoI proi (integer ip) := {1,2,3,ip}
type set of integer SoI;
function fb() return boolean { return true; }
function fi() return integer { return 1; }
function fs() return charstring { return "abcabc"; }
external function ef() return boolean;
testcase //^In testcase definition//
tc(in boolean fp,
in @fuzzy boolean ffp,
in template @fuzzy R ftfp,
in template @fuzzy U futfp,
in @fuzzy U fuvfp,