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
11 #include "AST_ttcn3.hh"
21 using namespace Common;
27 class ParamAssignment;
28 class ParamAssignments;
30 class VariableEntries;
41 /* not defined here: */
46 * Represents a %StatementBlock.
48 class StatementBlock : public Scope, public Location {
51 RS_NO, /**< indicates that the block does not have return statement
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 */
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 */
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 */
76 /** The function/altstep/testcase/etc. the StatementBlock belongs to. */
79 exception_handling_t exception_handling;
81 StatementBlock(const StatementBlock& p);
82 StatementBlock& operator=(const StatementBlock& p);
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, bool is_connecting);
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;
117 void set_exception_handling(exception_handling_t eh) { exception_handling = eh; }
118 exception_handling_t get_exception_handling() const { return exception_handling; }
120 virtual void dump(unsigned int level) const;
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);
128 /* checking functions */
130 /** checks whether all embedded statements are allowed in an interleaved
132 void chk_allowed_interleave();
135 void chk_unused_labels();
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);
145 virtual void set_parent_path(WithAttribPath* p_path);
149 * Represents a statement (FunctionStatement) in dynamic part of
152 class Statement : public Node, public Location {
154 enum statementtype_t {
155 /* erroneous statement */
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)
165 S_FUNCTION_INSTANCE, // ref_pard
166 S_FUNCTION_INVOKED, // fau_refd
172 S_CONTINUE, // brk_cnt
179 S_STOP_TESTCASE, // logargs
180 /* behaviour statements */
182 S_REPEAT, // ags BUT only a pointer (my_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
198 S_TRIGGER, // port rcv_par from_clause redirect.value
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
212 S_START_PORT, // port
215 /* component statements */
216 S_START_COMP, // comp_op
217 S_START_COMP_REFD, // comp_op
218 S_STOP_COMP, // comp_op
222 /* configuration statements */
225 S_DISCONNECT, // config
227 /* timer statements */
228 S_START_TIMER, // timer
229 S_STOP_TIMER, // timer
231 /* verdict statement */
232 S_SETVERDICT, // verdictval
235 /* control statement */
236 S_TESTCASE_INSTANCE, // testcase_inst
237 S_TESTCASE_INSTANCE_REFD, //execute_refd
238 S_STRING2TTCN // str2ttcn
247 statementtype_t statementtype;
248 /// The statement block this statement belongs to.
249 StatementBlock *my_sb;
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
256 Reference *portref; /**< NULL means any/all */
259 TemplateInstance *sendpar;
269 Reference *signature_ref;
270 Type *signature; /**< only for caching */
275 TemplateInstance *rcvpar;
276 TemplateInstance *fromclause;
279 ParamRedirect *param;
283 TemplateInstance *getreply_valuematch;
285 Reference *signature_ref;
286 Type *signature; /**< only for caching */
288 bool in_call, call_has_timer;
289 } ctch; /**< catch */
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 */
300 Reference *timerref; /**< 0 means any/all */
302 } timer_op; ///< used by S_START_TIMER, S_STOP_TIMER, S_TIMEOUT
309 } config_op; ///< used by S_CONNECT, S_MAP, S_DISCONNECT, S_UNMAP
312 Value *compref; /**< if S_STOP_COMP, S_KILL then compref==0
315 component_t any_or_all;
316 /**< used if S_DONE, S_KILLED and compref==0 */
318 TemplateInstance *donematch;
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 */
325 ParsedActualParameters *t_list1;
326 ActualParList *ap_list2;
330 } comp_op; /**< used by S_START_COMP, S_START_COMP_REFD, S_STOP_COMP,
331 S_KILL, S_KILLED, S_DONE */
335 LogArguments *logargs;
338 Value *deactivate; ///< used by S_DEACTIVATE
339 AltGuards *ags; ///< used by S_ALT and S_INTERLEAVE
349 TemplateInstances *t_list1;
350 ActualParList *ap_list2;
360 ParsedActualParameters *t_list1;
361 ActualParList *ap_list2;
363 } fau_refd; /**< used by S_ACTIVATE_REFD, S_UNKNOWN_INVOKED,
364 S_FUNCTION_INVOKED, S_ALTSTEP_INVOKED (function, altstep, or unknown) */
372 Assignment *init_ass;
373 Definitions *init_varinst;
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_... */
390 IfClauses *ics; /**< if-clauses */
391 StatementBlock *elseblock; /**< the last else-block */
392 Location *elseblock_location; /**< location of the last else-block */
403 bool gen_restriction_check; // set in chk_return()
408 size_t stmt_idx; /**< index of the statement within its block */
409 string *clabel; /**< C++ label identifier in the generated code */
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 */
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
430 struct { // S_STRING2TTCN
436 Statement(const Statement& p); ///< copy disabled
437 Statement& operator=(const Statement& p); ///< assignment disabled
440 /** Constructor used by S_ERROR, S_STOP_EXEC and S_REPEAT, S_BREAK and
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,
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,
490 /** Constructor used by S_RAISE */
491 Statement(statementtype_t p_st, Reference *p_ref,
492 Reference *p_sig, TemplateInstance *p_templinst,
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
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
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
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;
560 /** Returns the c++ identifier of the label, applicable if \a this is a
562 const string& get_clabel();
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 */
591 /** checks whether the statement (including all embedded statements) are
592 * allowed in an interleaved construct */
593 void chk_allowed_interleave();
595 void chk_start_undef();
596 void chk_stop_undef();
597 void chk_unknown_instance();
598 void chk_unknown_invoke();
599 void chk_assignment();
602 /* checks log, action */
603 void chk_log_action(LogArguments *logargs);
614 void chk_interleave();
618 void chk_activate_refd();
619 void chk_deactivate();
624 /* checks receive, check-receive trigger */
626 /* checks getcall, check-getcall */
628 /* checks getreply, check-getreply */
630 /* checks catch, check-catch */
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();
642 /* checks connect and disconnect */
644 /* checks map and unmap */
646 void chk_start_timer();
647 void chk_stop_timer_timeout();
648 void chk_setverdict();
650 void chk_execute_refd();
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
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
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
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
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
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. Flag \a is_connecting
706 * is set if the component is part of a 'map' or 'connect' statement. */
707 Type *chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system, bool is_connecting = false);
708 /** Checks an endpoint for a port connection or mapping. Parameter
709 * \a p_compref is a component reference, \a p_portref refers to
710 * a port within the corresponding component type. A pointer to
711 * the referred port type (or NULL in case of error) is
713 Type *chk_conn_endpoint(Value *p_compref, Reference *p_portref,
715 void chk_string2ttcn();
717 /** Sets the code section selector of all embedded values and
718 * templates to \a p_code_section. */
719 void set_code_section(GovernedSimple::code_section_t p_code_section);
720 char* generate_code(char *str);
721 void generate_code_expr(expression_struct *expr);
722 void ilt_generate_code(ILT *ilt);
724 /** Needed by implicit omit. Pushes attrib path down to definitions
726 virtual void set_parent_path(WithAttribPath* p_path);
728 char *generate_code_standalone(char *str);
729 /** used for function and altstep instances */
730 char *generate_code_funcinst(char *str);
731 char *generate_code_invoke(char *str);
732 char *generate_code_block(char *str);
733 char *generate_code_log(char *str);
734 char* generate_code_string2ttcn(char *str);
735 char *generate_code_testcase_stop(char *str);
736 char *generate_code_label(char *str);
737 char *generate_code_goto(char *str);
738 char *generate_code_if(char *str);
739 char *generate_code_select(char *str);
740 char *generate_code_for(char *str);
741 char *generate_code_while(char *str);
742 char *generate_code_dowhile(char *str);
743 char *generate_code_break(char *str);
744 char *generate_code_continue(char *str);
745 char *generate_code_repeat(char *str);
746 char *generate_code_interleave(char *str);
747 void ilt_generate_code_interleave(ILT *ilt);
748 void ilt_generate_code_alt(ILT *ilt);
749 void ilt_generate_code_receiving(ILT *ilt);
750 void ilt_generate_code_def(ILT *ilt);
751 void ilt_generate_code_if(ILT *ilt);
752 void ilt_generate_code_select(ILT *ilt);
753 void ilt_generate_code_call(ILT *ilt);
754 void ilt_generate_code_for(ILT *ilt);
755 void ilt_generate_code_while(ILT *ilt);
756 void ilt_generate_code_dowhile(ILT *ilt);
757 char *generate_code_return(char *str);
758 char *generate_code_activate(char *str);
759 char *generate_code_activate_refd(char *str);
760 char *generate_code_deactivate(char *str);
761 char *generate_code_send(char *str);
762 char *generate_code_call(char *str);
763 char *generate_code_reply(char *str);
764 char *generate_code_raise(char *str);
765 char *generate_code_portop(char *str, const char *opname);
766 char *generate_code_startcomp(char *str);
767 char *generate_code_startcomp_refd(char *str);
768 char *generate_code_compop(char *str, const char *opname);
769 char *generate_code_configop(char *str, const char *opname);
770 char *generate_code_starttimer(char *str);
771 char *generate_code_stoptimer(char *str);
772 char *generate_code_setverdict(char *str);
773 char *generate_code_action(char *str);
774 char *generate_code_testcaseinst(char *str);
775 char *generate_code_execute_refd(char *str);
776 /** used for receive, check-receive, trigger */
777 void generate_code_expr_receive(expression_struct *expr,
779 /** used for getcall, check-getcall */
780 void generate_code_expr_getcall(expression_struct *expr,
782 /** used for getreply, check-getreply */
783 void generate_code_expr_getreply(expression_struct *expr,
785 /** used for catch, check-catch */
786 void generate_code_expr_catch(expression_struct *expr);
787 void generate_code_expr_check(expression_struct *expr);
788 void generate_code_expr_done(expression_struct *expr);
789 void generate_code_expr_killed(expression_struct *expr);
790 void generate_code_expr_timeout(expression_struct *expr);
791 /** Generates the C++ equivalent of \a port_op.s.sendpar into \a expr.
792 * When \a sendpar contains a simple specific value the value -> template
793 * conversion is eliminated for better run-time performance. */
794 void generate_code_expr_sendpar(expression_struct *expr);
795 void generate_code_expr_fromclause(expression_struct *expr);
796 void generate_code_expr_senderredirect(expression_struct *expr);
797 /** Creates the string equivalent of port reference \a p_ref and
798 * appends it to \a expr->expr. Used in configuration operations
799 * when the component type cannot be determined from the
800 * component reference. */
801 static void generate_code_portref(expression_struct *expr,
806 * Class to store a VariableAssignment or TemplateAssignment.
807 * Class is entirely unrelated to Common::Assignment and Asn::Assignment.
809 class Assignment : public Node, public Location {
812 ASS_UNKNOWN, ///< unknown assignment
813 ASS_VAR, ///< variable assignment
814 ASS_TEMPLATE, ///< template assignment
815 ASS_ERROR ///< erroneous
820 Reference *ref; ///< reference to the "left hand side"
822 Value *val; ///< RHS for a variable assignment
823 Template *templ; ///< RHS for a template assignment
825 /** true if the LHS is mentioned in the RHS */
827 /** template restriction on ref, set in chk() for faster code generation */
828 template_restriction_t template_restriction;
829 /** set in chk(), used by code generation */
830 bool gen_restriction_check;
832 Assignment(const Assignment& p);
833 Assignment& operator=(const Assignment& p);
835 /** Creates a new template assignment. */
836 Assignment(Reference *p_ref, Template *p_templ);
837 /** Creates a new variable assignment. */
838 Assignment(Reference *p_ref, Value *p_val);
839 virtual ~Assignment();
840 virtual Assignment *clone() const;
841 virtual void set_my_scope(Scope *p_scope);
842 virtual void set_fullname(const string& p_fullname);
843 virtual void dump(unsigned int level) const;
845 void chk_unknown_ass();
847 void chk_template_ass();
848 void chk_template_restriction();
851 /** Sets the code section selector of all embedded values and templates
852 * to \a p_code_section. */
853 void set_code_section(GovernedSimple::code_section_t p_code_section);
854 char *generate_code(char *str);
858 * Class to store a ParamAssignment.
860 class ParamAssignment : public Node, public Location {
865 ParamAssignment(const ParamAssignment& p);
866 ParamAssignment& operator=(const ParamAssignment& p);
868 ParamAssignment(Identifier *p_id, Reference *p_ref);
869 virtual ~ParamAssignment();
870 virtual ParamAssignment* clone() const;
871 virtual void set_my_scope(Scope *p_scope);
872 virtual void set_fullname(const string& p_fullname);
873 const Identifier& get_id() const { return *id; }
874 Reference *get_ref() const;
875 Reference *steal_ref();
879 * Class to store a ParamAssignmentList
881 class ParamAssignments : public Node {
883 vector<ParamAssignment> parasss;
885 ParamAssignments(const ParamAssignments& p);
886 ParamAssignments& operator=(const ParamAssignments& p);
888 ParamAssignments() : Node() { }
889 virtual ~ParamAssignments();
890 virtual ParamAssignments* clone() const;
891 virtual void set_my_scope(Scope *p_scope);
892 virtual void set_fullname(const string& p_fullname);
893 void add_parass(ParamAssignment *p_parass);
894 size_t get_nof_parasss() const { return parasss.size(); }
895 ParamAssignment *get_parass_byIndex(size_t p_i) const
896 { return parasss[p_i]; }
900 * Class to represent a variable or notused-symbol in
901 * ParamAssignmentList of port redirect stuff.
903 class VariableEntry : public Node, public Location {
905 Reference *ref; /**< varref or notused if NULL. */
907 VariableEntry(const VariableEntry& p);
908 VariableEntry& operator=(const VariableEntry& p);
910 /** Creates a notused entry */
911 VariableEntry() : Node(), Location(), ref(0) { }
912 VariableEntry(Reference *p_ref);
913 virtual ~VariableEntry();
914 virtual VariableEntry* clone() const;
915 virtual void set_my_scope(Scope *p_scope);
916 virtual void set_fullname(const string& p_fullname);
917 Reference *get_ref() const { return ref; }
921 * Class to store a VariableEntries
923 class VariableEntries : public Node {
925 vector<VariableEntry> ves;
927 VariableEntries(const VariableEntries& p);
928 VariableEntries& operator=(const VariableEntries& p);
930 VariableEntries() : Node() { }
931 virtual ~VariableEntries();
932 virtual VariableEntries* clone() const;
933 virtual void set_my_scope(Scope *p_scope);
934 virtual void set_fullname(const string& p_fullname);
935 void add_ve(VariableEntry *p_ve);
936 size_t get_nof_ves() const { return ves.size(); }
937 VariableEntry *get_ve_byIndex(size_t p_i) const { return ves[p_i]; }
941 * Class to represent ParamAssignmentList in a param redirect of
942 * getcall/getreply port operation.
944 class ParamRedirect : public Node, public Location {
946 enum parredirtype_t {
947 P_ASS, /**< AssignmentList */
948 P_VAR /**< VariableList */
951 parredirtype_t parredirtype;
953 ParamAssignments *parasss;
954 VariableEntries *ves;
957 ParamRedirect(const ParamRedirect& p);
958 ParamRedirect& operator=(const ParamRedirect& p);
960 ParamRedirect(ParamAssignments *p_parasss);
961 ParamRedirect(VariableEntries *p_ves);
962 virtual ~ParamRedirect();
963 virtual ParamRedirect* clone() const;
964 virtual void set_my_scope(Scope *p_scope);
965 virtual void set_fullname(const string& p_fullname);
966 /** Performs some trivial checks on the variable references.
967 * Used when the signature cannot be determined in a getcall or getreply
968 * operation because of an error. */
969 void chk_erroneous();
970 /** Performs the checks on the param redirect clause. Parameter \a p_sig
971 * points to the respective signature. Flag \a is_out is true if the
972 * redirect belongs to a getreply operation (i.e. it may refer to out/inout
973 * parameters) and false in case of getcall. */
974 void chk(Type *p_sig, bool is_out);
976 /** Helper function for \a chk(). Used when AssignmentList is selected.
977 * If the redirect is correct it converts the AssignmentList to an
978 * equivalent VariableList for easier code generation. */
979 void chk_parasss(Type *p_sig, SignatureParamList *p_parlist, bool is_out);
980 /** Helper function for \a chk(). Used when VariableList is selected. */
981 void chk_ves(Type *p_sig, SignatureParamList *p_parlist, bool is_out);
982 /** Checks whether the reference \a p_ref points to a variable of type
984 static void chk_variable_ref(Reference *p_ref, Type *p_type);
986 /** Sets the code section selector of all embedded values and templates
987 * to \a p_code_section. */
988 void set_code_section(GovernedSimple::code_section_t p_code_section);
989 void generate_code(expression_struct_t *expr);
993 * Class to represent a LogArgument.
995 class LogArgument : public Node, public Location {
998 L_UNDEF, /**< undefined (set during parsing) */
999 L_ERROR, /**< erroneous */
1000 L_TI, /**< template instance */
1001 L_VAL, /**< literal value or expression */
1002 L_MATCH, /**< match expression */
1003 L_MACRO, /**< macro value (%something) */
1004 L_REF, /**< reference */
1005 L_STR /**< literal character string */
1009 logargtype_t logargtype;
1011 TemplateInstance *ti; ///< used by L_UNDEF and L_TI
1012 Value *val; ///< used by L_VAL, L_MATCH, L_MACRO
1013 Ref_base *ref; ///< used by L_REF
1014 string *cstr; ///< used by L_STR
1017 LogArgument(const LogArgument& p);
1018 LogArgument& operator=(const LogArgument& p);
1020 LogArgument(TemplateInstance *p_ti);
1021 virtual ~LogArgument();
1022 virtual LogArgument *clone() const;
1023 virtual void set_my_scope(Scope *p_scope);
1024 virtual void set_fullname(const string& p_fullname);
1025 logargtype_t get_type() const { return logargtype; }
1026 const string& get_str() const;
1027 Value *get_val() const;
1028 Ref_base *get_ref() const;
1029 TemplateInstance *get_ti () const;
1030 /** Appends the string \a p_str to \a cstr. Applicable only if
1031 * \a logargtype is L_STR. */
1032 void append_str(const string& p_str);
1034 virtual void dump(unsigned int level) const;
1039 /** Sets the code section selector of all embedded values and
1040 * templates to \a p_code_section. */
1041 void set_code_section(GovernedSimple::code_section_t p_code_section);
1042 char *generate_code_log(char *str);
1043 void chk_recursions(ReferenceChain& refch);
1044 bool has_single_expr();
1045 void generate_code_expr(expression_struct *expr);
1049 * Class to represent LogArgumentList.
1051 class LogArguments : public Node {
1053 vector<LogArgument> logargs;
1055 LogArguments(const LogArguments& p);
1056 LogArguments& operator=(const LogArguments& p);
1058 LogArguments() : Node() { }
1059 virtual ~LogArguments();
1060 virtual LogArguments *clone() const;
1061 void add_logarg(LogArgument *p_logarg);
1062 size_t get_nof_logargs() const { return logargs.size(); }
1063 LogArgument *get_logarg_byIndex(size_t p_i) const { return logargs[p_i]; }
1064 virtual void set_my_scope(Scope *p_scope);
1065 virtual void set_fullname(const string& p_fullname);
1067 /** Joins adjacent strings into one LogArgument for more efficient
1068 * code generation. */
1069 void join_strings();
1070 /** Sets the code section selector of all embedded values and
1071 * templates to \a p_code_section. */
1072 void set_code_section(GovernedSimple::code_section_t p_code_section);
1073 char *generate_code(char *str);
1074 void chk_recursions(ReferenceChain& refch);
1075 bool has_single_expr();
1076 void generate_code_expr(expression_struct *expr);
1080 * Class to represent an if-clause: the condition and the statement
1081 * block. Note that the else block is kept by Statement::if_stmt.
1083 class IfClause : public Node, public Location {
1085 Value *expr; /**< conditional expression */
1086 StatementBlock *block;
1088 IfClause(const IfClause& p);
1089 IfClause& operator=(const IfClause& p);
1091 IfClause(Value *p_expr, StatementBlock *p_block);
1092 virtual ~IfClause();
1093 virtual IfClause *clone() const;
1094 virtual void set_my_scope(Scope *p_scope);
1095 virtual void set_fullname(const string& p_fullname);
1096 Value *get_expr() const { return expr; }
1097 StatementBlock *get_block() const { return block; }
1098 /* checking functions */
1099 bool has_receiving_stmt() const;
1100 void chk(bool& unreach);
1101 /** Sets the code section selector of all embedded values and
1102 * templates to \a p_code_section. */
1103 void set_code_section(GovernedSimple::code_section_t p_code_section);
1104 char* generate_code(char *str, size_t& blockcount,
1105 bool& unreach, bool& eachfalse);
1106 void ilt_generate_code(ILT *ilt, const char *end_label, bool& unreach);
1108 /** Needed by implicit omit. Pushes attrib path down to definitions
1110 virtual void set_parent_path(WithAttribPath* p_path);
1111 virtual void dump(unsigned int level) const;
1115 * Class to represent IfClauseList, a chain of if-else-if-else-if
1117 class IfClauses : public Node {
1119 vector<IfClause> ics;
1121 IfClauses(const IfClauses& p);
1122 IfClauses& operator=(const IfClauses& p);
1124 IfClauses() : Node() { }
1125 virtual ~IfClauses();
1126 virtual IfClauses* clone() const;
1127 /// Called to add an "else-if" to a chain of "else-if"s
1128 void add_ic(IfClause *p_ic);
1129 /// Called to add the first "if" to a chain of "else-if"s
1130 void add_front_ic(IfClause *p_ic);
1131 size_t get_nof_ics() const {return ics.size();}
1132 IfClause *get_ic_byIndex(size_t p_i) const {return ics[p_i];}
1133 virtual void set_my_scope(Scope *p_scope);
1134 virtual void set_fullname(const string& p_fullname);
1135 void set_my_sb(StatementBlock *p_sb, size_t p_index);
1136 void set_my_def(Definition *p_def);
1137 void set_my_ags(AltGuards *p_ags);
1138 void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
1139 StatementBlock::returnstatus_t has_return(StatementBlock *elseblock) const;
1140 bool has_receiving_stmt() const;
1141 /* checking functions */
1142 void chk(bool& unreach);
1143 /** checks whether all embedded statements are allowed in an interleaved
1145 void chk_allowed_interleave();
1146 /** Sets the code section selector of all embedded values and
1147 * templates to \a p_code_section. */
1148 void set_code_section(GovernedSimple::code_section_t p_code_section);
1149 char* generate_code(char *str, size_t& blockcount,
1150 bool& unreach, bool& eachfalse);
1151 void ilt_generate_code(ILT *ilt, const char *end_label, bool& unreach);
1153 /** Needed by implicit omit. Pushes attrib path down to definitions
1155 virtual void set_parent_path(WithAttribPath* p_path);
1156 virtual void dump(unsigned int level) const;
1160 * Class to represent a select-case: the template instance list and
1161 * the statement block.
1163 class SelectCase : public Node, public Location {
1165 TemplateInstances *tis;
1166 StatementBlock *block;
1168 SelectCase(const SelectCase& p);
1169 SelectCase& operator=(const SelectCase& p);
1171 /** tis==0 means "else" case */
1172 SelectCase(TemplateInstances *p_tis, StatementBlock *p_block);
1173 virtual ~SelectCase();
1174 virtual SelectCase* clone() const;
1175 virtual void set_my_scope(Scope *p_scope);
1176 virtual void set_fullname(const string& p_fullname);
1177 TemplateInstances* get_tis() const { return tis; }
1178 StatementBlock *get_block() const { return block; }
1179 /* checking functions */
1180 void chk(Type *p_gov, bool& unreach);
1181 /** Sets the code section selector of all embedded values and
1182 * templates to \a p_code_section. */
1183 void set_code_section(GovernedSimple::code_section_t p_code_section);
1184 char* generate_code_if(char *str, const char *tmp_prefix,
1185 const char *expr_name, size_t idx, bool& unreach);
1186 char* generate_code_stmt(char *str, const char *tmp_prefix,
1187 size_t idx, bool& unreach);
1188 void ilt_generate_code_stmt(ILT *ilt, const char *tmp_prefix,
1189 size_t idx, bool& unreach);
1191 /** Needed by implicit omit. Pushes attrib path down to definitions
1193 virtual void set_parent_path(WithAttribPath* p_path);
1197 * Class to represent SelectCaseList.
1199 class SelectCases : public Node {
1201 vector<SelectCase> scs;
1203 SelectCases(const SelectCases& p);
1204 SelectCases& operator=(const SelectCases& p);
1206 SelectCases() : Node() { }
1207 virtual ~SelectCases();
1208 virtual SelectCases* clone() const;
1209 void add_sc(SelectCase *p_sc);
1210 size_t get_nof_scs() const {return scs.size();}
1211 SelectCase *get_sc_byIndex(size_t p_i) const {return scs[p_i];}
1212 virtual void set_my_scope(Scope *p_scope);
1213 virtual void set_fullname(const string& p_fullname);
1214 void set_my_sb(StatementBlock *p_sb, size_t p_index);
1215 void set_my_def(Definition *p_def);
1216 void set_my_ags(AltGuards *p_ags);
1217 void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
1218 StatementBlock::returnstatus_t has_return() const;
1219 bool has_receiving_stmt() const;
1220 /* checking functions */
1221 /** p_gov is the governor type of select expression */
1222 void chk(Type *p_gov);
1223 /** checks whether all embedded statements are allowed in an interleaved
1225 void chk_allowed_interleave();
1226 /** Sets the code section selector of all embedded values and
1227 * templates to \a p_code_section. */
1228 void set_code_section(GovernedSimple::code_section_t p_code_section);
1229 char *generate_code(char *str, const char *tmp_prefix,
1230 const char *expr_name);
1231 void ilt_generate_code(ILT *ilt, const char *tmp_prefix,
1232 const char *expr_init, const char *expr_name);
1234 /** Needed by implicit omit. Pushes attrib path down to definitions
1236 virtual void set_parent_path(WithAttribPath* p_path);
1240 * Class to represent an alt guard.
1242 class AltGuard : public Node, public Location {
1244 enum altguardtype_t {
1252 altguardtype_t altguardtype;
1253 Value *expr; /**< conditional expression */
1260 Ttcn::TemplateInstances *t_list;
1261 Ttcn::ActualParList *ap_list;
1264 StatementBlock *block;
1266 AltGuard(const AltGuard& p);
1267 AltGuard& operator=(const AltGuard& p);
1269 /** Constructor used by AG_OP */
1270 AltGuard(Value *p_expr, Statement *p_stmt, StatementBlock *p_block);
1271 /** Constructor used by AG_REF */
1272 AltGuard(Value *p_expr, Ref_pard *p_ref, StatementBlock *p_block);
1273 /** Constructor used by AG_INVOKE */
1274 AltGuard(Value *p_expr, Value *p_v,
1275 Ttcn::TemplateInstances *p_t_list, StatementBlock *p_block);
1276 /** Constructor used by AG_ELSE */
1277 AltGuard(StatementBlock *p_block);
1278 virtual ~AltGuard();
1279 virtual AltGuard* clone() const;
1280 virtual void set_my_scope(Scope *p_scope);
1281 void set_my_sb(StatementBlock *p_sb, size_t p_index);
1282 virtual void set_fullname(const string& p_fullname);
1283 altguardtype_t get_type() const { return altguardtype; }
1284 Value *get_guard_expr() const;
1285 Ref_pard *get_guard_ref() const;
1286 Statement *get_guard_stmt() const;
1287 StatementBlock *get_block() const { return block; }
1288 void set_my_def(Definition *p_def);
1289 void set_my_ags(AltGuards *p_ags);
1290 void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
1291 /* checking functions */
1293 /** Sets the code section selector of all embedded values and templates
1294 * to \a p_code_section. */
1295 void set_code_section(GovernedSimple::code_section_t p_code_section);
1296 /** generates altstep instantiation call */
1297 void generate_code_invoke_instance(expression_struct *p_expr);
1301 * Class to represent AltGuardList.
1303 class AltGuards : public Node {
1305 vector<AltGuard> ags;
1307 /** Indicates whether a repeat statement was found within the branches. */
1309 /** C++ label identifier that points to the beginning of the alternative.
1310 * Used only in alt constructs and within call statements. */
1313 string *il_label_end; /** label for break when ags is not compiled to loop*/
1315 AltGuards(const AltGuards& p);
1316 AltGuards& operator=(const AltGuards& p);
1318 AltGuards() : Node(), my_scope(0), has_repeat(false), label(0),
1319 is_altstep(false), il_label_end(0) { }
1320 virtual ~AltGuards();
1321 virtual AltGuards* clone() const;
1322 void add_ag(AltGuard *p_ag);
1323 size_t get_nof_ags() const {return ags.size();}
1324 AltGuard *get_ag_byIndex(size_t p_i) const {return ags[p_i];}
1325 virtual void set_my_scope(Scope *p_scope);
1326 virtual void set_fullname(const string& p_fullname);
1327 void set_my_sb(StatementBlock *p_sb, size_t p_index);
1328 void set_my_def(Definition *p_def);
1329 /** Sets the ags pointer of all embedded repeat statements to \a p_ags. */
1330 void set_my_ags(AltGuards *p_ags);
1331 void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
1332 void repeat_found() { has_repeat = true; }
1333 /** Returns the C++ label identifier that is used in code generation for
1334 * repeat statements. NULL pointer indicates that \a this belongs to an
1335 * altstep so the C++ equivalent of repeat shall be a return statement
1336 * instead of goto. */
1337 string* get_label() const { return label; }
1338 void set_is_altstep () { is_altstep = true; }
1339 bool get_is_altstep () { return is_altstep; }
1340 void set_il_label_end (const char *lbl) {
1341 il_label_end = new string (lbl); }
1342 const string* get_il_label_end () { return il_label_end; }
1343 bool has_else() const;
1344 StatementBlock::returnstatus_t has_return() const;
1345 bool has_receiving_stmt() const;
1346 /* checking functions */
1348 /** checks whether all embedded statements are allowed in an interleaved
1350 void chk_allowed_interleave();
1351 /** Sets the code section selector of all embedded values and templates
1352 * to \a p_code_section. */
1353 void set_code_section(GovernedSimple::code_section_t p_code_section);
1354 /** Generates the equivalent C++ code for the branches of an alt construct,
1355 * appends it to \a str and returns the resulting string. Parameter \a loc
1356 * shall contain the location of the alt construct. */
1357 char *generate_code_alt(char *str, const Location& loc);
1358 /** Generates the equivalent C++ code for the branches of an altstep,
1359 * appends it to \a str and returns the resulting string. */
1360 char *generate_code_altstep(char *str);
1361 /** Generates the equivalent C++ code for the response and
1362 * exception handling part of a call statement, appends it to \a
1363 * str and returns the resulting string. Parameter \a loc
1364 * contains the location of the call statement. \a temp_id is the
1365 * temporary id used as prefix for local temporary variables and
1366 * stuff. If used in interleave (in_interleave is true), then
1367 * those alt branches that contain receiving statement(s) are not
1368 * generated but a "goto label_str_branch_n" where 'n' is the
1370 char* generate_code_call_body(char *str, const Location& loc,
1371 const string& temp_id, bool in_interleave);
1372 void ilt_generate_code_call_body(ILT *ilt, const char *label_str);
1377 #endif // _Ttcn_Statement_HH