Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 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 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Baranyi, Botond | |
11 | * Delic, Adam | |
12 | * Feher, Csaba | |
13 | * Forstner, Matyas | |
14 | * Kovacs, Ferenc | |
15 | * Raduly, Csaba | |
16 | * Szabados, Kristof | |
17 | * Szabo, Janos Zoltan – initial implementation | |
18 | * Zalanyi, Balazs Andor | |
19 | * | |
20 | ******************************************************************************/ | |
970ed795 EL |
21 | #ifndef _Ttcn_Statement_HH |
22 | #define _Ttcn_Statement_HH | |
23 | ||
24 | #include "AST_ttcn3.hh" | |
25 | ||
26 | namespace Ttcn { | |
27 | ||
28 | /** | |
29 | * \addtogroup AST | |
30 | * | |
31 | * @{ | |
32 | */ | |
33 | ||
34 | using namespace Common; | |
35 | ||
36 | class StatementBlock; | |
37 | class Statement; | |
38 | class Assignment; | |
39 | class Assignments; | |
40 | class ParamAssignment; | |
41 | class ParamAssignments; | |
42 | class VariableEntry; | |
43 | class VariableEntries; | |
44 | class ParamRedirect; | |
45 | class LogArgument; | |
46 | class LogArguments; | |
47 | class IfClause; | |
48 | class IfClauses; | |
49 | class SelectCase; | |
50 | class SelectCases; | |
51 | class AltGuard; | |
52 | class AltGuards; | |
53 | class WithAttribPath; | |
54 | /* not defined here: */ | |
55 | class ILT; | |
56 | class ILT_branch; | |
57 | ||
58 | /** | |
59 | * Represents a %StatementBlock. | |
60 | */ | |
61 | class StatementBlock : public Scope, public Location { | |
62 | public: | |
63 | enum returnstatus_t { | |
64 | RS_NO, /**< indicates that the block does not have return statement | |
65 | at all */ | |
66 | RS_MAYBE, /**< indicates that some branches of the embedded statements | |
67 | have a return statement but others do not */ | |
68 | RS_YES /**< indicates that the block or all branches of the | |
69 | embedded statements have a return statement */ | |
70 | }; | |
71 | ||
72 | enum exception_handling_t { | |
73 | EH_NONE, /**< this is a normal statement block */ | |
74 | EH_TRY, /**< this is a try{} block */ | |
75 | EH_CATCH /**< this is a catch(exc_str){} block */ | |
76 | }; | |
77 | ||
78 | private: | |
79 | vector<Statement> stmts; | |
80 | /** to store pointers to definitions defined in scope */ | |
81 | map<Identifier, Definition> defs; | |
82 | /** to store goto labels and pointer to their statement */ | |
83 | map<Identifier, Statement> labels; | |
84 | bool checked, labels_checked; | |
85 | /** parent sb, if any */ | |
86 | StatementBlock *my_sb; | |
87 | /** my index in the parent sb, if applicable */ | |
88 | size_t my_sb_index; | |
89 | /** The function/altstep/testcase/etc. the StatementBlock belongs to. */ | |
90 | Definition *my_def; | |
91 | /** */ | |
92 | exception_handling_t exception_handling; | |
93 | ||
94 | StatementBlock(const StatementBlock& p); | |
95 | StatementBlock& operator=(const StatementBlock& p); | |
96 | public: | |
97 | StatementBlock(); | |
98 | virtual ~StatementBlock(); | |
99 | virtual StatementBlock* clone() const; | |
100 | void add_stmt(Statement *p_stmt, bool to_front=false); | |
101 | virtual void set_my_scope(Scope *p_scope); | |
102 | virtual void set_fullname(const string& p_fullname); | |
103 | size_t get_nof_stmts() const { return stmts.size(); } | |
104 | Statement *get_stmt_byIndex(size_t p_i) const { return stmts[p_i]; } | |
105 | /** Returns the first statement of the block or NULL if there is no such | |
106 | * statement. It ignores labels and goes recursively into nested blocks */ | |
107 | Statement *get_first_stmt() const; | |
108 | /* Scope-related functions */ | |
109 | void register_def(Definition *p_def); | |
110 | virtual bool has_ass_withId(const Identifier& p_id); | |
111 | virtual Common::Assignment* get_ass_bySRef(Ref_simple *p_ref); | |
af710487 | 112 | virtual Type *get_mtc_system_comptype(bool is_system); |
970ed795 EL |
113 | Definition* get_my_def() const { return my_def; } |
114 | virtual Ttcn::StatementBlock *get_statementblock_scope(); | |
115 | void set_my_sb(StatementBlock *p_sb, size_t p_index); | |
116 | StatementBlock* get_my_sb() const { return my_sb; } | |
117 | size_t get_my_sb_index() const; | |
118 | void set_my_def(Definition *p_def); | |
119 | void set_my_ags(AltGuards *p_ags); | |
120 | void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt); | |
121 | returnstatus_t has_return() const; | |
122 | /** Used when generating code for interleaved statement. If has | |
123 | * not recv stmt, then the general code generation can be used | |
124 | * (which may use blocks). */ | |
125 | bool has_receiving_stmt(size_t start_i=0) const; | |
126 | /** Used when generating code for interleaved statement. If has | |
127 | * not S_DEF stmt, then there is no need for {}. */ | |
128 | bool has_def_stmt_i(size_t start_i=0) const; | |
129 | ||
130 | void set_exception_handling(exception_handling_t eh) { exception_handling = eh; } | |
131 | exception_handling_t get_exception_handling() const { return exception_handling; } | |
132 | ||
133 | virtual void dump(unsigned int level) const; | |
134 | private: | |
135 | /** Returns the index of the last receiving statement after | |
136 | * start_i, or the number of statements if has not recv stmt. */ | |
137 | size_t last_receiving_stmt_i() const; | |
138 | StatementBlock *get_parent_block() const; | |
139 | void chk_trycatch_blocks(Statement* prev, Statement* act); | |
140 | public: | |
141 | /* checking functions */ | |
142 | void chk(); | |
143 | /** checks whether all embedded statements are allowed in an interleaved | |
144 | * construct */ | |
145 | void chk_allowed_interleave(); | |
146 | private: | |
147 | void chk_labels(); | |
148 | void chk_unused_labels(); | |
149 | public: | |
150 | bool has_label(const Identifier& p_id) const; | |
151 | Statement *get_label(const Identifier& p_id) const; | |
152 | /** Sets the code section selector of all embedded values and | |
153 | * templates to \a p_code_section. */ | |
154 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
155 | char* generate_code(char *str); | |
156 | void ilt_generate_code(ILT *ilt); | |
157 | ||
158 | virtual void set_parent_path(WithAttribPath* p_path); | |
159 | }; | |
160 | ||
161 | /** | |
162 | * Represents a statement (FunctionStatement) in dynamic part of | |
163 | * TTCN-3. | |
164 | */ | |
165 | class Statement : public Node, public Location { | |
166 | public: | |
167 | enum statementtype_t { | |
168 | /* erroneous statement */ | |
169 | S_ERROR, | |
170 | /* ambiguous statements */ | |
171 | S_START_UNDEF, // undefstartstop | |
172 | S_STOP_UNDEF, // undefstartstop | |
173 | S_UNKNOWN_INSTANCE, // ref_pard | |
174 | S_UNKNOWN_INVOKED, // fau_refd | |
175 | /* basic statements */ | |
176 | S_DEF, // def (const or template def; variable or timer instance) | |
177 | S_ASSIGNMENT, // ass | |
178 | S_FUNCTION_INSTANCE, // ref_pard | |
179 | S_FUNCTION_INVOKED, // fau_refd | |
180 | S_BLOCK, // block | |
181 | S_LOG, // logargs | |
182 | S_LABEL, // label | |
183 | S_GOTO, // go_to | |
184 | S_BREAK, // brk_cnt | |
185 | S_CONTINUE, // brk_cnt | |
186 | S_IF, // if_stmt | |
187 | S_SELECT, // select | |
188 | S_FOR, // loop | |
189 | S_WHILE, // loop | |
190 | S_DOWHILE, // loop | |
191 | S_STOP_EXEC, // - | |
192 | S_STOP_TESTCASE, // logargs | |
193 | /* behaviour statements */ | |
194 | S_ALT, // ags | |
195 | S_REPEAT, // ags BUT only a pointer (my_ags) | |
196 | S_INTERLEAVE, // ags | |
197 | S_ALTSTEP_INSTANCE, // ref_pard | |
198 | S_ALTSTEP_INVOKED, // fau_refd | |
199 | S_RETURN, // returnexpr | |
200 | /* default statements */ | |
201 | S_ACTIVATE, // ref_pard | |
202 | S_ACTIVATE_REFD, //activate_refd | |
203 | S_DEACTIVATE, // deactivate | |
204 | /* communication (port) statements */ | |
205 | S_SEND, // port send_par to_clause | |
206 | S_CALL, // port send_par call to_clause | |
207 | S_REPLY, // port send_par reply_val to_clause | |
208 | S_RAISE, // port raise_signature send_par to_clause | |
209 | S_RECEIVE, // port rcv_par from_clause redirect.value | |
210 | // redirect.sender | |
211 | S_TRIGGER, // port rcv_par from_clause redirect.value | |
212 | // redirect.sender | |
213 | S_GETCALL, // port rcv_par from_clause redirect.value | |
214 | // redirect.sender redirect.par_spec | |
215 | S_GETREPLY, // port rcv_par getreply_valuematch from_clause | |
216 | // redirect.value redirect.sender redirect.par_spec | |
217 | S_CATCH, // port ctch.signature rcv_par ctch.timeout from_clause | |
218 | // redirect.value redirect.sender | |
219 | S_CHECK, // port from_clause redirect.sender | |
220 | S_CHECK_RECEIVE, | |
221 | S_CHECK_GETCALL, | |
222 | S_CHECK_GETREPLY, | |
223 | S_CHECK_CATCH, | |
224 | S_CLEAR, // port | |
225 | S_START_PORT, // port | |
226 | S_STOP_PORT, // port | |
227 | S_HALT, // port | |
228 | /* component statements */ | |
229 | S_START_COMP, // comp_op | |
230 | S_START_COMP_REFD, // comp_op | |
231 | S_STOP_COMP, // comp_op | |
232 | S_DONE, // comp_op | |
233 | S_KILL, // comp_op | |
234 | S_KILLED, // comp_op | |
235 | /* configuration statements */ | |
236 | S_CONNECT, // config | |
237 | S_MAP, // config | |
238 | S_DISCONNECT, // config | |
239 | S_UNMAP, // config | |
240 | /* timer statements */ | |
241 | S_START_TIMER, // timer | |
242 | S_STOP_TIMER, // timer | |
243 | S_TIMEOUT, // timer | |
244 | /* verdict statement */ | |
245 | S_SETVERDICT, // verdictval | |
246 | /* SUT statement */ | |
247 | S_ACTION, // logargs | |
248 | /* control statement */ | |
249 | S_TESTCASE_INSTANCE, // testcase_inst | |
250 | S_TESTCASE_INSTANCE_REFD, //execute_refd | |
a38c6d4c | 251 | /* TTCN-3 Profiler statements */ |
252 | S_START_PROFILER, | |
3abe9331 | 253 | S_STOP_PROFILER, |
254 | /* Conversion statements */ | |
255 | S_STRING2TTCN, // convert_op | |
256 | S_INT2ENUM // convert_op | |
970ed795 EL |
257 | }; |
258 | ||
259 | enum component_t { | |
260 | C_ALL, | |
261 | C_ANY | |
262 | }; | |
263 | ||
264 | private: | |
265 | statementtype_t statementtype; | |
266 | /// The statement block this statement belongs to. | |
267 | StatementBlock *my_sb; | |
268 | union { | |
269 | Assignment *ass; ///< used by S_ASSIGNMENT | |
270 | Definition *def; ///< used by S_DEF | |
271 | StatementBlock *block; ///< used by S_BLOCK | |
272 | LogArguments *logargs; ///< used by S_ACTION, S_LOG, S_STOP_TESTCASE | |
273 | struct { | |
274 | Reference *portref; /**< NULL means any/all */ | |
275 | union { | |
276 | struct { | |
277 | TemplateInstance *sendpar; | |
278 | Value *toclause; | |
279 | union { | |
280 | struct { | |
281 | Value *timer; | |
282 | bool nowait; | |
283 | AltGuards *body; | |
284 | } call; | |
285 | Value *replyval; | |
286 | struct { | |
287 | Reference *signature_ref; | |
288 | Type *signature; /**< only for caching */ | |
289 | } raise; | |
290 | }; | |
291 | } s; | |
292 | struct { | |
293 | TemplateInstance *rcvpar; | |
294 | TemplateInstance *fromclause; | |
295 | struct { | |
296 | Reference *value; | |
297 | ParamRedirect *param; | |
298 | Reference *sender; | |
299 | } redirect; | |
300 | union { | |
301 | TemplateInstance *getreply_valuematch; | |
302 | struct { | |
303 | Reference *signature_ref; | |
304 | Type *signature; /**< only for caching */ | |
305 | bool timeout; | |
306 | bool in_call, call_has_timer; | |
307 | } ctch; /**< catch */ | |
308 | }; | |
309 | } r; | |
310 | }; | |
311 | } port_op; /**< used by S_SEND, S_CALL, S_REPLY, S_RAISE, | |
312 | S_RECEIVE, S_CHECK_RECEIVE, S_TRIGGER, | |
313 | S_GETCALL, S_CHECK_GETCALL, S_GETREPLY, S_CHECK_GETREPLY, | |
314 | S_CATCH, S_CHECK_CATCH, S_CHECK, S_CLEAR, | |
315 | S_START_PORT, S_STOP_PORT, S_HALT */ | |
316 | ||
317 | struct { | |
318 | Reference *timerref; /**< 0 means any/all */ | |
319 | Value *value; | |
320 | } timer_op; ///< used by S_START_TIMER, S_STOP_TIMER, S_TIMEOUT | |
321 | ||
322 | struct { | |
323 | Value *compref1; | |
324 | Reference *portref1; | |
325 | Value *compref2; | |
326 | Reference *portref2; | |
327 | } config_op; ///< used by S_CONNECT, S_MAP, S_DISCONNECT, S_UNMAP | |
328 | ||
329 | struct { | |
330 | Value *compref; /**< if S_STOP_COMP, S_KILL then compref==0 | |
331 | means ALL */ | |
332 | union { | |
333 | component_t any_or_all; | |
334 | /**< used if S_DONE, S_KILLED and compref==0 */ | |
335 | struct { | |
336 | TemplateInstance *donematch; | |
337 | Reference *redirect; | |
338 | } donereturn; /**< used if S_DONE and compref!=0 */ | |
339 | Ref_base *funcinstref; /**< used if S_START_COMP */ | |
340 | struct {/** used if S_START_COMP_REFD */ | |
341 | Value *value; | |
342 | union { | |
343 | ParsedActualParameters *t_list1; | |
344 | ActualParList *ap_list2; | |
345 | }; | |
346 | } derefered; | |
347 | }; | |
348 | } comp_op; /**< used by S_START_COMP, S_START_COMP_REFD, S_STOP_COMP, | |
349 | S_KILL, S_KILLED, S_DONE */ | |
350 | ||
351 | struct { | |
352 | Value *verdictval; | |
353 | LogArguments *logargs; | |
354 | } setverdict; | |
355 | ||
356 | Value *deactivate; ///< used by S_DEACTIVATE | |
357 | AltGuards *ags; ///< used by S_ALT and S_INTERLEAVE | |
358 | ||
359 | struct { | |
360 | Ref_pard *tcref; | |
361 | Value *timerval; | |
362 | } testcase_inst; | |
363 | ||
364 | struct { | |
365 | Value *value; | |
366 | union { | |
367 | TemplateInstances *t_list1; | |
368 | ActualParList *ap_list2; | |
369 | }; | |
370 | Value *timerval; | |
371 | } execute_refd; | |
372 | ||
373 | Ref_pard *ref_pard; | |
374 | ||
375 | struct { | |
376 | Value *value; | |
377 | union { | |
378 | ParsedActualParameters *t_list1; | |
379 | ActualParList *ap_list2; | |
380 | }; | |
381 | } fau_refd; /**< used by S_ACTIVATE_REFD, S_UNKNOWN_INVOKED, | |
382 | S_FUNCTION_INVOKED, S_ALTSTEP_INVOKED (function, altstep, or unknown) */ | |
383 | ||
384 | struct { | |
385 | union { | |
386 | Value *expr; | |
387 | struct { | |
388 | bool varinst; | |
389 | union { | |
390 | Assignment *init_ass; | |
391 | Definitions *init_varinst; | |
392 | }; | |
393 | Value *finalexpr; | |
394 | Assignment *step; | |
395 | } for_stmt; | |
396 | }; | |
397 | StatementBlock *block; | |
398 | string *label_next; /**< label for continue, left as 0 if not needed */ | |
399 | string *il_label_end; /**< label for break in interleave - if needed */ | |
400 | bool has_cnt; /**< Has continue with effect on the loop */ | |
401 | bool has_brk; /**< Has break with effect on the loop */ | |
402 | bool has_cnt_in_ags; /**< Has continue inside embedded ags(AltGuards)*/ | |
403 | bool iterate_once; /**< do-while loop has constant false expr */ | |
404 | bool is_ilt; /**< Is compiled specially with ilt_generate_code_... */ | |
405 | } loop; | |
406 | ||
407 | struct { | |
408 | IfClauses *ics; /**< if-clauses */ | |
409 | StatementBlock *elseblock; /**< the last else-block */ | |
410 | Location *elseblock_location; /**< location of the last else-block */ | |
411 | } if_stmt; | |
412 | ||
413 | struct { | |
414 | Value *expr; | |
415 | SelectCases *scs; | |
416 | } select; | |
417 | ||
418 | struct { | |
419 | Value *v; | |
420 | Template *t; | |
421 | bool gen_restriction_check; // set in chk_return() | |
422 | } returnexpr; | |
423 | ||
424 | struct { | |
425 | Identifier *id; | |
426 | size_t stmt_idx; /**< index of the statement within its block */ | |
427 | string *clabel; /**< C++ label identifier in the generated code */ | |
428 | bool used; | |
429 | } label; | |
430 | ||
431 | struct { | |
432 | Identifier *id; | |
433 | size_t stmt_idx; /**< index of the statement within its block */ | |
434 | Statement *label; /**< points to the referenced label */ | |
435 | bool jumps_forward; /**< indicates the direction of the jump */ | |
436 | } go_to; | |
437 | ||
438 | struct { | |
439 | Statement *loop_stmt; /**< loop that can be exited by the break*/ | |
440 | AltGuards *ags; /**< altstep, alt, interleave, call */ | |
441 | } brk_cnt; // break or continue | |
442 | ||
443 | struct { | |
444 | Ref_base *ref; | |
445 | Value *val; | |
446 | } undefstartstop; | |
447 | ||
448 | struct { // S_STRING2TTCN | |
449 | Value* val; | |
450 | Reference* ref; | |
3abe9331 | 451 | } convert_op; |
970ed795 EL |
452 | }; |
453 | ||
454 | Statement(const Statement& p); ///< copy disabled | |
455 | Statement& operator=(const Statement& p); ///< assignment disabled | |
456 | void clean_up(); | |
457 | public: | |
a38c6d4c | 458 | /** Constructor used by S_ERROR, S_STOP_EXEC and S_REPEAT, S_BREAK, |
459 | * S_CONTINUE, S_START_PROFILER and S_STOP_PROFILER */ | |
970ed795 EL |
460 | Statement(statementtype_t p_st); |
461 | /** Constructor used by S_START_UNDEF and S_STOP_UNDEF */ | |
462 | Statement(statementtype_t p_st, Ref_base *p_ref, Value *p_val); | |
463 | /** Constructor used by S_FUNCTION_INSTANCE, S_ALTSTEP_INSTANCE, | |
464 | * S_UNKNOWN_INSTANCE, S_ACTIVATE */ | |
465 | Statement(statementtype_t p_st, Ref_pard *p_ref); | |
466 | /** S_ACTIVATE_REFD , S_FUNCTION_INSTANCE_REFD */ | |
467 | Statement(statementtype_t p_st, Value *p_derefered_value, | |
468 | ParsedActualParameters *p_ap_list); | |
469 | /** Constructor used by S_DEF */ | |
470 | Statement(statementtype_t p_st, Definition *p_def); | |
471 | /** Constructor used by S_ASSIGNMENT */ | |
472 | Statement(statementtype_t p_st, Assignment *p_ass); | |
473 | /** Constructor used by S_BLOCK */ | |
474 | Statement(statementtype_t p_st, StatementBlock *p_block); | |
475 | /** Constructor used by S_LOG and S_ACTION */ | |
476 | Statement(statementtype_t p_st, LogArguments *p_logargs); | |
477 | /** Constructor used by S_LABEL and S_GOTO */ | |
478 | Statement(statementtype_t p_st, Identifier *p_id); | |
479 | /** Constructor used by S_IF */ | |
480 | Statement(statementtype_t p_st, IfClauses *p_ics, StatementBlock *p_block, | |
481 | Location *p_loc); | |
482 | /** Constructor used by S_SELECT */ | |
483 | Statement(statementtype_t p_st, Value *p_expr, SelectCases *p_scs); | |
484 | /** Constructor used by S_FOR */ | |
485 | Statement(statementtype_t p_st, Definitions *p_defs, Assignment *p_ass, | |
486 | Value *p_final, Assignment *p_step, StatementBlock *p_block); | |
487 | /** Constructor used by S_WHILE, S_DOWHILE */ | |
488 | Statement(statementtype_t p_st, Value *p_val, StatementBlock *p_block); | |
489 | /** Constructor used by S_ALT and S_INTERLEAVE */ | |
490 | Statement(statementtype_t p_st, AltGuards *p_ags); | |
491 | /** Constructor used by S_RETURN */ | |
492 | Statement(statementtype_t p_st, Template *p_temp); | |
493 | /** Constructor used by S_DEACTIVATE, S_STOP_COMP, S_KILL, S_KILLED */ | |
494 | Statement(statementtype_t p_st, Value *p_val); | |
495 | /** Constructor used by S_SETVERDICT */ | |
496 | Statement(statementtype_t p_st, Value *p_val, LogArguments *p_logargs); | |
497 | /** Constructor used by S_SEND */ | |
498 | Statement(statementtype_t p_st, Reference *p_ref, | |
499 | TemplateInstance *p_templinst, Value *p_val); | |
500 | /** Constructor used by S_CALL */ | |
501 | Statement(statementtype_t p_st, Reference *p_ref, | |
502 | TemplateInstance *p_templinst, Value *p_timerval, | |
503 | bool p_nowait, Value *p_toclause, AltGuards *p_callbody); | |
504 | /** Constructor used by S_REPLY */ | |
505 | Statement(statementtype_t p_st, Reference *p_ref, | |
506 | TemplateInstance *p_templinst, Value *p_replyval, | |
507 | Value *p_toclause); | |
508 | /** Constructor used by S_RAISE */ | |
509 | Statement(statementtype_t p_st, Reference *p_ref, | |
510 | Reference *p_sig, TemplateInstance *p_templinst, | |
511 | Value *p_toclause); | |
512 | /** Constructor used by S_RECEIVE, S_CHECK_RECEIVE and | |
513 | * S_TRIGGER. p_ref==0 means any port. */ | |
514 | Statement(statementtype_t p_st, Reference *p_ref, | |
515 | TemplateInstance *p_templinst, TemplateInstance *p_fromclause, | |
516 | Reference *p_redirectval, Reference *p_redirectsender); | |
517 | /** Constructor used by S_GETCALL and S_CHECK_GETCALL. p_ref==0 | |
518 | * means any port. */ | |
519 | Statement(statementtype_t p_st, Reference *p_ref, | |
520 | TemplateInstance *p_templinst, TemplateInstance *p_fromclause, | |
521 | ParamRedirect *p_redirectparam, Reference *p_redirectsender); | |
522 | /** Constructor used by S_GETREPLY and S_CHECK_GETREPLY. p_ref==0 | |
523 | * means any port. */ | |
524 | Statement(statementtype_t p_st, Reference *p_ref, | |
525 | TemplateInstance *p_templinst, TemplateInstance *p_valuematch, | |
526 | TemplateInstance *p_fromclause, | |
527 | Reference *p_redirectval, ParamRedirect *p_redirectparam, | |
528 | Reference *p_redirectsender); | |
529 | /** Constructor used by S_CATCH and S_CHECK_CATCH. p_ref==0 means | |
530 | * any port. */ | |
531 | Statement(statementtype_t p_st, Reference *p_ref, | |
532 | Reference *p_sig, TemplateInstance *p_templinst, | |
533 | bool p_timeout, TemplateInstance *p_fromclause, | |
534 | Reference *p_redirectval, Reference *p_redirectsender); | |
535 | /** Constructor used by S_CHECK. p_ref==0 means any port. */ | |
536 | Statement(statementtype_t p_st, Reference *p_ref, | |
537 | TemplateInstance *p_fromclause, Reference *p_redirectsender); | |
538 | /** Constructor used by S_CLEAR, S_START_PORT and S_STOP_PORT. | |
539 | * p_ref==0 means all port. S_STOP_TIMER (p_ref==0: all timer), | |
540 | * S_TIMEOUT (p_ref==0: any timer). */ | |
541 | Statement(statementtype_t p_st, Reference *p_ref); | |
542 | /** Constructor used by S_START_COMP */ | |
543 | Statement(statementtype_t p_st, Value *p_compref, Ref_pard *p_funcinst); | |
544 | /** Constructor used by S_START_COMP_REFD */ | |
545 | Statement(statementtype_t p_st, Value *p_compref, Value *p_derefered_value, | |
546 | ParsedActualParameters *p_ap_list); | |
547 | /** Constructor used by S_DONE */ | |
548 | Statement(statementtype_t p_st, Value *p_compref, | |
549 | TemplateInstance *p_donematch, Reference *p_redirect); | |
550 | /** Constructor used by S_DONE, S_KILLED */ | |
551 | Statement(statementtype_t p_st, component_t p_anyall); | |
552 | /** Constructor used by S_CONNECT, S_DISCONNECT, S_MAP, S_UNMAP */ | |
553 | Statement(statementtype_t p_st, | |
554 | Value *p_compref1, Reference *p_portref1, | |
555 | Value *p_compref2, Reference *p_portref2); | |
556 | /** Constructor used by S_TESTCASE_INSTANCE */ | |
557 | Statement(statementtype_t p_st, Ref_pard *p_ref, Value *p_val); | |
558 | /** Constructor used by S_ACTIVATE_REFD */ | |
559 | Statement(statementtype_t p_st, Value *p_derefered_value, | |
560 | TemplateInstances *p_ap_list, Value *p_val); | |
3abe9331 | 561 | /** Constructor used by S_STRING2TTCN, S_INT2ENUM */ |
970ed795 EL |
562 | Statement(statementtype_t p_st, Value* p_val, Reference* p_ref); |
563 | virtual ~Statement(); | |
564 | virtual Statement* clone() const; | |
565 | virtual void dump(unsigned int level) const; | |
566 | statementtype_t get_statementtype() const { return statementtype; } | |
567 | StatementBlock *get_my_sb() const { return my_sb; } | |
568 | size_t get_my_sb_index() const; | |
569 | const char *get_stmt_name() const; | |
570 | const Identifier& get_labelid() const; | |
571 | /** Returns whether the label is used by goto statements, applicable if | |
572 | * \a this is a label (S_LABEL) */ | |
573 | bool label_is_used() const; | |
574 | /** Returns whether the goto statement jumps forward in the statement block, | |
575 | * applicable if \a this is a goto (S_GOTO) */ | |
576 | bool goto_jumps_forward() const; | |
577 | private: | |
578 | /** Returns the c++ identifier of the label, applicable if \a this is a | |
579 | * label (S_LABEL) */ | |
580 | const string& get_clabel(); | |
581 | public: | |
582 | /** Applicable if \a this is a definition (S_DEF) */ | |
583 | Definition *get_def() const; | |
584 | /** Applicable if \a this is an alt (S_ALT) or interleave (S_INTERLEAVE) */ | |
585 | AltGuards *get_ags() const; | |
586 | /** Applicable if \a this is a block (S_BLOCK) or a loop | |
587 | * (S_FOR, S_WHILE, S_DOWHILE) */ | |
588 | StatementBlock *get_block() const; | |
589 | virtual void set_my_scope(Scope *p_scope); | |
590 | virtual void set_fullname(const string& p_fullname); | |
591 | /** pass down to embedded statementblocks */ | |
592 | void set_my_sb(StatementBlock *p_sb, size_t p_index); | |
593 | void set_my_def(Definition *p_def); | |
594 | /** used in S_REPEAT */ | |
595 | void set_my_ags(AltGuards *p_ags); | |
596 | /** used in S_BREAK and S_CONTINUE */ | |
597 | void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt); | |
598 | /** Returns true if the statement following \a this in a statement | |
599 | * block will never be executed sequentially after \a this. */ | |
600 | bool is_terminating() const; | |
601 | StatementBlock::returnstatus_t has_return() const; | |
602 | bool is_receiving_stmt() const; | |
603 | bool has_receiving_stmt() const; | |
604 | /** Indicates whether the C++ equivalent of the statement can | |
605 | * return ALT_REPEAT. Applicable to receiving statements only. */ | |
606 | bool can_repeat() const; | |
607 | /* checking functions */ | |
608 | void chk(); | |
609 | /** checks whether the statement (including all embedded statements) are | |
610 | * allowed in an interleaved construct */ | |
611 | void chk_allowed_interleave(); | |
612 | private: | |
613 | void chk_start_undef(); | |
614 | void chk_stop_undef(); | |
615 | void chk_unknown_instance(); | |
616 | void chk_unknown_invoke(); | |
617 | void chk_assignment(); | |
618 | void chk_function(); | |
619 | void chk_block(); | |
620 | /* checks log, action */ | |
621 | void chk_log_action(LogArguments *logargs); | |
622 | void chk_goto(); | |
623 | void chk_if(); | |
624 | void chk_select(); | |
625 | void chk_for(); | |
626 | void chk_while(); | |
627 | void chk_do_while(); | |
628 | void chk_break(); | |
629 | void chk_continue(); | |
630 | void chk_alt(); | |
631 | void chk_repeat(); | |
632 | void chk_interleave(); | |
633 | void chk_altstep(); | |
634 | void chk_return(); | |
635 | void chk_activate(); | |
636 | void chk_activate_refd(); | |
637 | void chk_deactivate(); | |
638 | void chk_send(); | |
639 | void chk_call(); | |
640 | void chk_reply(); | |
641 | void chk_raise(); | |
642 | /* checks receive, check-receive trigger */ | |
643 | void chk_receive(); | |
644 | /* checks getcall, check-getcall */ | |
645 | void chk_getcall(); | |
646 | /* checks getreply, check-getreply */ | |
647 | void chk_getreply(); | |
648 | /* checks catch, check-catch */ | |
649 | void chk_catch(); | |
650 | void chk_check(); | |
651 | void chk_clear(); | |
652 | /** checks start port, stop port, halt */ | |
653 | void chk_start_stop_port(); | |
654 | void chk_start_comp(); | |
655 | void chk_start_comp_refd(); | |
656 | /* checks stop comp, kill, killed */ | |
657 | void chk_stop_kill_comp(); | |
658 | void chk_done(); | |
659 | void chk_killed(); | |
660 | /* checks connect and disconnect */ | |
661 | void chk_connect(); | |
662 | /* checks map and unmap */ | |
663 | void chk_map(); | |
664 | void chk_start_timer(); | |
665 | void chk_stop_timer_timeout(); | |
666 | void chk_setverdict(); | |
667 | void chk_execute(); | |
668 | void chk_execute_refd(); | |
669 | ||
670 | /** Checks whether \a p_ref points to a port or port parameter. | |
671 | * If \a p_ref refers to a port array the array indices within \a | |
672 | * p_ref are also checked. Returns a pointer to the port type if | |
673 | * available or NULL otherwise. */ | |
674 | Type *chk_port_ref(Reference *p_ref); | |
675 | /** Checks the `to' clause of a port operation. Field | |
676 | * port_op.s.toclause shall be a component reference (or an | |
677 | * address) depending on the extension attributes of \a | |
678 | * port_type. */ | |
679 | void chk_to_clause(Type *port_type); | |
680 | /** Checks the `from' clause and `sender' redirect of a port | |
681 | * operation. Type of field port_op.r.fromclause and | |
682 | * port_op.r.redirect.sender shall be a component type (or | |
683 | * address) depending on the extension attributes of \a | |
684 | * port_type. */ | |
685 | void chk_from_clause(Type *port_type); | |
686 | /** Checks the response and exception handling part of a call | |
687 | * operation. Arguments \a port_type \a signature point to the | |
688 | * port type and signature used in the call operation. */ | |
689 | void chk_call_body(Type *port_type, Type *signature); | |
690 | /** Determines and returns the type of the outgoing message or | |
691 | * signature based on a template instance \a p_ti. */ | |
692 | static Type *get_outgoing_type(TemplateInstance *p_ti); | |
693 | /** Determines and returns the type of the incoming message or | |
694 | * signature based on a template instance \a p_ti and an optional | |
695 | * value redirect \a p_val_redir. Flag \a p_val_redir_checked is | |
696 | * set to true if the value redirect was analyzed during this | |
697 | * operation. */ | |
698 | Type *get_incoming_type(TemplateInstance *p_ti, Reference *p_val_redir, | |
699 | bool& p_val_redir_checked); | |
700 | /** Checks the variable reference of a value redirect. If | |
701 | * parameter \a p_type is not NULL it points to the type that the | |
702 | * variable reference should match. The type of variable is | |
703 | * returned. */ | |
704 | Type *chk_value_redirect(Reference *p_ref, Type *p_type); | |
705 | /** Checks the variable reference of a sender redirect. The type | |
706 | * of the variable (or NULL in case of non-existent sender clause | |
707 | * or error) is returned. The type of the variable is also | |
708 | * checked: it shall be a component type or \a address_type (if | |
709 | * it is not NULL). */ | |
710 | Type *chk_sender_redirect(Type *address_type); | |
711 | /** Checks whether \a p_ref points to a signature. The type | |
712 | * describing the respective signature is returned or NULL in | |
713 | * case of error. */ | |
714 | static Type *chk_signature_ref(Reference *p_ref); | |
715 | /** Checks whether \a p_ref points to a timer or timer parameter. | |
716 | * If \a p_ref refers to a timer array the array indices within | |
717 | * \a p_ref are also checked. */ | |
718 | static void chk_timer_ref(Reference *p_ref); | |
719 | /** Checks whether \a p_val is a component reference (i.e. its | |
720 | * type is a component type). Returns a pointer to the component | |
721 | * type if available or NULL otherwise. Flags \a allow_mtc and \a | |
722 | * allow_system indicate whether the mtc or system component | |
af710487 | 723 | * reference is acceptable in this context. */ |
724 | Type *chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system); | |
970ed795 EL |
725 | /** Checks an endpoint for a port connection or mapping. Parameter |
726 | * \a p_compref is a component reference, \a p_portref refers to | |
727 | * a port within the corresponding component type. A pointer to | |
728 | * the referred port type (or NULL in case of error) is | |
729 | * returned. */ | |
730 | Type *chk_conn_endpoint(Value *p_compref, Reference *p_portref, | |
731 | bool allow_system); | |
732 | void chk_string2ttcn(); | |
3abe9331 | 733 | void chk_int2enum(); |
970ed795 EL |
734 | public: |
735 | /** Sets the code section selector of all embedded values and | |
736 | * templates to \a p_code_section. */ | |
737 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
738 | char* generate_code(char *str); | |
739 | void generate_code_expr(expression_struct *expr); | |
740 | void ilt_generate_code(ILT *ilt); | |
741 | ||
742 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
743 | */ | |
744 | virtual void set_parent_path(WithAttribPath* p_path); | |
745 | private: | |
746 | char *generate_code_standalone(char *str); | |
747 | /** used for function and altstep instances */ | |
748 | char *generate_code_funcinst(char *str); | |
749 | char *generate_code_invoke(char *str); | |
750 | char *generate_code_block(char *str); | |
751 | char *generate_code_log(char *str); | |
752 | char* generate_code_string2ttcn(char *str); | |
753 | char *generate_code_testcase_stop(char *str); | |
754 | char *generate_code_label(char *str); | |
755 | char *generate_code_goto(char *str); | |
756 | char *generate_code_if(char *str); | |
757 | char *generate_code_select(char *str); | |
758 | char *generate_code_for(char *str); | |
759 | char *generate_code_while(char *str); | |
760 | char *generate_code_dowhile(char *str); | |
761 | char *generate_code_break(char *str); | |
762 | char *generate_code_continue(char *str); | |
763 | char *generate_code_repeat(char *str); | |
764 | char *generate_code_interleave(char *str); | |
765 | void ilt_generate_code_interleave(ILT *ilt); | |
766 | void ilt_generate_code_alt(ILT *ilt); | |
767 | void ilt_generate_code_receiving(ILT *ilt); | |
768 | void ilt_generate_code_def(ILT *ilt); | |
769 | void ilt_generate_code_if(ILT *ilt); | |
770 | void ilt_generate_code_select(ILT *ilt); | |
771 | void ilt_generate_code_call(ILT *ilt); | |
772 | void ilt_generate_code_for(ILT *ilt); | |
773 | void ilt_generate_code_while(ILT *ilt); | |
774 | void ilt_generate_code_dowhile(ILT *ilt); | |
775 | char *generate_code_return(char *str); | |
776 | char *generate_code_activate(char *str); | |
777 | char *generate_code_activate_refd(char *str); | |
778 | char *generate_code_deactivate(char *str); | |
779 | char *generate_code_send(char *str); | |
780 | char *generate_code_call(char *str); | |
781 | char *generate_code_reply(char *str); | |
782 | char *generate_code_raise(char *str); | |
783 | char *generate_code_portop(char *str, const char *opname); | |
784 | char *generate_code_startcomp(char *str); | |
785 | char *generate_code_startcomp_refd(char *str); | |
786 | char *generate_code_compop(char *str, const char *opname); | |
787 | char *generate_code_configop(char *str, const char *opname); | |
788 | char *generate_code_starttimer(char *str); | |
789 | char *generate_code_stoptimer(char *str); | |
790 | char *generate_code_setverdict(char *str); | |
791 | char *generate_code_action(char *str); | |
792 | char *generate_code_testcaseinst(char *str); | |
793 | char *generate_code_execute_refd(char *str); | |
794 | /** used for receive, check-receive, trigger */ | |
795 | void generate_code_expr_receive(expression_struct *expr, | |
796 | const char *opname); | |
797 | /** used for getcall, check-getcall */ | |
798 | void generate_code_expr_getcall(expression_struct *expr, | |
799 | const char *opname); | |
800 | /** used for getreply, check-getreply */ | |
801 | void generate_code_expr_getreply(expression_struct *expr, | |
802 | const char *opname); | |
803 | /** used for catch, check-catch */ | |
804 | void generate_code_expr_catch(expression_struct *expr); | |
805 | void generate_code_expr_check(expression_struct *expr); | |
806 | void generate_code_expr_done(expression_struct *expr); | |
807 | void generate_code_expr_killed(expression_struct *expr); | |
808 | void generate_code_expr_timeout(expression_struct *expr); | |
809 | /** Generates the C++ equivalent of \a port_op.s.sendpar into \a expr. | |
810 | * When \a sendpar contains a simple specific value the value -> template | |
811 | * conversion is eliminated for better run-time performance. */ | |
812 | void generate_code_expr_sendpar(expression_struct *expr); | |
813 | void generate_code_expr_fromclause(expression_struct *expr); | |
814 | void generate_code_expr_senderredirect(expression_struct *expr); | |
815 | /** Creates the string equivalent of port reference \a p_ref and | |
816 | * appends it to \a expr->expr. Used in configuration operations | |
817 | * when the component type cannot be determined from the | |
818 | * component reference. */ | |
819 | static void generate_code_portref(expression_struct *expr, | |
820 | Reference *p_ref); | |
3abe9331 | 821 | char* generate_code_int2enum(char* str); |
970ed795 EL |
822 | }; |
823 | ||
824 | /** | |
825 | * Class to store a VariableAssignment or TemplateAssignment. | |
826 | * Class is entirely unrelated to Common::Assignment and Asn::Assignment. | |
827 | */ | |
828 | class Assignment : public Node, public Location { | |
829 | public: | |
830 | enum asstype_t { | |
831 | ASS_UNKNOWN, ///< unknown assignment | |
832 | ASS_VAR, ///< variable assignment | |
833 | ASS_TEMPLATE, ///< template assignment | |
834 | ASS_ERROR ///< erroneous | |
835 | }; | |
836 | ||
837 | private: | |
838 | asstype_t asstype; | |
839 | Reference *ref; ///< reference to the "left hand side" | |
840 | union { | |
841 | Value *val; ///< RHS for a variable assignment | |
842 | Template *templ; ///< RHS for a template assignment | |
843 | }; | |
844 | /** true if the LHS is mentioned in the RHS */ | |
845 | bool self_ref; | |
846 | /** template restriction on ref, set in chk() for faster code generation */ | |
847 | template_restriction_t template_restriction; | |
848 | /** set in chk(), used by code generation */ | |
849 | bool gen_restriction_check; | |
850 | ||
851 | Assignment(const Assignment& p); | |
852 | Assignment& operator=(const Assignment& p); | |
853 | public: | |
854 | /** Creates a new template assignment. */ | |
855 | Assignment(Reference *p_ref, Template *p_templ); | |
856 | /** Creates a new variable assignment. */ | |
857 | Assignment(Reference *p_ref, Value *p_val); | |
858 | virtual ~Assignment(); | |
859 | virtual Assignment *clone() const; | |
860 | virtual void set_my_scope(Scope *p_scope); | |
861 | virtual void set_fullname(const string& p_fullname); | |
862 | virtual void dump(unsigned int level) const; | |
863 | private: | |
864 | void chk_unknown_ass(); | |
865 | void chk_var_ass(); | |
866 | void chk_template_ass(); | |
867 | void chk_template_restriction(); | |
868 | public: | |
869 | void chk(); | |
870 | /** Sets the code section selector of all embedded values and templates | |
871 | * to \a p_code_section. */ | |
872 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
873 | char *generate_code(char *str); | |
874 | }; | |
875 | ||
876 | /** | |
877 | * Class to store a ParamAssignment. | |
878 | */ | |
879 | class ParamAssignment : public Node, public Location { | |
880 | private: | |
881 | Identifier *id; | |
882 | Reference *ref; | |
883 | ||
884 | ParamAssignment(const ParamAssignment& p); | |
885 | ParamAssignment& operator=(const ParamAssignment& p); | |
886 | public: | |
887 | ParamAssignment(Identifier *p_id, Reference *p_ref); | |
888 | virtual ~ParamAssignment(); | |
889 | virtual ParamAssignment* clone() const; | |
890 | virtual void set_my_scope(Scope *p_scope); | |
891 | virtual void set_fullname(const string& p_fullname); | |
892 | const Identifier& get_id() const { return *id; } | |
893 | Reference *get_ref() const; | |
894 | Reference *steal_ref(); | |
895 | }; | |
896 | ||
897 | /** | |
898 | * Class to store a ParamAssignmentList | |
899 | */ | |
900 | class ParamAssignments : public Node { | |
901 | private: | |
902 | vector<ParamAssignment> parasss; | |
903 | ||
904 | ParamAssignments(const ParamAssignments& p); | |
905 | ParamAssignments& operator=(const ParamAssignments& p); | |
906 | public: | |
907 | ParamAssignments() : Node() { } | |
908 | virtual ~ParamAssignments(); | |
909 | virtual ParamAssignments* clone() const; | |
910 | virtual void set_my_scope(Scope *p_scope); | |
911 | virtual void set_fullname(const string& p_fullname); | |
912 | void add_parass(ParamAssignment *p_parass); | |
913 | size_t get_nof_parasss() const { return parasss.size(); } | |
914 | ParamAssignment *get_parass_byIndex(size_t p_i) const | |
915 | { return parasss[p_i]; } | |
916 | }; | |
917 | ||
918 | /** | |
919 | * Class to represent a variable or notused-symbol in | |
920 | * ParamAssignmentList of port redirect stuff. | |
921 | */ | |
922 | class VariableEntry : public Node, public Location { | |
923 | private: | |
924 | Reference *ref; /**< varref or notused if NULL. */ | |
925 | ||
926 | VariableEntry(const VariableEntry& p); | |
927 | VariableEntry& operator=(const VariableEntry& p); | |
928 | public: | |
929 | /** Creates a notused entry */ | |
930 | VariableEntry() : Node(), Location(), ref(0) { } | |
931 | VariableEntry(Reference *p_ref); | |
932 | virtual ~VariableEntry(); | |
933 | virtual VariableEntry* clone() const; | |
934 | virtual void set_my_scope(Scope *p_scope); | |
935 | virtual void set_fullname(const string& p_fullname); | |
936 | Reference *get_ref() const { return ref; } | |
937 | }; | |
938 | ||
939 | /** | |
940 | * Class to store a VariableEntries | |
941 | */ | |
942 | class VariableEntries : public Node { | |
943 | private: | |
944 | vector<VariableEntry> ves; | |
945 | ||
946 | VariableEntries(const VariableEntries& p); | |
947 | VariableEntries& operator=(const VariableEntries& p); | |
948 | public: | |
949 | VariableEntries() : Node() { } | |
950 | virtual ~VariableEntries(); | |
951 | virtual VariableEntries* clone() const; | |
952 | virtual void set_my_scope(Scope *p_scope); | |
953 | virtual void set_fullname(const string& p_fullname); | |
954 | void add_ve(VariableEntry *p_ve); | |
955 | size_t get_nof_ves() const { return ves.size(); } | |
956 | VariableEntry *get_ve_byIndex(size_t p_i) const { return ves[p_i]; } | |
957 | }; | |
958 | ||
959 | /** | |
960 | * Class to represent ParamAssignmentList in a param redirect of | |
961 | * getcall/getreply port operation. | |
962 | */ | |
963 | class ParamRedirect : public Node, public Location { | |
964 | public: | |
965 | enum parredirtype_t { | |
966 | P_ASS, /**< AssignmentList */ | |
967 | P_VAR /**< VariableList */ | |
968 | }; | |
969 | private: | |
970 | parredirtype_t parredirtype; | |
971 | union { | |
972 | ParamAssignments *parasss; | |
973 | VariableEntries *ves; | |
974 | }; | |
975 | ||
976 | ParamRedirect(const ParamRedirect& p); | |
977 | ParamRedirect& operator=(const ParamRedirect& p); | |
978 | public: | |
979 | ParamRedirect(ParamAssignments *p_parasss); | |
980 | ParamRedirect(VariableEntries *p_ves); | |
981 | virtual ~ParamRedirect(); | |
982 | virtual ParamRedirect* clone() const; | |
983 | virtual void set_my_scope(Scope *p_scope); | |
984 | virtual void set_fullname(const string& p_fullname); | |
985 | /** Performs some trivial checks on the variable references. | |
986 | * Used when the signature cannot be determined in a getcall or getreply | |
987 | * operation because of an error. */ | |
988 | void chk_erroneous(); | |
989 | /** Performs the checks on the param redirect clause. Parameter \a p_sig | |
990 | * points to the respective signature. Flag \a is_out is true if the | |
991 | * redirect belongs to a getreply operation (i.e. it may refer to out/inout | |
992 | * parameters) and false in case of getcall. */ | |
993 | void chk(Type *p_sig, bool is_out); | |
994 | private: | |
995 | /** Helper function for \a chk(). Used when AssignmentList is selected. | |
996 | * If the redirect is correct it converts the AssignmentList to an | |
997 | * equivalent VariableList for easier code generation. */ | |
998 | void chk_parasss(Type *p_sig, SignatureParamList *p_parlist, bool is_out); | |
999 | /** Helper function for \a chk(). Used when VariableList is selected. */ | |
1000 | void chk_ves(Type *p_sig, SignatureParamList *p_parlist, bool is_out); | |
1001 | /** Checks whether the reference \a p_ref points to a variable of type | |
1002 | * \a p_type. */ | |
1003 | static void chk_variable_ref(Reference *p_ref, Type *p_type); | |
1004 | public: | |
1005 | /** Sets the code section selector of all embedded values and templates | |
1006 | * to \a p_code_section. */ | |
1007 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1008 | void generate_code(expression_struct_t *expr); | |
1009 | }; | |
1010 | ||
1011 | /** | |
1012 | * Class to represent a LogArgument. | |
1013 | */ | |
1014 | class LogArgument : public Node, public Location { | |
1015 | public: | |
1016 | enum logargtype_t { | |
1017 | L_UNDEF, /**< undefined (set during parsing) */ | |
1018 | L_ERROR, /**< erroneous */ | |
1019 | L_TI, /**< template instance */ | |
1020 | L_VAL, /**< literal value or expression */ | |
1021 | L_MATCH, /**< match expression */ | |
1022 | L_MACRO, /**< macro value (%something) */ | |
1023 | L_REF, /**< reference */ | |
1024 | L_STR /**< literal character string */ | |
1025 | }; | |
1026 | ||
1027 | private: | |
1028 | logargtype_t logargtype; | |
1029 | union { | |
1030 | TemplateInstance *ti; ///< used by L_UNDEF and L_TI | |
1031 | Value *val; ///< used by L_VAL, L_MATCH, L_MACRO | |
1032 | Ref_base *ref; ///< used by L_REF | |
1033 | string *cstr; ///< used by L_STR | |
1034 | }; | |
1035 | ||
1036 | LogArgument(const LogArgument& p); | |
1037 | LogArgument& operator=(const LogArgument& p); | |
1038 | public: | |
1039 | LogArgument(TemplateInstance *p_ti); | |
1040 | virtual ~LogArgument(); | |
1041 | virtual LogArgument *clone() const; | |
1042 | virtual void set_my_scope(Scope *p_scope); | |
1043 | virtual void set_fullname(const string& p_fullname); | |
1044 | logargtype_t get_type() const { return logargtype; } | |
1045 | const string& get_str() const; | |
1046 | Value *get_val() const; | |
1047 | Ref_base *get_ref() const; | |
1048 | TemplateInstance *get_ti () const; | |
1049 | /** Appends the string \a p_str to \a cstr. Applicable only if | |
1050 | * \a logargtype is L_STR. */ | |
1051 | void append_str(const string& p_str); | |
1052 | void chk(); | |
1053 | virtual void dump(unsigned int level) const; | |
1054 | private: | |
1055 | void chk_ref(); | |
1056 | void chk_val(); | |
1057 | public: | |
1058 | /** Sets the code section selector of all embedded values and | |
1059 | * templates to \a p_code_section. */ | |
1060 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1061 | char *generate_code_log(char *str); | |
1062 | void chk_recursions(ReferenceChain& refch); | |
1063 | bool has_single_expr(); | |
1064 | void generate_code_expr(expression_struct *expr); | |
1065 | }; | |
1066 | ||
1067 | /** | |
1068 | * Class to represent LogArgumentList. | |
1069 | */ | |
1070 | class LogArguments : public Node { | |
1071 | private: | |
1072 | vector<LogArgument> logargs; | |
1073 | ||
1074 | LogArguments(const LogArguments& p); | |
1075 | LogArguments& operator=(const LogArguments& p); | |
1076 | public: | |
1077 | LogArguments() : Node() { } | |
1078 | virtual ~LogArguments(); | |
1079 | virtual LogArguments *clone() const; | |
1080 | void add_logarg(LogArgument *p_logarg); | |
1081 | size_t get_nof_logargs() const { return logargs.size(); } | |
1082 | LogArgument *get_logarg_byIndex(size_t p_i) const { return logargs[p_i]; } | |
1083 | virtual void set_my_scope(Scope *p_scope); | |
1084 | virtual void set_fullname(const string& p_fullname); | |
1085 | void chk(); | |
1086 | /** Joins adjacent strings into one LogArgument for more efficient | |
1087 | * code generation. */ | |
1088 | void join_strings(); | |
1089 | /** Sets the code section selector of all embedded values and | |
1090 | * templates to \a p_code_section. */ | |
1091 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1092 | char *generate_code(char *str); | |
1093 | void chk_recursions(ReferenceChain& refch); | |
1094 | bool has_single_expr(); | |
1095 | void generate_code_expr(expression_struct *expr); | |
1096 | }; | |
1097 | ||
1098 | /** | |
1099 | * Class to represent an if-clause: the condition and the statement | |
1100 | * block. Note that the else block is kept by Statement::if_stmt. | |
1101 | */ | |
1102 | class IfClause : public Node, public Location { | |
1103 | private: | |
1104 | Value *expr; /**< conditional expression */ | |
1105 | StatementBlock *block; | |
1106 | ||
1107 | IfClause(const IfClause& p); | |
1108 | IfClause& operator=(const IfClause& p); | |
1109 | public: | |
1110 | IfClause(Value *p_expr, StatementBlock *p_block); | |
1111 | virtual ~IfClause(); | |
1112 | virtual IfClause *clone() const; | |
1113 | virtual void set_my_scope(Scope *p_scope); | |
1114 | virtual void set_fullname(const string& p_fullname); | |
1115 | Value *get_expr() const { return expr; } | |
1116 | StatementBlock *get_block() const { return block; } | |
1117 | /* checking functions */ | |
1118 | bool has_receiving_stmt() const; | |
1119 | void chk(bool& unreach); | |
1120 | /** Sets the code section selector of all embedded values and | |
1121 | * templates to \a p_code_section. */ | |
1122 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1123 | char* generate_code(char *str, size_t& blockcount, | |
1124 | bool& unreach, bool& eachfalse); | |
1125 | void ilt_generate_code(ILT *ilt, const char *end_label, bool& unreach); | |
1126 | ||
1127 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1128 | */ | |
1129 | virtual void set_parent_path(WithAttribPath* p_path); | |
1130 | virtual void dump(unsigned int level) const; | |
1131 | }; | |
1132 | ||
1133 | /** | |
1134 | * Class to represent IfClauseList, a chain of if-else-if-else-if | |
1135 | */ | |
1136 | class IfClauses : public Node { | |
1137 | private: | |
1138 | vector<IfClause> ics; | |
1139 | ||
1140 | IfClauses(const IfClauses& p); | |
1141 | IfClauses& operator=(const IfClauses& p); | |
1142 | public: | |
1143 | IfClauses() : Node() { } | |
1144 | virtual ~IfClauses(); | |
1145 | virtual IfClauses* clone() const; | |
1146 | /// Called to add an "else-if" to a chain of "else-if"s | |
1147 | void add_ic(IfClause *p_ic); | |
1148 | /// Called to add the first "if" to a chain of "else-if"s | |
1149 | void add_front_ic(IfClause *p_ic); | |
1150 | size_t get_nof_ics() const {return ics.size();} | |
1151 | IfClause *get_ic_byIndex(size_t p_i) const {return ics[p_i];} | |
1152 | virtual void set_my_scope(Scope *p_scope); | |
1153 | virtual void set_fullname(const string& p_fullname); | |
1154 | void set_my_sb(StatementBlock *p_sb, size_t p_index); | |
1155 | void set_my_def(Definition *p_def); | |
1156 | void set_my_ags(AltGuards *p_ags); | |
1157 | void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt); | |
1158 | StatementBlock::returnstatus_t has_return(StatementBlock *elseblock) const; | |
1159 | bool has_receiving_stmt() const; | |
1160 | /* checking functions */ | |
1161 | void chk(bool& unreach); | |
1162 | /** checks whether all embedded statements are allowed in an interleaved | |
1163 | * construct */ | |
1164 | void chk_allowed_interleave(); | |
1165 | /** Sets the code section selector of all embedded values and | |
1166 | * templates to \a p_code_section. */ | |
1167 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1168 | char* generate_code(char *str, size_t& blockcount, | |
1169 | bool& unreach, bool& eachfalse); | |
1170 | void ilt_generate_code(ILT *ilt, const char *end_label, bool& unreach); | |
1171 | ||
1172 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1173 | */ | |
1174 | virtual void set_parent_path(WithAttribPath* p_path); | |
1175 | virtual void dump(unsigned int level) const; | |
1176 | }; | |
1177 | ||
1178 | /** | |
1179 | * Class to represent a select-case: the template instance list and | |
1180 | * the statement block. | |
1181 | */ | |
1182 | class SelectCase : public Node, public Location { | |
1183 | private: | |
1184 | TemplateInstances *tis; | |
1185 | StatementBlock *block; | |
1186 | ||
1187 | SelectCase(const SelectCase& p); | |
1188 | SelectCase& operator=(const SelectCase& p); | |
1189 | public: | |
1190 | /** tis==0 means "else" case */ | |
1191 | SelectCase(TemplateInstances *p_tis, StatementBlock *p_block); | |
1192 | virtual ~SelectCase(); | |
1193 | virtual SelectCase* clone() const; | |
1194 | virtual void set_my_scope(Scope *p_scope); | |
1195 | virtual void set_fullname(const string& p_fullname); | |
1196 | TemplateInstances* get_tis() const { return tis; } | |
1197 | StatementBlock *get_block() const { return block; } | |
1198 | /* checking functions */ | |
1199 | void chk(Type *p_gov, bool& unreach); | |
1200 | /** Sets the code section selector of all embedded values and | |
1201 | * templates to \a p_code_section. */ | |
1202 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1203 | char* generate_code_if(char *str, const char *tmp_prefix, | |
1204 | const char *expr_name, size_t idx, bool& unreach); | |
1205 | char* generate_code_stmt(char *str, const char *tmp_prefix, | |
1206 | size_t idx, bool& unreach); | |
1207 | void ilt_generate_code_stmt(ILT *ilt, const char *tmp_prefix, | |
1208 | size_t idx, bool& unreach); | |
1209 | ||
1210 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1211 | */ | |
1212 | virtual void set_parent_path(WithAttribPath* p_path); | |
1213 | }; | |
1214 | ||
1215 | /** | |
1216 | * Class to represent SelectCaseList. | |
1217 | */ | |
1218 | class SelectCases : public Node { | |
1219 | private: | |
1220 | vector<SelectCase> scs; | |
1221 | ||
1222 | SelectCases(const SelectCases& p); | |
1223 | SelectCases& operator=(const SelectCases& p); | |
1224 | public: | |
1225 | SelectCases() : Node() { } | |
1226 | virtual ~SelectCases(); | |
1227 | virtual SelectCases* clone() const; | |
1228 | void add_sc(SelectCase *p_sc); | |
1229 | size_t get_nof_scs() const {return scs.size();} | |
1230 | SelectCase *get_sc_byIndex(size_t p_i) const {return scs[p_i];} | |
1231 | virtual void set_my_scope(Scope *p_scope); | |
1232 | virtual void set_fullname(const string& p_fullname); | |
1233 | void set_my_sb(StatementBlock *p_sb, size_t p_index); | |
1234 | void set_my_def(Definition *p_def); | |
1235 | void set_my_ags(AltGuards *p_ags); | |
1236 | void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt); | |
1237 | StatementBlock::returnstatus_t has_return() const; | |
1238 | bool has_receiving_stmt() const; | |
1239 | /* checking functions */ | |
1240 | /** p_gov is the governor type of select expression */ | |
1241 | void chk(Type *p_gov); | |
1242 | /** checks whether all embedded statements are allowed in an interleaved | |
1243 | * construct */ | |
1244 | void chk_allowed_interleave(); | |
1245 | /** Sets the code section selector of all embedded values and | |
1246 | * templates to \a p_code_section. */ | |
1247 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1248 | char *generate_code(char *str, const char *tmp_prefix, | |
1249 | const char *expr_name); | |
1250 | void ilt_generate_code(ILT *ilt, const char *tmp_prefix, | |
1251 | const char *expr_init, const char *expr_name); | |
1252 | ||
1253 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1254 | */ | |
1255 | virtual void set_parent_path(WithAttribPath* p_path); | |
1256 | }; | |
1257 | ||
1258 | /** | |
1259 | * Class to represent an alt guard. | |
1260 | */ | |
1261 | class AltGuard : public Node, public Location { | |
1262 | public: | |
1263 | enum altguardtype_t { | |
1264 | AG_OP, | |
1265 | AG_REF, | |
1266 | AG_INVOKE, | |
1267 | AG_ELSE | |
1268 | }; | |
1269 | ||
1270 | private: | |
1271 | altguardtype_t altguardtype; | |
1272 | Value *expr; /**< conditional expression */ | |
1273 | union { | |
1274 | Ref_pard *ref; | |
1275 | Statement *stmt; | |
1276 | void *dummy; | |
1277 | struct { | |
1278 | Value *v; | |
1279 | Ttcn::TemplateInstances *t_list; | |
1280 | Ttcn::ActualParList *ap_list; | |
1281 | } invoke; | |
1282 | }; | |
1283 | StatementBlock *block; | |
1284 | ||
1285 | AltGuard(const AltGuard& p); | |
1286 | AltGuard& operator=(const AltGuard& p); | |
1287 | public: | |
1288 | /** Constructor used by AG_OP */ | |
1289 | AltGuard(Value *p_expr, Statement *p_stmt, StatementBlock *p_block); | |
1290 | /** Constructor used by AG_REF */ | |
1291 | AltGuard(Value *p_expr, Ref_pard *p_ref, StatementBlock *p_block); | |
1292 | /** Constructor used by AG_INVOKE */ | |
1293 | AltGuard(Value *p_expr, Value *p_v, | |
1294 | Ttcn::TemplateInstances *p_t_list, StatementBlock *p_block); | |
1295 | /** Constructor used by AG_ELSE */ | |
1296 | AltGuard(StatementBlock *p_block); | |
1297 | virtual ~AltGuard(); | |
1298 | virtual AltGuard* clone() const; | |
1299 | virtual void set_my_scope(Scope *p_scope); | |
1300 | void set_my_sb(StatementBlock *p_sb, size_t p_index); | |
1301 | virtual void set_fullname(const string& p_fullname); | |
1302 | altguardtype_t get_type() const { return altguardtype; } | |
1303 | Value *get_guard_expr() const; | |
1304 | Ref_pard *get_guard_ref() const; | |
1305 | Statement *get_guard_stmt() const; | |
1306 | StatementBlock *get_block() const { return block; } | |
1307 | void set_my_def(Definition *p_def); | |
1308 | void set_my_ags(AltGuards *p_ags); | |
1309 | void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt); | |
1310 | /* checking functions */ | |
1311 | void chk(); | |
1312 | /** Sets the code section selector of all embedded values and templates | |
1313 | * to \a p_code_section. */ | |
1314 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1315 | /** generates altstep instantiation call */ | |
1316 | void generate_code_invoke_instance(expression_struct *p_expr); | |
1317 | }; | |
1318 | ||
1319 | /** | |
1320 | * Class to represent AltGuardList. | |
1321 | */ | |
1322 | class AltGuards : public Node { | |
1323 | private: | |
1324 | vector<AltGuard> ags; | |
1325 | Scope *my_scope; | |
1326 | /** Indicates whether a repeat statement was found within the branches. */ | |
1327 | bool has_repeat; | |
1328 | /** C++ label identifier that points to the beginning of the alternative. | |
1329 | * Used only in alt constructs and within call statements. */ | |
1330 | string *label; | |
1331 | bool is_altstep; | |
1332 | string *il_label_end; /** label for break when ags is not compiled to loop*/ | |
1333 | ||
1334 | AltGuards(const AltGuards& p); | |
1335 | AltGuards& operator=(const AltGuards& p); | |
1336 | public: | |
1337 | AltGuards() : Node(), my_scope(0), has_repeat(false), label(0), | |
1338 | is_altstep(false), il_label_end(0) { } | |
1339 | virtual ~AltGuards(); | |
1340 | virtual AltGuards* clone() const; | |
1341 | void add_ag(AltGuard *p_ag); | |
1342 | size_t get_nof_ags() const {return ags.size();} | |
1343 | AltGuard *get_ag_byIndex(size_t p_i) const {return ags[p_i];} | |
1344 | virtual void set_my_scope(Scope *p_scope); | |
1345 | virtual void set_fullname(const string& p_fullname); | |
1346 | void set_my_sb(StatementBlock *p_sb, size_t p_index); | |
1347 | void set_my_def(Definition *p_def); | |
1348 | /** Sets the ags pointer of all embedded repeat statements to \a p_ags. */ | |
1349 | void set_my_ags(AltGuards *p_ags); | |
1350 | void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt); | |
1351 | void repeat_found() { has_repeat = true; } | |
1352 | /** Returns the C++ label identifier that is used in code generation for | |
1353 | * repeat statements. NULL pointer indicates that \a this belongs to an | |
1354 | * altstep so the C++ equivalent of repeat shall be a return statement | |
1355 | * instead of goto. */ | |
1356 | string* get_label() const { return label; } | |
1357 | void set_is_altstep () { is_altstep = true; } | |
1358 | bool get_is_altstep () { return is_altstep; } | |
1359 | void set_il_label_end (const char *lbl) { | |
1360 | il_label_end = new string (lbl); } | |
1361 | const string* get_il_label_end () { return il_label_end; } | |
1362 | bool has_else() const; | |
1363 | StatementBlock::returnstatus_t has_return() const; | |
1364 | bool has_receiving_stmt() const; | |
1365 | /* checking functions */ | |
1366 | void chk(); | |
1367 | /** checks whether all embedded statements are allowed in an interleaved | |
1368 | * construct */ | |
1369 | void chk_allowed_interleave(); | |
1370 | /** Sets the code section selector of all embedded values and templates | |
1371 | * to \a p_code_section. */ | |
1372 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
1373 | /** Generates the equivalent C++ code for the branches of an alt construct, | |
1374 | * appends it to \a str and returns the resulting string. Parameter \a loc | |
1375 | * shall contain the location of the alt construct. */ | |
1376 | char *generate_code_alt(char *str, const Location& loc); | |
1377 | /** Generates the equivalent C++ code for the branches of an altstep, | |
1378 | * appends it to \a str and returns the resulting string. */ | |
1379 | char *generate_code_altstep(char *str); | |
1380 | /** Generates the equivalent C++ code for the response and | |
1381 | * exception handling part of a call statement, appends it to \a | |
1382 | * str and returns the resulting string. Parameter \a loc | |
1383 | * contains the location of the call statement. \a temp_id is the | |
1384 | * temporary id used as prefix for local temporary variables and | |
1385 | * stuff. If used in interleave (in_interleave is true), then | |
1386 | * those alt branches that contain receiving statement(s) are not | |
1387 | * generated but a "goto label_str_branch_n" where 'n' is the | |
1388 | * branch number. */ | |
1389 | char* generate_code_call_body(char *str, const Location& loc, | |
1390 | const string& temp_id, bool in_interleave); | |
1391 | void ilt_generate_code_call_body(ILT *ilt, const char *label_str); | |
1392 | }; | |
1393 | ||
1394 | } // namespace Ttcn | |
1395 | ||
1396 | #endif // _Ttcn_Statement_HH |