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