Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef _Common_Value_HH | |
9 | #define _Common_Value_HH | |
10 | ||
11 | #include "Setting.hh" | |
12 | #include "Code.hh" | |
13 | #include "Type.hh" | |
14 | #include "Int.hh" | |
15 | #include "../common/ttcn3float.hh" | |
16 | ||
17 | class ustring; | |
18 | ||
19 | namespace Asn { | |
20 | class Block; | |
21 | } | |
22 | ||
23 | namespace Ttcn { | |
24 | class Reference; | |
25 | class Ref_base; | |
26 | class TemplateInstance; | |
27 | class TemplateInstances; | |
28 | class ActualParList; | |
29 | class ActualPar; | |
30 | class ParsedActualParameters; | |
31 | class LogArguments; | |
32 | } | |
33 | ||
34 | namespace Common { | |
35 | ||
36 | // not defined here | |
37 | class OID_comp; | |
38 | class Values; | |
39 | class NamedValue; | |
40 | class NamedValues; | |
41 | class CharSyms; | |
42 | class Assignment; | |
43 | class Scope; | |
44 | ||
45 | using Asn::Block; | |
46 | using Ttcn::TemplateInstance; | |
47 | using Ttcn::LogArguments; | |
48 | ||
49 | /** | |
50 | * \ingroup AST | |
51 | * | |
52 | * \defgroup AST_Value Value | |
53 | * | |
54 | * These classes provide a unified interface for values. | |
55 | * | |
56 | * @{ | |
57 | */ | |
58 | ||
59 | /** | |
60 | * Represents a value in the AST. | |
61 | */ | |
62 | class Value : public GovernedSimple { | |
63 | public: | |
64 | /** value type */ | |
65 | ||
66 | ||
67 | ||
68 | enum valuetype_t { | |
69 | V_ERROR, /**< erroneous */ | |
70 | V_NULL, /**< NULL (for ASN.1 NULL type, also in TTCN-3) */ | |
71 | V_BOOL, /**< boolean */ | |
72 | V_NAMEDINT, /**< integer / named number */ | |
73 | V_NAMEDBITS, /**< named bits (identifiers) */ | |
74 | V_INT, /**< integer */ | |
75 | V_REAL, /**< real/float */ | |
76 | V_ENUM, /**< enumerated */ | |
77 | V_BSTR, /**< bitstring */ | |
78 | V_HSTR, /**< hexstring */ | |
79 | V_OSTR, /**< octetstring */ | |
80 | V_CSTR, /**< charstring */ | |
81 | V_USTR, /**< universal charstring */ | |
82 | V_ISO2022STR, /**< ISO-2022 string (treat as octetstring) */ | |
83 | V_CHARSYMS, /**< parsed ASN.1 universal string notation */ | |
84 | V_OID, /**< object identifier */ | |
85 | V_ROID, /**< relative object identifier */ | |
86 | V_CHOICE, /**< choice; set directly by the ASN.1 parser */ | |
87 | V_SEQOF, /**< sequence (record) of */ | |
88 | V_SETOF, /**< set of */ | |
89 | V_ARRAY, /**< array */ | |
90 | V_SEQ, /**< sequence (record) */ | |
91 | V_SET, /**< set */ | |
92 | V_OPENTYPE, /**< open type */ | |
93 | V_REFD, /**< referenced */ | |
94 | V_UNDEF_LOWERID, /**< undefined loweridentifier */ | |
95 | V_UNDEF_BLOCK, /**< undefined {block} */ | |
96 | V_OMIT, /**< special value for optional values */ | |
97 | V_VERDICT, /**< verdict */ | |
98 | V_TTCN3_NULL, /**< TTCN-3 null (for component or default references) */ | |
99 | V_DEFAULT_NULL, /**< null default reference */ | |
100 | V_FAT_NULL, /**< null for function, altstep and testcase */ | |
101 | V_EXPR, /**< expressions */ | |
102 | V_MACRO, /**< macros (%%something) */ | |
103 | V_NOTUSED, /**< not used symbol ('-') */ | |
104 | V_FUNCTION, /**< function */ | |
105 | V_ALTSTEP, /**< altstep */ | |
106 | V_TESTCASE, /**< testcase */ | |
107 | V_INVOKE, /**< invoke operation */ | |
108 | V_REFER /**< refer(function) */ | |
109 | }; | |
110 | ||
111 | enum verdict_t { | |
112 | Verdict_NONE, | |
113 | Verdict_PASS, | |
114 | Verdict_INCONC, | |
115 | Verdict_FAIL, | |
116 | Verdict_ERROR | |
117 | }; | |
118 | ||
119 | /** Operation type, for V_EXPR */ | |
120 | enum operationtype_t { | |
121 | OPTYPE_RND, // - | |
122 | OPTYPE_TESTCASENAME, // - | |
123 | ||
124 | OPTYPE_UNARYPLUS, // v1 | |
125 | OPTYPE_UNARYMINUS, // v1 | |
126 | OPTYPE_NOT, // v1 | |
127 | OPTYPE_NOT4B, // v1 | |
128 | ||
129 | OPTYPE_BIT2HEX, // v1 6 | |
130 | OPTYPE_BIT2INT, // v1 | |
131 | OPTYPE_BIT2OCT, // v1 | |
132 | OPTYPE_BIT2STR, // v1 | |
133 | OPTYPE_CHAR2INT, // v1 10 | |
134 | OPTYPE_CHAR2OCT, // v1 | |
135 | OPTYPE_FLOAT2INT, // v1 | |
136 | OPTYPE_FLOAT2STR, // v1 | |
137 | OPTYPE_HEX2BIT, // v1 | |
138 | OPTYPE_HEX2INT, // v1 | |
139 | OPTYPE_HEX2OCT, // v1 | |
140 | OPTYPE_HEX2STR, // v1 | |
141 | OPTYPE_INT2CHAR, // v1 | |
142 | OPTYPE_INT2FLOAT, // v1 | |
143 | OPTYPE_INT2STR, // v1 20 | |
144 | OPTYPE_INT2UNICHAR, // v1 | |
145 | OPTYPE_OCT2BIT, // v1 | |
146 | OPTYPE_OCT2CHAR, // v1 | |
147 | OPTYPE_OCT2HEX, // v1 | |
148 | OPTYPE_OCT2INT, // v1 | |
149 | OPTYPE_OCT2STR, // v1 | |
150 | OPTYPE_OCT2UNICHAR, // v1 [v2] | |
151 | OPTYPE_STR2BIT, // v1 | |
152 | OPTYPE_STR2FLOAT, // v1 | |
153 | OPTYPE_STR2HEX, // v1 | |
154 | OPTYPE_STR2INT, // v1 30 | |
155 | OPTYPE_STR2OCT, // v1 | |
156 | OPTYPE_UNICHAR2INT, // v1 | |
157 | OPTYPE_UNICHAR2CHAR, // v1 | |
158 | OPTYPE_UNICHAR2OCT, // v1 [v2] | |
159 | OPTYPE_ENUM2INT, // v1 | |
160 | ||
161 | OPTYPE_ENCODE, // ti1 35 | |
162 | ||
163 | OPTYPE_RNDWITHVAL, /** \todo -> SEED */ // v1 | |
164 | ||
165 | OPTYPE_ADD, // v1 v2 | |
166 | OPTYPE_SUBTRACT, // v1 v2 | |
167 | OPTYPE_MULTIPLY, // v1 v2 | |
168 | OPTYPE_DIVIDE, // v1 v2 40 | |
169 | OPTYPE_MOD, // v1 v2 | |
170 | OPTYPE_REM, // v1 v2 | |
171 | OPTYPE_CONCAT, // v1 v2 | |
172 | OPTYPE_EQ, // v1 v2 | |
173 | OPTYPE_LT, // v1 v2 | |
174 | OPTYPE_GT, // v1 v2 | |
175 | OPTYPE_NE, // v1 v2 | |
176 | OPTYPE_GE, // v1 v2 | |
177 | OPTYPE_LE, // v1 v2 | |
178 | OPTYPE_AND, // v1 v2 50 | |
179 | OPTYPE_OR, // v1 v2 | |
180 | OPTYPE_XOR, // v1 v2 | |
181 | OPTYPE_AND4B, // v1 v2 | |
182 | OPTYPE_OR4B, // v1 v2 | |
183 | OPTYPE_XOR4B, // v1 v2 | |
184 | OPTYPE_SHL, // v1 v2 | |
185 | OPTYPE_SHR, // v1 v2 | |
186 | OPTYPE_ROTL, // v1 v2 | |
187 | OPTYPE_ROTR, // v1 v2 | |
188 | ||
189 | OPTYPE_INT2BIT, // v1 v2 60 | |
190 | OPTYPE_INT2HEX, // v1 v2 | |
191 | OPTYPE_INT2OCT, // v1 v2 | |
192 | ||
193 | OPTYPE_DECODE, // r1 r2 | |
194 | ||
195 | OPTYPE_SUBSTR, // ti1 v2 v3 | |
196 | OPTYPE_REGEXP, // ti1 t2 v3 | |
197 | OPTYPE_DECOMP, // v1 v2 v3 66 | |
198 | ||
199 | OPTYPE_REPLACE, // ti1 v2 v3 ti4 | |
200 | ||
201 | OPTYPE_ISVALUE, // ti1 68 | |
202 | OPTYPE_ISBOUND, // ti1 | |
203 | OPTYPE_ISPRESENT, // ti1 | |
204 | OPTYPE_ISCHOSEN, // r1 i2 | |
205 | OPTYPE_ISCHOSEN_V, // v1 i2 | |
206 | OPTYPE_ISCHOSEN_T, // t1 i2 | |
207 | ||
208 | OPTYPE_LENGTHOF, // ti1 | |
209 | OPTYPE_SIZEOF, // ti1 | |
210 | OPTYPE_VALUEOF, // ti1 | |
211 | OPTYPE_MATCH, // v1 t2 | |
212 | ||
213 | OPTYPE_TTCN2STRING, // ti1 | |
214 | OPTYPE_REMOVE_BOM, //v1 | |
215 | OPTYPE_GET_STRINGENCODING, //v1 | |
216 | OPTYPE_ENCODE_BASE64, //v1 [v2] | |
217 | OPTYPE_DECODE_BASE64, //v1 | |
218 | ||
219 | /** cannot distinguish during parsing; can be COMP or TMR */ | |
220 | OPTYPE_UNDEF_RUNNING, // r1 78 | |
221 | OPTYPE_COMP_NULL, // - (from V_TTCN3_NULL) | |
222 | OPTYPE_COMP_MTC, // - | |
223 | OPTYPE_COMP_SYSTEM, // - | |
224 | OPTYPE_COMP_SELF, // - | |
225 | OPTYPE_COMP_CREATE, // r1 [v2] [v3] b4 | |
226 | OPTYPE_COMP_RUNNING, // v1 | |
227 | OPTYPE_COMP_RUNNING_ANY, // - | |
228 | OPTYPE_COMP_RUNNING_ALL, // - | |
229 | OPTYPE_COMP_ALIVE, // v1 | |
230 | OPTYPE_COMP_ALIVE_ANY, // - | |
231 | OPTYPE_COMP_ALIVE_ALL, // - | |
232 | OPTYPE_TMR_READ, // r1 90 | |
233 | OPTYPE_TMR_RUNNING, // r1 | |
234 | OPTYPE_TMR_RUNNING_ANY, // - | |
235 | OPTYPE_GETVERDICT, // - | |
236 | OPTYPE_ACTIVATE, // r1 | |
237 | OPTYPE_ACTIVATE_REFD, //v1 t_list2 | |
238 | OPTYPE_EXECUTE, // r1 [v2] | |
239 | OPTYPE_EXECUTE_REFD, // v1 t_list2 [v3] | |
240 | ||
241 | OPTYPE_LOG2STR, // logagrs 98 | |
242 | ||
243 | NUMBER_OF_OPTYPES // must be last | |
244 | }; | |
245 | ||
246 | enum macrotype_t { | |
247 | MACRO_MODULEID, /**< module identifier (%moduleId) */ | |
248 | MACRO_FILENAME, /**< name of input file (%fileName) */ | |
249 | MACRO_BFILENAME, /**< name of input file (__BFILE__) */ | |
250 | MACRO_FILEPATH, /**< canonical file name (name with full path) */ | |
251 | MACRO_LINENUMBER, /**< line number (%lineNumber) */ | |
252 | MACRO_LINENUMBER_C, /**< line number in C style (__LINE__) | |
253 | gives an integer value */ | |
254 | MACRO_DEFINITIONID, /**< name of (top level) definition (%definitionId) */ | |
255 | /* the following macro may be needed in future versions of titan, | |
256 | * functionality will be explained by a quick study written by Kristof | |
257 | MACRO_NOTSCOPE_NAME_BUT_THE_NAME_OF_SOMETHING_ELSE */ | |
258 | MACRO_SCOPE, | |
259 | MACRO_TESTCASEID /**< name of current testcase (%testcaseId) | |
260 | (evaluated at runtime) */ | |
261 | }; | |
262 | ||
263 | enum expr_state_t {EXPR_NOT_CHECKED, EXPR_CHECKING, | |
264 | EXPR_CHECKING_ERR, EXPR_CHECKED}; | |
265 | private: | |
266 | ||
267 | valuetype_t valuetype; | |
268 | Type *my_governor; | |
269 | union { | |
270 | bool val_bool; | |
271 | int_val_t *val_Int; | |
272 | Identifier *val_id; | |
273 | ttcn3float val_Real; | |
274 | struct { | |
275 | string *val_str; | |
276 | map<size_t, Value> *str_elements; | |
277 | } str; | |
278 | struct { | |
279 | ustring *val_ustr; | |
280 | map<size_t, Value> *ustr_elements; | |
281 | bool convert_str; /**< Indicates that universal charstring is */ | |
282 | /* initialized with charstring */ | |
283 | } ustr; | |
284 | CharSyms *char_syms; | |
285 | vector<OID_comp> *oid_comps; | |
286 | struct { | |
287 | Identifier *alt_name; /**< The name of the selected alternative */ | |
288 | Value *alt_value; /**< The value given */ | |
289 | } choice; | |
290 | Values *val_vs; | |
291 | NamedValues *val_nvs; | |
292 | struct { | |
293 | Reference *ref; | |
294 | Value *refd_last; /**< cache */ | |
295 | } ref; | |
296 | Reference *refered; | |
297 | struct { | |
298 | operationtype_t v_optype; | |
299 | expr_state_t state; | |
300 | union { | |
301 | Value *v1; | |
302 | Template *t1; | |
303 | TemplateInstance *ti1; | |
304 | Ttcn::Ref_base *r1; /**< timer or component */ | |
305 | LogArguments *logargs; /**< arguments of log2str() */ | |
306 | }; | |
307 | union { | |
308 | Value *v2; | |
309 | TemplateInstance *t2; | |
310 | Identifier *i2; | |
311 | Ttcn::ParsedActualParameters *t_list2; | |
312 | Ttcn::ActualParList *ap_list2; | |
313 | Ttcn::Ref_base *r2; | |
314 | }; | |
315 | Value *v3; | |
316 | union { | |
317 | Value *v4; | |
318 | TemplateInstance *ti4; | |
319 | bool b4; | |
320 | }; | |
321 | } expr; | |
322 | macrotype_t macro; | |
323 | struct { | |
324 | Value *v; | |
325 | Ttcn::ParsedActualParameters *t_list; | |
326 | Ttcn::ActualParList *ap_list; | |
327 | } invoke; | |
328 | map<string, Identifier> *ids; | |
329 | Block *block; | |
330 | verdict_t verdict; | |
331 | Common::Assignment *refd_fat; /** function, altstep, testcase */ | |
332 | } u; | |
333 | ||
334 | /** Used to avoid infinite recursions of is_unfoldable() */ | |
335 | class UnfoldabilityCheck { | |
336 | static map<Value*, void> running; | |
337 | Value* value; | |
338 | public: | |
339 | static bool is_running(Value* p_value) { return running.has_key(p_value); } | |
340 | UnfoldabilityCheck(Value* p_value) : value(p_value) { running.add(value, 0); } | |
341 | ~UnfoldabilityCheck() { running.erase(value); } | |
342 | }; | |
343 | ||
344 | /** Copy constructor for Value::clone() only. */ | |
345 | Value(const Value& p); | |
346 | /** Assignment op not implemented. */ | |
347 | Value& operator=(const Value& p); | |
348 | /** Release resources. */ | |
349 | void clean_up(); | |
350 | /** Release resources if Value::valuetype == V_EXPR. | |
351 | * Called by Value::clean_up(). */ | |
352 | void clean_up_expr(); | |
353 | /** Copies (moves) the contents of \a src (valuetype & u) into \a this and | |
354 | * after that destroys (deletes) src. Before doing the copy the contents of | |
355 | * \a this are destroyed by calling \a clean_up(). */ | |
356 | void copy_and_destroy(Value *src); | |
357 | public: | |
358 | Value(valuetype_t p_vt); | |
359 | Value(valuetype_t p_vt, bool p_val_bool); | |
360 | Value(valuetype_t p_vt, const Int& p_val_Int); | |
361 | Value(valuetype_t p_vt, int_val_t *p_val_Int); | |
362 | Value(valuetype_t p_vt, string *p_val_str); | |
363 | Value(valuetype_t p_vt, ustring *p_val_ustr); | |
364 | Value(valuetype_t p_vt, CharSyms *p_char_syms); | |
365 | Value(valuetype_t p_vt, Identifier *p_val_id); | |
366 | Value(valuetype_t p_vt, Identifier *p_id, Value *p_val); | |
367 | Value(valuetype_t p_vt, const Real& p_val_Real); | |
368 | Value(valuetype_t p_vt, Values *p_vs); | |
369 | Value(valuetype_t p_vt, Value *p_v, Ttcn::ParsedActualParameters *p_t_list); | |
370 | /** Constructor used by V_EXPR "-": RND, TESTCASENAME, COMP_NULL, COMP_MTC, | |
371 | * COMP_SYSTEM, COMP_SELF, COMP_RUNNING_ANY, COMP_RUNNING_ALL, | |
372 | * COMP_ALIVE_ALL, COMP_ALIVE_ANY, TMR_RUNNING_ANY, GETVERDICT */ | |
373 | Value(operationtype_t p_optype); | |
374 | /** Constructor used by V_EXPR "v1" */ | |
375 | Value(operationtype_t p_optype, Value *p_v1); | |
376 | /** Constructor used by V_EXPR "ti1": LENGTHOF, SIZEOF, VALUEOF, TTCN2STRING */ | |
377 | Value(operationtype_t p_optype, TemplateInstance *p_ti1); | |
378 | /** Constructor used by V_EXPR "r1": COMP_RUNNING, COMP_ALIVE, | |
379 | * TMR_READ, TMR_RUNNING, ACTIVATE */ | |
380 | Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1); | |
381 | /** ACTIVATE_REFD, OPTYPE_INVOKE, OPTYPE_COMP_ALIVE_REFD */ | |
382 | Value(operationtype_t p_optype, Value *p_v1, | |
383 | Ttcn::ParsedActualParameters *p_ap_list); | |
384 | /** OPTYPE_EXECUTE_REFD */ | |
385 | Value(operationtype_t p_optype, Value *p_v1, | |
386 | Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3); | |
387 | /** Constructor used by V_EXPR "r1 [v2]": EXECUTE */ | |
388 | Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *v2); | |
389 | /** Constructor used by V_EXPR "r1 [v2] [v3] b4": COMP_CREATE */ | |
390 | Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2, | |
391 | Value *p_v3, bool p_b4); | |
392 | /** Constructor used by V_EXPR "v1 v2" */ | |
393 | Value(operationtype_t p_optype, Value *p_v1, Value *p_v2); | |
394 | /** Constructor used by V_EXPR "v1 v2 v3" */ | |
395 | Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3); | |
396 | /** Constructor used by V_EXPR "ti1 v2 v3" */ | |
397 | Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3); | |
398 | /** Constructor used by V_EXPR "ti1 t2 v3" */ | |
399 | Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3); | |
400 | /** Constructor used by V_EXPR "ti1 v2 v3 ti4" */ | |
401 | Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, | |
402 | Value *p_v3, TemplateInstance *p_ti4); | |
403 | /** Constructor used by V_EXPR "v1 t2": MATCH */ | |
404 | Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2); | |
405 | /** Constructor used by V_EXPR "r1 i2": ISPRESENT, ISCHOSEN */ | |
406 | Value(operationtype_t p_optype, Ttcn::Reference *p_r1, Identifier *p_i2); | |
407 | Value(operationtype_t p_optype, LogArguments *p_logargs); | |
408 | /** Constructor used by V_MACRO */ | |
409 | Value(valuetype_t p_vt, macrotype_t p_macrotype); | |
410 | Value(valuetype_t p_vt, NamedValues *p_nvs); | |
411 | /** V_REFD, V_REFER */ | |
412 | Value(valuetype_t p_vt, Reference *p_ref); | |
413 | Value(valuetype_t p_vt, Block *p_block); | |
414 | Value(valuetype_t p_vt, verdict_t p_verdict); | |
415 | /** Constructor used by decode */ | |
416 | Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2); | |
417 | virtual ~Value(); | |
418 | virtual Value* clone() const; | |
419 | valuetype_t get_valuetype() const {return valuetype;} | |
420 | /** it it is not V_EXPR then fatal error. */ | |
421 | operationtype_t get_optype() const; | |
422 | /** Sets the governor type. */ | |
423 | virtual void set_my_governor(Type *p_gov); | |
424 | /** Gets the governor type. */ | |
425 | virtual Type *get_my_governor() const; | |
426 | /** Returns true if it is a value reference. */ | |
427 | bool is_ref() const { return valuetype == V_REFD; } | |
428 | virtual void set_fullname(const string& p_fullname); | |
429 | virtual void set_my_scope(Scope *p_scope); | |
430 | private: | |
431 | void set_fullname_expr(const string& p_fullname); | |
432 | void set_my_scope_expr(Scope *p_scope); | |
433 | public: | |
434 | void set_genname_recursive(const string& p_genname); | |
435 | void set_genname_prefix(const char *p_genname_prefix); | |
436 | void set_code_section(code_section_t p_code_section); | |
437 | void change_sign(); | |
438 | void add_oid_comp(OID_comp* p_comp); | |
439 | void set_valuetype(valuetype_t p_valuetype); | |
440 | void set_valuetype_COMP_NULL(); | |
441 | void set_valuetype(valuetype_t p_valuetype, const Int& p_val_int); | |
442 | void set_valuetype(valuetype_t p_valuetype, string *p_str); | |
443 | void set_valuetype(valuetype_t p_valuetype, Identifier *p_id); | |
444 | void set_valuetype(valuetype_t p_valuetype, Assignment *p_ass); | |
445 | void add_id(Identifier *p_id); | |
446 | /** Follows the chain of references if any and returns the last | |
447 | * element of the chain. In other words, the returned value is | |
448 | * the first value which is not a reference. */ | |
449 | Value* get_value_refd_last | |
450 | (ReferenceChain *refch=0, | |
451 | Type::expected_value_t exp_val=Type::EXPECTED_DYNAMIC_VALUE); | |
452 | Value *get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs, | |
453 | size_t start_i, bool usedInIsbound, | |
454 | ReferenceChain *refch); | |
455 | /** Returns true if the value is unknown at compile-time. */ | |
456 | bool is_unfoldable | |
457 | (ReferenceChain *refch=0, | |
458 | Type::expected_value_t exp_val=Type::EXPECTED_DYNAMIC_VALUE); | |
459 | ||
460 | /** Returns whether the value is a single identifier, which can be either | |
461 | * a reference or an enum value. */ | |
462 | bool is_undef_lowerid(); | |
463 | /** Returns the single identifier. | |
464 | * It can be used only if \a is_undef_lowerid() returned true. */ | |
465 | const Identifier& get_undef_lowerid(); | |
466 | /** Converts the single identifier to a referenced value. */ | |
467 | void set_lowerid_to_ref(); | |
468 | /** Check if ref++; can be used instead of ref = ref + 1; */ | |
469 | bool can_use_increment(Reference *ref) const; | |
470 | ||
471 | /** If this value is used in an expression, what is its return type? */ | |
472 | Type::typetype_t get_expr_returntype | |
473 | (Type::expected_value_t exp_val=Type::EXPECTED_DYNAMIC_VALUE); | |
474 | /** If this value is used in an expression, what is its governor? | |
475 | * If has no governor, but is reference, then tries the | |
476 | * referenced stuff... If not known, returns NULL. */ | |
477 | Type* get_expr_governor(Type::expected_value_t exp_val); | |
478 | Type* get_expr_governor_v1v2(Type::expected_value_t exp_val); | |
479 | Type* get_expr_governor_last(); | |
480 | /** get the type invoked */ | |
481 | Type *get_invoked_type(Type::expected_value_t exp_val); | |
970ed795 EL |
482 | private: |
483 | const char* get_opname() const; | |
484 | /** Used to determine whether the reference points to value or | |
485 | * template in ISCHOSEN, then convert to {ISCHOSEN}_{V,T} */ | |
486 | void chk_expr_ref_ischosen(); | |
487 | void chk_expr_operandtype_enum(const char *opname, Value *v, | |
488 | Type::expected_value_t exp_val); | |
489 | void chk_expr_operandtype_bool(Type::typetype_t tt, const char *opnum, | |
490 | const char *opname, const Location *loc); | |
491 | void chk_expr_operandtype_int(Type::typetype_t tt, const char *opnum, | |
492 | const char *opname, const Location *loc); | |
493 | void chk_expr_operandtype_float(Type::typetype_t tt, const char *opnum, | |
494 | const char *opname, const Location *loc); | |
495 | void chk_expr_operandtype_int_float(Type::typetype_t tt, const char *opnum, | |
496 | const char *opname, const Location *loc); | |
497 | void chk_expr_operandtype_int_float_enum(Type::typetype_t tt, | |
498 | const char *opnum, | |
499 | const char *opname, | |
500 | const Location *loc); | |
501 | /** Check that the operand is a list or string or something like it. | |
502 | * | |
503 | * This Value is usually an expression like | |
504 | * @code lengthof(foo) @endcode | |
505 | * | |
506 | * @param t the type (governor) of the operand | |
507 | * @param opnum describes the operand ("first", "left", ...) | |
508 | * @param opname the name of the operation | |
509 | * @param loc the operand itself as a Location object | |
510 | * @param allow_array \a true if T_ARRAY is acceptable (rotate, lengthof) | |
511 | * or \a false if it's not (concat, substr, replace). | |
512 | */ | |
513 | void chk_expr_operandtype_list(Type* t, const char *opnum, | |
514 | const char *opname, const Location *loc, | |
515 | bool allow_array); | |
516 | // Check that the operand of the operation is a string value | |
517 | void chk_expr_operandtype_str(Type::typetype_t tt, const char *opnum, | |
518 | const char *opname, const Location *loc); | |
519 | void chk_expr_operandtype_charstr(Type::typetype_t tt, const char *opnum, | |
520 | const char *opname, const Location *loc); | |
521 | void chk_expr_operandtype_cstr(Type::typetype_t tt, const char *opnum, | |
522 | const char *opname, const Location *loc); | |
523 | void chk_expr_operandtype_binstr(Type::typetype_t tt, const char *opnum, | |
524 | const char *opname, const Location *loc); | |
525 | void chk_expr_operandtype_bstr(Type::typetype_t tt, const char *opnum, | |
526 | const char *opname, const Location *loc); | |
527 | void chk_expr_operandtype_hstr(Type::typetype_t tt, const char *opnum, | |
528 | const char *opname, const Location *loc); | |
529 | void chk_expr_operandtype_ostr(Type::typetype_t tt, const char *opnum, | |
530 | const char *opname, const Location *loc); | |
531 | void chk_expr_operandtypes_same(Type::typetype_t tt1, Type::typetype_t tt2, | |
532 | const char *opname); | |
533 | void chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1, Type::typetype_t tt2, | |
534 | const char *opnum1, const char *opnum2, | |
535 | const char *opname); | |
536 | void chk_expr_operandtypes_compat(Type::expected_value_t exp_val, | |
537 | Value *v1, Value *v2, | |
538 | const char *opnum1 = "left", | |
539 | const char *opnum2 = "right"); | |
540 | void chk_expr_operand_undef_running(Type::expected_value_t exp_val, | |
541 | Ttcn::Ref_base *ref, | |
542 | const char *opnum, const char *opname); | |
543 | /** Returns the referred component type if it is correct. */ | |
544 | Type *chk_expr_operand_comptyperef_create(); | |
545 | /** Checks whether the special component references mtc, system and self | |
546 | * have the correct component types (compatible with \a my_governor). */ | |
547 | void chk_expr_comptype_compat(); | |
548 | void chk_expr_operand_compref(Value *val, const char *opnum, | |
549 | const char *opname); | |
550 | void chk_expr_operand_tmrref(Ttcn::Ref_base *ref, | |
551 | const char *opnum, const char *opname); | |
552 | void chk_expr_operand_activate(Ttcn::Ref_base *ref, | |
553 | const char *opnum, const char *opname); | |
554 | void chk_expr_operand_activate_refd(Value *val, | |
555 | Ttcn::TemplateInstances* t_list2, | |
556 | Ttcn::ActualParList *&parlist, | |
557 | const char *opnum, const char *opname); | |
558 | void chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val, | |
559 | const char *opnum, const char *opname); | |
560 | void chk_expr_operand_execute_refd(Value *v1, | |
561 | Ttcn::TemplateInstances* t_list2, | |
562 | Ttcn::ActualParList *&parlist, | |
563 | Value *v3, const char *opnum, | |
564 | const char *opname); | |
565 | void chk_invoke(Type::expected_value_t exp_val); | |
566 | void chk_expr_eval_value(Value *val, Type &t, | |
567 | ReferenceChain *refch, | |
568 | Type::expected_value_t exp_val); | |
569 | void chk_expr_eval_ti(TemplateInstance *ti, Type *t, | |
570 | ReferenceChain *refch, Type::expected_value_t exp_val); | |
571 | void chk_expr_val_int_pos0(Value *val, const char *opnum, | |
572 | const char *opname); | |
573 | void chk_expr_val_int_pos7bit(Value *val, const char *opnum, | |
574 | const char *opname); | |
575 | void chk_expr_val_int_pos31bit(Value *val, const char *opnum, | |
576 | const char *opname); | |
577 | void chk_expr_val_int_float_not0(Value *val, const char *opnum, | |
578 | const char *opname); | |
579 | void chk_expr_val_large_int(Value *val, const char *opnum, | |
580 | const char *opname); | |
581 | void chk_expr_val_len1(Value *val, const char *opnum, | |
582 | const char *opname); | |
583 | void chk_expr_val_str_len_even(Value *val, const char *opnum, | |
584 | const char *opname); | |
585 | void chk_expr_val_str_bindigits(Value *val, const char *opnum, | |
586 | const char *opname); | |
587 | void chk_expr_val_str_hexdigits(Value *val, const char *opnum, | |
588 | const char *opname); | |
589 | void chk_expr_val_str_7bitoctets(Value *val, const char *opnum, | |
590 | const char *opname); | |
591 | void chk_expr_val_str_int(Value *val, const char *opnum, | |
592 | const char *opname); | |
593 | void chk_expr_val_str_float(Value *val, const char *opnum, | |
594 | const char *opname); | |
595 | void chk_expr_val_ustr_7bitchars(Value *val, const char *opnum, | |
596 | const char *opname); | |
597 | void chk_expr_val_bitstr_intsize(Value *val, const char *opnum, | |
598 | const char *opname); | |
599 | void chk_expr_val_hexstr_intsize(Value *val, const char *opnum, | |
600 | const char *opname); | |
601 | void chk_expr_operands_int2binstr(); | |
602 | void chk_expr_operands_str_samelen(); | |
603 | void chk_expr_operands_replace(); | |
604 | void chk_expr_operands_substr(); | |
605 | void chk_expr_operands_regexp(); | |
606 | void chk_expr_operands_ischosen(ReferenceChain *refch, | |
607 | Type::expected_value_t exp_val); | |
608 | void chk_expr_operand_encode(ReferenceChain *refch, | |
609 | Type::expected_value_t exp_val); | |
610 | void chk_expr_operands_decode(); | |
611 | /** Checks whether \a this can be compared with omit value (i.e. \a this | |
612 | * should be a referenced value pointing to a optional record/set field. */ | |
613 | void chk_expr_omit_comparison(Type::expected_value_t exp_val); | |
614 | Int chk_eval_expr_sizeof(ReferenceChain *refch, | |
615 | Type::expected_value_t exp_val); | |
616 | /** The governor is returned. */ | |
617 | Type *chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val); | |
618 | void chk_expr_operands_match(Type::expected_value_t exp_val); | |
619 | void chk_expr_dynamic_part(Type::expected_value_t exp_val, | |
620 | bool allow_controlpart, | |
621 | bool allow_runs_on = true, | |
622 | bool require_runs_on = false); | |
623 | /** Check the operands of an expression */ | |
624 | void chk_expr_operands(ReferenceChain *refch, | |
625 | Type::expected_value_t exp_val); | |
626 | void chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname); | |
627 | /** Evaluate... | |
628 | * Called by Value::get_value_refd_last() for V_EXPR */ | |
629 | void evaluate_value(ReferenceChain *refch, Type::expected_value_t exp_val); | |
630 | /** Evaluate macro. | |
631 | * Called by Value::get_value_refd_last() for V_MACRO */ | |
632 | void evaluate_macro(Type::expected_value_t exp_val); | |
633 | /** Compile-time evaluation of isvalue() | |
634 | * | |
635 | * @param from_sequence \c true if called for a member of a sequence/set | |
636 | * @return the compile-time result of calling isvalue() | |
637 | */ | |
638 | bool evaluate_isvalue(bool from_sequence); | |
639 | ||
640 | Value *get_refd_field_value(const Identifier& field_id, bool usedInIsbound, | |
641 | const Location& loc); | |
642 | Value *get_refd_array_value(Value *array_index, bool usedInIsbound, | |
643 | ReferenceChain *refch); | |
644 | Value *get_string_element(const Int& index, const Location& loc); | |
645 | ||
646 | public: | |
647 | /** Checks whether the value (expression) evaluates to built-in type | |
648 | * \a p_tt. Argument \a type_name is the name of that type, it is used in | |
649 | * error messages. */ | |
650 | void chk_expr_type(Type::typetype_t p_tt, const char *type_name, | |
651 | Type::expected_value_t exp_val); | |
652 | /** Checks that the value (expression) evals to a boolean value */ | |
653 | inline void chk_expr_bool(Type::expected_value_t exp_val) | |
654 | { chk_expr_type(Type::T_BOOL, "boolean", exp_val); } | |
655 | /** Checks that the value (expression) evals to an integer value */ | |
656 | inline void chk_expr_int(Type::expected_value_t exp_val) | |
657 | { chk_expr_type(Type::T_INT, "integer", exp_val); } | |
658 | /** Checks that the value (expression) evals to a float value */ | |
659 | inline void chk_expr_float(Type::expected_value_t exp_val) | |
660 | { chk_expr_type(Type::T_REAL, "float", exp_val); } | |
661 | /** Checks that the value (expression) evals to a verdict value */ | |
662 | inline void chk_expr_verdict(Type::expected_value_t exp_val) | |
663 | { chk_expr_type(Type::T_VERDICT, "verdict", exp_val); } | |
664 | /** Checks that the value (expression) evals to a default value */ | |
665 | inline void chk_expr_default(Type::expected_value_t exp_val) | |
666 | { chk_expr_type(Type::T_DEFAULT, "default", exp_val); } | |
667 | ||
668 | /* if "infinity" or "-infinity" was parsed then this is a real value or | |
669 | a unary - expression containing a real value, where the real value is | |
670 | infinity. | |
671 | Returns -1 if -infinity was parsed, +1 if infinity, 0 in other cases */ | |
672 | int is_parsed_infinity(); | |
673 | ||
674 | bool get_val_bool(); | |
675 | int_val_t* get_val_Int(); | |
676 | const Identifier* get_val_id(); | |
677 | const ttcn3float& get_val_Real(); | |
678 | string get_val_str(); | |
679 | ustring get_val_ustr(); | |
680 | string get_val_iso2022str(); | |
681 | size_t get_val_strlen(); | |
682 | verdict_t get_val_verdict(); | |
683 | size_t get_nof_comps(); | |
684 | bool is_indexed() const; | |
685 | const Identifier& get_alt_name(); | |
686 | Value *get_alt_value(); | |
687 | /** Returns whether the embedded object identifier components | |
688 | * contain any error. Applicable to OID/ROID values only. */ | |
689 | bool has_oid_error(); | |
690 | /** Collects all object identifier components of the value into \a | |
691 | * comps. It follows and expands the embedded references. | |
692 | * Applicable to OID/ROID values and referenced values pointing | |
693 | * to them. | |
694 | * @return true, if all components can be calculated in compile-time */ | |
695 | bool get_oid_comps(vector<string>& comps); | |
696 | /** Get a component of SEQUENCE/SET, zero-based */ | |
697 | void add_se_comp(NamedValue* nv); // needed by implicit_omit | |
698 | NamedValue* get_se_comp_byIndex(size_t n); | |
699 | /** Get a component of an array/REC-OF/SET-OF */ | |
700 | Value *get_comp_byIndex(size_t n); | |
701 | /** Get an index of an array/REC-OF/SET-OF */ | |
702 | Value *get_index_byIndex(size_t n); | |
703 | /** Does a named component exist ? For SEQ/SET/CHOICE */ | |
704 | bool has_comp_withName(const Identifier& p_name); | |
705 | NamedValue* get_se_comp_byName(const Identifier& p_name); | |
706 | Value* get_comp_value_byName(const Identifier& p_name); | |
707 | bool field_is_present(const Identifier& p_name); | |
708 | bool field_is_chosen(const Identifier& p_name); | |
709 | void chk_dupl_id(); | |
710 | size_t get_nof_ids() const; | |
711 | Identifier* get_id_byIndex(size_t p_i); | |
712 | bool has_id(const Identifier& p_id); | |
713 | Reference *get_reference() const; | |
714 | Reference *get_refered() const; | |
715 | Common::Assignment *get_refd_fat() const; | |
716 | /** Usable during AST building. If VariableRef is needed, then use | |
717 | * the return value of this function, then delete this. */ | |
718 | Ttcn::Reference* steal_ttcn_ref(); | |
719 | Ttcn::Ref_base* steal_ttcn_ref_base(); | |
720 | void steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti, | |
721 | Ttcn::ActualParList*& p_ap); | |
722 | Common::Assignment* get_refd_assignment(); | |
723 | ||
724 | void chk(); | |
725 | void chk_OID(ReferenceChain& refch); | |
726 | void chk_ROID(ReferenceChain& refch); | |
727 | /** Checks for circular references within embedded values */ | |
728 | void chk_recursions(ReferenceChain& refch); | |
729 | /** Checks for circular references within embedded expressions */ | |
730 | void chk_recursions_expr(ReferenceChain& refch); | |
731 | void chk_recursions_expr_decode(Ttcn::Ref_base* ref, ReferenceChain& refch); | |
732 | /** Check that the value (a V_EXPR) - being used as the RHS - refers to | |
733 | * the LHS of the assignment. | |
734 | * @return true if self-assignment*/ | |
735 | bool chk_expr_self_ref(Common::Assignment *lhs); | |
736 | ||
737 | virtual string create_stringRepr(); | |
738 | private: | |
739 | static bool chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs); | |
740 | static bool chk_expr_self_ref_val (Common::Value *v, Common::Assignment *lhs); | |
741 | string create_stringRepr_unary(const char *operator_str); | |
742 | string create_stringRepr_infix(const char *operator_str); | |
743 | string create_stringRepr_predef1(const char *function_name); | |
744 | string create_stringRepr_predef2(const char *function_name); | |
745 | public: | |
746 | bool operator==(Value& val); | |
747 | bool operator<(Value& val); | |
748 | public: | |
749 | /** Returns true if this value is of a string type */ | |
750 | bool is_string_type(Type::expected_value_t exp_val); | |
751 | /** Public entry points for code generation. */ | |
752 | /** Generates the equivalent C++ code for the value. It is used | |
753 | * when the value is part of a complex expression (e.g. as | |
754 | * operand of a built-in operation, actual parameter, array | |
755 | * index). The generated code fragments are appended to the | |
756 | * fields of visitor \a expr. */ | |
757 | void generate_code_expr(expression_struct *expr); | |
758 | /** Generates the C++ equivalent of \a this into \a expr and adds a "()" | |
759 | * to expr->expr if \a this is referenced value that points to an optional | |
760 | * field of a record/set value. */ | |
761 | void generate_code_expr_mandatory(expression_struct *expr); | |
762 | /** Generates a C++ code sequence, which initializes the C++ | |
763 | * object named \a name with the contents of the value. The code | |
764 | * sequence is appended to argument \a str and the resulting | |
765 | * string is returned. */ | |
766 | char *generate_code_init(char *str, const char *name); | |
767 | /** Appends the initialization sequence of all referred | |
768 | * non-parameterized templates to \a str and returns the | |
769 | * resulting string. Such templates may appear in the actual | |
770 | * parameter list of parameterized value references | |
771 | * (e.g. function calls) and in operands of valueof or match | |
772 | * operations. */ | |
773 | char *rearrange_init_code(char *str); | |
774 | /** | |
775 | * Generates a value for temporary use. Example: | |
776 | * | |
777 | * str: // empty | |
778 | * prefix: if( | |
779 | * blockcount: 0 | |
780 | * | |
781 | * if the value is simple, then returns: | |
782 | * | |
783 | * // empty | |
784 | * if(simple | |
785 | * | |
786 | * if the value is complex, then returns: | |
787 | * | |
788 | * // empty | |
789 | * { | |
790 | * booelan tmp_2; | |
791 | * { | |
792 | * preamble... tmp_1... | |
793 | * tmp_2=func5(tmp_1); | |
794 | * postamble | |
795 | * } | |
796 | * if(tmp_2 | |
797 | * | |
798 | * and also increments the blockcount because you have to close it... | |
799 | */ | |
800 | char* generate_code_tmp(char *str, const char *prefix, size_t& blockcount); | |
801 | char* generate_code_tmp(char *str, char*& init); | |
802 | /** Generates the C++ statement that puts the value of \a this into the | |
803 | * log. It is used when the value appears in the argument of a log() | |
804 | * statement. */ | |
805 | void generate_code_log(expression_struct *expr); | |
806 | /** Generates the C++ equivalent of a match operation if it | |
807 | * appears within a log() statement. Applicable only if \a this is | |
808 | * an expression containing a match operation. */ | |
809 | void generate_code_log_match(expression_struct *expr); | |
810 | ||
811 | private: | |
812 | /** Private helper functions for code generation. */ | |
813 | /** Helper function for \a generate_code_expr(). It is used when | |
814 | * the value is an expression. */ | |
815 | void generate_code_expr_expr(expression_struct *expr); | |
816 | /** Helper function for \a generate_code_expr_expr(). It handles | |
817 | * unary operators. */ | |
818 | static void generate_code_expr_unary(expression_struct *expr, | |
819 | const char *operator_str, Value *v1); | |
820 | /** Helper function for \a generate_code_expr_expr(). It handles infix | |
821 | * binary operators. Flag \a optional_allowed is true when the operation | |
822 | * has different meaning on optional fields (like comparison). Otherwise | |
823 | * the optional operands are explicitly converted to a regular data | |
824 | * type. */ | |
825 | void generate_code_expr_infix(expression_struct *expr, | |
826 | const char *operator_str, Value *v1, | |
827 | Value *v2, bool optional_allowed); | |
828 | /** Helper function for \a generate_code_expr_expr(). It handles the | |
829 | * logical "and" and "or" operation with short-circuit evaluation | |
830 | * semantics. */ | |
831 | void generate_code_expr_and_or(expression_struct *expr); | |
832 | /** Helper function for \a generate_code_expr_expr(). It handles | |
833 | * built-in functions with one argument. */ | |
834 | static void generate_code_expr_predef1(expression_struct *expr, | |
835 | const char *function_name, | |
836 | Value *v1); | |
837 | /** Helper function for \a generate_code_expr_expr(). It handles | |
838 | * built-in functions with two arguments. */ | |
839 | static void generate_code_expr_predef2(expression_struct *expr, | |
840 | const char *function_name, | |
841 | Value *v1, Value *v2); | |
842 | /** Helper function for \a generate_code_expr_expr(). It handles | |
843 | * built-in functions with three arguments. */ | |
844 | static void generate_code_expr_predef3(expression_struct *expr, | |
845 | const char *function_name, | |
846 | Value *v1, Value *v2, Value *v3); | |
847 | /** Helper functions for \a generate_code_expr_expr(). */ | |
848 | void generate_code_expr_substr(expression_struct *expr); | |
849 | void generate_code_expr_substr_replace_compat(expression_struct *expr); | |
850 | void generate_code_expr_regexp(expression_struct *expr); | |
851 | void generate_code_expr_replace(expression_struct *expr); | |
852 | /** Helper function for \a generate_code_expr_expr(). It handles | |
853 | * built-in function rnd(). */ | |
854 | static void generate_code_expr_rnd(expression_struct *expr, | |
855 | Value *v1); | |
856 | /** Helper function for \a generate_code_expr_expr(). It handles | |
857 | * create(). */ | |
858 | static void generate_code_expr_create(expression_struct *expr, | |
859 | Ttcn::Ref_base *type, Value *name, Value *location, bool alive); | |
860 | /** Helper function for \a generate_code_expr_expr(). It handles | |
861 | * activate(). */ | |
862 | void generate_code_expr_activate(expression_struct *expr); | |
863 | /** Helper function for \a generate_code_expr_expr(). It handles | |
864 | * activate() with derefers(). */ | |
865 | void generate_code_expr_activate_refd(expression_struct *expr); | |
866 | /** Helper function for \a generate_code_expr_expr(). It handles | |
867 | * execute(). */ | |
868 | void generate_code_expr_execute(expression_struct *expr); | |
869 | /** Helper function for \a generate_code_expr_expr(). It handles | |
870 | * execute() with derefers(). */ | |
871 | void generate_code_expr_execute_refd(expression_struct *expr); | |
872 | /** Helper function for \a generate_code_expr(). It handles invoke */ | |
873 | void generate_code_expr_invoke(expression_struct *expr); | |
874 | ||
875 | /** Adds the character sequence "()" to expr->expr if \a ref points to | |
876 | * an optional field of a record/set value. */ | |
877 | static void generate_code_expr_optional_field_ref(expression_struct *expr, | |
878 | Reference *ref); | |
879 | ||
880 | void generate_code_expr_encode(expression_struct *expr); | |
881 | ||
882 | void generate_code_expr_decode(expression_struct *expr); | |
883 | ||
884 | /** Helper function for \a generate_code_init(). It handles the | |
885 | * union (CHOICE) values. */ | |
886 | char *generate_code_init_choice(char *str, const char *name); | |
887 | /** Helper function for \a generate_code_init(). It handles the | |
888 | * 'record of'/'set of' ('SEQUENCE OF'/'SET OF') values. */ | |
889 | char *generate_code_init_seof(char *str, const char *name); | |
890 | /** Helper function for \a generate_code_init(). It handles the | |
891 | * indexed value notation for 'record of'/'set of' ('SEQUENCE OF'/ | |
892 | * 'SET OF') values. */ | |
893 | char *generate_code_init_indexed(char *str, const char *name); | |
894 | /** Helper function for \a generate_code_init(). It handles the | |
895 | * array values. */ | |
896 | char *generate_code_init_array(char *str, const char *name); | |
897 | /** Helper function for \a generate_code_init(). It handles the | |
898 | * record/set (SEQUENCE/SET) values. */ | |
899 | char *generate_code_init_se(char *str, const char *name); | |
900 | /** Helper function for \a generate_code_init(). It handles the | |
901 | * referenced values. */ | |
902 | char *generate_code_init_refd(char *str, const char *name); | |
903 | ||
904 | public: | |
905 | /** Returns whether C++ explicit cast (type conversion) is necessary when | |
906 | * \a this is the argument of a send() or log() statement. True is returned | |
907 | * when the type of the C++ equivalent is ambiguous or is a built-in type | |
908 | * that has to be converted to the respective TTCN-3 value class | |
909 | * (e.g. int -> class INTEGER). */ | |
910 | bool explicit_cast_needed(bool forIsValue = false); | |
911 | /** Returns whether the value can be represented by an in-line C++ | |
912 | * expression. */ | |
913 | bool has_single_expr(); | |
914 | /** Returns the equivalent C++ expression. It can be used only if | |
915 | * \a has_single_expr() returns true. */ | |
916 | string get_single_expr(); | |
917 | private: | |
918 | /** Helper function for has_single_expr(). Used when the value contains | |
919 | * an expression */ | |
920 | bool has_single_expr_expr(); | |
921 | /** Helper function for has_single_expr(). Used for invoke operations and | |
922 | * for activate and execute combined with derefer */ | |
923 | static bool has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list); | |
924 | /** Helper function for \a get_single_expr(). Used for enumerated | |
925 | * values only. It considers the enum-hack option. */ | |
926 | string get_single_expr_enum(); | |
927 | /** Helper function for \a get_single_expr(). Used for ISO2022 | |
928 | * string values only. The generated code refers to the | |
929 | * user-defined conversion functions of the RTE. */ | |
930 | string get_single_expr_iso2022str(); | |
931 | /** Helper function for \a get_single_expr(). Used by literal function, | |
932 | * altstep and testcase values denoted by refer(). */ | |
933 | string get_single_expr_fat(); | |
934 | /** Returns whether the value is compound (i.e. record, set, | |
935 | * union, record of, set of). */ | |
936 | bool is_compound(); | |
937 | /** Returns whether the C++ initialization sequence requires a | |
938 | * temporary variable reference to be introduced for efficiency | |
939 | * reasons. */ | |
940 | bool needs_temp_ref(); | |
941 | /** Returns whether the evaluation of \a this has side-effects that shall | |
942 | * be eliminated in case of short-circuit evaluation of logical "and" and | |
943 | * "or" operations. This function is applied on the second (right) operand | |
944 | * of the expression. */ | |
945 | bool needs_short_circuit(); | |
946 | public: | |
947 | virtual void dump(unsigned level) const; | |
948 | private: | |
949 | inline void set_val_str(string *p_val_str) | |
950 | { u.str.val_str = p_val_str; u.str.str_elements = 0; } | |
951 | inline void set_val_ustr(ustring *p_val_ustr) | |
952 | { u.ustr.val_ustr = p_val_ustr; u.ustr.ustr_elements = 0; } | |
953 | void add_string_element(size_t index, Value *v_element, | |
954 | map<size_t, Value>*& string_elements); | |
955 | }; | |
956 | ||
957 | /** @} end of AST_Value group */ | |
958 | ||
959 | class LazyParamData { | |
960 | static int depth; // recursive code generation: calling a func. with lazy param inside a lazy param | |
961 | static bool used_as_lvalue; | |
962 | static vector<string>* type_vec; | |
963 | static vector<string>* refd_vec; | |
964 | public: | |
965 | static bool in_lazy(); | |
966 | static void init(bool p_used_as_lvalue); | |
967 | static void clean(); | |
968 | static string add_ref_genname(Assignment* ass, Scope* scope); | |
969 | static string get_member_name(size_t idx); | |
970 | static string get_constr_param_name(size_t idx); | |
971 | static void generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope); | |
972 | static void generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope); | |
973 | static void generate_code(expression_struct *expr, Value* value, Scope* scope); | |
974 | static void generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope); | |
975 | static void generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name); | |
976 | static void generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope); | |
977 | static void generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope); | |
978 | static void generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope); | |
979 | }; | |
980 | ||
981 | } // namespace Common | |
982 | ||
983 | #endif // _Common_Value_HH |