Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef _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, 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; | |
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. 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 | |
712 | * returned. */ | |
713 | Type *chk_conn_endpoint(Value *p_compref, Reference *p_portref, | |
714 | bool allow_system); | |
715 | void chk_string2ttcn(); | |
716 | public: | |
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); | |
723 | ||
724 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
725 | */ | |
726 | virtual void set_parent_path(WithAttribPath* p_path); | |
727 | private: | |
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, | |
778 | const char *opname); | |
779 | /** used for getcall, check-getcall */ | |
780 | void generate_code_expr_getcall(expression_struct *expr, | |
781 | const char *opname); | |
782 | /** used for getreply, check-getreply */ | |
783 | void generate_code_expr_getreply(expression_struct *expr, | |
784 | const char *opname); | |
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, | |
802 | Reference *p_ref); | |
803 | }; | |
804 | ||
805 | /** | |
806 | * Class to store a VariableAssignment or TemplateAssignment. | |
807 | * Class is entirely unrelated to Common::Assignment and Asn::Assignment. | |
808 | */ | |
809 | class Assignment : public Node, public Location { | |
810 | public: | |
811 | enum asstype_t { | |
812 | ASS_UNKNOWN, ///< unknown assignment | |
813 | ASS_VAR, ///< variable assignment | |
814 | ASS_TEMPLATE, ///< template assignment | |
815 | ASS_ERROR ///< erroneous | |
816 | }; | |
817 | ||
818 | private: | |
819 | asstype_t asstype; | |
820 | Reference *ref; ///< reference to the "left hand side" | |
821 | union { | |
822 | Value *val; ///< RHS for a variable assignment | |
823 | Template *templ; ///< RHS for a template assignment | |
824 | }; | |
825 | /** true if the LHS is mentioned in the RHS */ | |
826 | bool self_ref; | |
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; | |
831 | ||
832 | Assignment(const Assignment& p); | |
833 | Assignment& operator=(const Assignment& p); | |
834 | public: | |
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; | |
844 | private: | |
845 | void chk_unknown_ass(); | |
846 | void chk_var_ass(); | |
847 | void chk_template_ass(); | |
848 | void chk_template_restriction(); | |
849 | public: | |
850 | void chk(); | |
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); | |
855 | }; | |
856 | ||
857 | /** | |
858 | * Class to store a ParamAssignment. | |
859 | */ | |
860 | class ParamAssignment : public Node, public Location { | |
861 | private: | |
862 | Identifier *id; | |
863 | Reference *ref; | |
864 | ||
865 | ParamAssignment(const ParamAssignment& p); | |
866 | ParamAssignment& operator=(const ParamAssignment& p); | |
867 | public: | |
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(); | |
876 | }; | |
877 | ||
878 | /** | |
879 | * Class to store a ParamAssignmentList | |
880 | */ | |
881 | class ParamAssignments : public Node { | |
882 | private: | |
883 | vector<ParamAssignment> parasss; | |
884 | ||
885 | ParamAssignments(const ParamAssignments& p); | |
886 | ParamAssignments& operator=(const ParamAssignments& p); | |
887 | public: | |
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]; } | |
897 | }; | |
898 | ||
899 | /** | |
900 | * Class to represent a variable or notused-symbol in | |
901 | * ParamAssignmentList of port redirect stuff. | |
902 | */ | |
903 | class VariableEntry : public Node, public Location { | |
904 | private: | |
905 | Reference *ref; /**< varref or notused if NULL. */ | |
906 | ||
907 | VariableEntry(const VariableEntry& p); | |
908 | VariableEntry& operator=(const VariableEntry& p); | |
909 | public: | |
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; } | |
918 | }; | |
919 | ||
920 | /** | |
921 | * Class to store a VariableEntries | |
922 | */ | |
923 | class VariableEntries : public Node { | |
924 | private: | |
925 | vector<VariableEntry> ves; | |
926 | ||
927 | VariableEntries(const VariableEntries& p); | |
928 | VariableEntries& operator=(const VariableEntries& p); | |
929 | public: | |
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]; } | |
938 | }; | |
939 | ||
940 | /** | |
941 | * Class to represent ParamAssignmentList in a param redirect of | |
942 | * getcall/getreply port operation. | |
943 | */ | |
944 | class ParamRedirect : public Node, public Location { | |
945 | public: | |
946 | enum parredirtype_t { | |
947 | P_ASS, /**< AssignmentList */ | |
948 | P_VAR /**< VariableList */ | |
949 | }; | |
950 | private: | |
951 | parredirtype_t parredirtype; | |
952 | union { | |
953 | ParamAssignments *parasss; | |
954 | VariableEntries *ves; | |
955 | }; | |
956 | ||
957 | ParamRedirect(const ParamRedirect& p); | |
958 | ParamRedirect& operator=(const ParamRedirect& p); | |
959 | public: | |
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); | |
975 | private: | |
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 | |
983 | * \a p_type. */ | |
984 | static void chk_variable_ref(Reference *p_ref, Type *p_type); | |
985 | public: | |
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); | |
990 | }; | |
991 | ||
992 | /** | |
993 | * Class to represent a LogArgument. | |
994 | */ | |
995 | class LogArgument : public Node, public Location { | |
996 | public: | |
997 | enum logargtype_t { | |
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 */ | |
1006 | }; | |
1007 | ||
1008 | private: | |
1009 | logargtype_t logargtype; | |
1010 | union { | |
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 | |
1015 | }; | |
1016 | ||
1017 | LogArgument(const LogArgument& p); | |
1018 | LogArgument& operator=(const LogArgument& p); | |
1019 | public: | |
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); | |
1033 | void chk(); | |
1034 | virtual void dump(unsigned int level) const; | |
1035 | private: | |
1036 | void chk_ref(); | |
1037 | void chk_val(); | |
1038 | public: | |
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); | |
1046 | }; | |
1047 | ||
1048 | /** | |
1049 | * Class to represent LogArgumentList. | |
1050 | */ | |
1051 | class LogArguments : public Node { | |
1052 | private: | |
1053 | vector<LogArgument> logargs; | |
1054 | ||
1055 | LogArguments(const LogArguments& p); | |
1056 | LogArguments& operator=(const LogArguments& p); | |
1057 | public: | |
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); | |
1066 | void chk(); | |
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); | |
1077 | }; | |
1078 | ||
1079 | /** | |
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. | |
1082 | */ | |
1083 | class IfClause : public Node, public Location { | |
1084 | private: | |
1085 | Value *expr; /**< conditional expression */ | |
1086 | StatementBlock *block; | |
1087 | ||
1088 | IfClause(const IfClause& p); | |
1089 | IfClause& operator=(const IfClause& p); | |
1090 | public: | |
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); | |
1107 | ||
1108 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1109 | */ | |
1110 | virtual void set_parent_path(WithAttribPath* p_path); | |
1111 | virtual void dump(unsigned int level) const; | |
1112 | }; | |
1113 | ||
1114 | /** | |
1115 | * Class to represent IfClauseList, a chain of if-else-if-else-if | |
1116 | */ | |
1117 | class IfClauses : public Node { | |
1118 | private: | |
1119 | vector<IfClause> ics; | |
1120 | ||
1121 | IfClauses(const IfClauses& p); | |
1122 | IfClauses& operator=(const IfClauses& p); | |
1123 | public: | |
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 | |
1144 | * construct */ | |
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); | |
1152 | ||
1153 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1154 | */ | |
1155 | virtual void set_parent_path(WithAttribPath* p_path); | |
1156 | virtual void dump(unsigned int level) const; | |
1157 | }; | |
1158 | ||
1159 | /** | |
1160 | * Class to represent a select-case: the template instance list and | |
1161 | * the statement block. | |
1162 | */ | |
1163 | class SelectCase : public Node, public Location { | |
1164 | private: | |
1165 | TemplateInstances *tis; | |
1166 | StatementBlock *block; | |
1167 | ||
1168 | SelectCase(const SelectCase& p); | |
1169 | SelectCase& operator=(const SelectCase& p); | |
1170 | public: | |
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); | |
1190 | ||
1191 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1192 | */ | |
1193 | virtual void set_parent_path(WithAttribPath* p_path); | |
1194 | }; | |
1195 | ||
1196 | /** | |
1197 | * Class to represent SelectCaseList. | |
1198 | */ | |
1199 | class SelectCases : public Node { | |
1200 | private: | |
1201 | vector<SelectCase> scs; | |
1202 | ||
1203 | SelectCases(const SelectCases& p); | |
1204 | SelectCases& operator=(const SelectCases& p); | |
1205 | public: | |
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 | |
1224 | * construct */ | |
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); | |
1233 | ||
1234 | /** Needed by implicit omit. Pushes attrib path down to definitions | |
1235 | */ | |
1236 | virtual void set_parent_path(WithAttribPath* p_path); | |
1237 | }; | |
1238 | ||
1239 | /** | |
1240 | * Class to represent an alt guard. | |
1241 | */ | |
1242 | class AltGuard : public Node, public Location { | |
1243 | public: | |
1244 | enum altguardtype_t { | |
1245 | AG_OP, | |
1246 | AG_REF, | |
1247 | AG_INVOKE, | |
1248 | AG_ELSE | |
1249 | }; | |
1250 | ||
1251 | private: | |
1252 | altguardtype_t altguardtype; | |
1253 | Value *expr; /**< conditional expression */ | |
1254 | union { | |
1255 | Ref_pard *ref; | |
1256 | Statement *stmt; | |
1257 | void *dummy; | |
1258 | struct { | |
1259 | Value *v; | |
1260 | Ttcn::TemplateInstances *t_list; | |
1261 | Ttcn::ActualParList *ap_list; | |
1262 | } invoke; | |
1263 | }; | |
1264 | StatementBlock *block; | |
1265 | ||
1266 | AltGuard(const AltGuard& p); | |
1267 | AltGuard& operator=(const AltGuard& p); | |
1268 | public: | |
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 */ | |
1292 | void chk(); | |
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); | |
1298 | }; | |
1299 | ||
1300 | /** | |
1301 | * Class to represent AltGuardList. | |
1302 | */ | |
1303 | class AltGuards : public Node { | |
1304 | private: | |
1305 | vector<AltGuard> ags; | |
1306 | Scope *my_scope; | |
1307 | /** Indicates whether a repeat statement was found within the branches. */ | |
1308 | bool has_repeat; | |
1309 | /** C++ label identifier that points to the beginning of the alternative. | |
1310 | * Used only in alt constructs and within call statements. */ | |
1311 | string *label; | |
1312 | bool is_altstep; | |
1313 | string *il_label_end; /** label for break when ags is not compiled to loop*/ | |
1314 | ||
1315 | AltGuards(const AltGuards& p); | |
1316 | AltGuards& operator=(const AltGuards& p); | |
1317 | public: | |
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 */ | |
1347 | void chk(); | |
1348 | /** checks whether all embedded statements are allowed in an interleaved | |
1349 | * construct */ | |
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 | |
1369 | * branch number. */ | |
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); | |
1373 | }; | |
1374 | ||
1375 | } // namespace Ttcn | |
1376 | ||
1377 | #endif // _Ttcn_Statement_HH |